diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Andrey Mulik (c) 2020
+
+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 Andrey Mulik 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/bench/bench-sort-io.hs b/bench/bench-sort-io.hs
new file mode 100644
--- /dev/null
+++ b/bench/bench-sort-io.hs
@@ -0,0 +1,35 @@
+module Main where
+
+import Prelude ()
+import SDP.SafePrelude
+import SDP.Unrolled.IO
+import SDP.ByteList.IO
+import SDP.Array.IO
+import SDP.Bytes.IO
+
+import Criterion.Main ( bench, nfIO, defaultMain )
+
+import Test.QuickCheck
+import Test.SDP.Gen
+
+import Control.DeepSeq.SDP as F ( force )
+
+default ()
+
+--------------------------------------------------------------------------------
+
+main :: IO ()
+main =  do
+  list     <- F.force <$> generate (linearLargeA 100000) ::  IO [Int]
+  array    <- newLinearN 100000 list :: IO (IOArray    Int Int)
+  bytes    <- newLinearN 100000 list :: IO (IOBytes    Int Int)
+  unrolled <- newLinearN 100000 list :: IO (IOUnrolled Int Int)
+  bytelist <- newLinearN 100000 list :: IO (IOByteList Int Int)
+  defaultMain
+    [
+      bench "bench-timsort-ioarray"    $ nfIO (sortM array >> sortedM array),
+      bench "bench-timsort-iobytes"    $ nfIO (sortM bytes >> sortedM bytes),
+      bench "bench-timsort-iounrolled" $ nfIO (sortM unrolled >> sortedM unrolled),
+      bench "bench-timsort-iobytelist" $ nfIO (sortM bytelist >> sortedM bytelist)
+    ]
+
diff --git a/bench/bench-sort.hs b/bench/bench-sort.hs
new file mode 100644
--- /dev/null
+++ b/bench/bench-sort.hs
@@ -0,0 +1,40 @@
+module Main where
+
+import Prelude ()
+import SDP.SafePrelude
+
+import Criterion.Main ( env, bench, whnf, defaultMain )
+
+import Test.QuickCheck
+import Test.SDP.Gen
+
+import SDP.Unrolled
+import SDP.ByteList
+import SDP.Array
+import SDP.Bytes
+
+import Control.DeepSeq.SDP as F ( force )
+
+default ()
+
+--------------------------------------------------------------------------------
+
+main :: IO ()
+main =  defaultMain
+  [
+    let arrayEnv        = F.force <$> generate (linearLargeA 10000) :: IO (Array Int Int)
+    in  env arrayEnv    $ bench "bench-timsort-array" . whnf sort,
+    
+    let bytesEnv        = F.force <$> generate (linearLargeA 10000) :: IO (Bytes Int Int)
+    in  env bytesEnv    $ bench "bench-timsort-bytes" . whnf sort,
+    
+    let unrolledEnv     = F.force <$> generate (linearLargeA 10000) :: IO (Unrolled Int Int)
+    in  env unrolledEnv $ bench "bench-timsort-unrolled" . whnf sort,
+    
+    let bytelistEnv     = F.force <$> generate (linearLargeA 10000) :: IO (ByteList Int Int)
+    in  env bytelistEnv $ bench "bench-timsort-bytelist" . whnf sort
+  ]
+
+
+
+
diff --git a/sdp-quickcheck.cabal b/sdp-quickcheck.cabal
new file mode 100644
--- /dev/null
+++ b/sdp-quickcheck.cabal
@@ -0,0 +1,310 @@
+name:          sdp-quickcheck
+version:       0.2
+category:      Data Structures
+
+synopsis:      SDP QuickCheck support
+description:   Arbitrary instances for SDP structures
+
+author:        Andrey Mulik
+maintainer:    <work.a.mulik@gmail.com>
+bug-reports:   https://github.com/andreymulik/sdp-quickcheck/issues
+
+copyright:     2020 Andrey Mulik
+license-file:  LICENSE
+license:       BSD3
+
+build-type:    Simple
+cabal-version: >=1.10
+
+source-repository head
+  type: git
+  location: https://github.com/andreymulik/sdp-quickcheck
+
+---            _      _____ ______ ______   ___  ______ __   __              ---
+---           | |    |_   _|| ___ \| ___ \ / _ \ | ___ \\ \ / /              ---
+---           | |      | |  | |_/ /| |_/ // /_\ \| |_/ / \ V /               ---
+---           | |      | |  | ___ \|    / |  _  ||    /   \ /                ---
+---           | |____ _| |_ | |_/ /| |\ \ | | | || |\ \   | |                ---
+---           \_____/ \___/ \____/ \_| \_|\_| |_/\_| \_|  \_/                ---
+
+Library
+  default-language: Haskell2010
+  hs-source-dirs:   src
+  build-depends:
+    base        >= 4.12 && < 5,
+    sdp         >= 0.2  && < 0.3,
+    QuickCheck  >= 2.12 && < 3
+  
+  ghc-options: -Wall -Wno-orphans
+  
+  exposed-modules:
+    Test.SDP.Arbitrary
+    Test.SDP.Estimate
+    Test.SDP.Indexed
+    Test.SDP.Linear
+    Test.SDP.Split
+    Test.SDP.Index
+    Test.SDP.Sort
+    Test.SDP.Set
+    Test.SDP.Gen
+    Test.SDP.Ord
+    Test.SDP.Eq
+    Test.SDP
+
+---            _____  _____  _____  _____  _____  _   _  _____               ---
+---           |_   _||  ___|/  ___||_   _||_   _|| \ | ||  __ \              ---
+---             | |  | |__  \ `--.   | |    | |  |  \| || |  \/              ---
+---             | |  |  __|  `--. \  | |    | |  | . ` || | __               ---
+---             | |  | |___ /\__/ /  | |   _| |_ | |\  || |_\ \              ---
+---             \_/  \____/ \____/   \_/   \___/ \_| \_/ \____/              ---
+
+test-suite test-indices
+  default-language: Haskell2010
+  hs-source-dirs:   test, src
+  main-is:          test-indices.hs
+  type:             exitcode-stdio-1.0
+  
+  other-modules:
+    Test.SDP.Arbitrary
+    Test.SDP.Estimate
+    Test.SDP.Indexed
+    Test.SDP.Linear
+    Test.SDP.Split
+    Test.SDP.Index
+    Test.SDP.Sort
+    Test.SDP.Set
+    Test.SDP.Gen
+    Test.SDP.Ord
+    Test.SDP.Eq
+    Test.SDP
+  
+  build-depends:
+    base                       >= 4.12 && < 5,
+    sdp                        >= 0.2  && < 0.3,
+    QuickCheck                 >= 2.12 && < 3,
+    test-framework             >= 0.8  && < 0.9,
+    test-framework-quickcheck2 >= 0.3  && < 0.4
+  
+  ghc-options: -Wall -Wno-orphans
+
+test-suite test-array
+  default-language: Haskell2010
+  hs-source-dirs:   test, src
+  main-is:          test-array.hs
+  type:             exitcode-stdio-1.0
+  
+  other-modules:
+    Test.SDP.Arbitrary
+    Test.SDP.Estimate
+    Test.SDP.Indexed
+    Test.SDP.Linear
+    Test.SDP.Split
+    Test.SDP.Sort
+    Test.SDP.Set
+    Test.SDP.Gen
+    Test.SDP.Ord
+    Test.SDP.Eq
+    Test.SDP
+  
+  build-depends:
+    base                       >= 4.12 && < 5,
+    sdp                        >= 0.2  && < 0.3,
+    QuickCheck                 >= 2.12 && < 3,
+    test-framework             >= 0.8  && < 0.9,
+    test-framework-quickcheck2 >= 0.3  && < 0.4
+  
+  ghc-options: -Wall -Wno-orphans
+
+test-suite test-bytes
+  default-language: Haskell2010
+  hs-source-dirs:   test, src
+  main-is:          test-bytes.hs
+  type:             exitcode-stdio-1.0
+  
+  other-modules:
+    Test.SDP.Arbitrary
+    Test.SDP.Estimate
+    Test.SDP.Indexed
+    Test.SDP.Linear
+    Test.SDP.Split
+    Test.SDP.Sort
+    Test.SDP.Set
+    Test.SDP.Gen
+    Test.SDP.Ord
+    Test.SDP.Eq
+    Test.SDP
+  
+  build-depends:
+    base                       >= 4.12 && < 5,
+    sdp                        >= 0.2  && < 0.3,
+    QuickCheck                 >= 2.12 && < 3,
+    test-framework             >= 0.8  && < 0.9,
+    test-framework-quickcheck2 >= 0.3  && < 0.4
+  
+  ghc-options: -Wall -Wno-orphans
+
+test-suite test-unrolled
+  default-language: Haskell2010
+  hs-source-dirs:   test, src
+  main-is:          test-unrolled.hs
+  type:             exitcode-stdio-1.0
+  
+  other-modules:
+    Test.SDP.Arbitrary
+    Test.SDP.Estimate
+    Test.SDP.Indexed
+    Test.SDP.Linear
+    Test.SDP.Split
+    Test.SDP.Sort
+    Test.SDP.Set
+    Test.SDP.Gen
+    Test.SDP.Ord
+    Test.SDP.Eq
+    Test.SDP
+  
+  build-depends:
+    base                       >= 4.12 && < 5,
+    sdp                        >= 0.2  && < 0.3,
+    QuickCheck                 >= 2.12 && < 3,
+    test-framework             >= 0.8  && < 0.9,
+    test-framework-quickcheck2 >= 0.3  && < 0.4
+  
+  ghc-options: -Wall -Wno-orphans
+
+test-suite test-bytelist
+  default-language: Haskell2010
+  hs-source-dirs:   test, src
+  main-is:          test-bytelist.hs
+  type:             exitcode-stdio-1.0
+  
+  other-modules:
+    Test.SDP.Arbitrary
+    Test.SDP.Estimate
+    Test.SDP.Indexed
+    Test.SDP.Linear
+    Test.SDP.Split
+    Test.SDP.Sort
+    Test.SDP.Set
+    Test.SDP.Gen
+    Test.SDP.Ord
+    Test.SDP.Eq
+    Test.SDP
+  
+  build-depends:
+    base                       >= 4.12 && < 5,
+    sdp                        >= 0.2  && < 0.3,
+    QuickCheck                 >= 2.12 && < 3,
+    test-framework             >= 0.8  && < 0.9,
+    test-framework-quickcheck2 >= 0.3  && < 0.4
+  
+  ghc-options: -Wall -Wno-orphans
+
+test-suite test-ublist
+  default-language: Haskell2010
+  hs-source-dirs:   test, src
+  main-is:          test-ublist.hs
+  type:             exitcode-stdio-1.0
+  
+  other-modules:
+    Test.SDP.Arbitrary
+    Test.SDP.Estimate
+    Test.SDP.Indexed
+    Test.SDP.Linear
+    Test.SDP.Split
+    Test.SDP.Sort
+    Test.SDP.Set
+    Test.SDP.Gen
+    Test.SDP.Ord
+    Test.SDP.Eq
+    Test.SDP
+  
+  build-depends:
+    base                       >= 4.12 && < 5,
+    sdp                        >= 0.2  && < 0.3,
+    QuickCheck                 >= 2.12 && < 3,
+    test-framework             >= 0.8  && < 0.9,
+    test-framework-quickcheck2 >= 0.3  && < 0.4
+  
+  ghc-options: -Wall -Wno-orphans
+
+test-suite test-unlist
+  default-language: Haskell2010
+  hs-source-dirs:   test, src
+  main-is:          test-unlist.hs
+  type:             exitcode-stdio-1.0
+  
+  other-modules:
+    Test.SDP.Arbitrary
+    Test.SDP.Estimate
+    Test.SDP.Indexed
+    Test.SDP.Linear
+    Test.SDP.Split
+    Test.SDP.Sort
+    Test.SDP.Set
+    Test.SDP.Gen
+    Test.SDP.Ord
+    Test.SDP.Eq
+    Test.SDP
+  
+  build-depends:
+    base                       >= 4.12 && < 5,
+    sdp                        >= 0.2  && < 0.3,
+    QuickCheck                 >= 2.12 && < 3,
+    test-framework             >= 0.8  && < 0.9,
+    test-framework-quickcheck2 >= 0.3  && < 0.4
+  
+  ghc-options: -Wall -Wno-orphans
+
+---   ______ _____ _   _ _____  _   _ ___  ___  ___  ______ _   __ _____     ---
+---   | ___ \  ___| \ | /  __ \| | | ||  \/  | / _ \ | ___ \ | / //  ___|    ---
+---   | |_/ / |__ |  \| | /  \/| |_| || .  . |/ /_\ \| |_/ / |/ / \ `--.     ---
+---   | ___ \  __|| . ` | |    |  _  || |\/| ||  _  ||    /|    \  `--. \    ---
+---   | |_/ / |___| |\  | \__/\| | | || |  | || | | || |\ \| |\  \/\__/ /    ---
+---   \____/\____/\_| \_/\____/\_| |_/\_|  |_/\_| |_/\_| \_\_| \_/\____/     ---
+
+benchmark bench-sort
+  default-language: Haskell2010
+  hs-source-dirs:   bench, src
+  main-is:          bench-sort.hs
+  type:             exitcode-stdio-1.0
+  
+  other-modules:
+    Test.SDP.Arbitrary
+    Test.SDP.Estimate
+    Test.SDP.Indexed
+    Test.SDP.Linear
+    Test.SDP.Split
+    Test.SDP.Sort
+    Test.SDP.Set
+    Test.SDP.Gen
+    Test.SDP.Ord
+    Test.SDP.Eq
+    Test.SDP
+  
+  build-depends:
+    base        >= 4.12 && < 5,
+    sdp         >= 0.2  && < 0.3,
+    sdp-deepseq >= 0.2  && < 1,
+    QuickCheck  >= 2.12 && < 3,
+    criterion   >= 1.5  && < 1.6
+  
+  ghc-options: -O2 -Wall -Wno-orphans
+
+benchmark bench-sort-io
+  default-language: Haskell2010
+  hs-source-dirs:   bench, src
+  ghc-options:      -O2 -Wall -Wno-orphans
+  main-is:          bench-sort-io.hs
+  type:             exitcode-stdio-1.0
+  
+  other-modules:
+    Test.SDP.Gen
+  
+  build-depends:
+    base         >= 4.12  && < 5,
+    sdp          >= 0.2   && < 0.3,
+    sdp-deepseq  >= 0.2   && < 1,
+    criterion    >= 1.5   && < 1.6,
+    ghc-prim     >= 0.5.3 && < 0.7,
+    QuickCheck   >= 2.12  && < 3
+
diff --git a/src/Test/SDP.hs b/src/Test/SDP.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP.hs
@@ -0,0 +1,35 @@
+{- |
+    Module      :  Test.SDP
+    Copyright   :  (c) Andrey Mulik 2019
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  non-portable (imports non-portable modules)
+    
+    @Test.SDP@ reexports all tests in @sdp-quickcheck@ (except "Test.SDP.Index")
+-}
+module Test.SDP
+  (
+    -- * Exports
+    module Test.SDP.Estimate,
+    module Test.SDP.Indexed,
+    module Test.SDP.Linear,
+    module Test.SDP.Split,
+    module Test.SDP.Sort,
+    module Test.SDP.Set,
+    module Test.SDP.Ord,
+    module Test.SDP.Eq
+  )
+where
+
+import Test.SDP.Estimate
+import Test.SDP.Indexed
+import Test.SDP.Linear
+import Test.SDP.Split
+import Test.SDP.Sort
+import Test.SDP.Set
+import Test.SDP.Ord
+import Test.SDP.Eq
+
+
+
+
diff --git a/src/Test/SDP/Arbitrary.hs b/src/Test/SDP/Arbitrary.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP/Arbitrary.hs
@@ -0,0 +1,65 @@
+{-# LANGUAGE MagicHash, TypeOperators, UndecidableInstances #-}
+
+{- |
+    Module      :  Test.SDP.Arbitrary
+    Copyright   :  (c) Andrey Mulik 2020
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  non-portable (GHC extensions)
+    
+    @Test.SDP.Arbitrary@ is service module that provides 'Arbitrary' instances
+    for @sdp@ structures.
+-}
+module Test.SDP.Arbitrary
+(
+  -- * Exports
+  module Test.QuickCheck,
+  
+  SArray#, SBytes#, AnyBorder (..), AnyChunks
+)
+where
+
+import Prelude ()
+import SDP.SafePrelude
+import SDP.Unboxed
+
+import SDP.Templates.AnyBorder
+import SDP.Templates.AnyChunks
+import SDP.Prim.SArray
+import SDP.Prim.SBytes
+
+import Test.QuickCheck
+
+default ()
+
+--------------------------------------------------------------------------------
+
+instance Arbitrary E where arbitrary = return E
+
+instance (Arbitrary i, Arbitrary i') => Arbitrary (i' :& i)
+  where
+    arbitrary = applyArbitrary2 (:&)
+
+--------------------------------------------------------------------------------
+
+instance (Arbitrary e) => Arbitrary (SArray# e)
+  where
+    arbitrary = fromList <$> arbitrary
+
+instance (Unboxed e, Arbitrary e) => Arbitrary (SBytes# e)
+  where
+    arbitrary = fromList <$> arbitrary
+
+--------------------------------------------------------------------------------
+
+-- TODO: rewrite as arbitrary chunk list generator (needs sdp improvements).
+
+instance (Bordered1 rep Int e, Linear1 rep e, Arbitrary e) => Arbitrary (AnyChunks rep e)
+  where
+    arbitrary = fromList <$> arbitrary
+
+instance (Index i, Bordered1 rep Int e, Arbitrary (rep e)) => Arbitrary (AnyBorder rep i e)
+  where
+    arbitrary = (\ es -> uncurry AnyBorder (defaultBounds $ sizeOf es) es) <$> arbitrary
+
+
diff --git a/src/Test/SDP/Eq.hs b/src/Test/SDP/Eq.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP/Eq.hs
@@ -0,0 +1,40 @@
+{- |
+    Module      :  Test.SDP.Eq
+    Copyright   :  (c) Andrey Mulik 2019
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  portable
+    
+    @Test.SDP.Eq@ provides basic test suite for 'Eq' instances.
+-}
+module Test.SDP.Eq
+(
+  -- * Eq test
+  TestEq, eqTest
+)
+where
+
+default ()
+
+--------------------------------------------------------------------------------
+
+-- | TestEq is service type synonym for more comfortable quickCheck using.
+type TestEq l = l -> l -> l -> Bool
+
+--------------------------------------------------------------------------------
+
+-- | eqTest is basic test suite for 'Eq' instances.
+eqTest :: (Eq l) => l -> l -> l -> Bool
+eqTest xs ys zs = and
+  [
+    -- transitive
+    (xs == ys && ys == zs) <= (xs == zs),
+    
+    -- symmetric
+    (xs == ys) == (ys == xs),
+    
+    -- reflexive
+    xs == xs
+  ]
+
+
diff --git a/src/Test/SDP/Estimate.hs b/src/Test/SDP/Estimate.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP/Estimate.hs
@@ -0,0 +1,80 @@
+{- |
+    Module      :  Test.SDP.Estimate
+    Copyright   :  (c) Andrey Mulik 2019
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  non-portable (requires non-portable modules)
+    
+    @Test.SDP.Estimate@ provides basic test suite for 'Estimate' instances.
+-}
+module Test.SDP.Estimate
+  (
+    -- * Estimate test
+    TestEstimate, estimateTest
+  )
+where
+
+import Prelude ()
+import SDP.SafePrelude hiding ( eq1 )
+import SDP.Linear
+
+default ()
+
+--------------------------------------------------------------------------------
+
+-- | TestEstimate is service type synonym for more comfortable quickCheck using.
+type TestEstimate e = Int -> e -> e -> Bool
+
+--------------------------------------------------------------------------------
+
+-- | 'estimateTest' is basic test suite for 'Estimate' instances.
+estimateTest :: (Bordered b i) => Int -> b -> b -> Bool
+estimateTest n xs ys = and
+  [
+    -- by definition
+    cmp == (sx <=>  sy),
+    cmp == (sx <=.> ys),
+    cmp == (xs <.=> sy),
+    
+    (xs <.=> n) == (sx <=> n),
+    
+    case xs <.=> n of
+      EQ -> xs .== n && not (xs ./= n)
+      LT -> xs .< n && n >. xs
+      GT -> xs .> n && n <. xs,
+    
+    case cmp of
+      LT -> lt1 && ys .>. xs
+      GT -> gt1 && ys .<. xs
+      EQ -> eq1 && not ne1,
+    
+    not (xs .>. xs), (xs .>=. xs),
+    not (xs .<. xs), (xs .<=. xs),
+    
+    -- equality
+    gt1 == (ys .<. xs),
+    lt1 == (ys .>. xs),
+    
+    ge1 == (ys .<=. xs),
+    le1 == (ys .>=. xs),
+    
+    ge1 || le1,
+    gt1 || lt1 || eq1,
+    
+    -- inequality
+    (gt1 || lt1) /= eq1,
+    
+    gt1 /= le1,
+    lt1 /= ge1
+  ]
+  where
+    gt1 = xs .>.  ys; lt1 = xs .<.  ys
+    ge1 = xs .>=. ys; le1 = xs .<=. ys
+    eq1 = xs .==. ys; ne1 = xs ./=. ys
+    cmp = xs <==> ys
+    sx  = sizeOf  xs
+    sy  = sizeOf  ys
+
+
+
+
diff --git a/src/Test/SDP/Gen.hs b/src/Test/SDP/Gen.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP/Gen.hs
@@ -0,0 +1,100 @@
+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleContexts #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+{- |
+    Module      :  Test.SDP.Gen
+    Copyright   :  (c) Andrey Mulik 2019
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  non-portable (requires non-portable modules)
+    
+    @Test.SDP.Gen@ provides newtypes for QuickCheck.
+-}
+module Test.SDP.Gen
+(
+  -- * Common newtypes for QuickCheck
+  Short (..), Medium (..), Long (..),
+  
+  -- ** Related functions
+  linearLargeA, linearA, orderA
+)
+where
+
+import Prelude ()
+import SDP.SafePrelude
+import SDP.Linear
+
+import Test.QuickCheck
+
+import Data.Coerce
+
+default ()
+
+--------------------------------------------------------------------------------
+
+{- |
+  Short is newtype of short data structures [0, 100) in QuickCheck properties.
+  
+  Short is the equivalent of the standard Arbitrary definition:
+  @arbitrary = fromList \<$\> arbitrary@.
+-}
+newtype Short a = Short a deriving ( Eq, Ord, Read, Show )
+
+{- |
+  Medium is newtype of medium data structures in QuickCheck properties. The
+  Arbitrary Medium instance must create a random-sized structure from the range
+  [100, 1024).
+  
+  Medium is useful in testing as a compromise between speed and reliability:
+  structures are too short for stress tests, but still human readable and enough
+  fast for auto-testing.
+-}
+newtype Medium a = Medium a deriving ( Eq, Ord, Read, Show )
+
+{- |
+  Long is newtype of large data structures (>= 1024) in QuickCheck properties.
+  Since Large can generate really huge numbers, the maximum length is limited by
+  16384 - [1024, 16384).
+  
+  Long is primarily intended for benchmarks, although a large range of lengths
+  makes them not very convenient for a pure comparison of several algorithms
+  (but for this can be used vector[Of] and generate). Long works well with
+  Unrolled and ByteList, since only the shortest of the allowed structures may
+  fit in one standard chunk (1024 elements).
+-}
+newtype Long a = Long a deriving ( Eq, Ord, Read, Show )
+
+--------------------------------------------------------------------------------
+
+instance (Linear l e, Arbitrary e) => Arbitrary (Short l)
+  where
+    arbitrary = arbitrary >>= \ n -> (Short . fromList) <$> vector n
+
+instance (Linear l e, Arbitrary e) => Arbitrary (Medium l)
+  where
+    arbitrary = arbitrary >>= \ (Large n) -> (Medium . fromList) <$> vector (100 + n `mod` 914)
+
+instance (Linear l e, Arbitrary e) => Arbitrary (Long l)
+  where
+    arbitrary = arbitrary >>= \ (Large n) -> (Long . fromList) <$> vector (1024 + n `mod` 15360)
+
+--------------------------------------------------------------------------------
+
+-- | 'linearA' is overloaded 'vector'.
+linearA :: (Linear l e, Arbitrary e) => Int -> Gen l
+linearA =  fmap fromList . vector
+
+-- | 'linearLargeA' is version of 'linearA', which generates 'Large' 'Int's.
+linearLargeA :: (Linear l Int) => Int -> Gen l
+linearLargeA =
+  let fromLarge = coerce :: [Large Int] -> [Int]
+  in  fmap (fromList . fromLarge) . vector
+
+{- |
+  'orderA' returns a simple comparator that can be used to test the behavior of
+  higher-order functions (for example, when comparing the results of @takeWhile@
+  for different structures).
+-}
+orderA :: (Ord e) => Gen (e -> e -> Bool)
+orderA =  elements [(>), (<), (>=), (<=), (==), (/=)]
+
diff --git a/src/Test/SDP/Index.hs b/src/Test/SDP/Index.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP/Index.hs
@@ -0,0 +1,130 @@
+{-# LANGUAGE TypeOperators, FlexibleContexts #-}
+
+{- |
+    Module      :  Test.SDP.Index
+    Copyright   :  (c) Andrey Mulik 2019
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  non-portable (requires non-portable modules)
+    
+    @Test.SDP.Index@ provides basic test suite for 'Index' class.
+-}
+module Test.SDP.Index
+(
+  -- * Shape test
+  TestShape, shapeTest,
+  
+  -- * Index test
+  TestIndex, indexTest,
+  
+  -- ** Particular tests
+  basicIndexTest, inBoundsTest, rangeTest, prevTest, nextTest, dumbSizeTest
+)
+where
+
+import SDP.Index
+
+default ()
+
+--------------------------------------------------------------------------------
+
+-- | 'TestShape' is service type synonym for more comfortable quickCheck using.
+type TestShape s = s -> Bool
+
+{- |
+  @'shapeTest' r sh@ is default 'Shape' test, where @r@ is expected rank for
+  this shape type. Note that 'shapeTest' also checks @'rank' 'undefined'@ case,
+  to make sure 'rank' is correct.
+-}
+shapeTest :: (Shape s, Eq s, Eq (DimInit s), Eq (DimLast s)) => Int -> s -> Bool
+shapeTest r sh' = let (s, sh) = unconsDim sh' in and
+  [
+    r == rank (undefined `asTypeOf` sh'),
+    r == rank sh',
+    
+    consDim s sh == sh',
+    lastDim sh' == sh,
+    initDim sh' == s
+  ]
+
+--------------------------------------------------------------------------------
+
+-- | TestIndex is service type synonym for more comfortable quickCheck using.
+type TestIndex i = (i, i) -> i -> Bool
+
+lim :: Int
+lim =  65536
+
+{- |
+  'rangeTest' checks relations of 'inRange', 'isOverflow', 'isUnderflow' and
+  'isEmpty'.
+-}
+rangeTest :: (Index i) => (i, i) -> i -> Bool
+rangeTest bnds i = and
+  [
+    not (inRange bnds i && isUnderflow bnds i),
+    not (inRange bnds i && isOverflow  bnds i),
+    not (inRange bnds i && isEmpty     bnds),
+    
+    not (isEmpty bnds)  || isOverflow  bnds i,
+    not (isEmpty bnds)  || isUnderflow bnds i
+  ]
+
+-- | 'prevTest' checks relations of 'prev' and 'range'.
+prevTest :: (Index i) => (i, i) -> Bool
+prevTest bnds =
+  let test = take lim $ zipWith (==) (range bnds) (tail $ prev bnds <$> range bnds)
+  in  isEmpty bnds || and test
+
+-- | 'nextTest' checks relations of 'next' and 'range'.
+nextTest :: (Index i) => (i, i) -> Bool
+nextTest bnds =
+  let test = take lim $ zipWith (==) (range bnds) (tail $ prev bnds <$> range bnds)
+  in  isEmpty bnds || and test
+
+-- | 'inBoundsTest' checks relations of 'inBounds' and other range functions.
+inBoundsTest :: (Index i) => (i, i) -> i -> Bool
+inBoundsTest bnds i = case inBounds bnds i of
+  ER -> isEmpty     bnds
+  IN -> inRange     bnds i
+  OR -> isOverflow  bnds i
+  UR -> isUnderflow bnds i
+
+{- |
+  'dumbSizeTest' is O(n) (may be very long) test, that checks relation of range
+  'size' and 'range' length.
+-}
+dumbSizeTest :: (Index i) => (i, i) -> Bool
+dumbSizeTest bnds = length (range bnds) == size bnds
+
+-- | 'basicIndexTest' checks relations of 'rank', 'size' and 'sizes'.
+basicIndexTest :: (Index i) => (i, i) -> i -> Bool
+basicIndexTest bnds@(l, u) i = and
+  [
+    rank u == rank i,
+    rank l == rank i,
+    
+    length  (sizes bnds) == rank i,
+    product (sizes bnds) == size bnds
+  ]
+
+{- |
+  'indexTest' is complex test, that includes all other tests.
+  May crash with very big numbers (Word64, Integer) because the tested functions
+  are limited by size of type Int.
+  In practice, structures of such sizes would take more memory than the address
+  space of computers can accommodate.
+-}
+indexTest :: (Index i) => (i, i) -> i -> Bool
+indexTest bnds i = and
+  [
+    basicIndexTest bnds i,
+    inBoundsTest   bnds i,
+    rangeTest      bnds i,
+    prevTest       bnds,
+    nextTest       bnds
+  ]
+
+
+
+
diff --git a/src/Test/SDP/Indexed.hs b/src/Test/SDP/Indexed.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP/Indexed.hs
@@ -0,0 +1,90 @@
+{- |
+    Module      :  Test.SDP.Indexed
+    Copyright   :  (c) Andrey Mulik 2019
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  non-portable (requires non-portable modules)
+    
+    @Test.SDP.Indexed@ provides simple set of test for 'Indexed' class.
+-}
+module Test.SDP.Indexed
+(
+  -- * Indexed test
+  TestIndexed, TestIndexed1, TestIndexed2, indexedTest,
+  
+  -- ** Particular tests
+  basicIndexedTest, assocIndexedTest, readIndexedTest
+)
+where
+
+import Prelude ()
+import SDP.SafePrelude
+import SDP.Indexed
+
+import Data.Maybe
+
+default ()
+
+--------------------------------------------------------------------------------
+
+-- | TestIndexed  is service type synonym for more comfortable quickCheck using.
+type TestIndexed  l i = i -> l -> Bool
+
+-- | TestIndexed1 is service type synonym for more comfortable quickCheck using.
+type TestIndexed1 l i e = i -> l e -> Bool
+
+-- | TestIndexed2 is service type synonym for more comfortable quickCheck using.
+type TestIndexed2 l i e = i -> l i e -> Bool
+
+--------------------------------------------------------------------------------
+
+-- | 'basicIndexedTest' checks relations of 'isNull', 'safeElem' and 'inRange'.
+basicIndexedTest :: (Bordered l i, Indexed l i e) => i -> l -> Bool
+basicIndexedTest i es = let bnds = bounds es in isNull es || inRange bnds (safeElem bnds i)
+
+{- |
+  'assocIndexedTest' checks relations of 'assoc', 'assocs', ('.$'), ('*$') and
+  ('//').
+-}
+assocIndexedTest :: (Bordered l i, Indexed l i e, Eq e, Eq l) => i -> l -> Bool
+assocIndexedTest i es = and
+  [
+    assoc (bounds es) (assocs es) == es,
+    
+    es // (assocs es) == es,
+    Z  // (assocs es) == es,
+    es //     []      == es,
+    
+    -- if structure contain dublicates, (.$) may find earlier match.
+    isNull es || i' >= fromJust ((== es ! i') .$ es),
+    isNull es || elem i' ((== es!safeElem bnds i) *$ es)
+  ]
+  where
+    i'   = safeElem bnds i
+    bnds = bounds es
+
+-- | 'readIndexedTest' checks relations of 'listL', ('.!'), ('!') and ('!?').
+readIndexedTest :: (Bordered l i, Indexed l i e, Eq e) => i -> l -> Bool
+readIndexedTest i es = and
+    [
+      -- just check (.!) on all range
+      fmap (es .!) (indices es) == listL es,
+      isNull es || (es ! i' == es .! i'),
+      
+      inRange bnds i || isNothing (es !? i),
+      isNull es || isJust (es !? i')
+    ]
+  where
+    i'   = safeElem bnds i
+    bnds = bounds es
+
+-- | 'indexedTest' is complex test, that includes all other tests.
+indexedTest :: (Bordered l i, Indexed l i e, Eq e, Eq l) => i -> l -> Bool
+indexedTest i es = and
+  [
+    basicIndexedTest i es,
+    assocIndexedTest i es,
+    readIndexedTest  i es
+  ]
+
+
diff --git a/src/Test/SDP/Linear.hs b/src/Test/SDP/Linear.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP/Linear.hs
@@ -0,0 +1,130 @@
+{- |
+    Module      :  Test.SDP.Linear
+    Copyright   :  (c) Andrey Mulik 2019
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  non-portable (requires non-portable modules)
+    
+    @Test.SDP.Linear@ provides basic test suite for 'Linear' class.
+-}
+module Test.SDP.Linear
+(
+  -- * Default Linear test
+  TestLinear, TestLinear1, TestLinear2, linearTest,
+  
+  -- ** Particular tests
+  deconstructionLinearTest, constructionLinearTest, basicLinearTest,
+  replicateTest, reverseTest, concatTest
+)
+where
+
+import Prelude ()
+import SDP.SafePrelude
+import SDP.Linear
+
+default ()
+
+--------------------------------------------------------------------------------
+
+-- | 'TestLinear' is service type synonym for more comfortable quickCheck using.
+type TestLinear  l e = Int -> e -> l -> Bool
+
+-- | 'TestLinear1' is service type synonym for more comfortable quickCheck using.
+type TestLinear1 f e = Int -> e -> f e -> Bool
+
+-- | 'TestLinear2' is service type synonym for more comfortable quickCheck using.
+type TestLinear2 f i e = Int -> e -> f i e -> Bool
+
+--------------------------------------------------------------------------------
+
+{- |
+  'basicLinearTest' checks relations of 'isNull', 'lzero', 'single' and
+  'fromList'.
+-}
+basicLinearTest :: (Linear l e, Eq l) => e -> l -> Bool
+basicLinearTest e line = and
+  [
+    isNull (   lzero    `asTypeOf` line),
+    isNull (fromList [] `asTypeOf` line),
+    
+    single  e == (fromList [e] `asTypeOf` line),
+    not $ isNull (  single e   `asTypeOf` line),
+    
+    fromList (listL line) == line
+  ]
+
+{- |
+  'deconstructionLinearTest' checks relations of 'isNull', 'head', 'last',
+  'init' and 'tail'.
+-}
+deconstructionLinearTest :: (Linear l e, Eq e) => l -> Bool
+deconstructionLinearTest line = and
+  [
+    isNull line || head line == head (listL line),
+    isNull line || last line == last (listL line),
+    
+    isNull line || listL (init line) == init (listL line),
+    isNull line || listL (tail line) == tail (listL line)
+  ]
+
+{- |
+  'constructionLinearTest' checks relations of 'toHead', 'toLast' and
+  'fromList'.
+-}
+constructionLinearTest :: (Linear l e, Eq l) => e -> l -> Bool
+constructionLinearTest e line = and
+  [
+    toHead e line == fromList (e  :  listL  line),
+    toLast line e == fromList (listL line ++ [e]),
+    
+    not . isNull $ toHead e line,
+    not . isNull $ toLast line e
+  ]
+
+-- | 'reverseTest' checks rules of 'reverse', 'listL' and 'listR'.
+reverseTest :: (Linear l e, Eq e) => l -> Bool
+reverseTest line = and
+  [
+    reverse (listL line) == listL (reverse line),
+    reverse (listL line) == listR line
+  ]
+
+-- | 'replicateTest' checks rules of 'replicate'.
+replicateTest :: (Linear l e, Eq l, Bordered l i) => Int -> e -> l -> Bool
+replicateTest n e line = and
+  [
+    line' == fromList (replicate n e),
+    n < 0 || sizeOf line' == n,
+    not $ n > 0 && isNull line'
+  ]
+  where
+    line' = (replicate n e) `asTypeOf` line
+
+-- | 'concatTest' checks rules of ('++') and 'concat'.
+concatTest :: (Linear l e, Eq e, Eq l) => l -> Bool
+concatTest line = and
+  [
+    listL line ++ listR line == listL (line ++ reverse line),
+    
+    Z ++ line == line,
+    line ++ Z == line,
+    
+    concat [line, reverse line] == fromList (concat [listL line, listR line]),
+    concat [line, reverse line] == line ++ reverse line
+  ]
+
+-- | 'linearTest' is complex test, that includes all ther tests.
+linearTest :: (Linear l e, Eq e, Eq l, Bordered l i) => Int -> e -> l -> Bool
+linearTest n e line = and
+  [
+    basicLinearTest e line,
+    deconstructionLinearTest line,
+    constructionLinearTest e line,
+    replicateTest n e line,
+    reverseTest line,
+    concatTest line
+  ]
+
+
+
+
diff --git a/src/Test/SDP/Ord.hs b/src/Test/SDP/Ord.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP/Ord.hs
@@ -0,0 +1,50 @@
+{- |
+    Module      :  Test.SDP.Ord
+    Copyright   :  (c) Andrey Mulik 2019
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  portable
+    
+    @Test.SDP.Ord@ provides basic test suite for 'Ord' instances.
+-}
+module Test.SDP.Ord
+(
+  -- * Ord test
+  TestOrd, ordTest,
+  
+  -- ** Lexicographic test
+  lexicographicOrdTest
+)
+where
+
+import Prelude ()
+import SDP.SafePrelude
+import SDP.Linear
+
+default ()
+
+--------------------------------------------------------------------------------
+
+-- | TestOrd is service type synonym for more comfortable quickCheck using.
+type TestOrd l = l -> l -> l -> Bool
+
+--------------------------------------------------------------------------------
+
+-- | ordTest is basic test suite for 'Ord' instances.
+ordTest :: (Ord l) => l -> l -> l -> Bool
+ordTest xs ys zs = and
+  [
+    -- antisymmetry
+    (xs <= ys && ys <= xs) <= (xs == ys),
+    
+    -- transitivity
+    (xs <= ys && ys <= zs) <= (xs <= zs),
+    
+    -- totality
+    (xs <= ys) /= (xs > ys)
+  ]
+
+-- | lexicographicOrdTest checks 'Linear' structures for lexicographic order.
+lexicographicOrdTest :: (Linear l e, Ord l, Ord e) => l -> l -> Bool
+lexicographicOrdTest xs ys = (xs <=> ys) == (listL xs <=> listL ys)
+
diff --git a/src/Test/SDP/Set.hs b/src/Test/SDP/Set.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP/Set.hs
@@ -0,0 +1,150 @@
+{- |
+    Module      :  Test.SDP.Set
+    Copyright   :  (c) Andrey Mulik 2019
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  non-portable (requires non-portable modules)
+    
+    @Test.SDP.Set@ provides basic test quite for 'Set' class.
+-}
+module Test.SDP.Set
+(
+  -- * Set test
+  TestSet, TestSet1, setTest,
+  
+  -- * Particular tests
+  basicSetTest, insdelSetTest, lookupSetTest, unintSetTest, diffSetTest,
+  elemSetTest
+)
+where
+
+import Prelude ()
+import SDP.SafePrelude
+import SDP.Linear
+import SDP.Set
+
+default ()
+
+--------------------------------------------------------------------------------
+
+-- | TestSet  is service type synonym for more comfortable quickCheck using.
+type TestSet  s o = o -> s -> s -> Bool
+
+-- | TestSet1 is service type synonym for more comfortable quickCheck using.
+type TestSet1 s o = o -> s o -> s o -> Bool
+
+--------------------------------------------------------------------------------
+
+{- |
+  'basicSetTest' checks relations of 'set', ('/?\') and ('\?/').
+  Note that basicSetTest requires any @('Set' s o) => s@, not necessarily a set
+  (may contain any data).
+-}
+basicSetTest :: (Set s o, Nullable s, Eq s, Ord o) => s -> Bool
+basicSetTest sx = and
+    [
+      isNull sx == isNull sx',
+      
+      set sx' == sx',
+      
+      (sx' \?/ sx') /= (sx' /?\ sx')
+    ]
+  where
+    sx' = set sx
+
+{- |
+  'insdelSetTest' checks rules of 'insert' and 'delete'.
+  Note that 'insdelSetTest' requires a set, not any @('Set' s o) => s@.
+-}
+insdelSetTest :: (Set s o, Eq s, Ord o) => o -> s -> Bool
+insdelSetTest e sx' = and
+  [
+    (insert e sx' == sx') || not (member e sx'),
+    (delete e sx' == sx') ||     (member e sx')
+  ]
+
+{- |
+  'unintSetTest' checks the laws of union ('\/') and intersection ('/\').
+  Note that unintSetTest requires any @('Set' s o) => s@, not necessarily a set
+  (may contain any data).
+-}
+unintSetTest :: (Set s o, Linear s o, Ord o) => s -> s -> Bool
+unintSetTest sx' sy' = and
+    [
+      (is `isSubseqOf` sx') && (is  `isSubseqOf` sy') && (is `isSubseqOf` un),
+      (sx' `isSubseqOf` un) && (sy' `isSubseqOf` un)
+    ]
+  where
+    is = sx' /\  sy'
+    un = sx' \/  sy'
+
+{- |
+  'diffSetTest' checks laws of difference ('\\') and symmetric difference
+  ('\^/'). Note that diffSetTest requires a set, not any @('Set' s o) => s@
+-}
+diffSetTest :: (Set s o, Linear s o, Ord o) => s -> s -> Bool
+diffSetTest sx' sy' = and
+    [
+      (cp `isSubseqOf` sx') && (isNull cp || not (cp `isSubseqOf` sy')) && (cp `isSubseqOf` un),
+      (isNull sd && isNull is || sd /?\ is) && (sd `isSubseqOf` un)
+    ]
+  where
+    is = sx' /\  sy'
+    un = sx' \/  sy'
+    cp = sx' \\  sy'
+    sd = sx' \^/ sy'
+
+{- |
+  'elemSetTest' checks relations of 'member' and 'isSubseqOf'.
+  Note that elemSetTest requires any @('Set' s o) => s@, not necessarily a set
+  (may contain any data).
+-}
+elemSetTest :: (Set s o, Linear s o, Ord o) => o -> s -> Bool
+elemSetTest e sx = and
+    [
+      (e' `isSubseqOf` sx) == member e sx',
+      (e' `isSubseqOf` sx) == member e sx'
+    ]
+  where
+    sx' = set sx; e' = single e
+
+{- |
+  'lookupSetTest' checks relations of 'lookupLT', 'lookupGT', 'lookupLE' and
+  'lookupGE'. Note that lookupSetTest requires a set, not any @('Set' s o) => s@.
+-}
+lookupSetTest :: (Set s o, Linear s o, Ord o) => o -> s -> Bool
+lookupSetTest e sx = and
+    [
+      lookupLT e sx == lookupLT e (listL sx),
+      lookupGT e sx == lookupGT e (listL sx),
+      lookupLE e sx == lookupLE e (listL sx),
+      lookupGE e sx == lookupGE e (listL sx),
+      
+      case lookupLT e sx of {Nothing -> True; Just x -> x <  e},
+      case lookupGT e sx of {Nothing -> True; Just x -> x >  e},
+      case lookupLE e sx of {Nothing -> True; Just x -> x <= e},
+      case lookupGE e sx of {Nothing -> True; Just x -> x >= e}
+    ]
+
+{- |
+  'setTest' is complex test, that includes all other tests.
+  Note that setTest requires any @('Set' s o) => s@, not necessarily a set (may
+  contain any data).
+-}
+setTest :: (Set s o, Linear s o, Ord s, Ord o) => o -> s -> s -> Bool
+setTest e xs ys = and
+    [
+      unintSetTest  sx sy,
+      diffSetTest   sx sy,
+      basicSetTest     xs,
+      insdelSetTest e  sx,
+      lookupSetTest e  sx,
+      elemSetTest   e  xs
+    ]
+  where
+    sx = set xs
+    sy = set ys
+
+
+
+
diff --git a/src/Test/SDP/Sort.hs b/src/Test/SDP/Sort.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP/Sort.hs
@@ -0,0 +1,40 @@
+{- |
+    Module      :  Test.SDP.Sort
+    Copyright   :  (c) Andrey Mulik 2019
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  non-portable (requires non-portable modules).
+    
+    @Test.SDP.Sort@ provides simple test for 'Sort' class.
+-}
+module Test.SDP.Sort
+  (
+    -- * Exports
+    module Test.SDP.Gen,
+    
+    -- * Default test
+    sortTest
+  )
+where
+
+import Prelude ()
+import SDP.SafePrelude
+import SDP.Linear
+
+import Test.SDP.Gen
+
+default ()
+
+--------------------------------------------------------------------------------
+
+{- |
+  'sortTest' is just @sorted . sort@ synonym.
+  Please note that for default definition of @Arbitrary@ generates very short
+  structures and this isn't enough for verification (if the length of the
+  structure is less than 65, then TimSort uses InsertionSort).
+-}
+sortTest :: (Sort s e, Split s e, Bordered s i, Ord e) => Medium s -> Bool
+sortTest (Medium es) =  sorted (sort es)
+
+
+
diff --git a/src/Test/SDP/Split.hs b/src/Test/SDP/Split.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/SDP/Split.hs
@@ -0,0 +1,105 @@
+{- |
+    Module      :  Test.SDP.Split
+    Copyright   :  (c) Andrey Mulik 2021
+    License     :  BSD-style
+    Maintainer  :  work.a.mulik@gmail.com
+    Portability :  portable
+    
+    @Test.SDP.Split@ is service module that provides 'Split' tests.
+-}
+module Test.SDP.Split
+(
+  -- * Split test
+  TestSplit, TestSplit1, TestSplit2, splitTest,
+  
+  -- ** Particular tests
+  basicSplitTest, whileSplitTest
+)
+where
+
+import Prelude ()
+import SDP.SafePrelude
+import SDP.Linear
+
+default ()
+
+--------------------------------------------------------------------------------
+
+-- | 'TestSplit' is service type synonym for more comfortable quickCheck using.
+type TestSplit s = Int -> s -> Bool
+
+-- | 'TestSplit1' is service type synonym for more comfortable quickCheck using.
+type TestSplit1 s e = Int -> s e -> Bool
+
+-- | 'TestSplit2' is service type synonym for more comfortable quickCheck using.
+type TestSplit2 s i e = Int -> s i e -> Bool
+
+--------------------------------------------------------------------------------
+
+{- |
+  @'splitTest' f n xs@ is default 'Split' test, where @f@ is arbitrary predicate
+  (e.g. "Test.SDP.Gen.orderA").
+-}
+splitTest :: (Split s e, Eq e, Eq s, Bordered s i) => (e -> Bool) -> TestSplit s
+splitTest f n xs = and
+  [
+    basicSplitTest n xs,
+    whileSplitTest f xs
+  ]
+
+{- |
+  'basicSplitTest' checks 'take', 'drop', 'sans', 'keep', 'split' and 'divide'
+  correctness and relations.
+-}
+basicSplitTest :: (Split s e, Eq e, Eq s, Bordered s i) => TestSplit s
+basicSplitTest n xs = and
+    [
+      split  n xs == (tx, dx),
+      divide n xs == (sx, kx),
+      
+      listL tx == ty, listL dx == dy,
+      listL sx == sy, listL kx == ky,
+      
+      -- additional tests
+      lx == sizeOf tx + sizeOf dx,
+      lx == sizeOf sx + sizeOf kx
+    ]
+  where
+    lx = sizeOf xs
+    ys = listL  xs
+    
+    tx = take n xs; ty = take n ys
+    dx = drop n xs; dy = drop n ys
+    sx = sans n xs; sy = sans n ys
+    kx = keep n xs; ky = keep n ys
+
+{- |
+  'whileSplitTest' checks 'takeWhile', 'dropWhile', 'takeEnd', 'dropEnd',
+  'spanl', 'spanr', 'breakl' and 'breakr' correctness and relations.
+-}
+whileSplitTest :: (Split s e, Eq e, Eq s, Bordered s i) => (e -> Bool) -> s -> Bool
+whileSplitTest f xs = and
+    [
+      spanl f xs == (tx, dx), breakl f xs == (ntx, ndx),
+      spanr f xs == (sx, kx), breakr f xs == (nsx, nkx),
+      
+      listL tx == ty, listL dx == dy,
+      listL sx == sy, listL kx == ky,
+      
+      -- additional tests
+      lx == sizeOf  tx + sizeOf  dx,
+      lx == sizeOf  sx + sizeOf  kx,
+      lx == sizeOf ntx + sizeOf ndx,
+      lx == sizeOf nsx + sizeOf nkx
+    ]
+  where
+    lx = sizeOf xs
+    ys = listL  xs
+    
+    tx = takeWhile f xs; ty = takeWhile f ys; ntx = takeWhile (not . f) xs
+    dx = dropWhile f xs; dy = dropWhile f ys; ndx = dropWhile (not . f) xs
+    sx = dropEnd   f xs; sy = dropEnd   f ys; nsx = dropEnd   (not . f) xs
+    kx = takeEnd   f xs; ky = takeEnd   f ys; nkx = takeEnd   (not . f) xs
+
+
+
diff --git a/test/test-array.hs b/test/test-array.hs
new file mode 100644
--- /dev/null
+++ b/test/test-array.hs
@@ -0,0 +1,130 @@
+module Main where
+
+import Test.Framework.Providers.QuickCheck2
+import Test.Framework
+
+import SDP.Array
+
+import Test.SDP.Arbitrary ()
+import Test.SDP
+
+default ()
+
+--------------------------------------------------------------------------------
+
+main :: IO ()
+main = defaultMain
+  [
+    -- common tests
+    testProperty "array-eq             " eqProp,
+    testProperty "array-ord            " ordProp,
+    testProperty "array-lexicographic  " lgoProp,
+    
+    -- linear tests
+    testProperty "array-linear-basic   " basicLinearProp,
+    testProperty "array-linear-decons  " deconstructionLinearProp,
+    testProperty "array-linear-cons    " constructionLinearProp,
+    testProperty "array-linear-reverse " reverseProp,
+    testProperty "array-linear-concat  " concatProp,
+    
+    -- split test
+    testProperty "array-split          " splitProp,
+    
+    -- indexed tests
+    testProperty "array-indexed-basic  " basicIndexedProp,
+    testProperty "array-indexed-assoc  " assocIndexedProp,
+    testProperty "array-indexed-read   " readIndexedProp,
+    
+    -- sort test
+    testProperty "array-sort           " sortProp,
+    
+    -- set test
+    testProperty "array-set            " setProp,
+    
+    -- estimate test
+    testProperty "array-estimate       " estimateProp
+  ]
+
+--------------------------------------------------------------------------------
+
+{- Eq property. -}
+
+eqProp :: TestEq (Array Int Int)
+eqProp =  eqTest
+
+--------------------------------------------------------------------------------
+
+{- Ord property. -}
+
+ordProp :: TestOrd (Array Int Int)
+ordProp =  ordTest
+
+lgoProp :: Long (Array Int Int) -> Long (Array Int Int) -> Bool
+lgoProp (Long xs) (Long ys) = lexicographicOrdTest xs ys
+
+--------------------------------------------------------------------------------
+
+{- Linear properties. -}
+
+basicLinearProp          :: Char -> Array Int Char -> Bool
+basicLinearProp          =  basicLinearTest
+
+deconstructionLinearProp :: Array Int Char -> Bool
+deconstructionLinearProp =  deconstructionLinearTest
+
+constructionLinearProp   :: Char -> Array Int Char -> Bool
+constructionLinearProp   =  constructionLinearTest
+
+reverseProp              :: Array Int Char -> Bool
+reverseProp              =  reverseTest
+
+replicateProp            :: TestLinear2 Array Int Char
+replicateProp            =  replicateTest
+
+concatProp               :: Array Int Char -> Bool
+concatProp               =  concatTest
+
+--------------------------------------------------------------------------------
+
+{- Split property. -}
+
+splitProp :: Char -> TestSplit2 Array Int Char
+splitProp =  splitTest . (>)
+
+--------------------------------------------------------------------------------
+
+{- Indexed property. -}
+
+basicIndexedProp :: TestIndexed2 Array Int Char
+basicIndexedProp =  basicIndexedTest
+
+assocIndexedProp :: TestIndexed2 Array Int Char
+assocIndexedProp =  assocIndexedTest
+
+readIndexedProp  :: TestIndexed2 Array Int Char
+readIndexedProp  =  readIndexedTest
+
+--------------------------------------------------------------------------------
+
+{- Sort property. -}
+
+sortProp :: Medium (Array Int Char) -> Bool
+sortProp =  sortTest
+
+--------------------------------------------------------------------------------
+
+{- Set property. -}
+
+setProp :: TestSet1 (Array Int) Char
+setProp =  setTest
+
+--------------------------------------------------------------------------------
+
+{- Estimate property. -}
+
+estimateProp :: TestEstimate (Array Int Int)
+estimateProp =  estimateTest
+
+
+
+
diff --git a/test/test-bytelist.hs b/test/test-bytelist.hs
new file mode 100644
--- /dev/null
+++ b/test/test-bytelist.hs
@@ -0,0 +1,130 @@
+module Main where
+
+import Test.Framework.Providers.QuickCheck2
+import Test.Framework
+
+import SDP.ByteList
+
+import Test.SDP.Arbitrary ()
+import Test.SDP
+
+default ()
+
+--------------------------------------------------------------------------------
+
+main :: IO ()
+main = defaultMain
+  [
+    -- common tests
+    testProperty "bytelist-eq             " eqProp,
+    testProperty "bytelist-ord            " ordProp,
+    testProperty "bytelist-lexicographic  " lgoProp,
+    
+    -- linear tests
+    testProperty "bytelist-linear-basic   " basicLinearProp,
+    testProperty "bytelist-linear-decons  " deconstructionLinearProp,
+    testProperty "bytelist-linear-cons    " constructionLinearProp,
+    testProperty "bytelist-linear-reverse " reverseProp,
+    testProperty "bytelist-linear-concat  " concatProp,
+    
+    -- split test
+    testProperty "bytelist-split          " splitProp,
+    
+    -- indexed tests
+    testProperty "bytelist-indexed-basic  " basicIndexedProp,
+    testProperty "bytelist-indexed-assoc  " assocIndexedProp,
+    testProperty "bytelist-indexed-read   " readIndexedProp,
+    
+    -- sort test
+    testProperty "bytelist-sort           " sortProp,
+    
+    -- set test
+    testProperty "bytelist-set            " setProp,
+    
+    -- estimate test
+    testProperty "bytelist-estimate       " estimateProp
+  ]
+
+--------------------------------------------------------------------------------
+
+{- Eq property. -}
+
+eqProp :: TestEq (ByteList Int Int)
+eqProp =  eqTest
+
+--------------------------------------------------------------------------------
+
+{- Ord property. -}
+
+ordProp :: TestOrd (ByteList Int Int)
+ordProp =  ordTest
+
+lgoProp :: Long (ByteList Int Int) -> Long (ByteList Int Int) -> Bool
+lgoProp (Long xs) (Long ys) = lexicographicOrdTest xs ys
+
+--------------------------------------------------------------------------------
+
+{- Linear properties. -}
+
+basicLinearProp          :: Char -> ByteList Int Char -> Bool
+basicLinearProp          =  basicLinearTest
+
+deconstructionLinearProp :: ByteList Int Char -> Bool
+deconstructionLinearProp =  deconstructionLinearTest
+
+constructionLinearProp   :: Char -> ByteList Int Char -> Bool
+constructionLinearProp   =  constructionLinearTest
+
+reverseProp              :: ByteList Int Char -> Bool
+reverseProp              =  reverseTest
+
+replicateProp            :: TestLinear2 ByteList Int Char
+replicateProp            =  replicateTest
+
+concatProp               :: ByteList Int Char -> Bool
+concatProp               =  concatTest
+
+--------------------------------------------------------------------------------
+
+{- Split property. -}
+
+splitProp :: Char -> TestSplit2 ByteList Int Char
+splitProp =  splitTest . (>)
+
+--------------------------------------------------------------------------------
+
+{- Indexed property. -}
+
+basicIndexedProp :: TestIndexed2 ByteList Int Char
+basicIndexedProp =  basicIndexedTest
+
+assocIndexedProp :: TestIndexed2 ByteList Int Char
+assocIndexedProp =  assocIndexedTest
+
+readIndexedProp  :: TestIndexed2 ByteList Int Char
+readIndexedProp  =  readIndexedTest
+
+--------------------------------------------------------------------------------
+
+{- Sort property. -}
+
+sortProp :: Medium (ByteList Int Char) -> Bool
+sortProp =  sortTest
+
+--------------------------------------------------------------------------------
+
+{- Set property. -}
+
+setProp :: TestSet1 (ByteList Int) Char
+setProp =  setTest
+
+--------------------------------------------------------------------------------
+
+{- Estimate property. -}
+
+estimateProp :: TestEstimate (ByteList Int Int)
+estimateProp =  estimateTest
+
+
+
+
diff --git a/test/test-bytes.hs b/test/test-bytes.hs
new file mode 100644
--- /dev/null
+++ b/test/test-bytes.hs
@@ -0,0 +1,130 @@
+module Main where
+
+import Test.Framework.Providers.QuickCheck2
+import Test.Framework
+
+import SDP.Bytes
+
+import Test.SDP.Arbitrary ()
+import Test.SDP
+
+default ()
+
+--------------------------------------------------------------------------------
+
+main :: IO ()
+main = defaultMain
+  [
+    -- common tests
+    testProperty "bytes-eq             " eqProp,
+    testProperty "bytes-ord            " ordProp,
+    testProperty "bytes-lexicographic  " lgoProp,
+    
+    -- linear tests
+    testProperty "bytes-linear-basic   " basicLinearProp,
+    testProperty "bytes-linear-decons  " deconstructionLinearProp,
+    testProperty "bytes-linear-cons    " constructionLinearProp,
+    testProperty "bytes-linear-reverse " reverseProp,
+    testProperty "bytes-linear-concat  " concatProp,
+    
+    -- split test
+    testProperty "bytes-split          " splitProp,
+    
+    -- indexed tests
+    testProperty "bytes-indexed-basic  " basicIndexedProp,
+    testProperty "bytes-indexed-assoc  " assocIndexedProp,
+    testProperty "bytes-indexed-read   " readIndexedProp,
+    
+    -- sort test
+    testProperty "bytes-sort           " sortProp,
+    
+    -- set test
+    testProperty "bytes-set            " setProp,
+    
+    -- estimate test
+    testProperty "bytes-estimate       " estimateProp
+  ]
+
+--------------------------------------------------------------------------------
+
+{- Eq property. -}
+
+eqProp :: TestEq (Bytes Int Int)
+eqProp =  eqTest
+
+--------------------------------------------------------------------------------
+
+{- Ord property. -}
+
+ordProp :: TestOrd (Bytes Int Int)
+ordProp =  ordTest
+
+lgoProp :: Long (Bytes Int Int) -> Long (Bytes Int Int) -> Bool
+lgoProp (Long xs) (Long ys) = lexicographicOrdTest xs ys
+
+--------------------------------------------------------------------------------
+
+{- Linear properties. -}
+
+basicLinearProp          :: Char -> Bytes Int Char -> Bool
+basicLinearProp          =  basicLinearTest
+
+deconstructionLinearProp :: Bytes Int Char -> Bool
+deconstructionLinearProp =  deconstructionLinearTest
+
+constructionLinearProp   :: Char -> Bytes Int Char -> Bool
+constructionLinearProp   =  constructionLinearTest
+
+reverseProp              :: Bytes Int Char -> Bool
+reverseProp              =  reverseTest
+
+replicateProp            :: TestLinear2 Bytes Int Char
+replicateProp            =  replicateTest
+
+concatProp               :: Bytes Int Char -> Bool
+concatProp               =  concatTest
+
+--------------------------------------------------------------------------------
+
+{- Split property. -}
+
+splitProp :: Char -> TestSplit2 Bytes Int Char
+splitProp =  splitTest . (>)
+
+--------------------------------------------------------------------------------
+
+{- Indexed property. -}
+
+basicIndexedProp :: TestIndexed2 Bytes Int Char
+basicIndexedProp =  basicIndexedTest
+
+assocIndexedProp :: TestIndexed2 Bytes Int Char
+assocIndexedProp =  assocIndexedTest
+
+readIndexedProp  :: TestIndexed2 Bytes Int Char
+readIndexedProp  =  readIndexedTest
+
+--------------------------------------------------------------------------------
+
+{- Sort property. -}
+
+sortProp :: Medium (Bytes Int Char) -> Bool
+sortProp =  sortTest
+
+--------------------------------------------------------------------------------
+
+{- Set property. -}
+
+setProp :: TestSet1 (Bytes Int) Char
+setProp =  setTest
+
+--------------------------------------------------------------------------------
+
+{- Estimate property. -}
+
+estimateProp :: TestEstimate (Bytes Int Int)
+estimateProp =  estimateTest
+
+
+
+
diff --git a/test/test-indices.hs b/test/test-indices.hs
new file mode 100644
--- /dev/null
+++ b/test/test-indices.hs
@@ -0,0 +1,130 @@
+module Main where
+
+import Test.Framework.Providers.QuickCheck2
+import Test.Framework
+
+import SDP.Index
+
+import Test.SDP.Arbitrary ()
+import Test.SDP.Index
+
+default ()
+
+--------------------------------------------------------------------------------
+
+main :: IO ()
+main = defaultMain
+  [
+    testProperty "index-int   " testIndexInt,
+    testProperty "index-int8  " testIndexInt8,
+    testProperty "index-int16 " testIndexInt16,
+    testProperty "index-int32 " testIndexInt32,
+    
+    testProperty "index-word  " testIndexWord,
+    testProperty "index-word8 " testIndexWord8,
+    testProperty "index-word16" testIndexWord16,
+    testProperty "index-word32" testIndexWord32,
+    
+    testProperty "index-char  " testIndexChar,
+    
+    testProperty "index-ind2  " testIndexI2,
+    testProperty "index-ind3  " testIndexI3,
+    testProperty "index-ind4  " testIndexI4,
+    testProperty "index-ind5  " testIndexI5,
+    testProperty "index-ind6  " testIndexI6,
+    testProperty "index-ind7  " testIndexI7,
+    testProperty "index-ind8  " testIndexI8,
+    testProperty "index-ind9  " testIndexI9,
+    testProperty "index-ind10 " testIndexI10,
+    testProperty "index-ind11 " testIndexI11,
+    testProperty "index-ind12 " testIndexI12,
+    testProperty "index-ind13 " testIndexI13,
+    testProperty "index-ind14 " testIndexI14,
+    testProperty "index-ind15 " testIndexI15
+  ]
+
+--------------------------------------------------------------------------------
+
+{- Int properties. -}
+
+testIndexInt   :: TestIndex Int
+testIndexInt   =  indexTest
+
+testIndexInt8  :: TestIndex Int8
+testIndexInt8  =  indexTest
+
+testIndexInt16 :: TestIndex Int16
+testIndexInt16 =  indexTest
+
+testIndexInt32 :: TestIndex Int32
+testIndexInt32 =  indexTest
+
+--------------------------------------------------------------------------------
+
+{- Word properties. -}
+
+testIndexWord   :: TestIndex Word
+testIndexWord   =  indexTest
+
+testIndexWord8  :: TestIndex Word8
+testIndexWord8  =  indexTest
+
+testIndexWord16 :: TestIndex Word16
+testIndexWord16 =  indexTest
+
+testIndexWord32 :: TestIndex Word32
+testIndexWord32 =  indexTest
+
+--------------------------------------------------------------------------------
+
+{- N-dimensional properties. -}
+
+testIndexI2  :: TestIndex (I2 Int)
+testIndexI2  =  indexTest
+
+testIndexI3  :: TestIndex (I3 Int)
+testIndexI3  =  indexTest
+
+testIndexI4  :: TestIndex (I4 Int)
+testIndexI4  =  indexTest
+
+testIndexI5  :: TestIndex (I5 Int)
+testIndexI5  =  indexTest
+
+testIndexI6  :: TestIndex (I6 Int)
+testIndexI6  =  indexTest
+
+testIndexI7  :: TestIndex (I7 Int)
+testIndexI7  =  indexTest
+
+testIndexI8  :: TestIndex (I8 Int)
+testIndexI8  =  indexTest
+
+testIndexI9  :: TestIndex (I9 Int)
+testIndexI9  =  indexTest
+
+testIndexI10 :: TestIndex (I10 Int)
+testIndexI10 =  indexTest
+
+testIndexI11 :: TestIndex (I11 Int)
+testIndexI11 =  indexTest
+
+testIndexI12 :: TestIndex (I12 Int)
+testIndexI12 =  indexTest
+
+testIndexI13 :: TestIndex (I13 Int)
+testIndexI13 =  indexTest
+
+testIndexI14 :: TestIndex (I14 Int)
+testIndexI14 =  indexTest
+
+testIndexI15 :: TestIndex (I15 Int)
+testIndexI15 =  indexTest
+
+--------------------------------------------------------------------------------
+
+{- Other properties. -}
+
+testIndexChar :: TestIndex Char
+testIndexChar =  indexTest
+
diff --git a/test/test-ublist.hs b/test/test-ublist.hs
new file mode 100644
--- /dev/null
+++ b/test/test-ublist.hs
@@ -0,0 +1,130 @@
+module Main where
+
+import Test.Framework.Providers.QuickCheck2
+import Test.Framework
+
+import SDP.ByteList.Ublist
+
+import Test.SDP.Arbitrary ()
+import Test.SDP
+
+default ()
+
+--------------------------------------------------------------------------------
+
+main :: IO ()
+main = defaultMain
+  [
+    -- common tests
+    testProperty "ublist-eq             " eqProp,
+    testProperty "ublist-ord            " ordProp,
+    testProperty "ublist-lexicographic  " lgoProp,
+    
+    -- linear tests
+    testProperty "ublist-linear-basic   " basicLinearProp,
+    testProperty "ublist-linear-decons  " deconstructionLinearProp,
+    testProperty "ublist-linear-cons    " constructionLinearProp,
+    testProperty "ublist-linear-reverse " reverseProp,
+    testProperty "ublist-linear-concat  " concatProp,
+    
+    -- split test
+    testProperty "ublist-split          " splitProp,
+    
+    -- indexed tests
+    testProperty "ublist-indexed-basic  " basicIndexedProp,
+    testProperty "ublist-indexed-assoc  " assocIndexedProp,
+    testProperty "ublist-indexed-read   " readIndexedProp,
+    
+    -- sort test
+    testProperty "ublist-sort           " sortProp,
+    
+    -- set test
+    testProperty "ublist-set            " setProp,
+    
+    -- estimate test
+    testProperty "ublist-estimate       " estimateProp
+  ]
+
+--------------------------------------------------------------------------------
+
+{- Eq property. -}
+
+eqProp :: TestEq (Ublist Int)
+eqProp =  eqTest
+
+--------------------------------------------------------------------------------
+
+{- Ord property. -}
+
+ordProp :: TestOrd (Ublist Int)
+ordProp =  ordTest
+
+lgoProp :: Long (Ublist Int) -> Long (Ublist Int) -> Bool
+lgoProp (Long xs) (Long ys) = lexicographicOrdTest xs ys
+
+--------------------------------------------------------------------------------
+
+{- Linear properties. -}
+
+basicLinearProp          :: Char -> Ublist Char -> Bool
+basicLinearProp          =  basicLinearTest
+
+deconstructionLinearProp :: Ublist Char -> Bool
+deconstructionLinearProp =  deconstructionLinearTest
+
+constructionLinearProp   :: Char -> Ublist Char -> Bool
+constructionLinearProp   =  constructionLinearTest
+
+reverseProp              :: Ublist Char -> Bool
+reverseProp              =  reverseTest
+
+replicateProp            :: TestLinear1 Ublist Char
+replicateProp            =  replicateTest
+
+concatProp               :: Ublist Char -> Bool
+concatProp               =  concatTest
+
+--------------------------------------------------------------------------------
+
+{- Split property. -}
+
+splitProp :: Char -> TestSplit1 Ublist Char
+splitProp =  splitTest . (>)
+
+--------------------------------------------------------------------------------
+
+{- Indexed property. -}
+
+basicIndexedProp :: TestIndexed1 Ublist Int Char
+basicIndexedProp =  basicIndexedTest
+
+assocIndexedProp :: TestIndexed1 Ublist Int Char
+assocIndexedProp =  assocIndexedTest
+
+readIndexedProp  :: TestIndexed1 Ublist Int Char
+readIndexedProp  =  readIndexedTest
+
+--------------------------------------------------------------------------------
+
+{- Sort property. -}
+
+sortProp :: Medium (Ublist Char) -> Bool
+sortProp =  sortTest
+
+--------------------------------------------------------------------------------
+
+{- Set property. -}
+
+setProp :: TestSet1 Ublist Char
+setProp =  setTest
+
+--------------------------------------------------------------------------------
+
+{- Estimate property. -}
+
+estimateProp :: TestEstimate (Ublist Int)
+estimateProp =  estimateTest
+
+
+
+
diff --git a/test/test-unlist.hs b/test/test-unlist.hs
new file mode 100644
--- /dev/null
+++ b/test/test-unlist.hs
@@ -0,0 +1,130 @@
+module Main where
+
+import Test.Framework.Providers.QuickCheck2
+import Test.Framework
+
+import SDP.Unrolled.Unlist
+
+import Test.SDP.Arbitrary ()
+import Test.SDP
+
+default ()
+
+--------------------------------------------------------------------------------
+
+main :: IO ()
+main = defaultMain
+  [
+    -- common tests
+    testProperty "unlist-eq             " eqProp,
+    testProperty "unlist-ord            " ordProp,
+    testProperty "unlist-lexicographic  " lgoProp,
+    
+    -- linear tests
+    testProperty "unlist-linear-basic   " basicLinearProp,
+    testProperty "unlist-linear-decons  " deconstructionLinearProp,
+    testProperty "unlist-linear-cons    " constructionLinearProp,
+    testProperty "unlist-linear-reverse " reverseProp,
+    testProperty "unlist-linear-concat  " concatProp,
+    
+    -- split test
+    testProperty "unlist-split          " splitProp,
+    
+    -- indexed tests
+    testProperty "unlist-indexed-basic  " basicIndexedProp,
+    testProperty "unlist-indexed-assoc  " assocIndexedProp,
+    testProperty "unlist-indexed-read   " readIndexedProp,
+    
+    -- sort test
+    testProperty "unlist-sort           " sortProp,
+    
+    -- set test
+    testProperty "unlist-set            " setProp,
+    
+    -- estimate test
+    testProperty "unlist-estimate       " estimateProp
+  ]
+
+--------------------------------------------------------------------------------
+
+{- Eq property. -}
+
+eqProp :: TestEq (Unlist Int)
+eqProp =  eqTest
+
+--------------------------------------------------------------------------------
+
+{- Ord property. -}
+
+ordProp :: TestOrd (Unlist Int)
+ordProp =  ordTest
+
+lgoProp :: Long (Unlist Int) -> Long (Unlist Int) -> Bool
+lgoProp (Long xs) (Long ys) = lexicographicOrdTest xs ys
+
+--------------------------------------------------------------------------------
+
+{- Linear properties. -}
+
+basicLinearProp          :: Char -> Unlist Char -> Bool
+basicLinearProp          =  basicLinearTest
+
+deconstructionLinearProp :: Unlist Char -> Bool
+deconstructionLinearProp =  deconstructionLinearTest
+
+constructionLinearProp   :: Char -> Unlist Char -> Bool
+constructionLinearProp   =  constructionLinearTest
+
+reverseProp              :: Unlist Char -> Bool
+reverseProp              =  reverseTest
+
+replicateProp            :: TestLinear1 Unlist Char
+replicateProp            =  replicateTest
+
+concatProp               :: Unlist Char -> Bool
+concatProp               =  concatTest
+
+--------------------------------------------------------------------------------
+
+{- Split property. -}
+
+splitProp :: Char -> TestSplit1 Unlist Char
+splitProp =  splitTest . (>)
+
+--------------------------------------------------------------------------------
+
+{- Indexed property. -}
+
+basicIndexedProp :: TestIndexed1 Unlist Int Char
+basicIndexedProp =  basicIndexedTest
+
+assocIndexedProp :: TestIndexed1 Unlist Int Char
+assocIndexedProp =  assocIndexedTest
+
+readIndexedProp  :: TestIndexed1 Unlist Int Char
+readIndexedProp  =  readIndexedTest
+
+--------------------------------------------------------------------------------
+
+{- Sort property. -}
+
+sortProp :: Medium (Unlist Char) -> Bool
+sortProp =  sortTest
+
+--------------------------------------------------------------------------------
+
+{- Set property. -}
+
+setProp :: TestSet1 Unlist Char
+setProp =  setTest
+
+--------------------------------------------------------------------------------
+
+{- Estimate property. -}
+
+estimateProp :: TestEstimate (Unlist Int)
+estimateProp =  estimateTest
+
+
+
+
diff --git a/test/test-unrolled.hs b/test/test-unrolled.hs
new file mode 100644
--- /dev/null
+++ b/test/test-unrolled.hs
@@ -0,0 +1,130 @@
+module Main where
+
+import Test.Framework.Providers.QuickCheck2
+import Test.Framework
+
+import SDP.Unrolled
+
+import Test.SDP.Arbitrary ()
+import Test.SDP
+
+default ()
+
+--------------------------------------------------------------------------------
+
+main :: IO ()
+main = defaultMain
+  [
+    -- common tests
+    testProperty "unrolled-eq             " eqProp,
+    testProperty "unrolled-ord            " ordProp,
+    testProperty "unrolled-lexicographic  " lgoProp,
+    
+    -- linear tests
+    testProperty "unrolled-linear-basic   " basicLinearProp,
+    testProperty "unrolled-linear-decons  " deconstructionLinearProp,
+    testProperty "unrolled-linear-cons    " constructionLinearProp,
+    testProperty "unrolled-linear-reverse " reverseProp,
+    testProperty "unrolled-linear-concat  " concatProp,
+    
+    -- split test
+    testProperty "unrolled-split          " splitProp,
+    
+    -- indexed tests
+    testProperty "unrolled-indexed-basic  " basicIndexedProp,
+    testProperty "unrolled-indexed-assoc  " assocIndexedProp,
+    testProperty "unrolled-indexed-read   " readIndexedProp,
+    
+    -- sort test
+    testProperty "unrolled-sort           " sortProp,
+    
+    -- set test
+    testProperty "unrolled-set            " setProp,
+    
+    -- estimate test
+    testProperty "unrolled-estimate       " estimateProp
+  ]
+
+--------------------------------------------------------------------------------
+
+{- Eq property. -}
+
+eqProp :: TestEq (Unrolled Int Int)
+eqProp =  eqTest
+
+--------------------------------------------------------------------------------
+
+{- Ord property. -}
+
+ordProp :: TestOrd (Unrolled Int Int)
+ordProp =  ordTest
+
+lgoProp :: Long (Unrolled Int Int) -> Long (Unrolled Int Int) -> Bool
+lgoProp (Long xs) (Long ys) = lexicographicOrdTest xs ys
+
+--------------------------------------------------------------------------------
+
+{- Linear properties. -}
+
+basicLinearProp          :: Char -> Unrolled Int Char -> Bool
+basicLinearProp          =  basicLinearTest
+
+deconstructionLinearProp :: Unrolled Int Char -> Bool
+deconstructionLinearProp =  deconstructionLinearTest
+
+constructionLinearProp   :: Char -> Unrolled Int Char -> Bool
+constructionLinearProp   =  constructionLinearTest
+
+reverseProp              :: Unrolled Int Char -> Bool
+reverseProp              =  reverseTest
+
+replicateProp            :: TestLinear2 Unrolled Int Char
+replicateProp            =  replicateTest
+
+concatProp               :: Unrolled Int Char -> Bool
+concatProp               =  concatTest
+
+--------------------------------------------------------------------------------
+
+{- Split property. -}
+
+splitProp :: Char -> TestSplit2 Unrolled Int Char
+splitProp =  splitTest . (>)
+
+--------------------------------------------------------------------------------
+
+{- Indexed property. -}
+
+basicIndexedProp :: TestIndexed2 Unrolled Int Char
+basicIndexedProp =  basicIndexedTest
+
+assocIndexedProp :: TestIndexed2 Unrolled Int Char
+assocIndexedProp =  assocIndexedTest
+
+readIndexedProp  :: TestIndexed2 Unrolled Int Char
+readIndexedProp  =  readIndexedTest
+
+--------------------------------------------------------------------------------
+
+{- Sort property. -}
+
+sortProp :: Medium (Unrolled Int Char) -> Bool
+sortProp =  sortTest
+
+--------------------------------------------------------------------------------
+
+{- Set property. -}
+
+setProp :: TestSet1 (Unrolled Int) Int
+setProp =  setTest
+
+--------------------------------------------------------------------------------
+
+{- Estimate property. -}
+
+estimateProp :: TestEstimate (Unrolled Int Int)
+estimateProp =  estimateTest
+
+
+
+
