diff --git a/Data/List/Unique.hs b/Data/List/Unique.hs
--- a/Data/List/Unique.hs
+++ b/Data/List/Unique.hs
@@ -1,7 +1,7 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.List.Unique
--- Copyright   :  (c) Volodymyr Yaschenko
+-- Copyright   :  (c) Volodymyr Yashchenko
 -- License     :  BSD3
 --
 -- Maintainer  :  ualinuxcn@gmail.com
diff --git a/Data/List/UniqueStrict.hs b/Data/List/UniqueStrict.hs
--- a/Data/List/UniqueStrict.hs
+++ b/Data/List/UniqueStrict.hs
@@ -1,7 +1,7 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.List.UniqueStrict
--- Copyright   :  (c) Volodymyr Yaschenko
+-- Copyright   :  (c) Volodymyr Yashchenko
 -- License     :  BSD3
 --
 -- Maintainer  :  ualinuxcn@gmail.com
@@ -13,24 +13,56 @@
 -- So it's much faster and it uses less memory.
 
 module Data.List.UniqueStrict
-        (
-          repeated
+        ( sortUniq
+        , isUnique
+        , isRepeated
+        , repeated
         , repeatedBy
         , unique
+        , allUnique
         , count
         , count_ )
         where
 
 import qualified Data.Map.Strict    as MS (Map, filter, fromListWith, keys,
-                                           toList)
+                                           toList, lookup, map, foldr)
 
 import qualified Data.IntMap.Strict as IM (fromListWith, toList)
 
-import qualified Data.List          as L (sort)
+import qualified Data.Set           as DS (fromList, toList)
 
+
 countMap :: Ord a => [a] -> MS.Map a Int
 countMap = MS.fromListWith (+) . flip zip (repeat 1)
 
+-- | 'isUnique' function is to check whether the given element is unique in the list or not.
+--
+-- It returns Nothing when the element does not present in the list. Examples:
+--
+-- > isUnique 'f' "foo bar" == Just True
+-- > isUnique 'o' "foo bar" == Just False
+-- > isUnique '!' "foo bar" == Nothing
+--
+-- Since 0.4.7.2
+--
+
+isUnique :: Ord a => a -> [a] -> Maybe Bool
+isUnique x = fmap (== 1) . MS.lookup x . countMap
+
+-- | 'isRepeated' is a reverse function to 'isUnique'
+--
+-- Since 0.4.5
+
+isRepeated :: Ord a => a -> [a] -> Maybe Bool
+isRepeated x = fmap not . isUnique x
+
+-- | 'sortUniq' sorts the list and removes the duplicates of elements. Example:
+--
+-- > sortUniq "foo bar" == " abfor"
+
+sortUniq :: Ord a => [a] -> [a]
+sortUniq = DS.toList . DS.fromList
+
 -- | The 'repeatedBy' function behaves just like repeated, except it uses a user-supplied equality predicate.
 --
 -- > repeatedBy (>2) "This is the test line" == " eist"
@@ -53,6 +85,16 @@
 unique :: Ord a => [a] -> [a]
 unique = repeatedBy (==1)
 
+-- | 'allUnique' checks whether all elements of the list are unique
+--
+-- > allUnique "foo bar" == False
+-- > allUnique ['a'..'z'] == True
+-- > allUnique [] == True (!)
+-- Since 0.4.7.2
+
+allUnique :: Ord a => [a] -> Bool
+allUnique = MS.foldr (&&) True . MS.map (==1) . countMap
+
 -- | 'count' of each element in the list, it sorts by keys (elements). Example:
 --
 -- > count "foo bar" == [(' ',1),('a',1),('b',1),('f',1),('o',2),('r',1)]
@@ -67,4 +109,4 @@
 count_ :: Ord a => [a] -> [(a, Int)]
 count_ = fromIntMap . toIntMap . MS.toList . countMap
     where toIntMap = IM.fromListWith (++) . map (\(x,y) -> (y,[x]))
-          fromIntMap = concatMap (\(x,y) -> L.sort . zip y $ repeat x) . IM.toList
+          fromIntMap = concatMap (\(x,y) -> sortUniq . zip y $ repeat x) . IM.toList
diff --git a/Data/List/UniqueUnsorted.hs b/Data/List/UniqueUnsorted.hs
--- a/Data/List/UniqueUnsorted.hs
+++ b/Data/List/UniqueUnsorted.hs
@@ -1,7 +1,7 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.List.UniqueUnsorted
--- Copyright   :  (c) Volodymyr Yaschenko
+-- Copyright   :  (c) Volodymyr Yashchenko
 -- License     :  BSD3
 --
 -- Maintainer  :  ualinuxcn@gmail.com
@@ -15,9 +15,13 @@
 -- This implementation is good for ByteStrings.
 
 module Data.List.UniqueUnsorted
-        ( repeated
+        ( isUnique
+        , isRepeated
+        , removeDuplicates
+        , repeated
         , repeatedBy
         , unique
+        , allUnique
         , count
         , count_
         )
@@ -25,14 +29,44 @@
 
 import           Data.Hashable
 import qualified Data.HashMap.Strict as HS (HashMap, filter, fromListWith, keys,
-                                            toList)
+                                            toList, lookup, map, foldr)
 
+import qualified Data.HashSet        as DHS (toList, fromList)
+
 import qualified Data.IntMap.Strict  as IM (fromListWith, toList)
 
 
 countMap :: (Hashable a, Eq a) => [a] -> HS.HashMap a Int
 countMap = HS.fromListWith (+) . flip zip (repeat 1)
 
+-- | 'isUnique' function is to check whether the given element is unique in the list or not.
+--
+-- It returns Nothing when the element does not present in the list. Examples:
+--
+-- > isUnique 'f' "foo bar" == Just True
+-- > isUnique 'o' "foo bar" == Just False
+-- > isUnique '!' "foo bar" == Nothing
+--
+-- Since 0.4.7.2
+--
+
+isUnique :: (Hashable a, Eq a) => a -> [a] -> Maybe Bool
+isUnique x = fmap (== 1) . HS.lookup x . countMap
+
+-- | 'isRepeated' is a reverse function to 'isUnique'
+--
+-- Since 0.4.7.2
+
+isRepeated :: (Hashable a, Eq a) => a -> [a] -> Maybe Bool
+isRepeated x = fmap not . isUnique x
+
+-- | 'removeDuplicates' removes the duplicates of elements. Example:
+--
+-- > removeDuplicates "foo bar" == " abrfo"
+
+removeDuplicates :: (Hashable a, Eq a) => [a] -> [a]
+removeDuplicates = DHS.toList . DHS.fromList
+
 -- | The 'repeatedBy' function behaves just like 'repeated', except it uses a user-supplied equality predicate.
 --
 -- > repeatedBy (>2) "This is the test line" == " stei"
@@ -53,6 +87,17 @@
 
 unique :: (Hashable a, Eq a) => [a] -> [a]
 unique = repeatedBy (==1)
+
+
+-- | 'allUnique' checks whether all elements of the list are unique
+--
+-- > allUnique "foo bar" == False
+-- > allUnique ['a'..'z'] == True
+-- > allUnique [] == True (!)
+-- Since 0.4.7.2
+
+allUnique :: (Hashable a, Eq a) => [a] -> Bool
+allUnique = HS.foldr (&&) True . HS.map (==1) . countMap
 
 -- | 'count' of each element in the list. Example:
 --
diff --git a/Unique.cabal b/Unique.cabal
--- a/Unique.cabal
+++ b/Unique.cabal
@@ -1,51 +1,61 @@
 name:                Unique
 
-version:             0.4.7.1
+version:             0.4.7.2
 
 synopsis:            It provides the functionality like unix "uniq" utility
 description:         Library provides the functions to find unique and duplicate elements in the list
 license:             BSD3
 license-file:        LICENSE
-author:              Volodymyr Yaschenko
+author:              Volodymyr Yashchenko
 maintainer:          ualinuxcn@gmail.com
 category:            Data
 build-type:          Simple
 cabal-version:       >=1.10
 
 source-repository head
-   type:             darcs
-   location:         http://hub.darcs.net/kapral/Unique/
+   type:             git
+   location:         https://github.com/kapralVV/Unique.git
 
 library
   exposed-modules:      Data.List.Unique,
                         Data.List.UniqueStrict,
                         Data.List.UniqueUnsorted
 
-  build-depends:         base >=4.0 && < 5
-                       , extra
-                       , containers
-                       , hashable
-                       , unordered-containers
+  build-depends:         base                 >= 4.0 && < 4.11
+                       , containers           >= 0.5.10 && < 0.6
+                       , extra                >= 1.6.2 && < 1.7
+                       , hashable             >= 1.2.6 && < 1.3
+                       , unordered-containers >= 0.2.8 && < 0.3
+
   default-language:    Haskell2010
-  ghc-options:         -Wall -O2
+  ghc-options:         -Wall
 
 
 Test-Suite HspecTest
   type:                exitcode-stdio-1.0
   hs-source-dirs:      tests
   main-is:             Main.hs
-  other-modules:       Complex
-                     , IsUnique
-                     , RepeatedBy
-                     , SortUniq
-                     , AllUnique
 
-  build-depends:       base >=4.0 && < 5
+  other-modules:       Unique.Complex
+                     , Unique.IsUnique
+                     , Unique.RepeatedBy
+                     , Unique.SortUniq
+                     , Unique.AllUnique
+                     , UniqueStrict.IsUnique
+                     , UniqueStrict.RepeatedBy
+                     , UniqueStrict.SortUniq
+                     , UniqueStrict.AllUnique
+                     , UniqueUnsorted.IsUnique
+                     , UniqueUnsorted.RemoveDuplicates
+                     , UniqueUnsorted.RepeatedBy
+                     , UniqueUnsorted.AllUnique
+                     
+
+  build-depends:       base          >= 4.0 && < 4.11
                      , hspec
-                     , containers
+                     , containers    >= 0.5.10 && < 0.6
                      , QuickCheck
                      , Unique
 
   default-language:    Haskell2010
-  ghc-options:        -Wall -O2
-                     
+  ghc-options:        -Wall
diff --git a/tests/AllUnique.hs b/tests/AllUnique.hs
deleted file mode 100644
--- a/tests/AllUnique.hs
+++ /dev/null
@@ -1,33 +0,0 @@
-module AllUnique where
-
-import Test.Hspec
-import Test.QuickCheck
-import Control.Exception (evaluate)
-import Data.List (nub)
-
-import Data.List.Unique
-
-
-allUnique' :: Eq a => [a] -> Bool
-allUnique' ls = (nub ls) == ls
-
-allUniqueTests :: SpecWith ()
-allUniqueTests =
-  describe "Data.List.Unique.allUnique" $ do
-  it "allUnique: returns True with empty list" $ do
-    allUnique "" `shouldBe` True
-
-  it "allUnique: returns False when some element is not unique" $ do
-    allUnique "foo bar" `shouldBe` False
-
-  it "allUnique: returns True when list does not have duplicates" $ do
-    allUnique ([1..1000] :: [Int]) `shouldBe` True
-
-  it "allUnique: fails if list consist of duplicate elements and 'undefined' after them" $ do
-    evaluate (allUnique ['a', 'a', undefined] )
-      `shouldThrow`
-      errorCall "Prelude.undefined"
-
-  it "allUnique: Test the function using slower analog and random data" $
-    property $
-    \ xs -> (allUnique' (xs :: String)) == (allUnique xs)
diff --git a/tests/Complex.hs b/tests/Complex.hs
deleted file mode 100644
--- a/tests/Complex.hs
+++ /dev/null
@@ -1,26 +0,0 @@
-module Complex where
-
-import Test.Hspec
-import Test.QuickCheck
-
-import Data.List.Unique
-import Data.List (sort)
-
-
-triplet :: (a -> b) -> (a, a, a) -> (b, b, b)
-triplet f (x, y, z) = (f x, f y, f z)
-
-complexTests :: SpecWith ()
-complexTests =
-  describe "Data.List.Unique.complex" $ do
-  
-  it "complex: should return ([],[],[]) with empty list" $ do
-    complex ( [] :: [Int] ) `shouldBe` ([],[],[])
-
-  it "complex: simple test" $ do
-    complex "This is the test line" `shouldBe` ("This teln","is hte","Tln")
-
-  it "complex: returns the same result as `sortUniq`, `repeated`, `unique` but not sorted" $
-    property $
-    \ xs -> triplet sort ( complex (xs :: String) )
-            == (sortUniq xs, repeated xs, unique xs)
diff --git a/tests/IsUnique.hs b/tests/IsUnique.hs
deleted file mode 100644
--- a/tests/IsUnique.hs
+++ /dev/null
@@ -1,70 +0,0 @@
-module IsUnique where
-
-import Test.Hspec
-import Test.QuickCheck
-import Control.Exception (evaluate)
-import Data.Maybe (isJust, isNothing)
-
-import Data.List.Unique
-
-isUniqueTests :: SpecWith ()
-isUniqueTests =
-  describe "Data.List.Unique.isUnique" $ do
-  it "isUnique should return Nothing with empty list" $ do
-    isUnique (1 :: Int) [] 
-    `shouldBe`
-      Nothing
-
-  it "isUnique should return Nothing with empty list (quickCheck)" $
-    property $
-    \x -> isNothing $ isUnique (x :: Char) []
-
-  it "isUnique, returns (Just True) when element is unique" $ do
-    isUnique 'a' "foo bar"  `shouldBe` Just True
-
-  it "isUnique , returns (Just False) when list has duplicate of element" $ do
-    isUnique 'o' "foo bar" `shouldBe` Just False
-
-  it "isUnique is a lazy function, 'undefined test'" $ do
-    isUnique 'g' ['g','a','g', undefined ]
-    `shouldBe`
-      Just False
-
-  it "isUnique is a lazy function, 'undefined test'. Generates exeption" $ do
-    evaluate (isUnique 't' ['t', 'd', undefined] )
-    `shouldThrow`
-      errorCall "Prelude.undefined"
-
-  it "isRepeated is a lazy function too, 'undefined test'" $ do
-    isRepeated 'g' ['g','a','g', undefined ]
-    `shouldBe`
-      Just True
-
-  it "isRepeated is reverse function to isUnique" $ do
-    property $
-      \ x xs
-      -> isUnique (x :: Int) xs == fmap not (isRepeated x xs)
-
-  it "isUnique should return (Just ANY) when element is exist in the list" $
-    property $
-    \ ( NonEmpty ls@(x:_) )
-    -> isJust (isUnique (x :: Char) ls)
-
-  context "isUnique should return (Just False) when at least two elements are exist in the list" $
-    it "- It checks laziness as well" $
-      property $
-      \ ( NonEmpty ls@(x:_) )
-      ->  isJust $ isUnique (x :: Char) (ls ++ [x, undefined])
-
-  it "isUnique should return Nothing when element is absent in the list" $
-    property $
-    \ x xs
-    -> notElem x xs
-       ==> isNothing (isUnique (x :: Char) xs)
-      
-  it "isUnique and isRepeated should return Nothing when element is absent in the list" $
-    property $
-    \ x xs
-    -> notElem x xs
-       ==> isNothing (isUnique (x :: Char) xs)
-       &&  isNothing (isRepeated x xs)
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -1,14 +1,34 @@
-import IsUnique
-import SortUniq
-import RepeatedBy
-import Complex
-import AllUnique
+import qualified Unique.IsUnique as U
+import qualified Unique.SortUniq as U
+import qualified Unique.RepeatedBy as U
+import qualified Unique.Complex as U
+import qualified Unique.AllUnique as U
+
+import qualified UniqueStrict.IsUnique as US
+import qualified UniqueStrict.SortUniq as US
+import qualified UniqueStrict.RepeatedBy as US
+import qualified UniqueStrict.AllUnique as US
+
+import qualified UniqueUnsorted.IsUnique as UA
+import qualified UniqueUnsorted.RemoveDuplicates as UA
+import qualified UniqueUnsorted.RepeatedBy as UA
+import qualified UniqueUnsorted.AllUnique as UA
+
 import Test.Hspec
 
 main :: IO ()
-main = mapM_ hspec [isUniqueTests
-                   , sortUniqTests
-                   , repeatedByTests
-                   , complexTests
-                   , allUniqueTests
+main = mapM_ hspec [ U.isUniqueTests
+                   , U.sortUniqTests
+                   , U.repeatedByTests
+                   , U.complexTests
+                   , U.allUniqueTests
+                   , US.isUniqueTests
+                   , US.sortUniqTests
+                   , US.repeatedByTests
+                   , US.allUniqueTests
+                   , UA.isUniqueTests
+                   , UA.removeDuplicatesTests
+                   , UA.repeatedByTests
+                   , UA.allUniqueTests
                    ]
+
diff --git a/tests/RepeatedBy.hs b/tests/RepeatedBy.hs
deleted file mode 100644
--- a/tests/RepeatedBy.hs
+++ /dev/null
@@ -1,61 +0,0 @@
-module RepeatedBy where
-
-import Test.Hspec
-import Test.QuickCheck
-
-import Data.List.Unique
-import Data.List (sort, group)
-
-
-repeatedByTests :: SpecWith ()
-repeatedByTests =
-  describe "Data.List.Unique.repeatedBy,repeated,unique" $ do
-  
-  it "repeatedBy: should return [] with empty list" $ do
-    repeatedBy (>100) ( [] :: [Int] ) `shouldBe` []
-
-  it "repeatedBy: simple test" $ do
-    repeatedBy (>2) "This is the test line" `shouldBe` " eist"
-
-  it "repeatedBy: returns [] when predicate (=< negative) " $
-    property $
-    \x xs -> x < 0
-             ==> null ( repeatedBy (<= x) (xs :: String) )
-
-  it "repeatedBy: removes the duplicated elements like `sortUniq` function when predicate (>= negative)" $
-     property $
-     \ x xs -> x < 0
-               ==> repeatedBy (>= x) (xs :: String) == sortUniq xs
-
-  it "repeatedBy: returns [] when preficate (== 0)" $
-     property $
-     \ xs -> null ( repeatedBy (== 0) (xs :: [Int]) )
-
-  it "repeatedBy: returns sorted result" $
-     property $
-     \x xs ->  x > 0
-              ==> repeatedBy (> x) (xs :: String) == sort (repeatedBy (> x) xs)
-
-  it "repeatedBy: resulted elements should occur only once" $
-    property $
-    \ x xs -> x > 0
-              ==> all (==1) . map length . group $ repeatedBy (> x) ( xs :: String )
-
-  it "unique: simple test" $ do
-    unique  "foo bar" `shouldBe` " abfr"
-
-  it "repeated: simple test" $ do
-    repeated  "foo bar" `shouldBe` "o"
-
-  it "unique: multiple execution should return the same result" $
-    property $
-    \ xs -> unique (xs :: String) == unique (unique xs)
-
-  it "repeated: multiple execution should return []" $
-    property $
-    \ xs -> null (repeated (repeated (xs :: String) ))
-
-  it "repeated && unique: should return different result on the same non empty list" $
-    property $
-    \ xs -> not (null xs)
-            ==> repeated (xs :: String) /= unique xs
diff --git a/tests/SortUniq.hs b/tests/SortUniq.hs
deleted file mode 100644
--- a/tests/SortUniq.hs
+++ /dev/null
@@ -1,44 +0,0 @@
-module SortUniq where
-
-import Test.Hspec
-import Test.QuickCheck
-
-import Data.List.Unique
-import Data.List (sort, group)
-import Data.Set (fromList, toList)
-
-
-sortUniqTests :: SpecWith ()
-sortUniqTests =
-  describe "Data.List.Unique.sortUniq" $ do
-  
-  it "sortUniq: should return [] with empty list" $ do
-    sortUniq ( [] :: [Int] ) `shouldBe` []
-
-  it "sortUniq: simple test" $ do
-    sortUniq "foo bar" `shouldBe` " abfor"
-
-  it "sortUniq: multiple execution should return the same result" $
-    property $
-    \ xs -> sortUniq (sortUniq ( xs :: String) ) == sortUniq xs
-
-  it "sortUniq: the result has to be sorted" $
-    property $
-    \ xs -> sortUniq ( xs :: [Int] ) == sort (sortUniq xs)
-
-  it "sortUniq: elements should occur only once" $
-    property $
-    \ ( NonEmpty ls@(x:_) ) -> isUnique (x :: Float) (sortUniq ls) == Just True
-
-  it "sortUniq: elements should occur only once #2" $
-    property $
-    \ xs -> all (==1) . map length . group $ sortUniq ( xs :: [Integer] )
-
-  it "sortUniq: check if it's correct by slow analog function" $
-    property $
-    \ xs -> ( map head . group . sort $ (xs :: String) )
-            == sortUniq xs
-
-  it "sortUniq: check if it's correct by the Faster analog function :)" $
-    property $
-    \ xs -> sortUniq ( xs :: String ) == toList (fromList xs)
diff --git a/tests/Unique/AllUnique.hs b/tests/Unique/AllUnique.hs
new file mode 100644
--- /dev/null
+++ b/tests/Unique/AllUnique.hs
@@ -0,0 +1,33 @@
+module Unique.AllUnique where
+
+import Test.Hspec
+import Test.QuickCheck
+import Control.Exception (evaluate)
+import Data.List (nub)
+
+import Data.List.Unique
+
+
+allUnique' :: Eq a => [a] -> Bool
+allUnique' ls = (nub ls) == ls
+
+allUniqueTests :: SpecWith ()
+allUniqueTests =
+  describe "Data.List.Unique.allUnique" $ do
+  it "allUnique: returns True with empty list" $ do
+    allUnique "" `shouldBe` True
+
+  it "allUnique: returns False when some element is not unique" $ do
+    allUnique "foo bar" `shouldBe` False
+
+  it "allUnique: returns True when list does not have duplicates" $ do
+    allUnique ([1..1000] :: [Int]) `shouldBe` True
+
+  it "allUnique: fails if list consist of duplicate elements and 'undefined' after them" $ do
+    evaluate (allUnique ['a', 'a', undefined] )
+      `shouldThrow`
+      errorCall "Prelude.undefined"
+
+  it "allUnique: Test the function using slower analog and random data" $
+    property $
+    \ xs -> (allUnique' (xs :: String)) == (allUnique xs)
diff --git a/tests/Unique/Complex.hs b/tests/Unique/Complex.hs
new file mode 100644
--- /dev/null
+++ b/tests/Unique/Complex.hs
@@ -0,0 +1,26 @@
+module Unique.Complex where
+
+import Test.Hspec
+import Test.QuickCheck
+
+import Data.List.Unique
+import Data.List (sort)
+
+
+triplet :: (a -> b) -> (a, a, a) -> (b, b, b)
+triplet f (x, y, z) = (f x, f y, f z)
+
+complexTests :: SpecWith ()
+complexTests =
+  describe "Data.List.Unique.complex" $ do
+  
+  it "complex: should return ([],[],[]) with empty list" $ do
+    complex ( [] :: [Int] ) `shouldBe` ([],[],[])
+
+  it "complex: simple test" $ do
+    complex "This is the test line" `shouldBe` ("This teln","is hte","Tln")
+
+  it "complex: returns the same result as `sortUniq`, `repeated`, `unique` but not sorted" $
+    property $
+    \ xs -> triplet sort ( complex (xs :: String) )
+            == (sortUniq xs, repeated xs, unique xs)
diff --git a/tests/Unique/IsUnique.hs b/tests/Unique/IsUnique.hs
new file mode 100644
--- /dev/null
+++ b/tests/Unique/IsUnique.hs
@@ -0,0 +1,70 @@
+module Unique.IsUnique where
+
+import Test.Hspec
+import Test.QuickCheck
+import Control.Exception (evaluate)
+import Data.Maybe (isJust, isNothing)
+
+import Data.List.Unique
+
+isUniqueTests :: SpecWith ()
+isUniqueTests =
+  describe "Data.List.Unique.isUnique" $ do
+  it "isUnique: should return Nothing with empty list" $ do
+    isUnique (1 :: Int) [] 
+    `shouldBe`
+      Nothing
+
+  it "isUnique: should return Nothing with empty list (quickCheck)" $
+    property $
+    \x -> isNothing $ isUnique (x :: Char) []
+
+  it "isUnique: returns (Just True) when element is unique" $ do
+    isUnique 'a' "foo bar"  `shouldBe` Just True
+
+  it "isUnique: returns (Just False) when list has duplicate of element" $ do
+    isUnique 'o' "foo bar" `shouldBe` Just False
+
+  it "isUnique: is a lazy function, 'undefined test'" $ do
+    isUnique 'g' ['g','a','g', undefined ]
+    `shouldBe`
+      Just False
+
+  it "isUnique: is a lazy function, 'undefined test'. Generates exeption" $ do
+    evaluate (isUnique 't' ['t', 'd', undefined] )
+    `shouldThrow`
+      errorCall "Prelude.undefined"
+
+  it "isRepeated is a lazy function too, 'undefined test'" $ do
+    isRepeated 'g' ['g','a','g', undefined ]
+    `shouldBe`
+      Just True
+
+  it "isRepeated: is reverse function to isUnique" $ do
+    property $
+      \ x xs
+      -> isUnique (x :: Int) xs == fmap not (isRepeated x xs)
+
+  it "isUnique: should return (Just ANY) when element is exist in the list" $
+    property $
+    \ ( NonEmpty ls@(x:_) )
+    -> isJust (isUnique (x :: Char) ls)
+
+  context "isUnique: should return (Just False) when at least two elements are exist in the list" $
+    it "- It checks laziness as well" $
+      property $
+      \ ( NonEmpty ls@(x:_) )
+      ->  isJust $ isUnique (x :: Char) (ls ++ [x, undefined])
+
+  it "isUnique: should return Nothing when element is absent in the list" $
+    property $
+    \ x xs
+    -> notElem x xs
+       ==> isNothing (isUnique (x :: Char) xs)
+      
+  it "isUnique: and isRepeated should return Nothing when element is absent in the list" $
+    property $
+    \ x xs
+    -> notElem x xs
+       ==> isNothing (isUnique (x :: Char) xs)
+       &&  isNothing (isRepeated x xs)
diff --git a/tests/Unique/RepeatedBy.hs b/tests/Unique/RepeatedBy.hs
new file mode 100644
--- /dev/null
+++ b/tests/Unique/RepeatedBy.hs
@@ -0,0 +1,61 @@
+module Unique.RepeatedBy where
+
+import Test.Hspec
+import Test.QuickCheck
+
+import Data.List.Unique
+import Data.List (sort, group)
+
+
+repeatedByTests :: SpecWith ()
+repeatedByTests =
+  describe "Data.List.Unique.repeatedBy,repeated,unique" $ do
+  
+  it "repeatedBy: should return [] with empty list" $ do
+    repeatedBy (>100) ( [] :: [Int] ) `shouldBe` []
+
+  it "repeatedBy: simple test" $ do
+    repeatedBy (>2) "This is the test line" `shouldBe` " eist"
+
+  it "repeatedBy: returns [] when predicate (=< negative) " $
+    property $
+    \x xs -> x < 0
+             ==> null ( repeatedBy (<= x) (xs :: String) )
+
+  it "repeatedBy: removes the duplicated elements like `sortUniq` function when predicate (>= negative)" $
+     property $
+     \ x xs -> x < 0
+               ==> repeatedBy (>= x) (xs :: String) == sortUniq xs
+
+  it "repeatedBy: returns [] when preficate (== 0)" $
+     property $
+     \ xs -> null ( repeatedBy (== 0) (xs :: [Int]) )
+
+  it "repeatedBy: returns sorted result" $
+     property $
+     \x xs ->  x > 0
+              ==> repeatedBy (> x) (xs :: String) == sort (repeatedBy (> x) xs)
+
+  it "repeatedBy: resulted elements should occur only once" $
+    property $
+    \ x xs -> x > 0
+              ==> all (==1) . map length . group $ repeatedBy (> x) ( xs :: String )
+
+  it "unique: simple test" $ do
+    unique  "foo bar" `shouldBe` " abfr"
+
+  it "repeated: simple test" $ do
+    repeated  "foo bar" `shouldBe` "o"
+
+  it "unique: multiple execution should return the same result" $
+    property $
+    \ xs -> unique (xs :: String) == unique (unique xs)
+
+  it "repeated: multiple execution should return []" $
+    property $
+    \ xs -> null (repeated (repeated (xs :: String) ))
+
+  it "repeated && unique: should return different result on the same non empty list" $
+    property $
+    \ xs -> not (null xs)
+            ==> repeated (xs :: String) /= unique xs
diff --git a/tests/Unique/SortUniq.hs b/tests/Unique/SortUniq.hs
new file mode 100644
--- /dev/null
+++ b/tests/Unique/SortUniq.hs
@@ -0,0 +1,44 @@
+module Unique.SortUniq where
+
+import Test.Hspec
+import Test.QuickCheck
+
+import Data.List.Unique
+import Data.List (sort, group)
+import Data.Set (fromList, toList)
+
+
+sortUniqTests :: SpecWith ()
+sortUniqTests =
+  describe "Data.List.Unique.sortUniq" $ do
+  
+  it "sortUniq: should return [] with empty list" $ do
+    sortUniq ( [] :: [Int] ) `shouldBe` []
+
+  it "sortUniq: simple test" $ do
+    sortUniq "foo bar" `shouldBe` " abfor"
+
+  it "sortUniq: multiple execution should return the same result" $
+    property $
+    \ xs -> sortUniq (sortUniq ( xs :: String) ) == sortUniq xs
+
+  it "sortUniq: the result has to be sorted" $
+    property $
+    \ xs -> sortUniq ( xs :: [Int] ) == sort (sortUniq xs)
+
+  it "sortUniq: elements should occur only once" $
+    property $
+    \ ( NonEmpty ls@(x:_) ) -> isUnique (x :: Float) (sortUniq ls) == Just True
+
+  it "sortUniq: elements should occur only once #2" $
+    property $
+    \ xs -> all (==1) . map length . group $ sortUniq ( xs :: [Integer] )
+
+  it "sortUniq: check if it's correct by slow analog function" $
+    property $
+    \ xs -> ( map head . group . sort $ (xs :: String) )
+            == sortUniq xs
+
+  it "sortUniq: check if it's correct by the Faster analog function :)" $
+    property $
+    \ xs -> sortUniq ( xs :: String ) == toList (fromList xs)
diff --git a/tests/UniqueStrict/AllUnique.hs b/tests/UniqueStrict/AllUnique.hs
new file mode 100644
--- /dev/null
+++ b/tests/UniqueStrict/AllUnique.hs
@@ -0,0 +1,33 @@
+module UniqueStrict.AllUnique where
+
+import Test.Hspec
+import Test.QuickCheck
+import Control.Exception (evaluate)
+import Data.List (nub)
+
+import Data.List.UniqueStrict
+
+
+allUnique' :: Eq a => [a] -> Bool
+allUnique' ls = (nub ls) == ls
+
+allUniqueTests :: SpecWith ()
+allUniqueTests =
+  describe "Data.List.UniqueStrict.allUnique" $ do
+  it "allUnique: returns True with empty list" $ do
+    allUnique "" `shouldBe` True
+
+  it "allUnique: returns False when some element is not unique" $ do
+    allUnique "foo bar" `shouldBe` False
+
+  it "allUnique: returns True when list does not have duplicates" $ do
+    allUnique ([1..1000] :: [Int]) `shouldBe` True
+
+  it "allUnique: fails if list consist of duplicate elements and 'undefined' after them" $ do
+    evaluate (allUnique ['a', 'a', undefined] )
+      `shouldThrow`
+      errorCall "Prelude.undefined"
+
+  it "allUnique: Test the function using slower analog and random data" $
+    property $
+    \ xs -> (allUnique' (xs :: String)) == (allUnique xs)
diff --git a/tests/UniqueStrict/IsUnique.hs b/tests/UniqueStrict/IsUnique.hs
new file mode 100644
--- /dev/null
+++ b/tests/UniqueStrict/IsUnique.hs
@@ -0,0 +1,54 @@
+module UniqueStrict.IsUnique where
+
+import Test.Hspec
+import Test.QuickCheck
+import Control.Exception (evaluate)
+import Data.Maybe (isJust, isNothing)
+
+import Data.List.UniqueStrict
+
+isUniqueTests :: SpecWith ()
+isUniqueTests =
+  describe "Data.List.UniqueStrict.isUnique" $ do
+  it "isUnique: should return Nothing with empty list" $ do
+    isUnique (1 :: Int) [] 
+    `shouldBe`
+      Nothing
+
+  it "isUnique: should return Nothing with empty list (quickCheck)" $
+    property $
+    \x -> isNothing $ isUnique (x :: Char) []
+
+  it "isUnique: returns (Just True) when element is unique" $ do
+    isUnique 'a' "foo bar"  `shouldBe` Just True
+
+  it "isUnique: returns (Just False) when list has duplicate of element" $ do
+    isUnique 'o' "foo bar" `shouldBe` Just False
+
+  it "isUnique: is NOT a lazy function, 'undefined test'" $ do
+    evaluate (isUnique 'g' ['g','a','g', undefined ])
+      `shouldThrow`
+      errorCall "Prelude.undefined"
+    
+  it "isRepeated: is reverse function to isUnique" $ do
+    property $
+      \ x xs
+      -> isUnique (x :: Int) xs == fmap not (isRepeated x xs)
+
+  it "isUnique: should return (Just ANY) when element is exist in the list" $
+    property $
+    \ ( NonEmpty ls@(x:_) )
+    -> isJust (isUnique (x :: Char) ls)
+
+  it "isUnique: should return Nothing when element is absent in the list" $
+    property $
+    \ x xs
+    -> notElem x xs
+       ==> isNothing (isUnique (x :: Char) xs)
+      
+  it "isUnique: and isRepeated should return Nothing when element is absent in the list" $
+    property $
+    \ x xs
+    -> notElem x xs
+       ==> isNothing (isUnique (x :: Char) xs)
+       &&  isNothing (isRepeated x xs)
diff --git a/tests/UniqueStrict/RepeatedBy.hs b/tests/UniqueStrict/RepeatedBy.hs
new file mode 100644
--- /dev/null
+++ b/tests/UniqueStrict/RepeatedBy.hs
@@ -0,0 +1,61 @@
+module UniqueStrict.RepeatedBy where
+
+import Test.Hspec
+import Test.QuickCheck
+
+import Data.List.UniqueStrict
+import Data.List (sort, group)
+
+
+repeatedByTests :: SpecWith ()
+repeatedByTests =
+  describe "Data.List.UniqueStrict.repeatedBy,repeated,unique" $ do
+  
+  it "repeatedBy: should return [] with empty list" $ do
+    repeatedBy (>100) ( [] :: [Int] ) `shouldBe` []
+
+  it "repeatedBy: simple test" $ do
+    repeatedBy (>2) "This is the test line" `shouldBe` " eist"
+
+  it "repeatedBy: returns [] when predicate (=< negative) " $
+    property $
+    \x xs -> x < 0
+             ==> null ( repeatedBy (<= x) (xs :: String) )
+
+  it "repeatedBy: removes the duplicated elements like `sortUniq` function when predicate (>= negative)" $
+     property $
+     \ x xs -> x < 0
+               ==> repeatedBy (>= x) (xs :: String) == sortUniq xs
+
+  it "repeatedBy: returns [] when preficate (== 0)" $
+     property $
+     \ xs -> null ( repeatedBy (== 0) (xs :: [Int]) )
+
+  it "repeatedBy: returns sorted result" $
+     property $
+     \x xs ->  x > 0
+              ==> repeatedBy (> x) (xs :: String) == sort (repeatedBy (> x) xs)
+
+  it "repeatedBy: resulted elements should occur only once" $
+    property $
+    \ x xs -> x > 0
+              ==> all (==1) . map length . group $ repeatedBy (> x) ( xs :: String )
+
+  it "unique: simple test" $ do
+    unique  "foo bar" `shouldBe` " abfr"
+
+  it "repeated: simple test" $ do
+    repeated  "foo bar" `shouldBe` "o"
+
+  it "unique: multiple execution should return the same result" $
+    property $
+    \ xs -> unique (xs :: String) == unique (unique xs)
+
+  it "repeated: multiple execution should return []" $
+    property $
+    \ xs -> null (repeated (repeated (xs :: String) ))
+
+  it "repeated && unique: should return different result on the same non empty list" $
+    property $
+    \ xs -> not (null xs)
+            ==> repeated (xs :: String) /= unique xs
diff --git a/tests/UniqueStrict/SortUniq.hs b/tests/UniqueStrict/SortUniq.hs
new file mode 100644
--- /dev/null
+++ b/tests/UniqueStrict/SortUniq.hs
@@ -0,0 +1,44 @@
+module UniqueStrict.SortUniq where
+
+import Test.Hspec
+import Test.QuickCheck
+
+import Data.List.UniqueStrict
+import Data.List (sort, group)
+import Data.Set (fromList, toList)
+
+
+sortUniqTests :: SpecWith ()
+sortUniqTests =
+  describe "Data.List.UniqueStrict.sortUniq" $ do
+  
+  it "sortUniq: should return [] with empty list" $ do
+    sortUniq ( [] :: [Int] ) `shouldBe` []
+
+  it "sortUniq: simple test" $ do
+    sortUniq "foo bar" `shouldBe` " abfor"
+
+  it "sortUniq: multiple execution should return the same result" $
+    property $
+    \ xs -> sortUniq (sortUniq ( xs :: String) ) == sortUniq xs
+
+  it "sortUniq: the result has to be sorted" $
+    property $
+    \ xs -> sortUniq ( xs :: [Int] ) == sort (sortUniq xs)
+
+  it "sortUniq: elements should occur only once" $
+    property $
+    \ ( NonEmpty ls@(x:_) ) -> isUnique (x :: Float) (sortUniq ls) == Just True
+
+  it "sortUniq: elements should occur only once #2" $
+    property $
+    \ xs -> all (==1) . map length . group $ sortUniq ( xs :: [Integer] )
+
+  it "sortUniq: check if it's correct by slow analog function" $
+    property $
+    \ xs -> ( map head . group . sort $ (xs :: String) )
+            == sortUniq xs
+
+  it "sortUniq: check if it's correct by the Faster analog function :)" $
+    property $
+    \ xs -> sortUniq ( xs :: String ) == toList (fromList xs)
diff --git a/tests/UniqueUnsorted/AllUnique.hs b/tests/UniqueUnsorted/AllUnique.hs
new file mode 100644
--- /dev/null
+++ b/tests/UniqueUnsorted/AllUnique.hs
@@ -0,0 +1,33 @@
+module UniqueUnsorted.AllUnique where
+
+import Test.Hspec
+import Test.QuickCheck
+import Control.Exception (evaluate)
+import Data.List (nub)
+
+import Data.List.UniqueUnsorted
+
+
+allUnique' :: Eq a => [a] -> Bool
+allUnique' ls = (nub ls) == ls
+
+allUniqueTests :: SpecWith ()
+allUniqueTests =
+  describe "Data.List.UniqueUnsorted.allUnique" $ do
+  it "allUnique: returns True with empty list" $ do
+    allUnique "" `shouldBe` True
+
+  it "allUnique: returns False when some element is not unique" $ do
+    allUnique "foo bar" `shouldBe` False
+
+  it "allUnique: returns True when list does not have duplicates" $ do
+    allUnique ([1..1000] :: [Int]) `shouldBe` True
+
+  it "allUnique: fails if list consist of duplicate elements and 'undefined' after them" $ do
+    evaluate (allUnique ['a', 'a', undefined] )
+      `shouldThrow`
+      errorCall "Prelude.undefined"
+
+  it "allUnique: Test the function using slower analog and random data" $
+    property $
+    \ xs -> (allUnique' (xs :: String)) == (allUnique xs)
diff --git a/tests/UniqueUnsorted/IsUnique.hs b/tests/UniqueUnsorted/IsUnique.hs
new file mode 100644
--- /dev/null
+++ b/tests/UniqueUnsorted/IsUnique.hs
@@ -0,0 +1,54 @@
+module UniqueUnsorted.IsUnique where
+
+import Test.Hspec
+import Test.QuickCheck
+import Control.Exception (evaluate)
+import Data.Maybe (isJust, isNothing)
+
+import Data.List.UniqueUnsorted
+
+isUniqueTests :: SpecWith ()
+isUniqueTests =
+  describe "Data.List.UniqueUnsorted.isUnique" $ do
+  it "isUnique: should return Nothing with empty list" $ do
+    isUnique (1 :: Int) [] 
+    `shouldBe`
+      Nothing
+
+  it "isUnique: should return Nothing with empty list (quickCheck)" $
+    property $
+    \x -> isNothing $ isUnique (x :: Char) []
+
+  it "isUnique: returns (Just True) when element is unique" $ do
+    isUnique 'a' "foo bar"  `shouldBe` Just True
+
+  it "isUnique: returns (Just False) when list has duplicate of element" $ do
+    isUnique 'o' "foo bar" `shouldBe` Just False
+
+  it "isUnique: is NOT a lazy function, 'undefined test'" $ do
+    evaluate (isUnique 'g' ['g','a','g', undefined ])
+      `shouldThrow`
+      errorCall "Prelude.undefined"
+    
+  it "isRepeated: is reverse function to isUnique" $ do
+    property $
+      \ x xs
+      -> isUnique (x :: Int) xs == fmap not (isRepeated x xs)
+
+  it "isUnique: should return (Just ANY) when element is exist in the list" $
+    property $
+    \ ( NonEmpty ls@(x:_) )
+    -> isJust (isUnique (x :: Char) ls)
+
+  it "isUnique: should return Nothing when element is absent in the list" $
+    property $
+    \ x xs
+    -> notElem x xs
+       ==> isNothing (isUnique (x :: Char) xs)
+      
+  it "isUnique: and isRepeated should return Nothing when element is absent in the list" $
+    property $
+    \ x xs
+    -> notElem x xs
+       ==> isNothing (isUnique (x :: Char) xs)
+       &&  isNothing (isRepeated x xs)
diff --git a/tests/UniqueUnsorted/RemoveDuplicates.hs b/tests/UniqueUnsorted/RemoveDuplicates.hs
new file mode 100644
--- /dev/null
+++ b/tests/UniqueUnsorted/RemoveDuplicates.hs
@@ -0,0 +1,30 @@
+module UniqueUnsorted.RemoveDuplicates where
+
+import Test.Hspec
+import Test.QuickCheck
+
+import Data.List.UniqueUnsorted
+import Data.List (group)
+
+
+removeDuplicatesTests :: SpecWith ()
+removeDuplicatesTests =
+  describe "Data.List.UniqueUnsorted.removeDuplicates" $ do
+  
+  it "removeDuplicates: should return [] with empty list" $ do
+    removeDuplicates ( [] :: [Int] ) `shouldBe` []
+
+  it "removeDuplicates: simple test" $ do
+    removeDuplicates "foo bar" `shouldBe` " abrfo"
+
+  it "removeDuplicates: multiple execution should return the same result" $
+    property $
+    \ xs -> removeDuplicates (removeDuplicates ( xs :: String) ) == removeDuplicates xs
+
+  it "removeDuplicates: elements should occur only once" $
+    property $
+    \ ( NonEmpty ls@(x:_) ) -> isUnique (x :: Float) (removeDuplicates ls) == Just True
+
+  it "removeDuplicates: elements should occur only once #2" $
+    property $
+    \ xs -> all (==1) . map length . group $ removeDuplicates ( xs :: [Integer] )
diff --git a/tests/UniqueUnsorted/RepeatedBy.hs b/tests/UniqueUnsorted/RepeatedBy.hs
new file mode 100644
--- /dev/null
+++ b/tests/UniqueUnsorted/RepeatedBy.hs
@@ -0,0 +1,51 @@
+module UniqueUnsorted.RepeatedBy where
+
+import Test.Hspec
+import Test.QuickCheck
+
+import Data.List.UniqueUnsorted
+import Data.List (group)
+
+
+repeatedByTests :: SpecWith ()
+repeatedByTests =
+  describe "Data.List.UniqueUnsorted.repeatedBy,repeated,unique" $ do
+  
+  it "repeatedBy: should return [] with empty list" $ do
+    repeatedBy (>100) ( [] :: [Int] ) `shouldBe` []
+
+  it "repeatedBy: simple test" $ do
+    repeatedBy (>2) "This is the test line" `shouldBe` " stei"
+
+  it "repeatedBy: returns [] when predicate (=< negative) " $
+    property $
+    \x xs -> x < 0
+             ==> null ( repeatedBy (<= x) (xs :: String) )
+
+  it "repeatedBy: returns [] when preficate (== 0)" $
+     property $
+     \ xs -> null ( repeatedBy (== 0) (xs :: [Int]) )
+
+  it "repeatedBy: resulted elements should occur only once" $
+    property $
+    \ x xs -> x > 0
+              ==> all (==1) . map length . group $ repeatedBy (> x) ( xs :: String )
+
+  it "unique: simple test" $ do
+    unique  "foo bar" `shouldBe` " abrf"
+
+  it "repeated: simple test" $ do
+    repeated  "foo bar" `shouldBe` "o"
+
+  it "unique: multiple execution should return the same result" $
+    property $
+    \ xs -> unique (xs :: String) == unique (unique xs)
+
+  it "repeated: multiple execution should return []" $
+    property $
+    \ xs -> null (repeated (repeated (xs :: String) ))
+
+  it "repeated && unique: should return different result on the same non empty list" $
+    property $
+    \ xs -> not (null xs)
+            ==> repeated (xs :: String) /= unique xs
