diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/enumeration.cabal b/enumeration.cabal
--- a/enumeration.cabal
+++ b/enumeration.cabal
@@ -1,17 +1,17 @@
-Name:                   enumeration
-Category:               Data, Serialization, Test, Testing
-Version:                0.1.0
-License:                BSD3
-License-File:           LICENSE
-Author:                 Eric McCorkle
-Maintainer:             Eric McCorkle <emc2@metricspace.net>
-Stability:              Beta
-Synopsis:               A practical API for building recursive enumeration
-                        procedures and enumerating datatypes.
-Homepage:               https://github.com/emc2/enumeration
-Bug-Reports:            https://github.com/emc2/enumeration/issues
-Copyright:              Copyright (c) 2014 Eric McCorkle.  All rights reserved.
-Description:
+name: enumeration
+version: 0.2.0
+cabal-version: >=1.16
+license: BSD3
+license-file: LICENSE
+copyright: Copyright (c) 2014 Eric McCorkle.  All rights reserved.
+maintainer: Eric McCorkle <emc2@metricspace.net>, Andrew Lelechenko <andrew.lelechenko@gmail.com>
+author: Eric McCorkle
+stability: Beta
+homepage: https://github.com/emc2/enumeration
+bug-reports: https://github.com/emc2/enumeration/issues
+synopsis: A practical API for building recursive enumeration
+          procedures and enumerating datatypes.
+description:
   A library providing tools for building enumeration procedures for recursively-
   enumerable datatypes.  This is built atop the arith-encode library, and makes
   use of the natural number isomorphisms it provides to represent individual
@@ -30,31 +30,44 @@
   enumeration procedure can double as a binary serializer/deserializer.  For
   well-behaved enumeration procedures (ie. those where the mapping is an
   isomorphism), the resulting binary format should be very nearly succinct.
-  .
-  This is the first release candidate for 1.0 (initial release)
-Build-type:             Simple
-Cabal-version:          >= 1.16
+category: Data, Serialization, Test, Testing
+build-type: Simple
+tested-with: GHC==8.8.1, GHC==8.6.5, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2
 
-Source-Repository head
-  Type: git
-  Location: git@github.com:emc2/enumeration.git
+source-repository head
+  type: git
+  location: git@github.com:Bodigrim/enumeration.git
 
-Test-Suite UnitTest
-  default-language:     Haskell2010
-  type:                 exitcode-stdio-1.0
-  Main-Is:              UnitTest.hs
-  hs-source-dirs:       src test
-  build-depends:        base >= 4.4.0 && < 5, Cabal >= 1.16.0, HUnit-Plus, arith-encode,
-                        containers, binary, arithmoi, heap
-  ghc-options:          -fhpc
+library
+  exposed-modules:
+    Data.Enumeration
+    Data.Enumeration.Binary
+    Data.Enumeration.Traversal
+  hs-source-dirs: src
+  other-modules:
+    Data.Enumeration.Traversal.Class
+  default-language: Haskell2010
+  build-depends:
+    base >=4.9.0 && <5,
+    arith-encode,
+    binary,
+    containers,
+    heap,
+    integer-logarithms
 
-Library
-  default-language:     Haskell2010
-  hs-source-dirs:       src
-  build-depends:        base >= 4.4.0 && < 5, Cabal >= 1.16.0, containers, arith-encode,
-                        binary, arithmoi, heap
-  exposed-modules:      Data.Enumeration
-                        Data.Enumeration.Binary
-                        Data.Enumeration.Traversal
+test-suite UnitTest
+  type: exitcode-stdio-1.0
+  main-is: UnitTest.hs
   other-modules:
-                        Data.Enumeration.Traversal.Class
+    Tests.Data
+    Tests.Data.Enumeration
+    Tests.Data.Enumeration.Binary
+    Tests.Data.Enumeration.Traversal
+  hs-source-dirs: test
+  default-language: Haskell2010
+  build-depends:
+    base >=4.9.0 && <5,
+    arith-encode,
+    binary,
+    enumeration,
+    HUnit-Plus
diff --git a/test/Tests/Data.hs b/test/Tests/Data.hs
new file mode 100644
--- /dev/null
+++ b/test/Tests/Data.hs
@@ -0,0 +1,38 @@
+-- Copyright (c) 2014 Eric McCorkle.  All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- 1. Redistributions of source code must retain the above copyright
+--    notice, this list of conditions and the following disclaimer.
+--
+-- 2. 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.
+--
+-- 3. Neither the name of the author nor the names of any contributors
+--    may be used to endorse or promote products derived from this software
+--    without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS
+-- 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.
+
+module Tests.Data(tests) where
+
+import Test.HUnitPlus.Base
+
+import qualified Tests.Data.Enumeration as Enumeration
+
+tests :: Test
+tests = "Data" ~: [Enumeration.tests]
diff --git a/test/Tests/Data/Enumeration.hs b/test/Tests/Data/Enumeration.hs
new file mode 100644
--- /dev/null
+++ b/test/Tests/Data/Enumeration.hs
@@ -0,0 +1,178 @@
+-- Copyright (c) 2014 Eric McCorkle.  All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- 1. Redistributions of source code must retain the above copyright
+--    notice, this list of conditions and the following disclaimer.
+--
+-- 2. 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.
+--
+-- 3. Neither the name of the author nor the names of any contributors
+--    may be used to endorse or promote products derived from this software
+--    without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS
+-- 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.
+
+module Tests.Data.Enumeration(tests) where
+
+import Data.Enumeration
+import Data.Word
+import Test.HUnitPlus.Base hiding (withPrefix)
+
+import qualified Data.ArithEncode as ArithEncode
+import qualified Tests.Data.Enumeration.Binary as Binary
+import qualified Tests.Data.Enumeration.Traversal as Traversal
+
+intervalWord8 :: Word8 -> Word8 -> ArithEncode.Encoding Word8
+intervalWord8 = ArithEncode.interval
+
+throwsIllegalArgument (IllegalArgument _) = assertSuccess
+throwsBadPath (BadPath _) = assertSuccess
+
+singletonTests enum val nonval prefixPath =
+  let
+    noRecurseTests enum = [
+        "toPath_succeed" ~: toPath enum val @?= [],
+        "toPath_fail" ~: assertThrows throwsIllegalArgument
+                                      (return $! toPath enum nonval),
+        "toSizedPath_succeed" ~: toSizedPath enum val @?= [],
+        "toSizedPath_fail" ~: assertThrows throwsIllegalArgument
+                                           (return $! toSizedPath enum nonval),
+        "fromPath_succeed" ~: fromPath enum [] @?= val,
+        "fromPath_fail" ~: assertThrows throwsBadPath (return $! fromPath enum [0]),
+        "withPrefix_fail" ~: assertThrows throwsBadPath
+                                          (return $! withPrefix enum [0]),
+        "numBranches" ~: numBranches enum @?= Just 0,
+        "prefix" ~: prefix enum @?= prefixPath
+      ]
+  in
+    ("withPrefix_empty" ~: noRecurseTests (withPrefix enum [])) :
+    noRecurseTests enum
+
+fromEncodingTests enum vals prefixPath =
+  let
+    len = toInteger (length vals)
+
+    makePrefixTest val =
+      ("withPrefix_" ++ show val) ~:
+        singletonTests (withPrefix enum [toInteger val]) val (val + 1)
+                       (prefixPath ++ [toInteger val])
+
+    noRecurseTests enum = [
+        "toPath" ~: mapM_ (\val -> toPath enum val @?= [toInteger val]) vals,
+        "toSizedPath" ~:
+          mapM_ (\val -> toSizedPath enum val @?= [(toInteger val, Just len)]) vals,
+        "fromPath" ~: mapM_ (\val -> fromPath enum [toInteger val] @?= val) vals,
+        "fromPath_short" ~: assertThrows throwsBadPath (return $! fromPath enum []),
+        "fromPath_long" ~: assertThrows throwsBadPath
+                                        (return $! fromPath enum [0, 0]),
+        "withPrefix_long" ~: assertThrows throwsBadPath
+                                          (return $! withPrefix enum [0, 0]),
+        "numBranches" ~: numBranches enum @?= Just len,
+        "prefix" ~: prefix enum @?= prefixPath
+      ] ++ map makePrefixTest vals
+  in
+    ("withPrefix_empty" ~: noRecurseTests (withPrefix enum [])) :
+    noRecurseTests enum
+
+stepTests enum nums vals prefixPath =
+  let
+    innerEncodingTests enum num prefixPath =
+      let
+        nums = [0..num]
+        len = toInteger (num + 1)
+
+        makePrefixTest num' =
+          ("withPrefix_" ++ show num') ~:
+          singletonTests (withPrefix enum [toInteger num']) (num, num')
+                         (num, num' + 1) (prefixPath ++ [toInteger num'])
+
+        noRecurseTests enum = [
+            "toPath" ~: mapM_ (\num' -> toPath enum (num, num') @?=
+                                        [toInteger num']) nums,
+            "toSizedPath" ~:
+              mapM_ (\num' -> toSizedPath enum (num, num') @?=
+                             [(toInteger num', Just len)]) nums,
+            "fromPath" ~: mapM_ (\num' -> fromPath enum [toInteger num'] @?=
+                                          (num, num')) nums,
+            "fromPath_short" ~:
+              assertThrows throwsBadPath (return $! fromPath enum []),
+            "fromPath_long" ~:
+              assertThrows throwsBadPath (return $! fromPath enum [0, 0]),
+            "withPrefix_long" ~: assertThrows throwsBadPath
+                                              (return $! withPrefix enum [0, 0]),
+            "numBranches" ~: numBranches enum @?= Just len,
+            "prefix" ~: prefix enum @?= prefixPath
+          ] ++ map makePrefixTest nums
+      in
+        ("withPrefix_empty" ~: noRecurseTests (withPrefix enum [])) :
+        noRecurseTests enum
+
+    len = toInteger (length nums)
+
+    makePrefixTest num =
+      ("withPrefix_" ++ show num) ~:
+        innerEncodingTests (withPrefix enum [toInteger num]) num
+                           (prefixPath ++ [toInteger num])
+
+    noRecurseTests enum = [
+        "toPath" ~: mapM_ (\val @ (v1, v2) -> toPath enum val @?=
+                                              [toInteger v1, toInteger v2]) vals,
+        "toSizedPath" ~:
+          mapM_ (\val @ (v1, v2) -> toSizedPath enum val @?=
+                                    [(toInteger v1, Just len),
+                                     (toInteger v2, Just (toInteger v1 + 1))]) vals,
+        "fromPath" ~:
+          mapM_ (\val @ (v1, v2) -> fromPath enum [toInteger v1, toInteger v2] @?=
+                                    val) vals,
+        "fromPath_short" ~: assertThrows throwsBadPath (return $! fromPath enum []),
+        "fromPath_long" ~: assertThrows throwsBadPath
+                                        (return $! fromPath enum [0, 0, 0]),
+        "withPrefix_long" ~: assertThrows throwsBadPath
+                                          (return $! withPrefix enum [0, 0, 0]),
+        "numBranches" ~: numBranches enum @?= Just len,
+        "prefix" ~: prefix enum @?= prefixPath
+      ] ++ map makePrefixTest nums
+  in
+    ("withPrefix_empty" ~: noRecurseTests (withPrefix enum [])) :
+    noRecurseTests enum
+
+testlist :: [Test]
+testlist =
+  let
+    intervalEncoding = intervalWord8 0 100
+
+    innerEncoding n = ArithEncode.wrap (Just . snd) (\n' -> Just (n, n'))
+                                       (intervalWord8 0 n)
+
+    innerEnum prefixPath = fromEncodingWithPrefix prefixPath . innerEncoding
+
+    makeVals = concat . map (\n -> map (\n' -> (n, n')) [0..n])
+  in [
+    "singleton" ~: singletonTests (singleton 'A') 'A' 'B' [],
+    "singletonWithPrefix" ~:
+      singletonTests (singletonWithPrefix [0] 'A') 'A' 'B' [0],
+    "fromEncoding" ~: fromEncodingTests (fromEncoding intervalEncoding) [0..100] [],
+    "fromEncodingWithPrefix" ~:
+      fromEncodingTests (fromEncodingWithPrefix [1] intervalEncoding) [0..100] [1],
+    "step" ~: stepTests (step intervalEncoding innerEnum fst)
+                        [0..100] (makeVals [0..100]) []
+  ]
+
+tests :: Test
+tests = "Enumeration" ~: Binary.tests : Traversal.tests : testlist
diff --git a/test/Tests/Data/Enumeration/Binary.hs b/test/Tests/Data/Enumeration/Binary.hs
new file mode 100644
--- /dev/null
+++ b/test/Tests/Data/Enumeration/Binary.hs
@@ -0,0 +1,94 @@
+-- Copyright (c) 2014 Eric McCorkle.  All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- 1. Redistributions of source code must retain the above copyright
+--    notice, this list of conditions and the following disclaimer.
+--
+-- 2. 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.
+--
+-- 3. Neither the name of the author nor the names of any contributors
+--    may be used to endorse or promote products derived from this software
+--    without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS
+-- 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.
+
+-- Note: It takes an enormously long time for these tests to complete.
+module Tests.Data.Enumeration.Binary(tests) where
+
+import Data.Binary.Get
+import Data.Binary.Put
+import Data.Bits
+import Data.List
+import Data.Enumeration
+import Data.Enumeration.Binary
+import Test.HUnitPlus.Base
+
+import qualified Data.ArithEncode as ArithEncode
+
+integralInteger :: ArithEncode.Encoding Integer
+integralInteger = ArithEncode.integral
+
+intervalInteger :: Integer -> Integer -> ArithEncode.Encoding Integer
+intervalInteger = ArithEncode.interval
+
+testPutGet :: (Eq ty, Show ty) => Enumeration ty -> ty -> Assertion
+testPutGet enum val =
+  let
+    bs = runPut (putWithEnumeration enum val)
+    val' = runGet (getWithEnumeration enum) bs
+  in do
+    val @=? val'
+
+testEnumeration :: (Eq ty, Show ty) => String -> Enumeration ty -> [ty] -> Test
+testEnumeration name enc vals =
+  name ~: mapM_ (testPutGet enc) vals
+
+infiniteVals = [((1 `shiftL` 64) - 0x100)..((1 `shiftL` 64) + 0x100)] ++
+  (map (\n -> product (map (\m -> m * 8 + 1) [1..n])) [1..1500])
+
+components :: [(String, ArithEncode.Encoding Integer, [Integer])]
+components = [
+    ("singleton", (ArithEncode.singleton 1), [1]),
+    ("finite_2", (intervalInteger 1 2), [1, 2]),
+    ("finite_10", (intervalInteger 1 10), [1..10]),
+    ("finite_100", (intervalInteger 1 100), [1..100]),
+    ("finite_10000", (intervalInteger 1 10000), [1..1000]),
+    ("finite_64bit", (intervalInteger 0 0x100000000000000000000), [1..1000]),
+    ("infinite", integralInteger, infiniteVals)
+  ]
+
+crossprod as bs =
+  foldr (\a accum -> foldr (\b accum -> (a, b) : accum) accum bs) [] as
+
+pairs = crossprod components components
+
+makeTestCase ((name1, enc1, vals1), (name2, enc2, vals2)) =
+  let
+    vals = crossprod vals1 vals2
+    innerEncoding n = ArithEncode.wrap (Just . snd) (\n' -> Just (n, n')) enc2
+    innerEnum prefixPath = fromEncodingWithPrefix prefixPath . innerEncoding
+    enum = step enc1 innerEnum fst
+  in
+    (name1 ++ "_" ++ name2) ~: mapM_ (testPutGet enum) vals
+
+testlist :: [Test]
+testlist = map makeTestCase pairs
+
+tests :: Test
+tests = "Binary" ~: testlist
diff --git a/test/Tests/Data/Enumeration/Traversal.hs b/test/Tests/Data/Enumeration/Traversal.hs
new file mode 100644
--- /dev/null
+++ b/test/Tests/Data/Enumeration/Traversal.hs
@@ -0,0 +1,224 @@
+-- Copyright (c) 2014 Eric McCorkle.  All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- 1. Redistributions of source code must retain the above copyright
+--    notice, this list of conditions and the following disclaimer.
+--
+-- 2. 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.
+--
+-- 3. Neither the name of the author nor the names of any contributors
+--    may be used to endorse or promote products derived from this software
+--    without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS
+-- 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.
+
+module Tests.Data.Enumeration.Traversal(tests) where
+
+import Data.Enumeration
+import Data.Enumeration.Traversal
+import Test.HUnitPlus.Base
+
+import qualified Data.ArithEncode as ArithEncode
+
+firstEncoding :: ArithEncode.Encoding [Int]
+firstEncoding = ArithEncode.fromHashableList [[0], [1], [2], [3]]
+
+stepFunc :: Path -> [Int] -> Enumeration [Int]
+stepFunc path val @ (0 : _) =
+  fromEncodingWithPrefix path (ArithEncode.singleton (reverse val))
+stepFunc path val @ (n : _) =
+  let
+    nextEncoding :: ArithEncode.Encoding [Int]
+    nextEncoding = ArithEncode.wrap (Just . head) (Just . (: val))
+                                    (ArithEncode.interval 0 (n - 1))
+  in
+    stepWithPrefix path nextEncoding stepFunc tail
+
+enum :: Enumeration [Int]
+enum = step firstEncoding stepFunc tail
+
+depthFirstVals = [
+    ([0], [0,0]),
+    ([1,0], [1,0,0]),
+    ([2,0], [2,0,0]),
+    ([2,1,0], [2,1,0,0]),
+    ([3,0], [3,0,0]),
+    ([3,1,0], [3,1,0,0]),
+    ([3,2,0], [3,2,0,0]),
+    ([3,2,1,0], [3,2,1,0,0])
+  ]
+
+breadthFirstVals = [
+    ([0], [0,0]),
+    ([1,0], [1,0,0]),
+    ([2,0], [2,0,0]),
+    ([3,0], [3,0,0]),
+    ([2,1,0], [2,1,0,0]),
+    ([3,1,0], [3,1,0,0]),
+    ([3,2,0], [3,2,0,0]),
+    ([3,2,1,0], [3,2,1,0,0])
+  ]
+
+prioritizedVals = [
+    ([3,2,1,0], [3,2,1,0,0]),
+    ([3,2,0], [3,2,0,0]),
+    ([3,1,0], [3,1,0,0]),
+    ([3,0], [3,0,0]),
+    ([2,1,0], [2,1,0,0]),
+    ([2,0], [2,0,0]),
+    ([1,0], [1,0,0]),
+    ([0], [0,0])
+  ]
+
+infOne :: ArithEncode.Encoding Integer
+infOne = ArithEncode.integral
+
+finTwo :: Path -> Integer -> Enumeration (Integer, Integer)
+finTwo path n =
+  fromEncodingWithPrefix path (ArithEncode.wrap (Just . snd) (\m -> Just (n, m))
+                                                (ArithEncode.interval 0 3))
+finOne :: ArithEncode.Encoding Integer
+finOne = ArithEncode.interval 0 3
+
+infTwo :: Path -> Integer -> Enumeration (Integer, Integer)
+infTwo path n =
+  fromEncodingWithPrefix path (ArithEncode.wrap (Just . snd) (\m -> Just (n, m))
+                                                ArithEncode.integral)
+
+infiniteFinite :: Enumeration (Integer, Integer)
+infiniteFinite = step infOne finTwo fst
+
+finiteInfinite :: Enumeration (Integer, Integer)
+finiteInfinite = step finOne infTwo fst
+
+infiniteInfinite :: Enumeration (Integer, Integer)
+infiniteInfinite = step infOne infTwo fst
+
+breadthFirstInfFinVals = [
+    ((0,0), [0,0]),
+    ((0,1), [0,1]),
+    ((0,2), [0,2]),
+    ((0,3), [0,3]),
+    ((-1,0), [1,0]),
+    ((-1,1), [1,1]),
+    ((-1,2), [1,2]),
+    ((-1,3), [1,3])
+  ]
+
+breadthFirstFinInfVals = [
+    ((0,0), [0,0]),
+    ((1,0), [1,0]),
+    ((2,0), [2,0]),
+    ((3,0), [3,0]),
+    ((0,-1), [0,1]),
+    ((1,-1), [1,1]),
+    ((2,-1), [2,1]),
+    ((3,-1), [3,1])
+  ]
+
+breadthFirstInfInfVals = [
+    ((0,0), [0,0]),
+    ((0,-1), [0,1]),
+    ((-1,0), [1,0]),
+    ((0,1), [0,2]),
+    ((-1,-1), [1,1]),
+    ((1,0), [2,0]),
+    ((0,-2), [0,3]),
+    ((-1,1), [1,2])
+  ]
+
+depthFirstFinInfVals = [
+    ((0,0), [0,0]),
+    ((0,-1), [0,1]),
+    ((0,1), [0,2]),
+    ((0,-2), [0,3]),
+    ((0,2), [0,4]),
+    ((0,-3), [0,5]),
+    ((0,3), [0,6]),
+    ((0,-4), [0,7])
+  ]
+
+depthFirstFinite :: DepthFirst [Int]
+depthFirstFinite = mkTraversal enum
+
+breadthFirstFinite :: BreadthFirst [Int]
+breadthFirstFinite = mkTraversal enum
+
+breadthFirstInfiniteFinite :: BreadthFirst (Integer, Integer)
+breadthFirstInfiniteFinite = mkTraversal infiniteFinite
+
+breadthFirstFiniteInfinite :: BreadthFirst (Integer, Integer)
+breadthFirstFiniteInfinite = mkTraversal finiteInfinite
+
+breadthFirstInfiniteInfinite :: BreadthFirst (Integer, Integer)
+breadthFirstInfiniteInfinite = mkTraversal infiniteInfinite
+
+depthFirstFiniteInfinite :: DepthFirst (Integer, Integer)
+depthFirstFiniteInfinite = mkTraversal finiteInfinite
+
+scorefunc (enum, curr) = fromIntegral (curr + sum (prefix enum))
+
+prioritizedFinite :: Prioritized [Int]
+prioritizedFinite = mkPrioritizedTraversal scorefunc enum
+
+prioritizedDefaultVals = [
+    ([1,0], [1,0,0]),
+    ([0], [0,0]),
+    ([3,0], [3,0,0]),
+    ([2,0], [2,0,0]),
+    ([2,1,0], [2,1,0,0]),
+    ([3,1,0], [3,1,0,0]),
+    ([3,2,0], [3,2,0,0]),
+    ([3,2,1,0], [3,2,1,0,0])
+  ]
+
+prioritizedFiniteDefault :: Prioritized [Int]
+prioritizedFiniteDefault = mkTraversal enum
+
+depthFirstTests = [
+    "finite" ~: getAll depthFirstFinite @?= depthFirstVals,
+    "finiteInfinite" ~: take 8 (getAll depthFirstFiniteInfinite) @?=
+                        depthFirstFinInfVals
+  ]
+
+breadthFirstTests = [
+    "finite" ~: getAll breadthFirstFinite @?= breadthFirstVals,
+    "infiniteFinite" ~: take 8 (getAll breadthFirstInfiniteFinite) @?=
+                        breadthFirstInfFinVals,
+    "finiteInfinite" ~: take 8 (getAll breadthFirstFiniteInfinite) @?=
+                        breadthFirstFinInfVals,
+    "infiniteInfinite" ~: take 8 (getAll breadthFirstInfiniteInfinite) @?=
+                          breadthFirstInfInfVals
+  ]
+
+prioritizedTests = [
+    "finite" ~: getAll prioritizedFinite @?= prioritizedVals,
+    "default_finite" ~: getAll prioritizedFiniteDefault @?=
+                        prioritizedDefaultVals
+  ]
+
+testlist :: [Test]
+testlist = [
+    "depthFirst" ~: depthFirstTests,
+    "breadthFirst" ~: breadthFirstTests,
+    "prioritized" ~: prioritizedTests
+  ]
+
+tests :: Test
+tests = "Traversal" ~: testlist
diff --git a/test/UnitTest.hs b/test/UnitTest.hs
--- a/test/UnitTest.hs
+++ b/test/UnitTest.hs
@@ -28,6 +28,8 @@
 -- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 -- SUCH DAMAGE.
 
+{-# LANGUAGE OverloadedStrings #-}
+
 module Main(main) where
 
 import Test.HUnitPlus
