diff --git a/firanka/__init__.py b/firanka/__init__.py
index 2fb25139f1489c1c5f9f939ddc411d187d5c8e75..563f38cda781127c00bd64756e35b54eafe2c350 100644
--- a/firanka/__init__.py
+++ b/firanka/__init__.py
@@ -1 +1 @@
-__version__ = '0.1.6'
+__version__ = '0.1.7rc1'
diff --git a/firanka/series/series.py b/firanka/series.py
similarity index 83%
rename from firanka/series/series.py
rename to firanka/series.py
index dcc777ae37a3a4ef27b0a182b669daf9eb5536fc..b59d5df57f5e3843b02889f335c56139aa9d3d98 100644
--- a/firanka/series/series.py
+++ b/firanka/series.py
@@ -9,6 +9,13 @@ import six
 from firanka.exceptions import NotInDomainError
 from firanka.ranges import Range, REAL_SET, EMPTY_SET
 
+__all__ = [
+    'FunctionSeries',
+    'DiscreteSeries',
+    'ModuloSeries',
+    'Series',
+]
+
 
 class Series(object):
     """
@@ -18,10 +25,11 @@ class Series(object):
     for minimum functionality
     """
 
-    def __init__(self, domain):
+    def __init__(self, domain, comment=u''):
         if not isinstance(domain, Range):
             domain = Range(domain)
         self.domain = domain
+        self.comment = comment
 
     def __getitem__(self, item):
         """
@@ -62,6 +70,14 @@ class Series(object):
         :param fun: callable/1 => 1
         :return: Series instance
         """
+        return AppliedSeries(self, lambda k, v: fun(v))
+
+    def apply_with_indices(self, fun):
+        """
+        Return this series with a function applied to each value
+        :param fun: callable(index: float, value: any) => 1
+        :return: Series instance
+        """
         return AppliedSeries(self, fun)
 
     def discretize(self, points, domain=None):
@@ -101,18 +117,19 @@ class Series(object):
 
 
 class AppliedSeries(Series):
-    def __init__(self, series, applyfun):
-        super(AppliedSeries, self).__init__(series.domain)
+    def __init__(self, series, applyfun, *args, **kwargs):
+        """:type applyfun: callable(float, v) -> any"""
+        super(AppliedSeries, self).__init__(series.domain, *args, **kwargs)
         self.fun = applyfun
         self.series = series
 
     def _get_for(self, item):
-        return self.fun(self.series._get_for(item))
+        return self.fun(item, self.series._get_for(item))
 
 
 class TranslatedSeries(Series):
-    def __init__(self, series, x):
-        super(TranslatedSeries, self).__init__(self.domain.translate(x))
+    def __init__(self, series, x, *args, **kwargs):
+        super(TranslatedSeries, self).__init__(self.domain.translate(x), *args, **kwargs)
         self.series = series
         self.x = x
 
@@ -121,8 +138,8 @@ class TranslatedSeries(Series):
 
 
 class SlicedSeries(Series):
-    def __init__(self, parent, domain):
-        super(SlicedSeries, self).__init__(domain)
+    def __init__(self, parent, domain, *args, **kwargs):
+        super(SlicedSeries, self).__init__(domain, *args, **kwargs)
         self.parent = parent
 
     def _get_for(self, item):
@@ -141,14 +158,14 @@ def _appendif(lst, ptr, v):
 
 class DiscreteSeries(Series):
 
-    def __init__(self, data, domain=None):
+    def __init__(self, data, domain=None, *args, **kwargs):
         if len(data) == 0:
             domain = EMPTY_SET
         elif domain is None:
             domain = Range(data[0][0], data[-1][0], True, True)
 
         self.data = data
-        super(DiscreteSeries, self).__init__(domain)
+        super(DiscreteSeries, self).__init__(domain, *args, **kwargs)
 
         if len(data) > 0:
             if self.domain.start < data[0][0]:
@@ -157,6 +174,9 @@ class DiscreteSeries(Series):
     def apply(self, fun):
         return DiscreteSeries([(k, fun(v)) for k, v in self.data], self.domain)
 
+    def apply_with_indices(self, fun):
+        return DiscreteSeries([(k, fun(k, v)) for k, v in self.data], self.domain)
+
     def _get_for(self, item):
         for k, v in reversed(self.data):
             if k <= item:
@@ -225,7 +245,6 @@ class DiscreteSeries(Series):
 
         return DiscreteSeries(c, new_domain)
 
-
     def compute(self):
         """Simplify self"""
         nd = [self.data[0]]
@@ -239,8 +258,8 @@ class FunctionSeries(Series):
     """
     Series with values defined by a function
     """
-    def __init__(self, fun, domain):
-        super(FunctionSeries, self).__init__(domain)
+    def __init__(self, fun, domain, *args, **kwargs):
+        super(FunctionSeries, self).__init__(domain, *args, **kwargs)
         self.fun = fun
 
     def _get_for(self, item):
@@ -251,9 +270,9 @@ class JoinedSeries(Series):
     """
     Series stemming from performing an operation on two series
     """
-    def __init__(self, ser1, ser2, op):
+    def __init__(self, ser1, ser2, op, *args, **kwargs):
         domain = ser1.domain.intersection(ser2.domain)
-        super(JoinedSeries, self).__init__(domain)
+        super(JoinedSeries, self).__init__(domain, *args, **kwargs)
         self.ser1 = ser1
         self.ser2 = ser2
         self.op = op
@@ -264,13 +283,13 @@ class JoinedSeries(Series):
 
 class ModuloSeries(Series):
 
-    def __init__(self, series):
+    def __init__(self, series, *args, **kwargs):
         """
         Construct a modulo series
         :param series: base series to use
         :raise ValueError: invalid domain length
         """
-        super(ModuloSeries, self).__init__(REAL_SET)
+        super(ModuloSeries, self).__init__(REAL_SET, *args, **kwargs)
 
         self.series = series
         self.period = self.series.domain.length()
diff --git a/firanka/series/__init__.py b/firanka/series/__init__.py
deleted file mode 100644
index 3407ef614f2778c78992bee020fd4f4cbcec5dc6..0000000000000000000000000000000000000000
--- a/firanka/series/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# coding=UTF-8
-from __future__ import print_function, absolute_import, division
-
-from .series import DiscreteSeries, FunctionSeries, ModuloSeries, Series
-
-__all__ = [
-    'FunctionSeries',
-    'DiscreteSeries',
-    'ModuloSeries',
-    'Series',
-]
diff --git a/firanka/timeproviders.py b/firanka/timeproviders.py
new file mode 100644
index 0000000000000000000000000000000000000000..91d18a5bfac04382cb566bb54aa61ef50a14c825
--- /dev/null
+++ b/firanka/timeproviders.py
@@ -0,0 +1,58 @@
+# coding=UTF-8
+from __future__ import print_function, absolute_import, division
+import six
+import logging
+
+
+from .series import Series
+from .ranges import Range
+
+
+class BijectionMapping(object):
+
+    def __init__(self, user2float, float2user):
+        """
+        :param user2float: callable/1 => float, mapping from your time system to floats
+        :param float2user: callable/float => 1, mapping from float to your time systen
+        """
+        self.user2float = user2float
+        self.float2user = float2user
+
+    def to_float(self, user):
+        return self.user2float(user)
+
+    def to_user(self, flt):
+        return self.float2user(flt)
+
+
+class TimeProvidedSeries(Series):
+    """
+    If your time is something else than simple floats, this will help you out
+    """
+    def __init__(self, series, mapping, *args, **kwargs):
+        """
+        :param series: series to overlay
+        """
+        super(TimeProvidedSeries, self).__init__(series.domain, *args, **kwargs)
+        self.mapping = mapping
+        self.series = series
+
+    def _withmap(self, series):
+        return TimeProvidedSeries(series, self.mapping)
+
+    def __getitem__(self, item):
+        if isinstance(item, slice):
+            item = slice(float('-inf') if slice.start is None else self.to_float(slice.start),
+                         float('+inf') if slice.stop is None else self.to_float(slice.stop),)
+
+            return self._withmap(self.series[item])
+        elif isinstance(item, Range):
+            return self._withmap(self.series[item])
+        else:
+            return self.series[self.mapping.to_float(item)]
+
+    def _get_for(self, item):
+        return self.series[self.l2f(item)]
+
+    def join(self, series, fun):
+        return TimeProvidedSeries(self.series.join(series, fun), self.mapping)
diff --git a/tests/test_series/test_range.py b/tests/test_range.py
similarity index 100%
rename from tests/test_series/test_range.py
rename to tests/test_range.py
diff --git a/tests/test_series/test_series.py b/tests/test_series.py
similarity index 94%
rename from tests/test_series/test_series.py
rename to tests/test_series.py
index f83a952e478e8a147f0c1b54ae26f0dd29bac45d..1b45267efa8ac2526203d5eadea89286d8ff9244 100644
--- a/tests/test_series/test_series.py
+++ b/tests/test_series.py
@@ -79,6 +79,9 @@ class TestDiscreteSeries(unittest.TestCase):
         sa = DiscreteSeries([[0, 0], [1, 1], [2, 2]]).apply(lambda x: x+1)
         self.assertEquals(sa.data, [(0,1),(1,2),(2,3)])
 
+        sb = DiscreteSeries([[0, 0], [1, 1], [2, 2]]).apply_with_indices(lambda k,v: k)
+        self.assertEquals(sb.data, [(0,0),(1,1),(2,2)])
+
     def test_eval3(self):
         sa = FunctionSeries(lambda x: x**2, '<-10;10)')
         sb = FunctionSeries(NOOP, '<0;2)')
@@ -127,6 +130,11 @@ class TestFunctionSeries(unittest.TestCase):
 
         self.assertEqual(series.eval_points(PTS), [x*2 for x in PTS])
 
+        PTS = [-1,-2,-3,1,2,3]
+        series = FunctionSeries(NOOP, '<-5;5>').apply_with_indices(lambda k, x: k)
+
+        self.assertEqual(series.eval_points(PTS), [x for x in PTS])
+
     def test_domain_sensitivity(self):
         logs = FunctionSeries(math.log, '(0;5>')
         dirs = DiscreteSeries([(0,1),(1,2),(3,4)], '<0;5>')
diff --git a/tests/test_series/__init__.py b/tests/test_series/__init__.py
deleted file mode 100644
index 1c762b12fd99adc2f7d4e5137c5b872079457510..0000000000000000000000000000000000000000
--- a/tests/test_series/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# coding=UTF-8
-from __future__ import print_function, absolute_import, division
-import six
-import logging
-
-logger = logging.getLogger(__name__)
-
-
diff --git a/tests/test_timeproviders.py b/tests/test_timeproviders.py
new file mode 100644
index 0000000000000000000000000000000000000000..eeb784991781e4f58309bf9e5d535f48893085be
--- /dev/null
+++ b/tests/test_timeproviders.py
@@ -0,0 +1,21 @@
+# coding=UTF-8
+from __future__ import print_function, absolute_import, division
+import six
+import unittest
+
+from firanka.series import DiscreteSeries
+from firanka.timeproviders import TimeProvidedSeries, BijectionMapping
+
+
+class TestTimeproviders(unittest.TestCase):
+
+    def test_base(self):
+        map = BijectionMapping(
+            lambda hhmm: hhmm[0] * 60 + hhmm[1],
+            lambda t: (t // 60, t % 60)
+        )
+
+        ser = DiscreteSeries([(0,17), (60, 20), (120, 18)])
+        ts = TimeProvidedSeries(ser, map)
+
+        self.assertEqual(ts[(2, 0)], 18)