diff --git a/Data/SimpleIndex.hs b/Data/SimpleIndex.hs
new file mode 100644
--- /dev/null
+++ b/Data/SimpleIndex.hs
@@ -0,0 +1,412 @@
+{-# LANGUAGE TemplateHaskell, TypeFamilies #-}
+module Data.SimpleIndex
+   (
+  -- * The Data Type to use
+  Indexed
+
+  -- ** Creation functions
+  , create1
+  , create2
+  , create3
+  , create4
+  , create5
+  , create6
+
+  -- * Fill this type class to make your type indexable
+  , SimpleIx(..)
+
+  -- * Insert, Delete, Update and Read
+  , ixInsert
+  , ixDelete
+  , ixUpdate
+  , ixRead1
+  , ixRead2
+  , ixRead3
+  , ixRead4
+  , ixRead5
+  , ixRead6
+  )
+where
+
+import Prelude
+import Data.Foldable
+import qualified Data.Foldable as Fold
+import Data.Sequence (Seq, (|>), (><))
+import qualified Data.Sequence as Seq
+import Data.HashMap.Lazy (HashMap)
+import qualified Data.HashMap.Lazy as HM
+import Data.SafeCopy
+import Data.Hashable
+-- import GHC.Generics
+
+
+-- | define index insert, update and delete functions
+_ixInsertIx f h pos u = HM.insert (f u) pos h
+_ixInsertData u ux baseData constructor = 
+    (pos, constructor newBase)
+    where 
+        -- baseData = base ux
+        newBase = baseData |> u
+        pos = Seq.length baseData
+_ixIt f hix u ux (pos, c) = (pos, c (_ixInsertIx f hix pos u) f)
+_getIx = snd
+_ixInsertData1 u ux c bd hix1 f1 = 
+    _ixIt f1 hix1 u ux $ 
+    _ixInsertData u ux bd c
+_ixInsertData2 u ux c b hix1 hix2 f1 f2 = 
+    _ixIt f2 hix2 u ux $ _ixInsertData1 u ux c b hix1 f1
+_ixInsertData3 u ux c b hix1 hix2 hix3 f1 f2 f3 = 
+    _ixIt f3 hix3 u ux $ _ixInsertData2 u ux c b hix1 hix2 f1 f2
+_ixInsertData4 u ux c b hix1 hix2 hix3 hix4 f1 f2 f3 f4 = 
+    _ixIt f4 hix4 u ux $ _ixInsertData3 u ux c b hix1 hix2 hix3 f1 f2 f3
+_ixInsertData5 u ux c b hix1 hix2 hix3 hix4 hix5 f1 f2 f3 f4 f5 = 
+    _ixIt f5 hix5 u ux $ _ixInsertData4 u ux c b hix1 hix2 hix3 hix4 f1 f2 f3 f4
+_ixInsertData6 u ux c b hix1 hix2 hix3 hix4 hix5 hix6 f1 f2 f3 f4 f5 f6= 
+    _ixIt f6 hix6 u ux $ _ixInsertData5 u ux c b hix1 hix2 hix3 hix4 hix5 f1 f2 f3 f4 f5
+
+_ixUpdateIx getIndex h pos old new =
+    HM.insert (getIndex new) pos $ HM.delete (getIndex old) h
+
+_ixUpdateData ux constructor base hix uid updateF = 
+    fmap genTuple $ HM.lookup uid hix 
+    where 
+        old' pos = Seq.index base pos
+        new' pos = updateF (old' pos)
+        newBase pos = Seq.update pos (new' pos) base
+        genTuple pos = (pos, old' pos, new' pos, constructor (newBase pos))
+
+_ixUp f hix ux (pos, old, new, c) = 
+    (pos, old, new, c (_ixUpdateIx f hix pos old new) f)
+_getUp u t = case t of
+                Nothing -> u
+                Just (_,_,_,f) -> f
+_ixUpdateData1 ux c b hix1 f1 uid f = 
+    fmap (_ixUp f1 hix1 ux) (_ixUpdateData ux c b hix1 uid f)
+_ixUpdateData2 ux c b hix1 hix2 f1 f2 uid f = 
+    fmap (_ixUp f2 hix2 ux) (_ixUpdateData1 ux c b hix1 f1 uid f)
+_ixUpdateData3 ux c b hix1 hix2 hix3 f1 f2 f3 uid f = 
+    fmap (_ixUp f3 hix3 ux) (_ixUpdateData2 ux c b hix1 hix2 f1 f2 uid f)
+_ixUpdateData4 ux c b hix1 hix2 hix3 hix4 f1 f2 f3 f4 uid f = 
+    fmap (_ixUp f4 hix4 ux) (_ixUpdateData3 ux c b hix1 hix2 hix3 f1 f2 f3 uid f)
+_ixUpdateData5 ux c b hix1 hix2 hix3 hix4 hix5 f1 f2 f3 f4 f5 uid f = 
+    fmap (_ixUp f5 hix5 ux) (_ixUpdateData4 ux c b hix1 hix2 hix3 hix4 f1 f2 f3 f4 uid f)
+_ixUpdateData6 ux c b hix1 hix2 hix3 hix4 hix5 hix6 f1 f2 f3 f4 f5 f6 uid f = 
+    fmap (_ixUp f6 hix6 ux) (_ixUpdateData5 ux c b hix1 hix2 hix3 hix4 hix5 f1 f2 f3 f4 f5 uid f)
+
+_ixDeleteIx getIndex h u = HM.delete (getIndex u) h
+_ixDeleteData u ux constructor base = constructor newBase
+    where
+        newBase = _seqDelete u base
+
+_seqDelete :: Eq a => a -> Seq a -> Seq a
+_seqDelete item ss = left >< Seq.drop 1 right
+    where (left, right) = Seq.breakl (== item) ss
+
+_ixDeleteData1 ux c b hix1 f1 u = 
+    (_ixDeleteData u ux c b) (_ixDeleteIx f1 hix1 u) f1
+_ixDeleteData2 ux c b hix1 hix2 f1 f2 u = 
+    (_ixDeleteData1 ux c b hix1 f1 u) (_ixDeleteIx f2 hix2 u) f2
+_ixDeleteData3 ux c b hix1 hix2 hix3 f1 f2 f3 u = 
+    (_ixDeleteData2 ux c b hix1 hix2 f1 f2 u) (_ixDeleteIx f3 hix3 u) f3
+_ixDeleteData4 ux c b hix1 hix2 hix3 hix4 f1 f2 f3 f4 u = 
+    (_ixDeleteData3 ux c b hix1 hix2 hix3 f1 f2 f3 u) (_ixDeleteIx f4 hix4 u) f4
+_ixDeleteData5 ux c b hix1 hix2 hix3 hix4 hix5 f1 f2 f3 f4 f5 u = 
+    (_ixDeleteData4 ux c b hix1 hix2 hix3 hix4 f1 f2 f3 f4 u) (_ixDeleteIx f5 hix5 u) f5
+_ixDeleteData6 ux c b hix1 hix2 hix3 hix4 hix5 hix6 f1 f2 f3 f4 f5 f6 u = 
+    (_ixDeleteData5 ux c b hix1 hix2 hix3 hix4 hix5 f1 f2 f3 f4 f5 u) (_ixDeleteIx f6 hix6 u) f6
+
+data Indexed a i1 i2 i3 i4 i5 i6
+    = -- forall i1. (Eq i1, Hashable i1) =>
+      IxHas1 { has1Base :: Seq a 
+             , has1Ix1 :: (HashMap i1 Int) 
+             , has1Fetch1 :: (a -> i1)
+             }
+    | IxHas2 { has2Base :: Seq a
+             , has2Ix1 :: (HashMap i1 Int)
+             , has2Fetch1 :: (a -> i1)
+             , has2Ix2 :: (HashMap i2 Int)
+             , has2Fetch2 :: (a -> i2)
+             }
+    | IxHas3 { has3Base :: Seq a
+             , has3Ix1 :: (HashMap i1 Int)
+             , has3Fetch1 :: (a -> i1)
+             , has3Ix2 :: (HashMap i2 Int)
+             , has3Fetch2 :: (a -> i2)
+             , has3Ix3 :: (HashMap i3 Int)
+             , has3Fetch3 :: (a -> i3)
+             }
+    | IxHas4 { has4Base :: Seq a
+             , has4Ix1 :: (HashMap i1 Int)
+             , has4Fetch1 :: (a -> i1)
+             , has4Ix2 :: (HashMap i2 Int)
+             , has4Fetch2 :: (a -> i2)
+             , has4Ix3 :: (HashMap i3 Int)
+             , has4Fetch3 :: (a -> i3)
+             , has4Ix4 :: (HashMap i4 Int)
+             , has4Fetch4 :: (a -> i4)
+             }
+    | IxHas5 { has5Base :: Seq a
+             , has5Ix1 :: (HashMap i1 Int)
+             , has5Fetch1 :: (a -> i1)
+             , has5Ix2 :: (HashMap i2 Int)
+             , has5Fetch2 :: (a -> i2)
+             , has5Ix3 :: (HashMap i3 Int)
+             , has5Fetch3 :: (a -> i3)
+             , has5Ix4 :: (HashMap i4 Int)
+             , has5Fetch4 :: (a -> i4)
+             , has5Ix5 :: (HashMap i5 Int)
+             , has5Fetch5 :: (a -> i5)
+             }
+    | IxHas6 { has6Base :: Seq a
+             , has6Ix1 :: (HashMap i1 Int)
+             , has6Fetch1 :: (a -> i1)
+             , has6Ix2 :: (HashMap i2 Int)
+             , has6Fetch2 :: (a -> i2)
+             , has6Ix3 :: (HashMap i3 Int)
+             , has6Fetch3 :: (a -> i3)
+             , has6Ix4 :: (HashMap i4 Int)
+             , has6Fetch4 :: (a -> i4)
+             , has6Ix5 :: (HashMap i5 Int)
+             , has6Fetch5 :: (a -> i5)
+             , has6Ix6 :: (HashMap i6 Int)
+             , has6Fetch6 :: (a -> i6)
+             }
+
+-- | Use this function to create an Indexed data type with only 1 index for your type
+create1 :: (Eq a, Eq i1, Hashable i1) 
+        => (a -> i1) 
+        -- ^ The function that returns the index for the base datatype
+        -> Indexed a i1 () () () () ()
+create1 f = IxHas1 Seq.empty HM.empty f
+-- | Create an Indexed data type with 2 indexes for your type
+-- create2 :: forall a i1 i2 i3 i4 i5 i6. (Eq i1, Eq i2, Eq i3, Eq i4, Eq i5, Eq i6, Hashable i1,
+--          Hashable i2, Hashable i3, Hashable i4, Hashable i5, Hashable i6, SafeCopy a) 
+--        => (a -> i1) 
+--        -- ^ The function that returns the first index for your datatype
+--        -> (a -> i2) 
+--        -- ^ The function that returns the second index for your datatype
+--        -> Indexed a i1 i2 i3 i4 i5 i6
+create2 f1 f2 = IxHas2 Seq.empty HM.empty f1 HM.empty f2
+
+-- | Create an Indexed data type with 3 indexes for your type
+create3 :: (a -> i1) 
+        -- ^ The function that returns the first index for your datatype
+        -> (a -> i2) 
+        -- ^ The function that returns the second index for your datatype
+        -> (a -> i3)
+        -- ^ The function that returns the third index for your datatype
+        -> Indexed a i1 i2 i3 () () ()
+create3 f1 f2 f3 = IxHas3 Seq.empty HM.empty f1 HM.empty f2 HM.empty f3
+
+-- | Create an Indexed data type with 4 indexes for your type
+create4 :: (a -> i1) 
+        -- ^ The function that returns the first index for your datatype
+        -> (a -> i2) 
+        -- ^ The function that returns the second index for your datatype
+        -> (a -> i3) 
+        -- ^ The function that returns the third index for your datatype
+        -> (a -> i4) 
+        -- ^ The function that returns the fourth index for your datatype
+        -> Indexed a i1 i2 i3 i4 () ()
+create4 f1 f2 f3 f4 = IxHas4 Seq.empty HM.empty f1 HM.empty f2 HM.empty f3 
+                             HM.empty f4
+
+-- | Create an Indexed data type with 5 indexes for your type
+create5 :: (a -> i1) 
+        -- ^ The function that returns the first index for your datatype
+        -> (a -> i2) 
+        -- ^ The function that returns the second index for your datatype
+        -> (a -> i3) 
+        -- ^ The function that returns the third index for your datatype
+        -> (a -> i4) 
+        -- ^ The function that returns the fourth index for your datatype
+        -> (a -> i5) 
+        -- ^ The function that returns the fifth index for your datatype
+        -> Indexed a i1 i2 i3 i4 i5 ()
+create5 f1 f2 f3 f4 f5 = IxHas5 Seq.empty HM.empty f1 HM.empty f2 HM.empty f3 
+                                HM.empty f4 HM.empty f5
+
+-- | Create an Indexed data type with 6 indexes for your type
+create6 :: (a -> i1) 
+        -- ^ The function that returns the first index for your datatype
+        -> (a -> i2) 
+        -- ^ The function that returns the second index for your datatype
+        -> (a -> i3) 
+        -- ^ The function that returns the third index for your datatype
+        -> (a -> i4) 
+        -- ^ The function that returns the fourth index for your datatype
+        -> (a -> i5) 
+        -- ^ The function that returns the fifth index for your datatype
+        -> (a -> i6) 
+        -- ^ The function that returns the sixth index for your datatype
+        -> Indexed a i1 i2 i3 i4 i5 i6
+create6 f1 f2 f3 f4 f5 f6 = IxHas6 Seq.empty HM.empty f1 HM.empty f2 
+                            HM.empty f3 HM.empty f4 HM.empty f5 HM.empty f6
+
+-- http://lpaste.net/91233
+class SimpleIx a where
+    -- | Creates your indexed dataype, you can use "create1" .. "create6" functions to help you here
+    type I1 a
+    type I2 a
+    type I3 a
+    type I4 a
+    type I5 a
+    type I6 a
+    create :: Indexed a (I1 a) (I2 a) (I3 a) (I4 a) (I5 a) (I6 a)
+               
+-- | Inserts a new value into the Indexed data type and updates all the information
+-- in the indexes
+ixInsert :: 
+    (Eq k4, Eq k3, Eq k2, Eq k1, Eq k, Eq i6, Hashable k4,
+      Hashable k3, Hashable k2, Hashable k1, Hashable k, Hashable i6) =>
+           Indexed a k4 k3 k2 k1 k i6 -> a -> Indexed a k4 k3 k2 k1 k i6
+ixInsert ux u = _getIx $ 
+    case ux of
+        (IxHas1 b h1 f1) -> _ixInsertData1 u ux IxHas1 b h1 f1
+        (IxHas2 b h1 f1 h2 f2) -> 
+            _ixInsertData2 u ux IxHas2 b h1 h2 f1 f2
+        (IxHas3 b h1 f1 h2 f2 h3 f3) -> 
+            _ixInsertData3 u ux IxHas3 b h1 h2 h3 f1 f2 f3
+        (IxHas4 b h1 f1 h2 f2 h3 f3 h4 f4) -> 
+            _ixInsertData4 u ux IxHas4 b h1 h2 h3 h4 f1 f2 f3 f4
+        (IxHas5 b h1 f1 h2 f2 h3 f3 h4 f4 h5 f5) -> 
+            _ixInsertData5 u ux IxHas5 b h1 h2 h3 h4 h5 f1 f2 f3 f4 f5
+        (IxHas6 b h1 f1 h2 f2 h3 f3 h4 f4 h5 f5 h6 f6) -> 
+            _ixInsertData6 u ux IxHas6 b h1 h2 h3 h4 h5 h6 f1 f2 f3 f4 f5 f6
+
+-- | Deletes a value from the Indexed data type and updates all the information
+-- in the indexes
+ixDelete :: (Eq a, Eq k, Eq i2, Eq i3, Eq i4, Eq i5, Eq i6, Hashable k,
+      Hashable i2, Hashable i3, Hashable i4, Hashable i5, Hashable i6) =>
+           Indexed a k i2 i3 i4 i5 i6 -> a -> Indexed a k i2 i3 i4 i5 i6
+ixDelete ux u = 
+    case ux of
+        (IxHas1 b h1 f1) -> _ixDeleteData1 ux IxHas1 b h1 f1 u
+        (IxHas2 b h1 f1 h2 f2) -> 
+            _ixDeleteData2 ux IxHas2 b h1 h2 f1 f2 u
+        (IxHas3 b h1 f1 h2 f2 h3 f3) -> 
+            _ixDeleteData3 ux IxHas3 b h1 h2 h3 f1 f2 f3 u
+        (IxHas4 b h1 f1 h2 f2 h3 f3 h4 f4) -> 
+            _ixDeleteData4 ux IxHas4 b h1 h2 h3 h4 f1 f2 f3 f4 u
+        (IxHas5 b h1 f1 h2 f2 h3 f3 h4 f4 h5 f5) -> 
+            _ixDeleteData5 ux IxHas5 b h1 h2 h3 h4 h5 f1 f2 f3 f4 f5 u
+        (IxHas6 b h1 f1 h2 f2 h3 f3 h4 f4 h5 f5 h6 f6) -> 
+            _ixDeleteData6 ux IxHas6 b h1 h2 h3 h4 h5 h6 f1 f2 f3 f4 f5 f6 u
+
+
+-- | Updates a value in the Indexed data type and all the information
+-- in the indexes
+ixUpdate :: (Eq k, Eq i2, Eq i3, Eq i4, Eq i5, Eq i6, Hashable k,
+      Hashable i2, Hashable i3, Hashable i4, Hashable i5, Hashable i6) =>
+           Indexed a k i2 i3 i4 i5 i6
+                -> k -> (a -> a) -> Maybe (Int, a, a, Indexed a k i2 i3 i4 i5 i6)
+ixUpdate ux uid f = 
+    case ux of
+        (IxHas1 b h1 f1) -> _ixUpdateData1 ux IxHas1 b h1 f1 uid f
+        (IxHas2 b h1 f1 h2 f2) -> 
+            _ixUpdateData2 ux IxHas2 b h1 h2 f1 f2 uid f
+        (IxHas3 b h1 f1 h2 f2 h3 f3) -> 
+            _ixUpdateData3 ux IxHas3 b h1 h2 h3 f1 f2 f3 uid f
+        (IxHas4 b h1 f1 h2 f2 h3 f3 h4 f4) -> 
+            _ixUpdateData4 ux IxHas4 b h1 h2 h3 h4 f1 f2 f3 f4 uid f
+        (IxHas5 b h1 f1 h2 f2 h3 f3 h4 f4 h5 f5) -> 
+            _ixUpdateData5 ux IxHas5 b h1 h2 h3 h4 h5 f1 f2 f3 f4 f5 uid f
+        (IxHas6 b h1 f1 h2 f2 h3 f3 h4 f4 h5 f5 h6 f6) -> 
+            _ixUpdateData6 ux IxHas6 b h1 h2 h3 h4 h5 h6 f1 f2 f3 f4 f5 f6 uid f
+
+_read :: (Eq k, Hashable k) 
+      => (Indexed b t1 t2 t3 t4 t5 t6 -> Maybe (HashMap k Int))
+      -> k -> Indexed b t1 t2 t3 t4 t5 t6 -> Maybe b
+_read f b ux = do
+    ixHashMap <- f ux
+    index     <- HM.lookup b ixHashMap
+    return $ Seq.index (_ixData ux) index
+
+-- | Reads your datatype from the Indexed data by looking up a first index value
+ixRead1 :: (Eq b, Hashable b) => b -> Indexed a b t2 t3 t4 t5 t6 -> Maybe a
+ixRead1 = _read _getIx1
+-- | Reads your datatype from the Indexed data by looking up a value on the second index
+ixRead2 :: (Eq b, Hashable b) => b -> Indexed a t1 b t3 t4 t5 t6 -> Maybe a
+ixRead2 = _read _getIx2
+-- | Reads your datatype from the Indexed data by looking up a value on the third index
+ixRead3 :: (Eq b, Hashable b) => b -> Indexed a t1 t2 b t4 t5 t6 -> Maybe a
+ixRead3 = _read _getIx3
+-- | Reads your datatype from the Indexed data by looking up a value on the fourth index
+ixRead4 :: (Eq b, Hashable b) => b -> Indexed a t1 t2 t3 b t5 t6 -> Maybe a
+ixRead4 = _read _getIx4
+-- | Reads your datatype from the Indexed data by looking up a value on the fifth index
+ixRead5 :: (Eq b, Hashable b) => b -> Indexed a t1 t2 t3 t4 b t6 -> Maybe a
+ixRead5 = _read _getIx5
+-- | Reads your datatype from the Indexed data by looking up a value on the sixth index
+ixRead6 :: (Eq b, Hashable b) => b -> Indexed a t1 t2 t3 t4 t5 b -> Maybe a
+ixRead6 = _read _getIx6
+
+_ixData :: Indexed a t1 t2 t3 t4 t5 t6 -> Seq a
+_ixData ux = 
+    case ux of
+        (IxHas1 b _ _) -> b
+        (IxHas2 b _ _ _ _) -> b
+        (IxHas3 b _ _ _ _ _ _) -> b
+        (IxHas4 b _ _ _ _ _ _ _ _) -> b
+        (IxHas5 b _ _ _ _ _ _ _ _ _ _) -> b
+        (IxHas6 b _ _ _ _ _ _ _ _ _ _ _ _) -> b
+
+_getIx1 :: Indexed a b t2 t3 t4 t5 t6 -> Maybe (HashMap b Int)
+_getIx1 ux = 
+    case ux of
+        (IxHas1 _ i _) -> Just i
+        (IxHas2 _ i _ _ _) -> Just i
+        (IxHas3 _ i _ _ _ _ _) -> Just i
+        (IxHas4 _ i _ _ _ _ _ _ _) -> Just i
+        (IxHas5 _ i _ _ _ _ _ _ _ _ _) -> Just i
+        (IxHas6 _ i _ _ _ _ _ _ _ _ _ _ _) -> Just i
+_getIx2 :: Indexed a t1 b t3 t4 t5 t6 -> Maybe (HashMap b Int)
+_getIx2 ux = 
+    case ux of
+        (IxHas2 _ _ _ i _) -> Just i
+        (IxHas3 _ _ _ i _ _ _) -> Just i
+        (IxHas4 _ _ _ i _ _ _ _ _) -> Just i
+        (IxHas5 _ _ _ i _ _ _ _ _ _ _) -> Just i
+        (IxHas6 _ _ _ i _ _ _ _ _ _ _ _ _) -> Just i
+        _ -> Nothing
+_getIx3 :: Indexed a t1 t2 b t4 t5 t6 -> Maybe (HashMap b Int)
+_getIx3 ux = 
+    case ux of
+        (IxHas3 _ _ _ _ _ i _) -> Just i
+        (IxHas4 _ _ _ _ _ i _ _ _) -> Just i
+        (IxHas5 _ _ _ _ _ i _ _ _ _ _) -> Just i
+        (IxHas6 _ _ _ _ _ i _ _ _ _ _ _ _) -> Just i
+        _ -> Nothing
+_getIx4 :: Indexed a t1 t2 t3 b t5 t6 -> Maybe (HashMap b Int)
+_getIx4 ux = 
+    case ux of
+        (IxHas4 _ _ _ _ _ _ _ i _) -> Just i
+        (IxHas5 _ _ _ _ _ _ _ i _ _ _) -> Just i
+        (IxHas6 _ _ _ _ _ _ _ i _ _ _ _ _) -> Just i
+        _ -> Nothing
+_getIx5 :: Indexed a t1 t2 t3 t4 b t6 -> Maybe (HashMap b Int)
+_getIx5 ux = 
+    case ux of
+        (IxHas5 _ _ _ _ _ _ _ _ _ i _) -> Just i
+        (IxHas6 _ _ _ _ _ _ _ _ _ i _ _ _) -> Just i
+        _ -> Nothing
+_getIx6 :: Indexed a t1 t2 t3 t4 t5 b -> Maybe (HashMap b Int)
+_getIx6 ux = 
+    case ux of
+        (IxHas6 _ _ _ _ _ _ _ _ _ _ _ i _) -> Just i
+        _ -> Nothing
+
+instance (Eq a, Eq t1, Eq t2, Eq t3, Eq t4, Eq t5, Eq t6, Hashable t1,
+          Hashable t2, Hashable t3, Hashable t4, Hashable t5, Hashable t6,
+          t1 ~ I1 a, t2 ~ I2 a, t3 ~ I3 a, t4 ~ I4 a, t5 ~ I5 a, t6 ~ I6 a,
+          SafeCopy a, SimpleIx a) => SafeCopy (Indexed a t1 t2 t3 t4 t5 t6) where
+    version = 0
+    putCopy ux = contain $ safePut $ _ixData ux
+    getCopy = contain $ fmap withData safeGet
+        where
+            withData :: 
+                (Eq a, Eq t1, Eq t2, Eq t3, Eq t4, Eq t5, Eq t6, Hashable t1,
+                 Hashable t2, Hashable t3, Hashable t4, Hashable t5, Hashable t6,
+                 t1 ~ I1 a, t2 ~ I2 a, t3 ~ I3 a, t4 ~ I4 a, t5 ~ I5 a, t6 ~ I6 a,
+                 SafeCopy a, SimpleIx a) => Seq a -> Indexed a t1 t2 t3 t4 t5 t6
+            withData seq = Fold.foldl ixInsert create seq
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2013, Hugo Gomes
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Hugo Gomes nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/simple-index.cabal b/simple-index.cabal
new file mode 100644
--- /dev/null
+++ b/simple-index.cabal
@@ -0,0 +1,17 @@
+name:                simple-index
+version:             0.1.0.0
+synopsis:            Allows simple indexation on any data type
+-- description:         
+license:             BSD3
+license-file:        LICENSE
+author:              Hugo Gomes
+maintainer:          mr.hugo.gomes@gmail.com
+-- copyright:           
+category:            Data
+build-type:          Simple
+cabal-version:       >=1.8
+
+library
+  exposed-modules:     Data.SimpleIndex
+  -- other-modules:       
+  build-depends:       base ==4.6.*, containers ==0.5.*, unordered-containers ==0.2.*, safecopy ==0.8.*, hashable ==1.2.*
