diff --git a/DataencQC.hs b/DataencQC.hs
deleted file mode 100644
--- a/DataencQC.hs
+++ /dev/null
@@ -1,170 +0,0 @@
-{-
- - Copyright : (c) 2007 Magnus Therning
- - License   : BSD3
- -}
-
-module DataencQC
-    where
-
-import Data.Maybe
-import Data.Word
-import Test.QuickCheck
-import Test.Framework.Providers.QuickCheck2
-
-import qualified Codec.Binary.Uu as Uu
-import qualified Codec.Binary.Uu as Xx
-import qualified Codec.Binary.Base85 as Base85
-import qualified Codec.Binary.Base64 as Base64
-import qualified Codec.Binary.Base64Url as Base64Url
-import qualified Codec.Binary.Base32 as Base32
-import qualified Codec.Binary.Base32Hex as Base32Hex
-import qualified Codec.Binary.Base16 as Base16
-import qualified Codec.Binary.Yenc as Yenc
-import qualified Codec.Binary.QuotedPrintable as QP
-import qualified Codec.Binary.PythonString as Py
-import qualified Codec.Binary.Url as Url
-
--- {{{1 Arbitrary instances
-instance Arbitrary Word8 where
-    arbitrary = do
-        n <- choose ((fromIntegral (minBound::Word8))::Int,
-                (fromIntegral (maxBound::Word8))::Int)
-        return $ fromIntegral n
-
--- {{{1 uuencode properties
-prop_uuEncode ws = ws == (fromJust . Uu.decode . Uu.encode) ws
-    where types = ws::[Word8]
-
-prop_uuChop n ws = s == (Uu.unchop . Uu.chop n) s
-    where
-        types = (n :: Int, ws::[Word8])
-        s = Uu.encode ws
-
-prop_uuCombined n ws = ws == (fromJust $ Uu.decode $ Uu.unchop $ Uu.chop n $ Uu.encode ws)
-    where types = (n::Int, ws::[Word8])
-
--- {{{1 xxencode properties
-prop_xxEncode ws = ws == (fromJust . Xx.decode . Xx.encode) ws
-    where types = ws::[Word8]
-
-prop_xxChop n ws = s == (Xx.unchop . Xx.chop n) s
-    where
-        types = (n:: Int, ws::[Word8])
-        s = Xx.encode ws
-
-prop_xxCombined n ws = ws == (fromJust $ Xx.decode $ Xx.unchop $ Xx.chop n $ Xx.encode ws)
-    where types = (n::Int, ws::[Word8])
-
--- {{{1 base85 properties
-prop_base85Encode ws = ws == (fromJust $ Base85.decode $ Base85.encode ws)
-    where types = ws::[Word8]
-
-prop_base85Chop n s = s == (Base85.unchop $ Base85.chop n s)
-    where types = (n::Int, s::String)
-
--- {{{1 base64 properties
-prop_base64Encode ws = ws == (fromJust $ Base64.decode $ Base64.encode ws)
-    where types = ws::[Word8]
-
-prop_base64Chop n s = s == (Base64.unchop $ Base64.chop n s)
-    where types = (n::Int, s::String)
-
--- {{{1 base64url properties
-prop_base64UrlEncode ws = ws == (fromJust $ Base64Url.decode $ Base64Url.encode ws)
-    where types = ws::[Word8]
-
-prop_base64UrlChop n s = s == (Base64Url.unchop $ Base64Url.chop n s)
-    where types = (n::Int, s::String)
-
--- {{{1 base32
-prop_base32Encode ws = ws == (fromJust $ Base32.decode $ Base32.encode ws)
-    where types = ws::[Word8]
-
-prop_base32Chop n s = s == (Base32.unchop $ Base32.chop n s)
-    where types = (n::Int, s::String)
-
--- {{{1 base32hex
-prop_base32HexEncode ws = ws == (fromJust $ Base32Hex.decode $ Base32Hex.encode ws)
-    where types = ws::[Word8]
-
-prop_base32HexChop n s = s == (Base32Hex.unchop $ Base32Hex.chop n s)
-    where types = (n::Int, s::String)
-
--- {{{1 base16
-prop_base16Encode ws = ws == (fromJust $ Base16.decode $ Base16.encode ws)
-    where types = ws::[Word8]
-
-prop_base16Chop n s = s == (Base16.unchop $ Base16.chop n s)
-    where types = (n::Int, s::String)
-
--- {{{1 yEncoding
-prop_yencEncode ws = ws == (fromJust $ Yenc.decode $ Yenc.encode ws)
-    where types = ws ::[Word8]
-
-prop_yencChop n ws = ws == (Yenc.unchop $ Yenc.chop n ws)
-    where types = (n::Int, ws :: [Word8])
-
--- {{{1 qp
-prop_qpEncode ws = ws == (fromJust $ QP.decode $ QP.encode ws)
-    where types = ws :: [Word8]
-
-prop_qpChop n ws = s == (QP.unchop . QP.chop n) s
-    where
-        types = (n::Int, ws::[Word8])
-        s = QP.encode ws
-
-prop_qpCombined n ws = ws == (fromJust $ QP.decode $ QP.unchop $ QP.chop n $ QP.encode ws)
-    where types = (n::Int, ws::[Word8])
-
--- {{{1 py
-prop_pyEncode ws = ws == (fromJust $ Py.decode $ Py.encode ws)
-    where types = ws :: [Word8]
-
-prop_pyChop n s = s == (Py.unchop $ Py.chop n s)
-    where types = (n :: Int, s :: String)
-
-prop_pyCombined n ws = ws == (fromJust $ runAll ws)
-    where runAll = Py.decode . Py.unchop . Py.chop n . Py.encode
-
--- {{{1 url
-prop_urlEncode ws = ws == (fromJust $ Url.decode $ Url.encode ws)
-    where types = ws :: [Word8]
-
-prop_urlChop n s = s == (Url.unchop $ Url.chop n s)
-    where types = (n :: Int, s :: String)
-
-prop_urlCombined n ws = ws == (fromJust $ runAll ws)
-    where runAll = Url.decode . Url.unchop . Url.chop n . Url.encode
-
--- {{{1 all the tests
-allTests =
-    [ testProperty "uuEncode" prop_uuEncode
-    , testProperty "uuChop" prop_uuChop
-    , testProperty "uuCombined" prop_uuCombined
-    , testProperty "xxEncode" prop_xxEncode
-    , testProperty "xxChop" prop_xxChop
-    , testProperty "xxCombined" prop_xxCombined
-    , testProperty "base85Encode" prop_base85Encode
-    , testProperty "base85Chop" prop_base85Chop
-    , testProperty "base64Encode" prop_base64Encode
-    , testProperty "base64Chop" prop_base64Chop
-    , testProperty "base64UrlEncode" prop_base64UrlEncode
-    , testProperty "base64UrlChop" prop_base64UrlChop
-    , testProperty "base32Encode" prop_base32Encode
-    , testProperty "base32Chop" prop_base32Chop
-    , testProperty "base32HexEncode" prop_base32HexEncode
-    , testProperty "base32HexChop" prop_base32HexChop
-    , testProperty "base16Encode" prop_base16Encode
-    , testProperty "base16Chop" prop_base16Chop
-    , testProperty "yencEncode" prop_yencEncode
-    , testProperty "yencChop" prop_yencChop
-    , testProperty "qpEncode" prop_qpEncode
-    , testProperty "qpChop" prop_qpChop
-    , testProperty "qpCombined" prop_qpCombined
-    , testProperty "pyEncode" prop_pyEncode
-    , testProperty "pyChop" prop_pyChop
-    , testProperty "pyCombined" prop_pyCombined
-    , testProperty "urlEncode" prop_urlEncode
-    , testProperty "urlChop" prop_urlChop
-    , testProperty "urlCombined" prop_urlCombined
-    ]
diff --git a/DataencUT.hs b/DataencUT.hs
deleted file mode 100644
--- a/DataencUT.hs
+++ /dev/null
@@ -1,290 +0,0 @@
-{-
- - Copyright : (c) 2007 Magnus Therning
- - License   : BSD3
- -}
-
-module DataencUT
-    where
-
-import Test.HUnit
-import Control.Monad
-import System.Exit
-import Data.Maybe
-import qualified Test.Framework.Providers.API as TFAPI
-import Test.Framework.Providers.HUnit
-
-import Codec.Binary.DataEncoding
-import qualified Codec.Binary.Yenc as Yenc
-
--- {{{1 buildTestList
--- builds a list of successful tests based on a tuple (suite, description,
--- encoded data, decoded data, codec)
-buildTestList td = TestList $ concat [
-    [ TestLabel (suite ++ " encode " ++ desc) (enc ~=? (encode codec dec))
-    , TestLabel (suite ++ " decode " ++ desc) (dec ~=? (fromJust $ decode codec $ enc))
-    ] | (suite, desc, enc, dec, codec) <- td ]
-
--- {{{1 unitTest2TFTest
-unitTest2TFTest :: Test -> [TFAPI.Test]
-unitTest2TFTest t = let
-        unitTest2TFTest' desc (TestCase a) = [testCase desc a]
-        unitTest2TFTest' desc (TestLabel s t) = unitTest2TFTest' (desc ++ ":" ++ s) t
-        unitTest2TFTest' desc (TestList ts) = concat $ map (unitTest2TFTest' desc) ts
-    in unitTest2TFTest' "" t
-
-
--- {{{1 uuencode tests
-uuTestData =
-    [ ("uu", "empty", "", [], uu)
-    , ("uu", "\\0", "``", [0], uu)
-    , ("uu", "\\255", "_P", [255], uu)
-    , ("uu", "AA", "04$", [65, 65], uu)
-    , ("uu", "AAA", "04%!", [65, 65, 65], uu)
-    , ("uu", "AAAA", "04%!00", [65, 65, 65, 65], uu)
-    , ("uu", "Example", "17AA;7!L90", [69,120,97,109,112,108,101], uu)
-    ]
-uuTests = buildTestList uuTestData
-
-uuTests2 = test
-    [ "uu unchop.chop" ~: "EI2" ~=? (unchop uu $ chop uu 1 "EI2")
-    , "uu unchop.chop" ~: "EI3-" ~=? (unchop uu $ chop uu 1 "EI3-")
-    , "uu unchop.chop" ~: "EI3-EE" ~=? (unchop uu $ chop uu 1 "EI3-EE")
-    , "uu full circle" ~: [0..255] ~=? fromJust (decode uu $ unchop uu $ chop uu 1 $ encode uu [0..255])
-    , "uu full circle" ~: [0..255] ~=? fromJust (decode uu $ unchop uu $ chop uu 61 $ encode uu [0..255])
-    , "uu full circle" ~: [0..255] ~=? fromJust (decode uu $ unchop uu $ chop uu 100 $ encode uu [0..255])
-    ]
-
-uuTestsFail = test
-    [ "uu decode short" ~: Nothing ~=? decode uu "A"
-    , "uu decode' short" ~: [Nothing] ~=? decode' uu "A"
-    , "uu decode illegal" ~: Nothing ~=? decode uu "aa"
-    , "uu decode' illegal" ~: [Nothing] ~=? decode' uu "aa"
-    ]
-
--- {{{1 xxencode tests
-xxTestData =
-    [ ("xx", "empty", "", [], xx)
-    , ("xx", "\\0", "++", [0], xx)
-    , ("xx", "\\255", "zk", [255], xx)
-    , ("xx", "AA", "EI2", [65, 65], xx)
-    , ("xx", "AAA", "EI3-", [65, 65, 65], xx)
-    , ("xx", "AAAA", "EI3-EE", [65, 65, 65, 65], xx)
-    , ("xx", "Example", "FLVVPL-gNE", [69,120,97,109,112,108,101], xx)
-    ]
-xxTests = buildTestList xxTestData
-
-xxTests2 = test
-    [ "xx unchop.chop" ~: "EI2" ~=? (unchop xx $ chop xx 1 "EI2")
-    , "xx unchop.chop" ~: "EI3-" ~=? (unchop xx $ chop xx 1 "EI3-")
-    , "xx unchop.chop" ~: "EI3-EE" ~=? (unchop xx $ chop xx 1 "EI3-EE")
-    , "xx full circle" ~: [0..255] ~=? fromJust (decode xx $ unchop xx $ chop xx 1 $ encode xx [0..255])
-    , "xx full circle" ~: [0..255] ~=? fromJust (decode xx $ unchop xx $ chop xx 61 $ encode xx [0..255])
-    , "xx full circle" ~: [0..255] ~=? fromJust (decode xx $ unchop xx $ chop xx 100 $ encode xx [0..255])
-    ]
-
-xxTestsFail = test
-    [ "xx decode short" ~: Nothing ~=? decode xx "A"
-    , "xx decode' short" ~: [Nothing] ~=? decode' xx "A"
-    , "xx decode illegal" ~: Nothing ~=? decode xx "''"
-    , "xx decode' illegal" ~: [Nothing] ~=? decode' xx "''"
-    ]
-
--- {{{1 base85 tests
-base85TestData =
-    [ ("base85", "empty", "", [], base85)
-    , ("base85", "f", "Ac", [102], base85)
-    , ("base85", "fo", "Ao@", [102,111], base85)
-    , ("base85", "foo", "AoDS", [102,111,111], base85)
-    , ("base85", "foob", "AoDTs", [102,111,111,98], base85)
-    , ("base85", "fooba", "AoDTs@/", [102,111,111,98,97], base85)
-    , ("base85", "foobar", "AoDTs@<)", [102,111,111,98,97,114], base85)
-    , ("base85", "\0", "!!", [0], base85)
-    , ("base85", "foob\0\0\0\0ar", "AoDTszEW", [102,111,111,98,0,0,0,0,114], base85)
-    , ("base85", "Example", "7<i6XE,9(", [69,120,97,109,112,108,101], base85)
-    ]
-base85Tests = buildTestList base85TestData
-
-base85TestsFail = test
-    [ "base85 decode short" ~: Nothing ~=? decode base85 "A"
-    , "base85 decode' short" ~: [Nothing] ~=? decode' base85 "A"
-    , "base85 decode illegal" ~: Nothing ~=? decode base85 "!z"
-    , "base85 decode' illegal" ~: [Nothing] ~=? decode' base85 "!z"
-    ]
-
--- {{{1 base64 tests
-base64TestData =
-    [ ("base64", "empty", "", [], base64)
-    , ("base64", "f", "Zg==", [102], base64)
-    , ("base64", "fo", "Zm8=", [102,111], base64)
-    , ("base64", "foo", "Zm9v", [102,111,111], base64)
-    , ("base64", "foob", "Zm9vYg==", [102,111,111,98], base64)
-    , ("base64", "fooba", "Zm9vYmE=", [102,111,111,98,97], base64)
-    , ("base64", "foobar", "Zm9vYmFy", [102,111,111,98,97,114], base64)
-    , ("base64", "\0", "AA==", [0], base64)
-    , ("base64", "\255", "/w==", [255], base64)
-    , ("base64", "Example", "RXhhbXBsZQ==", [69,120,97,109,112,108,101], base64)
-    ]
-base64Tests = buildTestList base64TestData
-
-base64TestsFail = test
-    [ "base64 decode short" ~: Nothing ~=? decode base64 "A"
-    , "base64 decode' short" ~: [Nothing] ~=? decode' base64 "A"
-    , "base64 decode illegal" ~: Nothing ~=? decode base64 "!!"
-    , "base64 decode' illegal" ~: [Nothing] ~=? decode' base64 "!!"
-    ]
-
--- {{{1 base64url tests
-base64UrlTestData =
-    [ ("base64url", "empty", "", [], base64Url)
-    , ("base64url", "\0", "AA==", [0], base64Url)
-    , ("base64url", "\255", "_w==", [255], base64Url)
-    , ("base64url", "Example", "RXhhbXBsZQ==", [69,120,97,109,112,108,101], base64Url)
-    ]
-base64UrlTests = buildTestList base64UrlTestData
-
--- {{{1 base32 tests
-base32TestData =
-    [ ("base32", "empty", "", [], base32)
-    , ("base32", "f", "MY======", [102], base32)
-    , ("base32", "fo", "MZXQ====", [102,111], base32)
-    , ("base32", "foo", "MZXW6===", [102,111,111], base32)
-    , ("base32", "foob", "MZXW6YQ=", [102,111,111,98], base32)
-    , ("base32", "fooba", "MZXW6YTB", [102,111,111,98,97], base32)
-    , ("base32", "foobar", "MZXW6YTBOI======", [102,111,111,98,97,114], base32)
-    ]
-base32Tests = buildTestList base32TestData
-
-base32TestsFail = test
-    [ "base32 decode short" ~: Nothing ~=? decode base32 "A"
-    , "base32 decode' short" ~: [Nothing] ~=? decode' base32 "A"
-    , "base32 decode illegal" ~: Nothing ~=? decode base32 "gh"
-    , "base32 decode' illegal" ~: [Nothing] ~=? decode' base32 "gh"
-    ]
-
--- {{{1 base32hex tests
-base32HexTestData =
-    [ ("base32hex", "empty", "", [], base32Hex)
-    , ("base32hex", "f", "CO======", [102], base32Hex)
-    , ("base32hex", "fo", "CPNG====", [102,111], base32Hex)
-    , ("base32hex", "foo", "CPNMU===", [102,111,111], base32Hex)
-    , ("base32hex", "foob", "CPNMUOG=", [102,111,111,98], base32Hex)
-    , ("base32hex", "fooba", "CPNMUOJ1", [102,111,111,98,97], base32Hex)
-    , ("base32hex", "foobar", "CPNMUOJ1E8======", [102,111,111,98,97,114], base32Hex)
-    ]
-base32HexTests = buildTestList base32HexTestData
-
-base32HexTestsFail = test
-    [ "base32hex decode short" ~: Nothing ~=? decode base32Hex "A"
-    , "base32hex decode' short" ~: [Nothing] ~=? decode' base32Hex "A"
-    , "base32hex decode illegal" ~: Nothing ~=? decode base32Hex "gh"
-    , "base32hex decode' illegal" ~: [Nothing] ~=? decode' base32Hex "gh"
-    ]
-
--- {{{1 base16 (hex)
-base16TestData =
-    [ ("base16", "empty", "", [], base16)
-    , ("base16", "f", "66", [102], base16)
-    , ("base16", "fo", "666F", [102,111], base16)
-    , ("base16", "foo", "666F6F", [102,111,111], base16)
-    , ("base16", "foob", "666F6F62", [102,111,111,98], base16)
-    , ("base16", "fooba", "666F6F6261", [102,111,111,98,97], base16)
-    , ("base16", "foobar", "666F6F626172", [102,111,111,98,97,114], base16)
-    ]
-base16Tests = buildTestList base16TestData
-
-base16TestsFail = test
-    [ "base16 decode short" ~: Nothing ~=? decode base16 "A"
-    , "base16 decode' short" ~: [Nothing] ~=? decode' base16 "A"
-    , "base16 decode illegal" ~: Nothing ~=? decode base16 "GH"
-    , "base16 decode' illegal" ~: [Nothing] ~=? decode' base16 "GH"
-    ]
-
--- {{{1 yEncoding
-yencTests = test
-    [ "yEnc encode empty" ~: [] ~=? Yenc.encode []
-    , "yEnc decode empty" ~: Just [] ~=? Yenc.decode []
-    , "yEnc encode 'f'" ~: [0x90] ~=? Yenc.encode [0x66]
-    , "yEnc decode enc('f')" ~: Just [0x66] ~=? Yenc.decode [0x90]
-    , "yEnc encode 'foobar'" ~: [0x90, 0x99, 0x99, 0x8c, 0x8b, 0x9c] ~=? Yenc.encode [0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]
-    , "yEnc decode enc('foobar')" ~: Just [0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72] ~=? Yenc.decode [0x90, 0x99, 0x99, 0x8c, 0x8b, 0x9c]
-    , "yEnc encode [0xd6, 0xd7]" ~: [0x3d, 0x40, 0x01] ~=? Yenc.encode [0xd6, 0xd7]
-    , "yEnc decode enc([0xd6, 0xd7])" ~:  Just [0xd6, 0xd7] ~=? Yenc.decode [0x3d, 0x40, 0x01]
-    , "yEnc encode criticals" ~: [0x3d, 0x40, 0x3d, 0x4a, 0x3d, 0x4d, 0x3d, 0x7d] ~=? Yenc.encode [0xd6, 0xe0, 0xe3, 0x13]
-    , "yEnc decode criticals" ~:  Just [0xd6, 0xe0, 0xe3, 0x13] ~=? Yenc.decode [0x3d, 0x40, 0x3d, 0x4a, 0x3d, 0x4d, 0x3d, 0x7d]
-    , "yEnc chop" ~: [[0x3d, 0x40], [0x01, 0x3d, 0x4a]] ~=? Yenc.chop 2 [0x3d, 0x40, 0x01, 0x3d, 0x4a]
-    ]
-
--- {{{1 quoted-printable
-qpTestData =
-    [ ("qp", "empty", "", [], qp)
-    , ("qp", "foo=bar", "foo=3Dbar", [102,111,111,61,98,97,114], qp)
-    ]
-qpTests = buildTestList qpTestData
-
-qpTestsSucc = test
-    [ "qp chop one" ~: ["foo=","=3D=","bar"] ~=? chop qp 4 "foo=3Dbar"
-    ]
-
-qpTestsFail = test
-    [ "qp decode short" ~: Nothing ~=? decode qp "=4"
-    , "qp decode' short" ~: [Nothing] ~=? decode' qp "=4"
-    , "qp decode non-hex" ~: Nothing ~=? decode qp "=G"
-    , "qp decode' non-hex" ~: [Nothing] ~=? decode' qp "=G"
-    ]
-
--- {{{1 python string
-pyTestData =
-    [ ("py", "empty", "", [], py)
-    , ("py", "<0x00><0x1f><0x20><0x7e><0x7f><0xff>", "\\x00\\x1F ~\\x7F\\xFF", [0x00, 0x1f, 0x20, 0x7e, 0x7f, 0xff], py)
-    , ("py", "\"\'\\", "\\\"\\'\\\\", [34, 39, 92], py)
-    ]
-pyTests = buildTestList pyTestData
-
-pyTestsFail = test
-    [ "py decode bad char after \\" ~: Nothing ~=? decode py "\\z"
-    , "py decode' bad char after \\" ~: [Nothing] ~=? decode' py "\\z"
-    ]
-
--- {{{1 url encoding
-urlTestData =
-    [ ("url", "empty", "", [], url)
-    , ("url", "aA", "aA", [97, 65], url)
-    , ("url", "~ ", "~%20", [126, 0x20], url)
-    ]
-urlTests = buildTestList urlTestData
-
-urlTestsFail = test
-    [ "url decode bad char after %" ~: Nothing ~=? decode url "%ga"
-    , "url decode' bad char after %" ~: [Nothing] ~=? decode' url "%ga"
-    , "url decode bad char after %" ~: Nothing ~=? decode url "%%"
-    , "url decode' bad char after %" ~: [Nothing] ~=? decode' url "%%"
-    ]
-
--- {{{1 all the tests
-allTests = concat
-    [ unitTest2TFTest uuTests
-    , unitTest2TFTest uuTests2
-    , unitTest2TFTest uuTestsFail
-    , unitTest2TFTest xxTests
-    , unitTest2TFTest xxTests2
-    , unitTest2TFTest xxTestsFail
-    , unitTest2TFTest base85Tests
-    , unitTest2TFTest base85TestsFail
-    , unitTest2TFTest base64Tests
-    , unitTest2TFTest base64TestsFail
-    , unitTest2TFTest base64UrlTests
-    , unitTest2TFTest base32Tests
-    , unitTest2TFTest base32TestsFail
-    , unitTest2TFTest base32HexTests
-    , unitTest2TFTest base32HexTestsFail
-    , unitTest2TFTest base16Tests
-    , unitTest2TFTest base16TestsFail
-    , unitTest2TFTest yencTests
-    , unitTest2TFTest qpTests
-    , unitTest2TFTest qpTestsSucc
-    , unitTest2TFTest qpTestsFail
-    , unitTest2TFTest pyTests
-    , unitTest2TFTest pyTestsFail
-    , unitTest2TFTest urlTests
-    , unitTest2TFTest urlTestsFail
-    ]
diff --git a/GNUmakefile b/GNUmakefile
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,32 +1,32 @@
-.PHONY: all clean markup report test
+# Simple makefile for _running_ tests, use Cabal to build.
 
-TESTS = Test
-ifeq (,$(shell ghc-pkg list dataenc | grep dataenc))
-GHCOPTS = -fhpc -isrc
-else
-GHCOPTS = -fhpc -hide-package dataenc -isrc
-endif
-HPC_SUM_OPTS = --exclude=Main --exclude=DataencUT --exclude=DataencQC
+.PHONY: all clean markup report test really-clean
 
-% : %.hs
-	ghc --make $(GHCOPTS) $<
+TESTS = dist/build/tests/tests
 
-all: $(TESTS)
+HPC = hpc
+HPC_SUM_OPTS = --exclude=Main --exclude=DataencUT --exclude=DataencQC
 
+all:
+	@echo "Use Cabal to build, this is only used to run tests!"
+
 test: $(TESTS)
-	./Test
+	for t in $(TESTS); do ./$${t}; done
 
 report : test
-	hpc6 sum $(HPC_SUM_OPTS) --output test.tix Test.tix
-	hpc6 report test.tix
+	$(HPC) sum $(HPC_SUM_OPTS) --output run_test.tix tests.tix
+	$(HPC) report run_test.tix
 
 markup : test
-	hpc6 sum $(HPC_SUM_OPTS) --output test.tix Test.tix
-	hpc6 markup test.tix
+	$(HPC) sum $(HPC_SUM_OPTS) --output run_test.tix tests.tix
+	$(HPC) markup run_test.tix
 
 clean:
-	rm -f *~ Test *.tix *.html *.o *.hi
-	rm -rf .hpc
+	rm -f *~ *.tix *.html *.o *.hi
 	rm -f src/Codec/Binary/*.o
 	rm -f src/Codec/Binary/*.hi
 	rm -f src/Codec/Binary/*~
+
+really-clean: clean
+	rm -rf .hpc
+	./Setup.hs clean
diff --git a/Test.hs b/Test.hs
deleted file mode 100644
--- a/Test.hs
+++ /dev/null
@@ -1,19 +0,0 @@
-{-
- - Copyright : (c) 2009 Magnus Therning
- - License   : BSD3
- -}
-
-module Main
-    where
-
-import Test.Framework
-
-import qualified DataencQC as DQC
-import qualified DataencUT as DUT
-
-tests =
-    [ testGroup "quickcheck" DQC.allTests
-    , testGroup "unit test" DUT.allTests
-    ]
-
-main = defaultMain tests
diff --git a/dataenc.cabal b/dataenc.cabal
--- a/dataenc.cabal
+++ b/dataenc.cabal
@@ -1,5 +1,5 @@
 name: dataenc
-version: 0.13.0.0
+version: 0.13.0.1
 license: BSD3
 license-file: LICENSE
 cabal-version: >= 1.2
@@ -13,24 +13,37 @@
 description: Data encoding library currently providing Base16, Base32,
         Base32Hex, Base64, Base64Url, Base85, Python string escaping,
         Quoted-Printable, URL encoding, uuencode, xxencode, and yEncoding.
-extra-source-files: DataencUT.hs DataencQC.hs Test.hs GNUmakefile
+extra-source-files: test-src/DataencUT.hs test-src/DataencQC.hs test-src/Test.hs GNUmakefile
 
+flag BuildTests
+    Description: Build unit and quickcheck tests.
+    Default: False
+
 library
-        hs-source-dirs: src
-        build-depends: array >= 0.2.0 && < 0.3, base >= 4.0.0 && < 4.2, containers >= 0.2.0 && < 0.3
-        exposed-modules:
-                Codec.Binary.Base16
-                Codec.Binary.Base32
-                Codec.Binary.Base32Hex
-                Codec.Binary.Base64
-                Codec.Binary.Base64Url
-                Codec.Binary.Base85
-                Codec.Binary.DataEncoding
-                Codec.Binary.PythonString
-                Codec.Binary.QuotedPrintable
-                Codec.Binary.Url
-                Codec.Binary.Uu
-                Codec.Binary.Xx
-                Codec.Binary.Yenc
-        other-modules:
-                Codec.Binary.Util
+    hs-source-dirs: src
+    build-depends: array >= 0.1.0 && < 0.3, base >= 3.0.0 && < 4.2, containers >= 0.1.0 && < 0.3
+    exposed-modules:
+            Codec.Binary.Base16
+            Codec.Binary.Base32
+            Codec.Binary.Base32Hex
+            Codec.Binary.Base64
+            Codec.Binary.Base64Url
+            Codec.Binary.Base85
+            Codec.Binary.DataEncoding
+            Codec.Binary.PythonString
+            Codec.Binary.QuotedPrintable
+            Codec.Binary.Url
+            Codec.Binary.Uu
+            Codec.Binary.Xx
+            Codec.Binary.Yenc
+    other-modules:
+            Codec.Binary.Util
+
+executable tests
+    main-is: Test.hs
+    hs-source-dirs: test-src src
+    ghc-options: -fhpc
+    if flag(BuildTests)
+        build-depends: test-framework, test-framework-hunit, HUnit, test-framework-quickcheck2, QuickCheck >= 2.1.0.0
+    else
+        buildable: False
diff --git a/src/Codec/Binary/Base16.hs b/src/Codec/Binary/Base16.hs
--- a/src/Codec/Binary/Base16.hs
+++ b/src/Codec/Binary/Base16.hs
@@ -43,7 +43,7 @@
     -> String
 encode os = let
         splitOctet o = [ o `shiftR` 4, o .&. 0xf ]
-    in map (encodeArray !) $ foldr (\ o l -> (splitOctet o) ++ l) [] os
+    in map (encodeArray !) $ foldr ((++) . splitOctet) [] os
 
 -- {{{1 decode
 -- | Decode data (lazy).
@@ -51,7 +51,7 @@
     -> [Maybe Word8]
 decode' = let
         dec [] = []
-        dec (Just o1:Just o2:os) =
+        dec (Just o1 : Just o2 : os) =
                     Just (o1 `shiftL` 4 .|. o2) : dec os
         dec _ = [Nothing]
     in
@@ -73,7 +73,7 @@
 chop n s = let
         enc_len | n < 2 = 2
                 | otherwise = n `div` 2 * 2
-    in (take enc_len s) : chop n (drop enc_len s)
+    in take enc_len s : chop n (drop enc_len s)
 
 -- {{{1 unchop
 -- | Concatenate the strings into one long string.
diff --git a/src/Codec/Binary/Base32.hs b/src/Codec/Binary/Base32.hs
--- a/src/Codec/Binary/Base32.hs
+++ b/src/Codec/Binary/Base32.hs
@@ -46,13 +46,13 @@
 encode :: [Word8]
     -> String
 encode = let
-        pad n = take n $ repeat 0
+        pad n = replicate n 0
         enc [] = ""
         enc l@[o] = (++ "======") . take 2 . enc $ l ++ pad 4
         enc l@[o1, o2] = (++ "====") . take 4 . enc $ l ++ pad 3
         enc l@[o1, o2, o3] = (++ "===") . take 5 . enc $ l ++ pad 2
         enc l@[o1, o2, o3, o4] = (++ "=") . take 7 . enc $ l ++ pad 1
-        enc (o1:o2:o3:o4:o5:os) = let
+        enc (o1 : o2 : o3 : o4 : o5 : os) = let
                 i1 = o1 `shiftR` 3
                 i2 = (o1 `shiftL` 2 .|. o2 `shiftR` 6) .&. 0x1f
                 i3 = o2 `shiftR` 1 .&. 0x1f
@@ -61,7 +61,7 @@
                 i6 = o4 `shiftR` 2 .&. 0x1f
                 i7 = (o4 `shiftL` 3 .|. o5 `shiftR` 5) .&. 0x1f
                 i8 = o5 .&. 0x1f
-            in (foldr (\ i s -> (encodeArray ! i) : s) "" [i1, i2, i3, i4, i5, i6, i7, i8]) ++ (enc os)
+            in foldr ((:) . (encodeArray !)) "" [i1, i2, i3, i4, i5, i6, i7, i8] ++ enc os
     in enc
 
 -- {{{1 decode
@@ -69,19 +69,19 @@
 decode' :: String
     -> [Maybe Word8]
 decode' = let
-        pad n = take n $ repeat $ Just 0
+        pad n = replicate n $ Just 0
         dec [] = []
         dec l@[Just eo1, Just eo2] = take 1 . dec $ l ++ pad 6
         dec l@[Just eo1, Just eo2, Just eo3, Just eo4] = take 2 . dec $ l ++ pad 4
         dec l@[Just eo1, Just eo2, Just eo3, Just eo4, Just eo5] = take 3 . dec $ l ++ pad 3
         dec l@[Just eo1, Just eo2, Just eo3, Just eo4, Just eo5, Just eo6, Just eo7] = take 4 . dec $ l ++ pad 1
-        dec (Just eo1:Just eo2:Just eo3:Just eo4:Just eo5:Just eo6:Just eo7:Just eo8:eos) = let
+        dec (Just eo1 : Just eo2 : Just eo3 : Just eo4 : Just eo5 : Just eo6 : Just eo7 : Just eo8 : eos) = let
                 o1 = eo1 `shiftL` 3 .|. eo2 `shiftR` 2
                 o2 = eo2 `shiftL` 6 .|. eo3 `shiftL` 1 .|. eo4 `shiftR` 4
                 o3 = eo4 `shiftL` 4 .|. eo5 `shiftR` 1
                 o4 = eo5 `shiftL` 7 .|. eo6 `shiftL` 2 .|. eo7 `shiftR` 3
                 o5 = eo7 `shiftL` 5 .|. eo8
-            in Just o1:Just o2:Just o3:Just o4:Just o5:(dec eos)
+            in Just o1 : Just o2 : Just o3 : Just o4 : Just o5 : dec eos
         dec _ = [Nothing]
     in
         dec . map (flip M.lookup decodeMap) . takeWhile (/= '=')
@@ -102,7 +102,7 @@
 chop n s = let
         enc_len | n < 8 = 8
                 | otherwise = n `div` 8 * 8
-    in (take enc_len s) : chop n (drop enc_len s)
+    in take enc_len s : chop n (drop enc_len s)
 
 -- {{{1 unchop
 -- | Concatenate the strings into one long string.
diff --git a/src/Codec/Binary/Base32Hex.hs b/src/Codec/Binary/Base32Hex.hs
--- a/src/Codec/Binary/Base32Hex.hs
+++ b/src/Codec/Binary/Base32Hex.hs
@@ -48,13 +48,13 @@
 encode :: [Word8]
     -> String
 encode = let
-        pad n = take n $ repeat 0
+        pad n = replicate n 0
         enc [] = ""
         enc l@[o] = (++ "======") . take 2 . enc $ l ++ pad 4
         enc l@[o1, o2] = (++ "====") . take 4 . enc $ l ++ pad 3
         enc l@[o1, o2, o3] = (++ "===") . take 5 . enc $ l ++ pad 2
         enc l@[o1, o2, o3, o4] = (++ "=") . take 7 . enc $ l ++ pad 1
-        enc (o1:o2:o3:o4:o5:os) = let
+        enc (o1 : o2 : o3 : o4 : o5 : os) = let
                 i1 = o1 `shiftR` 3
                 i2 = (o1 `shiftL` 2 .|. o2 `shiftR` 6) .&. 0x1f
                 i3 = o2 `shiftR` 1 .&. 0x1f
@@ -63,7 +63,7 @@
                 i6 = o4 `shiftR` 2 .&. 0x1f
                 i7 = (o4 `shiftL` 3 .|. o5 `shiftR` 5) .&. 0x1f
                 i8 = o5 .&. 0x1f
-            in (foldr (\ i s -> (encodeArray ! i) : s) "" [i1, i2, i3, i4, i5, i6, i7, i8]) ++ (enc os)
+            in foldr ((:) . (encodeArray !)) "" [i1, i2, i3, i4, i5, i6, i7, i8] ++ enc os
     in enc
 
 -- {{{1 decode
@@ -71,19 +71,19 @@
 decode' :: String
     -> [Maybe Word8]
 decode' = let
-        pad n = take n . repeat $ Just 0
+        pad n = replicate n $ Just 0
         dec [] = []
         dec l@[Just eo1, Just eo2] = take 1 . dec $ l ++ pad 6
         dec l@[Just eo1, Just eo2, Just eo3, Just eo4] = take 2 . dec $ l ++ pad 4
         dec l@[Just eo1, Just eo2, Just eo3, Just eo4, Just eo5] = take 3 . dec $ l ++ pad 3
         dec l@[Just eo1, Just eo2, Just eo3, Just eo4, Just eo5, Just eo6, Just eo7] = take 4 . dec $ l ++ pad 1
-        dec (Just eo1:Just eo2:Just eo3:Just eo4:Just eo5:Just eo6:Just eo7:Just eo8:eos) = let
+        dec (Just eo1 : Just eo2 : Just eo3 : Just eo4 : Just eo5 : Just eo6 : Just eo7 : Just eo8 : eos) = let
                 o1 = eo1 `shiftL` 3 .|. eo2 `shiftR` 2
                 o2 = eo2 `shiftL` 6 .|. eo3 `shiftL` 1 .|. eo4 `shiftR` 4
                 o3 = eo4 `shiftL` 4 .|. eo5 `shiftR` 1
                 o4 = eo5 `shiftL` 7 .|. eo6 `shiftL` 2 .|. eo7 `shiftR` 3
                 o5 = eo7 `shiftL` 5 .|. eo8
-            in Just o1:Just o2:Just o3:Just o4:Just o5:(dec eos)
+            in Just o1 : Just o2 : Just o3 : Just o4 : Just o5 : dec eos
         dec _ = [Nothing]
     in
         dec . map (flip M.lookup decodeMap) . takeWhile (/= '=')
diff --git a/src/Codec/Binary/Base64.hs b/src/Codec/Binary/Base64.hs
--- a/src/Codec/Binary/Base64.hs
+++ b/src/Codec/Binary/Base64.hs
@@ -52,16 +52,16 @@
 encode :: [Word8]
     -> String
 encode = let
-        pad n = take n $ repeat 0
+        pad n = replicate n 0
         enc [] = ""
         enc l@[o] = (++ "==") . take 2 .enc $ l ++ pad 2
         enc l@[o1, o2] = (++ "=") . take 3 . enc $ l ++ pad 1
-        enc (o1:o2:o3:os) = let
+        enc (o1 : o2 : o3 : os) = let
                 i1 = o1 `shiftR` 2
                 i2 = (o1 `shiftL` 4 .|. o2 `shiftR` 4) .&. 0x3f
                 i3 = (o2 `shiftL` 2 .|. o3 `shiftR` 6) .&. 0x3f
                 i4 = o3 .&. 0x3f
-            in (foldr (\ i s -> (encodeArray ! i) : s) "" [i1, i2, i3, i4]) ++ enc os
+            in foldr ((:) . (encodeArray !)) "" [i1, i2, i3, i4] ++ enc os
     in enc
 
 -- {{{1 decode
@@ -69,15 +69,15 @@
 decode' :: String
     -> [Maybe Word8]
 decode' = let
-        pad n = take n $ repeat $ Just 0
+        pad n = replicate n $ Just 0
         dec [] = []
         dec l@[Just eo1, Just eo2] = take 1 . dec $ l ++ pad 2
         dec l@[Just eo1, Just eo2, Just eo3] = take 2 . dec $ l ++ pad 1
-        dec (Just eo1:Just eo2:Just eo3:Just eo4:eos) = let
+        dec (Just eo1 : Just eo2 : Just eo3 : Just eo4 : eos) = let
                 o1 = eo1 `shiftL` 2 .|. eo2 `shiftR` 4
                 o2 = eo2 `shiftL` 4 .|. eo3 `shiftR` 2
                 o3 = eo3 `shiftL` 6 .|. eo4
-            in Just o1:Just o2:Just o3:(dec eos)
+            in Just o1 : Just o2 : Just o3 : dec eos
         dec _ = [Nothing]
     in
         dec . map (flip M.lookup decodeMap) . takeWhile (/= '=')
@@ -104,7 +104,7 @@
 chop n s = let
         enc_len | n < 4 = 4
                 | otherwise = n `div` 4 * 4
-    in (take enc_len s) : chop n (drop enc_len s)
+    in take enc_len s : chop n (drop enc_len s)
 
 -- {{{1 unchop
 -- | Concatenate the strings into one long string.
diff --git a/src/Codec/Binary/Base85.hs b/src/Codec/Binary/Base85.hs
--- a/src/Codec/Binary/Base85.hs
+++ b/src/Codec/Binary/Base85.hs
@@ -44,13 +44,13 @@
 encode [b1] = take 2 $ encode [b1, 0, 0, 1]
 encode [b1, b2] = take 3 $ encode [b1, b2, 0, 1]
 encode [b1, b2, b3] = take 4 $ encode [b1, b2, b3, 1]
-encode (0:0:0:0:bs) = "z" ++ encode bs
-encode (b1:b2:b3:b4:bs) = (foldr (\ i s -> (encodeArray ! i) : s) "" group) ++ (encode bs)
+encode (0 : 0 : 0 : 0 : bs) = 'z' : encode bs
+encode (b1 : b2 : b3 : b4 : bs) = foldr ((:) . (encodeArray !)) "" group ++ encode bs
     where
         group2Word32 :: Word32
-        group2Word32 = foldl (\ a b -> a `shiftL` 8 + (fromIntegral b)) 0 [b1, b2, b3, b4]
+        group2Word32 = foldl (\ a b -> a `shiftL` 8 + fromIntegral b) 0 [b1, b2, b3, b4]
         encodeWord32ToWord8s :: Word32 -> [Word8]
-        encodeWord32ToWord8s = map fromIntegral . map (`mod` 85) . take 5 . iterate (`div` 85)
+        encodeWord32ToWord8s = map (fromIntegral . (`mod` 85)) . take 5 . iterate (`div` 85)
         adjustNReverse = reverse . map (+ 33)
         group = (adjustNReverse .encodeWord32ToWord8s) group2Word32
 
@@ -61,9 +61,9 @@
 decode' :: String
     -> [Maybe Word8]
 decode' [] = []
-decode' ('z':cs) = (Just 0:Just 0:Just 0:Just 0:decode' cs)
+decode' ('z' : cs) = Just 0 : Just 0 : Just 0 : Just 0 : decode' cs
 decode' cs = let
-        pad n = take n $ repeat $ Just 0
+        pad n = replicate n $ Just 0
         dec :: [Maybe Word8] -> [Maybe Word8]
         dec l@[Just c1, Just c2] = take 1 . dec $ l ++ pad 3
         dec l@[Just c1, Just c2, Just c3] = take 2 . dec $ l ++ pad 2
@@ -71,9 +71,9 @@
         dec l@[Just c1, Just c2, Just c3, Just c4, Just c5] = let
                 adjRev = map (flip (-) 33) [c5, c4, c3, c2, c1]
                 group2Word32 :: [Word8] -> Word32
-                group2Word32 = foldl1 (+) . map (uncurry (*)) . zip (map (85 ^) [0..4]) . map fromIntegral
+                group2Word32 = foldl1 (+) . zipWith (*) (map (85 ^) [0..4]) . map fromIntegral
                 word32ToGroup :: Word32 -> [Maybe Word8]
-                word32ToGroup = map Just . map fromIntegral . reverse . take 4 . iterate (`div` 256)
+                word32ToGroup = map (Just . fromIntegral) . reverse . take 4 . iterate (`div` 256)
             in (word32ToGroup . group2Word32) adjRev
         dec _ = [Nothing]
     in (dec . map (flip M.lookup decodeMap) $ take 5 cs) ++ decode' (drop 5 cs)
@@ -96,7 +96,7 @@
 chop n s = let
         enc_len | n < 5 = 5
                 | otherwise = n `div` 5 * 5
-    in (take enc_len s) : chop n (drop enc_len s)
+    in take enc_len s : chop n (drop enc_len s)
 
 -- {{{1 unchop
 -- | Concatenate the strings into one long string.
diff --git a/src/Codec/Binary/PythonString.hs b/src/Codec/Binary/PythonString.hs
--- a/src/Codec/Binary/PythonString.hs
+++ b/src/Codec/Binary/PythonString.hs
@@ -44,7 +44,7 @@
 encode :: [Word8]
     -> String
 encode [] = ""
-encode (o:os)
+encode (o : os)
     | o < 0x20 || o > 0x7e = ('\\' : 'x' : toHex o) ++ encode os
     | o == 34 = "\\\"" ++ encode os
     | o == 39 = "\\'" ++ encode os
@@ -56,11 +56,11 @@
 decode' :: String
     -> [Maybe Word8]
 decode' [] = []
-decode' ('\\':'x':c0:c1:cs) = fromHex [c0, c1] : decode' cs
-decode' ('\\':'\\':cs) = (Just $ fromIntegral $ ord '\\') : decode' cs
-decode' ('\\':'\'':cs) = (Just $ fromIntegral $ ord '\'') : decode' cs
-decode' ('\\':'\"':cs) = (Just $ fromIntegral $ ord '\"') : decode' cs
-decode' (c:cs)
+decode' ('\\':'x' : c0 : c1 : cs) = fromHex [c0, c1] : decode' cs
+decode' ('\\':'\\' : cs) = (Just $ fromIntegral $ ord '\\') : decode' cs
+decode' ('\\':'\'' : cs) = (Just $ fromIntegral $ ord '\'') : decode' cs
+decode' ('\\':'\"' : cs) = (Just $ fromIntegral $ ord '\"') : decode' cs
+decode' (c : cs)
     | c /= '\\' = (Just $ fromIntegral $ ord c) : decode' cs
     | otherwise = [Nothing]
 
@@ -76,7 +76,7 @@
 chop n = let
         _n = max 1 n
         _chop [] = []
-        _chop cs = take _n cs : (_chop $ drop _n cs)
+        _chop cs = take _n cs : _chop (drop _n cs)
     in _chop
 
 -- {{{1 unchop
diff --git a/src/Codec/Binary/QuotedPrintable.hs b/src/Codec/Binary/QuotedPrintable.hs
--- a/src/Codec/Binary/QuotedPrintable.hs
+++ b/src/Codec/Binary/QuotedPrintable.hs
@@ -31,7 +31,7 @@
 encode :: [Word8]
     -> String
 encode [] = ""
-encode (o:os)
+encode (o : os)
     | o < 33 || o == 61 || o > 126 = ('=' : toHex o) ++ encode os
     | otherwise = chr (fromIntegral o) : encode os
 
@@ -41,8 +41,8 @@
 decode' :: String
     -> [Maybe Word8]
 decode' [] = []
-decode' ('=':c0:c1:cs) = fromHex [c0, c1] : decode' cs
-decode' (c:cs)
+decode' ('=' : c0 : c1 : cs) = fromHex [c0, c1] : decode' cs
+decode' (c : cs)
     | c /= '=' = (Just $ fromIntegral $ ord c) : decode' cs
     | otherwise = [Nothing]
 
@@ -59,10 +59,10 @@
 chop n s = let
         n' = max 3 $ n - 1
         _c i ts "" acc = ts : acc
-        _c i ts tss@('=':tss') acc
+        _c i ts tss@('=' : tss') acc
             | i + 2 < n' = _c (i + 1) ('=' : ts) tss' acc
             | otherwise = _c 0 "" tss (('=' : ts) : acc)
-        _c i ts tss@(c:tss') acc
+        _c i ts tss@(c : tss') acc
             | i < n' = _c (i + 1) (c : ts) tss' acc
             | otherwise = _c 0 "" tss (('=' : ts) : acc)
     in map reverse . reverse $ _c 0 "" s []
@@ -71,9 +71,9 @@
 -- | Concatenate the list of strings into one long string.
 unchop :: [String] -> String
 unchop [] = ""
-unchop (s:ss) = let
+unchop (s : ss) = let
         dropLast = last s == '='
         len = length s
     in if dropLast
-        then (take (len - 1) s) ++ (unchop ss)
-        else s ++ (unchop ss)
+        then take (len - 1) s ++ unchop ss
+        else s ++ unchop ss
diff --git a/src/Codec/Binary/Url.hs b/src/Codec/Binary/Url.hs
--- a/src/Codec/Binary/Url.hs
+++ b/src/Codec/Binary/Url.hs
@@ -23,9 +23,9 @@
 
 import Codec.Binary.Util(toHex,fromHex)
 
-_unreservedChars = (zip [65..90] "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
-        ++ (zip [97..122] "abcdefghijklmnopqrstuvwxyz")
-        ++ (zip [48..57] "0123456789")
+_unreservedChars = zip [65..90] "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+        ++ zip [97..122] "abcdefghijklmnopqrstuvwxyz"
+        ++ zip [48..57] "0123456789"
         ++ [(45, '-'), (95, '_'), (46, '.'), (126, '~')]
 
 encodeMap :: M.Map Word8 Char
@@ -39,7 +39,7 @@
 encode :: [Word8]
     -> String
 encode [] = ""
-encode (o:os) = case (M.lookup o encodeMap) of
+encode (o : os) = case (M.lookup o encodeMap) of
     Just c -> c : encode os
     Nothing -> ('%' : toHex o) ++ encode os
 
@@ -48,8 +48,8 @@
 decode' :: String
     -> [Maybe Word8]
 decode' [] = []
-decode' ('%':c0:c1:cs) = fromHex [c0, c1] : decode' cs
-decode' (c:cs)
+decode' ('%' : c0 : c1 : cs) = fromHex [c0, c1] : decode' cs
+decode' (c : cs)
     | c /= '%' = (Just $ fromIntegral $ ord c) : decode' cs
     | otherwise = [Nothing]
 
@@ -66,7 +66,7 @@
 chop n = let
         _n = max 1 n
         _chop [] = []
-        _chop cs = take _n cs : (_chop $ drop _n cs)
+        _chop cs = take _n cs : _chop (drop _n cs)
     in _chop
 
 -- {{{1 unchop
diff --git a/src/Codec/Binary/Util.hs b/src/Codec/Binary/Util.hs
--- a/src/Codec/Binary/Util.hs
+++ b/src/Codec/Binary/Util.hs
@@ -38,4 +38,4 @@
                 o = hn `shiftL` 4 .|. ln
             in Just o
         dec _ = Nothing
-    in dec . map ((flip M.lookup hexDecodeMap) . toUpper)
+    in dec . map (flip M.lookup hexDecodeMap . toUpper)
diff --git a/src/Codec/Binary/Uu.hs b/src/Codec/Binary/Uu.hs
--- a/src/Codec/Binary/Uu.hs
+++ b/src/Codec/Binary/Uu.hs
@@ -40,16 +40,16 @@
 encode :: [Word8]
     -> String
 encode = let
-        pad n = take n $ repeat 0
+        pad n = replicate n 0
         enc [] = ""
         enc l@[o] = take 2 . enc $ l ++ pad 2
         enc l@[o1, o2] = take 3 . enc $ l ++ pad 1
-        enc (o1:o2:o3:os) = let
+        enc (o1 : o2 : o3 : os) = let
                 i1 = o1 `shiftR` 2
                 i2 = (o1 `shiftL` 4 .|. o2 `shiftR` 4) .&. 0x3f
                 i3 = (o2 `shiftL` 2 .|. o3 `shiftR` 6) .&. 0x3f
                 i4 = o3 .&. 0x3f
-            in (foldr (\ i s -> (encodeArray ! i) : s) "" [i1, i2, i3, i4]) ++ enc os
+            in foldr ((:) . (encodeArray !)) "" [i1, i2, i3, i4] ++ enc os
     in enc
 
 -- {{{1 decode
@@ -57,15 +57,15 @@
 decode' :: String
     -> [Maybe Word8]
 decode' = let
-        pad n = take n . repeat $ Just 0
+        pad n = replicate n $ Just 0
         dec [] = []
         dec l@[Just eo1, Just eo2] = take 1 . dec $ l ++ pad 2
         dec l@[Just eo1, Just eo2, Just eo3] = take 2 . dec $ l ++ pad 1
-        dec (Just eo1:Just eo2:Just eo3:Just eo4:eos) = let
+        dec (Just eo1 : Just eo2 : Just eo3 : Just eo4 : eos) = let
                 o1 = eo1 `shiftL` 2 .|. eo2 `shiftR` 4
                 o2 = eo2 `shiftL` 4 .|. eo3 `shiftR` 2
                 o3 = eo3 `shiftL` 6 .|. eo4
-            in Just o1:Just o2:Just o3:(dec eos)
+            in Just o1 : Just o2 : Just o3 : dec eos
         dec _ = [Nothing]
     in
         dec . map (flip M.lookup decodeMap)
@@ -109,11 +109,11 @@
 unchop :: [String]
     -> String
 unchop ss = let
-        singleUnchop (l:cs) = let
+        singleUnchop (l : cs) = let
                 act_len = fromIntegral $ decodeMap M.! l
                 enc_len = case (act_len `divMod` 3) of
                     (n, 0) -> n * 4
                     (n, 1) -> n * 4 + 2
                     (n, 2) -> n * 4 + 3
             in take enc_len cs
-    in foldr (\ s res -> (singleUnchop s) ++ res) "" ss
+    in foldr ((++) . singleUnchop) "" ss
diff --git a/src/Codec/Binary/Xx.hs b/src/Codec/Binary/Xx.hs
--- a/src/Codec/Binary/Xx.hs
+++ b/src/Codec/Binary/Xx.hs
@@ -42,16 +42,16 @@
 encode :: [Word8]
     -> String
 encode = let
-        pad n = take n $ repeat 0
+        pad n = replicate n 0
         enc [] = ""
         enc l@[o] = take 2 . enc $ l ++ pad 2
         enc l@[o1, o2] = take 3 . enc $ l ++ pad 1
-        enc (o1:o2:o3:os) = let
+        enc (o1 : o2 : o3 : os) = let
                 i1 = o1 `shiftR` 2
                 i2 = (o1 `shiftL` 4 .|. o2 `shiftR` 4) .&. 0x3f
                 i3 = (o2 `shiftL` 2 .|. o3 `shiftR` 6) .&. 0x3f
                 i4 = o3 .&. 0x3f
-            in (foldr (\ i s -> (encodeArray ! i) : s) "" [i1, i2, i3, i4]) ++ enc os
+            in foldr ((:) . (encodeArray !)) "" [i1, i2, i3, i4] ++ enc os
     in enc
 
 -- {{{1 decode
@@ -59,15 +59,15 @@
 decode' :: String
     -> [Maybe Word8]
 decode' = let
-        pad n = take n . repeat $ Just 0
+        pad n = replicate n $ Just 0
         dec [] = []
         dec l@[Just eo1, Just eo2] = take 1 . dec $ l ++ pad 2
         dec l@[Just eo1, Just eo2, Just eo3] = take 2 . dec $ l ++ pad 1
-        dec (Just eo1:Just eo2:Just eo3:Just eo4:eos) = let
+        dec (Just eo1 : Just eo2 : Just eo3 : Just eo4 : eos) = let
                 o1 = eo1 `shiftL` 2 .|. eo2 `shiftR` 4
                 o2 = eo2 `shiftL` 4 .|. eo3 `shiftR` 2
                 o3 = eo3 `shiftL` 6 .|. eo4
-            in Just o1:Just o2:Just o3:(dec eos)
+            in Just o1 : Just o2 : Just o3 : dec eos
         dec _ = [Nothing]
     in
         dec . map (flip M.lookup decodeMap)
@@ -109,11 +109,11 @@
 unchop :: [String]
     -> String
 unchop ss = let
-        singleUnchop (l:cs) = let
+        singleUnchop (l : cs) = let
                 act_len = fromIntegral $ decodeMap M.! l
                 enc_len = case (act_len `divMod` 3) of
                     (n, 0) -> n * 4
                     (n, 1) -> n * 4 + 2
                     (n, 2) -> n * 4 + 3
             in take enc_len cs
-    in foldr (\ s res -> (singleUnchop s) ++ res) "" ss
+    in foldr ((++) . singleUnchop) "" ss
diff --git a/src/Codec/Binary/Yenc.hs b/src/Codec/Binary/Yenc.hs
--- a/src/Codec/Binary/Yenc.hs
+++ b/src/Codec/Binary/Yenc.hs
@@ -18,15 +18,15 @@
 
 import Data.Word
 
-_criticals_in = [0xd6, 0xe0, 0xe3, 0x13]
+_criticalsIn = [0xd6, 0xe0, 0xe3, 0x13]
 _equal = 0x3d
 
 -- {{{1 encode
 -- | Encode data.
 encode :: [Word8]
     -> [Word8]
-encode (d:ds)
-    | d `elem` _criticals_in = _equal : d + 106 : encode ds
+encode (d : ds)
+    | d `elem` _criticalsIn = _equal : d + 106 : encode ds
     | otherwise = d + 42 : encode ds
 encode _ = []
 
@@ -34,8 +34,8 @@
 -- | Decode data (lazy).
 decode' :: [Word8]
     -> [Maybe Word8]
-decode' (0x3d:d:ds) = Just (d + 150) : decode' ds
-decode' (d:ds) = Just (d + 214) : decode' ds
+decode' (0x3d : d : ds) = Just (d + 150) : decode' ds
+decode' (d : ds) = Just (d + 214) : decode' ds
 decode' _ = []
 
 -- | Decode data (strict).
@@ -53,8 +53,8 @@
         _n = max n 1
         (p1, p2) = splitAt _n ws
     in
-        if (last p1 == _equal)
-            then (p1 ++ (take 1 p2)) : chop _n (drop 1 p2)
+        if last p1 == _equal
+            then (p1 ++ take 1 p2) : chop _n (drop 1 p2)
             else p1 : chop _n p2
 
 -- {{{1 unchop
diff --git a/test-src/DataencQC.hs b/test-src/DataencQC.hs
new file mode 100644
--- /dev/null
+++ b/test-src/DataencQC.hs
@@ -0,0 +1,170 @@
+{-
+ - Copyright : (c) 2007 Magnus Therning
+ - License   : BSD3
+ -}
+
+module DataencQC
+    where
+
+import Data.Maybe
+import Data.Word
+import Test.QuickCheck
+import Test.Framework.Providers.QuickCheck2
+
+import qualified Codec.Binary.Uu as Uu
+import qualified Codec.Binary.Uu as Xx
+import qualified Codec.Binary.Base85 as Base85
+import qualified Codec.Binary.Base64 as Base64
+import qualified Codec.Binary.Base64Url as Base64Url
+import qualified Codec.Binary.Base32 as Base32
+import qualified Codec.Binary.Base32Hex as Base32Hex
+import qualified Codec.Binary.Base16 as Base16
+import qualified Codec.Binary.Yenc as Yenc
+import qualified Codec.Binary.QuotedPrintable as QP
+import qualified Codec.Binary.PythonString as Py
+import qualified Codec.Binary.Url as Url
+
+-- {{{1 Arbitrary instances
+instance Arbitrary Word8 where
+    arbitrary = do
+        n <- choose (fromIntegral (minBound::Word8) :: Int,
+                fromIntegral (maxBound::Word8) :: Int)
+        return $ fromIntegral n
+
+-- {{{1 uuencode properties
+prop_uuEncode ws = ws == (fromJust . Uu.decode . Uu.encode) ws
+    where types = ws::[Word8]
+
+prop_uuChop n ws = s == (Uu.unchop . Uu.chop n) s
+    where
+        types = (n :: Int, ws::[Word8])
+        s = Uu.encode ws
+
+prop_uuCombined n ws = ws == fromJust (Uu.decode $ Uu.unchop $ Uu.chop n $ Uu.encode ws)
+    where types = (n::Int, ws::[Word8])
+
+-- {{{1 xxencode properties
+prop_xxEncode ws = ws == (fromJust . Xx.decode . Xx.encode) ws
+    where types = ws::[Word8]
+
+prop_xxChop n ws = s == (Xx.unchop . Xx.chop n) s
+    where
+        types = (n:: Int, ws::[Word8])
+        s = Xx.encode ws
+
+prop_xxCombined n ws = ws == fromJust (Xx.decode $ Xx.unchop $ Xx.chop n $ Xx.encode ws)
+    where types = (n::Int, ws::[Word8])
+
+-- {{{1 base85 properties
+prop_base85Encode ws = ws == fromJust (Base85.decode $ Base85.encode ws)
+    where types = ws::[Word8]
+
+prop_base85Chop n s = s == Base85.unchop (Base85.chop n s)
+    where types = (n::Int, s::String)
+
+-- {{{1 base64 properties
+prop_base64Encode ws = ws == fromJust (Base64.decode $ Base64.encode ws)
+    where types = ws::[Word8]
+
+prop_base64Chop n s = s == Base64.unchop (Base64.chop n s)
+    where types = (n::Int, s::String)
+
+-- {{{1 base64url properties
+prop_base64UrlEncode ws = ws == fromJust (Base64Url.decode $ Base64Url.encode ws)
+    where types = ws::[Word8]
+
+prop_base64UrlChop n s = s == Base64Url.unchop (Base64Url.chop n s)
+    where types = (n::Int, s::String)
+
+-- {{{1 base32
+prop_base32Encode ws = ws == fromJust (Base32.decode $ Base32.encode ws)
+    where types = ws::[Word8]
+
+prop_base32Chop n s = s == Base32.unchop (Base32.chop n s)
+    where types = (n::Int, s::String)
+
+-- {{{1 base32hex
+prop_base32HexEncode ws = ws == fromJust (Base32Hex.decode $ Base32Hex.encode ws)
+    where types = ws::[Word8]
+
+prop_base32HexChop n s = s == Base32Hex.unchop (Base32Hex.chop n s)
+    where types = (n::Int, s::String)
+
+-- {{{1 base16
+prop_base16Encode ws = ws == fromJust (Base16.decode $ Base16.encode ws)
+    where types = ws::[Word8]
+
+prop_base16Chop n s = s == Base16.unchop (Base16.chop n s)
+    where types = (n::Int, s::String)
+
+-- {{{1 yEncoding
+prop_yencEncode ws = ws == fromJust (Yenc.decode $ Yenc.encode ws)
+    where types = ws ::[Word8]
+
+prop_yencChop n ws = ws == Yenc.unchop (Yenc.chop n ws)
+    where types = (n::Int, ws :: [Word8])
+
+-- {{{1 qp
+prop_qpEncode ws = ws == fromJust (QP.decode $ QP.encode ws)
+    where types = ws :: [Word8]
+
+prop_qpChop n ws = s == (QP.unchop . QP.chop n) s
+    where
+        types = (n::Int, ws::[Word8])
+        s = QP.encode ws
+
+prop_qpCombined n ws = ws == fromJust (QP.decode $ QP.unchop $ QP.chop n $ QP.encode ws)
+    where types = (n::Int, ws::[Word8])
+
+-- {{{1 py
+prop_pyEncode ws = ws == fromJust (Py.decode $ Py.encode ws)
+    where types = ws :: [Word8]
+
+prop_pyChop n s = s == Py.unchop (Py.chop n s)
+    where types = (n :: Int, s :: String)
+
+prop_pyCombined n ws = ws == fromJust (runAll ws)
+    where runAll = Py.decode . Py.unchop . Py.chop n . Py.encode
+
+-- {{{1 url
+prop_urlEncode ws = ws == fromJust (Url.decode $ Url.encode ws)
+    where types = ws :: [Word8]
+
+prop_urlChop n s = s == Url.unchop (Url.chop n s)
+    where types = (n :: Int, s :: String)
+
+prop_urlCombined n ws = ws == fromJust (runAll ws)
+    where runAll = Url.decode . Url.unchop . Url.chop n . Url.encode
+
+-- {{{1 all the tests
+allTests =
+    [ testProperty "uuEncode" prop_uuEncode
+    , testProperty "uuChop" prop_uuChop
+    , testProperty "uuCombined" prop_uuCombined
+    , testProperty "xxEncode" prop_xxEncode
+    , testProperty "xxChop" prop_xxChop
+    , testProperty "xxCombined" prop_xxCombined
+    , testProperty "base85Encode" prop_base85Encode
+    , testProperty "base85Chop" prop_base85Chop
+    , testProperty "base64Encode" prop_base64Encode
+    , testProperty "base64Chop" prop_base64Chop
+    , testProperty "base64UrlEncode" prop_base64UrlEncode
+    , testProperty "base64UrlChop" prop_base64UrlChop
+    , testProperty "base32Encode" prop_base32Encode
+    , testProperty "base32Chop" prop_base32Chop
+    , testProperty "base32HexEncode" prop_base32HexEncode
+    , testProperty "base32HexChop" prop_base32HexChop
+    , testProperty "base16Encode" prop_base16Encode
+    , testProperty "base16Chop" prop_base16Chop
+    , testProperty "yencEncode" prop_yencEncode
+    , testProperty "yencChop" prop_yencChop
+    , testProperty "qpEncode" prop_qpEncode
+    , testProperty "qpChop" prop_qpChop
+    , testProperty "qpCombined" prop_qpCombined
+    , testProperty "pyEncode" prop_pyEncode
+    , testProperty "pyChop" prop_pyChop
+    , testProperty "pyCombined" prop_pyCombined
+    , testProperty "urlEncode" prop_urlEncode
+    , testProperty "urlChop" prop_urlChop
+    , testProperty "urlCombined" prop_urlCombined
+    ]
diff --git a/test-src/DataencUT.hs b/test-src/DataencUT.hs
new file mode 100644
--- /dev/null
+++ b/test-src/DataencUT.hs
@@ -0,0 +1,290 @@
+{-
+ - Copyright : (c) 2007 Magnus Therning
+ - License   : BSD3
+ -}
+
+module DataencUT
+    where
+
+import Test.HUnit
+import Control.Monad
+import System.Exit
+import Data.Maybe
+import qualified Test.Framework.Providers.API as TFAPI
+import Test.Framework.Providers.HUnit
+
+import Codec.Binary.DataEncoding
+import qualified Codec.Binary.Yenc as Yenc
+
+-- {{{1 buildTestList
+-- builds a list of successful tests based on a tuple (suite, description,
+-- encoded data, decoded data, codec)
+buildTestList td = TestList $ concat [
+    [ TestLabel (suite ++ " encode " ++ desc) (enc ~=? encode codec dec)
+    , TestLabel (suite ++ " decode " ++ desc) (dec ~=? fromJust (decode codec enc))
+    ] | (suite, desc, enc, dec, codec) <- td ]
+
+-- {{{1 unitTest2TFTest
+unitTest2TFTest :: Test -> [TFAPI.Test]
+unitTest2TFTest t = let
+        unitTest2TFTest' desc (TestCase a) = [testCase desc a]
+        unitTest2TFTest' desc (TestLabel s t) = unitTest2TFTest' (desc ++ ":" ++ s) t
+        unitTest2TFTest' desc (TestList ts) = concatMap (unitTest2TFTest' desc) ts
+    in unitTest2TFTest' "" t
+
+
+-- {{{1 uuencode tests
+uuTestData =
+    [ ("uu", "empty", "", [], uu)
+    , ("uu", "\\0", "``", [0], uu)
+    , ("uu", "\\255", "_P", [255], uu)
+    , ("uu", "AA", "04$", [65, 65], uu)
+    , ("uu", "AAA", "04%!", [65, 65, 65], uu)
+    , ("uu", "AAAA", "04%!00", [65, 65, 65, 65], uu)
+    , ("uu", "Example", "17AA;7!L90", [69,120,97,109,112,108,101], uu)
+    ]
+uuTests = buildTestList uuTestData
+
+uuTests2 = test
+    [ "uu unchop.chop" ~: "EI2" ~=? unchop uu (chop uu 1 "EI2")
+    , "uu unchop.chop" ~: "EI3-" ~=? unchop uu (chop uu 1 "EI3-")
+    , "uu unchop.chop" ~: "EI3-EE" ~=? unchop uu (chop uu 1 "EI3-EE")
+    , "uu full circle" ~: [0..255] ~=? fromJust (decode uu $ unchop uu $ chop uu 1 $ encode uu [0..255])
+    , "uu full circle" ~: [0..255] ~=? fromJust (decode uu $ unchop uu $ chop uu 61 $ encode uu [0..255])
+    , "uu full circle" ~: [0..255] ~=? fromJust (decode uu $ unchop uu $ chop uu 100 $ encode uu [0..255])
+    ]
+
+uuTestsFail = test
+    [ "uu decode short" ~: Nothing ~=? decode uu "A"
+    , "uu decode' short" ~: [Nothing] ~=? decode' uu "A"
+    , "uu decode illegal" ~: Nothing ~=? decode uu "aa"
+    , "uu decode' illegal" ~: [Nothing] ~=? decode' uu "aa"
+    ]
+
+-- {{{1 xxencode tests
+xxTestData =
+    [ ("xx", "empty", "", [], xx)
+    , ("xx", "\\0", "++", [0], xx)
+    , ("xx", "\\255", "zk", [255], xx)
+    , ("xx", "AA", "EI2", [65, 65], xx)
+    , ("xx", "AAA", "EI3-", [65, 65, 65], xx)
+    , ("xx", "AAAA", "EI3-EE", [65, 65, 65, 65], xx)
+    , ("xx", "Example", "FLVVPL-gNE", [69,120,97,109,112,108,101], xx)
+    ]
+xxTests = buildTestList xxTestData
+
+xxTests2 = test
+    [ "xx unchop.chop" ~: "EI2" ~=? unchop xx (chop xx 1 "EI2")
+    , "xx unchop.chop" ~: "EI3-" ~=? unchop xx (chop xx 1 "EI3-")
+    , "xx unchop.chop" ~: "EI3-EE" ~=? unchop xx (chop xx 1 "EI3-EE")
+    , "xx full circle" ~: [0..255] ~=? fromJust (decode xx $ unchop xx $ chop xx 1 $ encode xx [0..255])
+    , "xx full circle" ~: [0..255] ~=? fromJust (decode xx $ unchop xx $ chop xx 61 $ encode xx [0..255])
+    , "xx full circle" ~: [0..255] ~=? fromJust (decode xx $ unchop xx $ chop xx 100 $ encode xx [0..255])
+    ]
+
+xxTestsFail = test
+    [ "xx decode short" ~: Nothing ~=? decode xx "A"
+    , "xx decode' short" ~: [Nothing] ~=? decode' xx "A"
+    , "xx decode illegal" ~: Nothing ~=? decode xx "''"
+    , "xx decode' illegal" ~: [Nothing] ~=? decode' xx "''"
+    ]
+
+-- {{{1 base85 tests
+base85TestData =
+    [ ("base85", "empty", "", [], base85)
+    , ("base85", "f", "Ac", [102], base85)
+    , ("base85", "fo", "Ao@", [102,111], base85)
+    , ("base85", "foo", "AoDS", [102,111,111], base85)
+    , ("base85", "foob", "AoDTs", [102,111,111,98], base85)
+    , ("base85", "fooba", "AoDTs@/", [102,111,111,98,97], base85)
+    , ("base85", "foobar", "AoDTs@<)", [102,111,111,98,97,114], base85)
+    , ("base85", "\0", "!!", [0], base85)
+    , ("base85", "foob\0\0\0\0ar", "AoDTszEW", [102,111,111,98,0,0,0,0,114], base85)
+    , ("base85", "Example", "7<i6XE,9(", [69,120,97,109,112,108,101], base85)
+    ]
+base85Tests = buildTestList base85TestData
+
+base85TestsFail = test
+    [ "base85 decode short" ~: Nothing ~=? decode base85 "A"
+    , "base85 decode' short" ~: [Nothing] ~=? decode' base85 "A"
+    , "base85 decode illegal" ~: Nothing ~=? decode base85 "!z"
+    , "base85 decode' illegal" ~: [Nothing] ~=? decode' base85 "!z"
+    ]
+
+-- {{{1 base64 tests
+base64TestData =
+    [ ("base64", "empty", "", [], base64)
+    , ("base64", "f", "Zg==", [102], base64)
+    , ("base64", "fo", "Zm8=", [102,111], base64)
+    , ("base64", "foo", "Zm9v", [102,111,111], base64)
+    , ("base64", "foob", "Zm9vYg==", [102,111,111,98], base64)
+    , ("base64", "fooba", "Zm9vYmE=", [102,111,111,98,97], base64)
+    , ("base64", "foobar", "Zm9vYmFy", [102,111,111,98,97,114], base64)
+    , ("base64", "\0", "AA==", [0], base64)
+    , ("base64", "\255", "/w==", [255], base64)
+    , ("base64", "Example", "RXhhbXBsZQ==", [69,120,97,109,112,108,101], base64)
+    ]
+base64Tests = buildTestList base64TestData
+
+base64TestsFail = test
+    [ "base64 decode short" ~: Nothing ~=? decode base64 "A"
+    , "base64 decode' short" ~: [Nothing] ~=? decode' base64 "A"
+    , "base64 decode illegal" ~: Nothing ~=? decode base64 "!!"
+    , "base64 decode' illegal" ~: [Nothing] ~=? decode' base64 "!!"
+    ]
+
+-- {{{1 base64url tests
+base64UrlTestData =
+    [ ("base64url", "empty", "", [], base64Url)
+    , ("base64url", "\0", "AA==", [0], base64Url)
+    , ("base64url", "\255", "_w==", [255], base64Url)
+    , ("base64url", "Example", "RXhhbXBsZQ==", [69,120,97,109,112,108,101], base64Url)
+    ]
+base64UrlTests = buildTestList base64UrlTestData
+
+-- {{{1 base32 tests
+base32TestData =
+    [ ("base32", "empty", "", [], base32)
+    , ("base32", "f", "MY======", [102], base32)
+    , ("base32", "fo", "MZXQ====", [102,111], base32)
+    , ("base32", "foo", "MZXW6===", [102,111,111], base32)
+    , ("base32", "foob", "MZXW6YQ=", [102,111,111,98], base32)
+    , ("base32", "fooba", "MZXW6YTB", [102,111,111,98,97], base32)
+    , ("base32", "foobar", "MZXW6YTBOI======", [102,111,111,98,97,114], base32)
+    ]
+base32Tests = buildTestList base32TestData
+
+base32TestsFail = test
+    [ "base32 decode short" ~: Nothing ~=? decode base32 "A"
+    , "base32 decode' short" ~: [Nothing] ~=? decode' base32 "A"
+    , "base32 decode illegal" ~: Nothing ~=? decode base32 "gh"
+    , "base32 decode' illegal" ~: [Nothing] ~=? decode' base32 "gh"
+    ]
+
+-- {{{1 base32hex tests
+base32HexTestData =
+    [ ("base32hex", "empty", "", [], base32Hex)
+    , ("base32hex", "f", "CO======", [102], base32Hex)
+    , ("base32hex", "fo", "CPNG====", [102,111], base32Hex)
+    , ("base32hex", "foo", "CPNMU===", [102,111,111], base32Hex)
+    , ("base32hex", "foob", "CPNMUOG=", [102,111,111,98], base32Hex)
+    , ("base32hex", "fooba", "CPNMUOJ1", [102,111,111,98,97], base32Hex)
+    , ("base32hex", "foobar", "CPNMUOJ1E8======", [102,111,111,98,97,114], base32Hex)
+    ]
+base32HexTests = buildTestList base32HexTestData
+
+base32HexTestsFail = test
+    [ "base32hex decode short" ~: Nothing ~=? decode base32Hex "A"
+    , "base32hex decode' short" ~: [Nothing] ~=? decode' base32Hex "A"
+    , "base32hex decode illegal" ~: Nothing ~=? decode base32Hex "gh"
+    , "base32hex decode' illegal" ~: [Nothing] ~=? decode' base32Hex "gh"
+    ]
+
+-- {{{1 base16 (hex)
+base16TestData =
+    [ ("base16", "empty", "", [], base16)
+    , ("base16", "f", "66", [102], base16)
+    , ("base16", "fo", "666F", [102,111], base16)
+    , ("base16", "foo", "666F6F", [102,111,111], base16)
+    , ("base16", "foob", "666F6F62", [102,111,111,98], base16)
+    , ("base16", "fooba", "666F6F6261", [102,111,111,98,97], base16)
+    , ("base16", "foobar", "666F6F626172", [102,111,111,98,97,114], base16)
+    ]
+base16Tests = buildTestList base16TestData
+
+base16TestsFail = test
+    [ "base16 decode short" ~: Nothing ~=? decode base16 "A"
+    , "base16 decode' short" ~: [Nothing] ~=? decode' base16 "A"
+    , "base16 decode illegal" ~: Nothing ~=? decode base16 "GH"
+    , "base16 decode' illegal" ~: [Nothing] ~=? decode' base16 "GH"
+    ]
+
+-- {{{1 yEncoding
+yencTests = test
+    [ "yEnc encode empty" ~: [] ~=? Yenc.encode []
+    , "yEnc decode empty" ~: Just [] ~=? Yenc.decode []
+    , "yEnc encode 'f'" ~: [0x90] ~=? Yenc.encode [0x66]
+    , "yEnc decode enc('f')" ~: Just [0x66] ~=? Yenc.decode [0x90]
+    , "yEnc encode 'foobar'" ~: [0x90, 0x99, 0x99, 0x8c, 0x8b, 0x9c] ~=? Yenc.encode [0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]
+    , "yEnc decode enc('foobar')" ~: Just [0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72] ~=? Yenc.decode [0x90, 0x99, 0x99, 0x8c, 0x8b, 0x9c]
+    , "yEnc encode [0xd6, 0xd7]" ~: [0x3d, 0x40, 0x01] ~=? Yenc.encode [0xd6, 0xd7]
+    , "yEnc decode enc([0xd6, 0xd7])" ~:  Just [0xd6, 0xd7] ~=? Yenc.decode [0x3d, 0x40, 0x01]
+    , "yEnc encode criticals" ~: [0x3d, 0x40, 0x3d, 0x4a, 0x3d, 0x4d, 0x3d, 0x7d] ~=? Yenc.encode [0xd6, 0xe0, 0xe3, 0x13]
+    , "yEnc decode criticals" ~:  Just [0xd6, 0xe0, 0xe3, 0x13] ~=? Yenc.decode [0x3d, 0x40, 0x3d, 0x4a, 0x3d, 0x4d, 0x3d, 0x7d]
+    , "yEnc chop" ~: [[0x3d, 0x40], [0x01, 0x3d, 0x4a]] ~=? Yenc.chop 2 [0x3d, 0x40, 0x01, 0x3d, 0x4a]
+    ]
+
+-- {{{1 quoted-printable
+qpTestData =
+    [ ("qp", "empty", "", [], qp)
+    , ("qp", "foo=bar", "foo=3Dbar", [102,111,111,61,98,97,114], qp)
+    ]
+qpTests = buildTestList qpTestData
+
+qpTestsSucc = test
+    [ "qp chop one" ~: ["foo=","=3D=","bar"] ~=? chop qp 4 "foo=3Dbar"
+    ]
+
+qpTestsFail = test
+    [ "qp decode short" ~: Nothing ~=? decode qp "=4"
+    , "qp decode' short" ~: [Nothing] ~=? decode' qp "=4"
+    , "qp decode non-hex" ~: Nothing ~=? decode qp "=G"
+    , "qp decode' non-hex" ~: [Nothing] ~=? decode' qp "=G"
+    ]
+
+-- {{{1 python string
+pyTestData =
+    [ ("py", "empty", "", [], py)
+    , ("py", "<0x00><0x1f><0x20><0x7e><0x7f><0xff>", "\\x00\\x1F ~\\x7F\\xFF", [0x00, 0x1f, 0x20, 0x7e, 0x7f, 0xff], py)
+    , ("py", "\"\'\\", "\\\"\\'\\\\", [34, 39, 92], py)
+    ]
+pyTests = buildTestList pyTestData
+
+pyTestsFail = test
+    [ "py decode bad char after \\" ~: Nothing ~=? decode py "\\z"
+    , "py decode' bad char after \\" ~: [Nothing] ~=? decode' py "\\z"
+    ]
+
+-- {{{1 url encoding
+urlTestData =
+    [ ("url", "empty", "", [], url)
+    , ("url", "aA", "aA", [97, 65], url)
+    , ("url", "~ ", "~%20", [126, 0x20], url)
+    ]
+urlTests = buildTestList urlTestData
+
+urlTestsFail = test
+    [ "url decode bad char after %" ~: Nothing ~=? decode url "%ga"
+    , "url decode' bad char after %" ~: [Nothing] ~=? decode' url "%ga"
+    , "url decode bad char after %" ~: Nothing ~=? decode url "%%"
+    , "url decode' bad char after %" ~: [Nothing] ~=? decode' url "%%"
+    ]
+
+-- {{{1 all the tests
+allTests = concat
+    [ unitTest2TFTest uuTests
+    , unitTest2TFTest uuTests2
+    , unitTest2TFTest uuTestsFail
+    , unitTest2TFTest xxTests
+    , unitTest2TFTest xxTests2
+    , unitTest2TFTest xxTestsFail
+    , unitTest2TFTest base85Tests
+    , unitTest2TFTest base85TestsFail
+    , unitTest2TFTest base64Tests
+    , unitTest2TFTest base64TestsFail
+    , unitTest2TFTest base64UrlTests
+    , unitTest2TFTest base32Tests
+    , unitTest2TFTest base32TestsFail
+    , unitTest2TFTest base32HexTests
+    , unitTest2TFTest base32HexTestsFail
+    , unitTest2TFTest base16Tests
+    , unitTest2TFTest base16TestsFail
+    , unitTest2TFTest yencTests
+    , unitTest2TFTest qpTests
+    , unitTest2TFTest qpTestsSucc
+    , unitTest2TFTest qpTestsFail
+    , unitTest2TFTest pyTests
+    , unitTest2TFTest pyTestsFail
+    , unitTest2TFTest urlTests
+    , unitTest2TFTest urlTestsFail
+    ]
diff --git a/test-src/Test.hs b/test-src/Test.hs
new file mode 100644
--- /dev/null
+++ b/test-src/Test.hs
@@ -0,0 +1,19 @@
+{-
+ - Copyright : (c) 2009 Magnus Therning
+ - License   : BSD3
+ -}
+
+module Main
+    where
+
+import Test.Framework
+
+import qualified DataencQC as DQC
+import qualified DataencUT as DUT
+
+tests =
+    [ testGroup "quickcheck" DQC.allTests
+    , testGroup "unit test" DUT.allTests
+    ]
+
+main = defaultMain tests
