diff --git a/int-multimap.cabal b/int-multimap.cabal
--- a/int-multimap.cabal
+++ b/int-multimap.cabal
@@ -1,7 +1,7 @@
 name:
   int-multimap
 version:
-  0.2
+  0.2.1
 synopsis:
   A data structure that associates each Int key with a set of values
 category:
@@ -47,3 +47,24 @@
     hashable >=1.2 && <2,
     containers >=0.5.10 && <0.5.15,
     unordered-containers >=0.2.8.0 && <0.3
+
+test-suite test
+  type:
+    exitcode-stdio-1.0
+  hs-source-dirs:
+    test
+  main-is:
+    Main.hs
+  default-extensions:
+    Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples
+  default-language:
+    Haskell2010
+  build-depends:
+    int-multimap,
+    base >=4.7 && <5,
+    hashable >=1.2 && <2,
+    containers >=0.5.10 && <0.5.15,
+    unordered-containers >=0.2.8.0 && <0.3,
+    tasty >=1.0.1 && <1.0.2,
+    tasty-hunit >=0.9 && <0.11,
+    tasty-quickcheck >=0.10 && <0.12
diff --git a/library/IntMultimap.hs b/library/IntMultimap.hs
--- a/library/IntMultimap.hs
+++ b/library/IntMultimap.hs
@@ -25,7 +25,8 @@
   keys,
 
   -- * Filter
-  split
+  split,
+  splitLookup
 )
 where
 
@@ -39,6 +40,7 @@
 import Data.Hashable
 import Data.Functor
 import Data.List(length)
+import Data.Maybe
 import Control.Monad
 
 {-|
@@ -64,7 +66,7 @@
   toList = toList
   fromList = fromList
 
-toList :: IntMultiMap b -> [(Int, b)]
+toList :: IntMultiMap a -> [(Int, a)]
 toList (IntMultiMap multiMap) = do
   (key, hashSet) <- A.toList multiMap
   fmap ((,) key) $ B.toList hashSet
@@ -98,7 +100,9 @@
 
 insert :: (Hashable a, Ord a) => Int -> a -> IntMultiMap a -> IntMultiMap a
 insert key value (IntMultiMap intMap) =
-  IntMultiMap $ A.update (\hash -> Just $ B.insert value hash) key intMap
+  IntMultiMap $ A.insertWith (f value) key (B.singleton value) intMap
+    where
+      f v new old = B.insert v old
 
 delete :: (Hashable a, Eq a) => Int {-^ Key -} -> a -> IntMultiMap a -> IntMultiMap a
 delete key value (IntMultiMap intMap) =
@@ -123,3 +127,8 @@
 split key (IntMultiMap intMap) = (IntMultiMap oldMap, IntMultiMap newMap)
   where
     (oldMap, newMap) = A.split key intMap
+
+splitLookup :: Int -> IntMultiMap a -> (IntMultiMap a, Maybe (B.HashSet a), IntMultiMap a)
+splitLookup key (IntMultiMap intMap) = (IntMultiMap oldMap, elemHashSet, IntMultiMap newMap)
+  where
+    (oldMap, elemHashSet, newMap) = A.splitLookup key intMap
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,82 @@
+module Main where
+
+import Prelude hiding (first, second)
+import Control.Arrow
+import Test.Tasty
+import Test.Tasty.Runners
+import Test.Tasty.HUnit
+import Test.Tasty.QuickCheck
+-- import Test.QuickCheck.Instances
+import qualified IntMultimap as A
+import qualified Data.List as B
+import Data.Maybe
+import Data.Foldable as F
+import qualified Data.HashSet as B
+
+main =
+  defaultMain $
+  testGroup "All tests" $
+  [
+    testCase "Member" $ do
+      let
+        list = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
+        multimap = A.fromList list
+      assertEqual "" True $ A.member 3 multimap
+      assertEqual "" False $ A.member 5 multimap
+    ,
+    testCase "Lists" $ do
+      let
+        list = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
+        multimap = A.fromList list
+      assertEqual "" list $ A.toList $ A.fromList list
+      assertEqual "" multimap $ A.fromList $ A.toList multimap
+    ,
+    testCase "Conversions" $ do
+      let
+        list = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
+        multimap = A.fromList list
+      assertEqual "" (map fst list) $ A.keys multimap
+      assertEqual "" (map snd list) $ A.elems multimap
+    ,
+    testCase "Filter" $ do
+      let
+        list = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
+        multimap = A.fromList list
+        (old, maybeElem, new) = A.splitLookup 3 multimap
+      assertEqual "" ((A.toList old), [(3, 'c')] ++ A.toList new) (B.span (\(k,a) -> k < 3) list)
+    ,
+    testCase "Insert and Delete" $ do
+      let
+        list = [(1, 'a'), (2, 'b'), (4, 'd'), (5, 'e')]
+        key = 3
+        el = 'c'
+        list2 = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')]
+      assertEqual "" list2 $ A.toList $ A.insert key el $ A.fromList list
+      assertEqual "" list $ A.toList $ A.delete key el $ A.fromList list2
+    ,
+    testCase "singleton and empty" $ do
+      let
+        list = [(1, 'a')]
+        multimap = A.fromList list
+      assertEqual "" True $ A.null A.empty
+      assertEqual "" list $ A.toList $ A.singleton 1 'a'
+      assertEqual "" (A.toList multimap) $ A.toList $ A.singleton 1 'a'
+    ,
+    testProperty "list to list(Int, String)" $ \ (list :: [(Int, String)]) ->
+    (B.fromList list) === (B.fromList $ A.toList $ A.fromList list)
+    ,
+    testProperty "list to list(Int, Int)" $ \ (list :: [(Int, Int)]) ->
+    (B.fromList list) === (B.fromList $ A.toList $ A.fromList list)
+    ,
+    testProperty "insert and delete" $ \ (list :: [(Int, Char)], key :: Int, value :: Char) ->
+    (B.fromList list) === (B.fromList $ A.toList $ A.delete key value $ A.insert key value $ A.fromList list)
+    ,
+    testProperty "Mapping" $ \ (list :: [(Int, Int)]) ->
+    (B.fromList $ map testFuncL list) === (B.fromList $ A.toList $ A.map testFunc $ A.fromList list)
+  ]
+
+testFunc :: (Show a) => a -> String
+testFunc = show
+
+testFuncL :: (Show a)  => (Int, a) -> (Int, String)
+testFuncL (a, b) = (a, show b)
