diff --git a/System/IO/UTF8.hs b/System/IO/UTF8.hs
--- a/System/IO/UTF8.hs
+++ b/System/IO/UTF8.hs
@@ -88,13 +88,13 @@
 -- to the file @file@.
 writeFile :: FilePath -> String -> IO ()
 writeFile n c = IO.withBinaryFile n IO.WriteMode $ \ h ->
-                    hPutStr h $ encodeString c
+                    IO.hPutStr h $ encodeString c
 
 -- | The computation 'appendFile' @file str@ function appends the UTF8 string @str@,
 -- to the file @file@.
 appendFile :: FilePath -> String -> IO ()
 appendFile n c = IO.withBinaryFile n IO.AppendMode $ \h ->
-                    hPutStr h $ encodeString c
+                    IO.hPutStr h $ encodeString c
 
 -- | Read a UTF8 line from a Handle
 hGetLine :: Handle -> IO String
diff --git a/tests/Bench.hs b/tests/Bench.hs
deleted file mode 100644
--- a/tests/Bench.hs
+++ /dev/null
@@ -1,211 +0,0 @@
-{-# OPTIONS -cpp -fglasgow-exts #-}
-
-{-
-$ ghc --make -O2 Bench.hs -o bench 
-
-$ ./bench 
-Size of test data: 2428k
-Char    Optimal byteString decode
- 1 0.102  0.109  0.102  0.109  0.102  
-   0.063  0.063  0.070  0.055  0.070        # "decode"   
--}
-
---
--- Benchmark tool.
--- Compare a function against equivalent code from other libraries for
--- space and time.
---
-
-import Data.ByteString (ByteString)
-import qualified Data.ByteString as P
--- import qualified Data.ByteString as L
-
-import Data.List
-import Data.Char
-import Data.Word
-import Data.Int
-
-import System.Mem
-import Control.Concurrent
-
-import System.IO
-import System.CPUTime
-import System.IO.Unsafe
-import Control.Monad
-import Control.Exception
-import Text.Printf
-
-------------------------------------------------------------------------
--- a reference (incorrect, but fast) implementation:
-
-import GHC.Ptr
-import qualified GHC.Base as GHC
-import qualified Data.ByteString      as B
-import qualified Data.ByteString.Base as B
-
-import Data.ByteString (ByteString)
-import qualified Data.ByteString        as B
-import qualified Data.ByteString.Char8  as C
-import qualified Data.ByteString.Lazy   as L
-
-import Data.List
-import Data.Char
-import Data.Word
-import Data.Int
-
-import System.IO
-import Control.Monad
-import Text.Printf
-
-import qualified Codec.Binary.UTF8.String as UTF8
-
-------------------------------------------------------------------------
-
-main :: IO ()
-main = do
-    force (fps,chars,strs)
-    printf "# Size of test data: %dk\n" ((floor $ (fromIntegral (B.length fps)) / 1024) :: Int)
-    printf "#Char\t Optimal byteString decode\n"
-    run 5 (fps,chars,strs) tests
-
---
--- Measure the difference building an decoded String from
--- bytestring+GHC's inbuilt decoder, and ours.
---
--- Most cost is in building the String.
---
-tests =
-    [ ("decode",
-        [F ( app UTF8.decode)
-        ,F ( app unpackCStringUTF8) ])
-
-    , ("encode",
-        [F ( app UTF8.encode) ])
-    ]
-
-
--- unpackCStringUtf8# wants \0 termianted strings. rewrite it to take a
--- length instead, and we avoid the copy in useAsCString.
-unpackCStringUTF8 :: B.ByteString -> [Char]
-unpackCStringUTF8 b = unsafePerformIO $ B.unsafeUseAsCString b $ \(Ptr a) ->
-    return (GHC.unpackCStringUtf8# a)
-
-
-------------------------------------------------------------------------
-
-run c x tests = sequence_ $ zipWith (doit c x) [1..] tests
-
-doit :: Int -> a -> Int -> (String, [F a]) -> IO ()
-doit count x n (s,ls) = do
-    printf "%2d " n
-    fn ls
-    printf "\t# %-16s\n" (show s)
-    hFlush stdout
-  where fn xs = case xs of
-                    [f,g]   -> runN count f x >> putStr "\n   "
-                            >> runN count g x >> putStr "\t"
-                    [f]     -> runN count f x >> putStr "\t"
-                    _       -> return ()
-        run f x = dirtyCache fps >> performGC >> threadDelay 100 >> time f x
-        runN 0 f x = return ()
-        runN c f x = run f x >> runN (c-1) f x
-
-dirtyCache x = evaluate (P.foldl1' (+) x)
-{-# NOINLINE dirtyCache #-}
-
-time :: F a -> a -> IO ()
-time (F f) a = do
-    start <- getCPUTime
-    v     <- force (f a)
-    case v of
-        B -> printf "--\t"
-        _ -> do
-            end   <- getCPUTime
-            let diff = (fromIntegral (end - start)) / (10^12)
-            printf "%0.3f  " (diff :: Double)
-    hFlush stdout
-
-------------------------------------------------------------------------
--- 
--- an existential list
---
-data F a = forall b . Forceable b => F (a -> b)
-
-data Result = T | B
-
---
--- a bit deepSeqish
---
-class Forceable a where
-    force :: a -> IO Result
-    force v = v `seq` return T
-
-#if !defined(HEAD)
-instance Forceable P.ByteString where
-    force v = P.length v `seq` return T
-#endif
-
-instance Forceable L.ByteString where
-    force v = L.length v `seq` return T
-
--- instance Forceable SPS.PackedString where
---     force v = SPS.length v `seq` return T
-
--- instance Forceable PS.PackedString where
---     force v = PS.lengthPS v `seq` return T
-
-instance Forceable a => Forceable (Maybe a) where
-    force Nothing  = return T
-    force (Just v) = force v `seq` return T
-
-instance Forceable [a] where
-    force v = length v `seq` return T
-
-instance (Forceable a, Forceable b) => Forceable (a,b) where
-    force (a,b) = force a >> force b
-
-instance (Forceable a, Forceable b, Forceable c) => Forceable (a,b,c) where
-    force (a,b,c) = force a >> force b >> force c
-
-instance Forceable Int
-instance Forceable Int64
-instance Forceable Bool
-instance Forceable Char
-instance Forceable Word8
-instance Forceable Ordering
-
--- used to signal undefinedness
-instance Forceable () where force () = return B
-
-------------------------------------------------------------------------
---
--- some large strings to play with
---
-
-fps     :: P.ByteString
-fps     = unsafePerformIO $ P.readFile dict
-{-# NOINLINE fps #-}
-
-chars   :: [Word8]
-chars   = B.unpack fps
-{-# NOINLINE chars #-}
-
-strs    :: String
-strs    = C.unpack fps
-{-# NOINLINE strs #-}
-
-dict  = "/usr/share/dict/words"
-
-------------------------------------------------------------------------
-
-type Input = (B.ByteString,[Word8],String)
-
-class (Eq a, Ord a) => Ap a where app :: (a -> b) -> Input -> b
-
-instance Ap B.ByteString where app f x = f (fst3 x)
-instance Ap [Word8]      where app f x = f (snd3 x)
-instance Ap String       where app f x = f (thd3 x)
-
-fst3 (a,_,_) = a
-snd3 (_,a,_) = a
-thd3 (_,_,a) = a
diff --git a/tests/BenchBytestring.hs b/tests/BenchBytestring.hs
deleted file mode 100644
--- a/tests/BenchBytestring.hs
+++ /dev/null
@@ -1,55 +0,0 @@
-import qualified Data.ByteString      as S
-import qualified Data.ByteString.Lazy as L
-import qualified Data.String.UTF8     as UTF8
-import qualified Codec.Binary.UTF8.String as List
-
-import System.Environment(getArgs)
-import System.IO
-import Data.Word
-
-main  = mapM_ run_test =<< getArgs
-
-run_test x  = case reads x of
-                [(n,"")] | n < test_num -> tests !! n
-                _ -> hPutStrLn stderr ("Invalid test: " ++ x)
-
-tests     = [ main0, main1, main2, main3, main4 ]
-test_num  = length tests
-
-
-main0 = do putStrLn "Correctness: Data.ByteString"
-           putStrLn ("Errors: " ++ show encodeDecodeTest)
-
-main1 = do putStrLn "Speed: Data.ByteString"
-           txt <- S.readFile "test"
-           print (UTF8.length $ UTF8.fromRep txt)
-
-main2 = do putStrLn "Speed: Data.ByteString.Lazy"
-           txt <- L.readFile "test"
-           print (UTF8.length $ UTF8.fromRep txt)
-
-main3 = do putStrLn "Speed: [Word8]"
-           txt <- hGetContents =<< openBinaryFile "test" ReadMode
-           let bytes :: [Word8]
-               bytes = map (fromIntegral . fromEnum) txt
-           print (UTF8.length $ UTF8.fromRep bytes)
-
-main4 = do putStrLn "Speed: [Word8] (direct)"
-           txt <- hGetContents =<< openBinaryFile "test" ReadMode
-           let bytes :: [Word8]
-               bytes = map (fromIntegral . fromEnum) txt
-           print (length $ List.decode bytes)
-
-encodeDecodeTest :: String
-encodeDecodeTest =
-     filter (\x -> enc x /= [x]) legal_codepoints
-  ++ filter (\x -> enc x /= [UTF8.replacement_char]) illegal_codepoints
-  where
-    legal_codepoints    = ['\0'..'\xd7ff'] ++ ['\xe000'..'\xfffd']
-                       ++ ['\x10000'..'\x10ffff']
-    illegal_codepoints  = '\xffff' : '\xfffe' : ['\xd800'..'\xdfff']
-
-{-# INLINE enc #-}
-enc x = UTF8.toString (UTF8.fromString [x] :: UTF8.UTF8 S.ByteString)
-
-
diff --git a/tests/Tests.hs b/tests/Tests.hs
deleted file mode 100644
--- a/tests/Tests.hs
+++ /dev/null
@@ -1,182 +0,0 @@
-import Codec.Binary.UTF8.String
-import Test.HUnit
-import System.Exit (exitFailure)
-import Control.Monad (when)
-
-main = do counts <- runTestTT tests
-          when (errors counts > 0 || failures counts > 0) exitFailure
-
-tests = TestList [test_1, test_2, test_3, test_4, test_5]
-
-test_1 = TestLabel "1 Some correct UTF-8 text" $
-  TestCase $ assertEqual "kosme, " "\x03ba\x1f79\x03c3\x03bc\x03b5 "
-    (decode [0xce,0xba,0xe1,0xbd,0xb9,0xcf,0x83,0xce,0xbc,0xce,0xb5,0x20])
-
-test_2 = TestLabel "2 Boundary condition test cases" $
-  TestList [test_2_1, test_2_2, test_2_3]
-
-test_2_1 = TestLabel "2.1 First possible sequence of a certain length" $
-  TestList $ map TestCase $ 
-  [ assertEqual "2.1.1, " "\0\0" (decode [0, 0])
-  , assertEqual "2.1.2, " "\x80\0" (decode [0xc2, 0x80, 0])
-  , assertEqual "2.1.3, " "\x800\0" (decode [0xe0, 0xa0, 0x80, 0])
-  , assertEqual "2.1.4, " "\x10000\0" (decode [0xf0, 0x90, 0x80, 0x80, 0])
-  , assertEqual "2.1.5, " "\xfffd\0" (decode [0xf8, 0x88, 0x80, 0x80, 0x80, 0])
-  , assertEqual "2.1.6, " "\xfffd\0" (decode [0xfc,0x84,0x80,0x80,0x80,0x80,0])
-  ]
-
-test_2_2 = TestLabel "2.2 Last possible sequence of a certain length" $
-  TestList $ map TestCase $ 
-  [ assertEqual "2.2.1, " "\x7f\0" (decode [0x7f, 0])
-  , assertEqual "2.2.2, " "\x7ff\0" (decode [0xdf, 0xbf, 0])
-  , assertEqual "2.2.3, " "\xfffd\0" (decode [0xef, 0xbf, 0xbf, 0])
-  , assertEqual "2.2.4, " "\xfffd\0" (decode [0xf7, 0xbf, 0xbf, 0xbf, 0])
-  , assertEqual "2.2.5, " "\xfffd\0" (decode [0xfb, 0xbf, 0xbf, 0xbf, 0xbf, 0])
-  , assertEqual "2.2.6, " "\xfffd\0" (decode [0xfd,0xbf,0xbf,0xbf,0xbf,0xbf,0])
-  ]
-
-test_2_3 = TestLabel "2.3 Other boundary conditions" $
-  TestList $ map TestCase $ 
-  [ assertEqual "2.3.1, " "\xd7ff\0" (decode [0xed, 0x9f, 0xbf, 0])
-  , assertEqual "2.3.2, " "\xe000\0" (decode [0xee, 0x80, 0x80, 0])
-  , assertEqual "2.3.3, " "\xfffd\0" (decode [0xef, 0xbf, 0xbd, 0])
-  , assertEqual "2.3.4, " "\x10ffff\0" (decode [0xf4, 0x8f, 0xbf, 0xbf, 0])
-  , assertEqual "2.3.5, " "\xfffd\0" (decode [0xf4, 0x90, 0x80, 0x80, 0])
-  ]
-
-test_3 = TestLabel "3 Malformed sequences" $
-  TestList [test_3_1, test_3_2, test_3_3, test_3_4, test_3_5]
-
-test_3_1 = TestLabel "3.1 Unexpected continuation bytes" $
-  TestList $ map TestCase $
-  [ assertEqual "3.1.1, " "\xfffd\0" (decode [0x80, 0])
-  , assertEqual "3.1.2, " "\xfffd\0" (decode [0xbf, 0])
-  , assertEqual "3.1.3, " "\xfffd\xfffd\0" (decode [0x80, 0xbf, 0])
-  , assertEqual "3.1.4, " "\xfffd\xfffd\xfffd\0" (decode [0x80, 0xbf, 0x80, 0])
-  , assertEqual "3.1.5, " "\xfffd\xfffd\xfffd\xfffd\0"
-                          (decode [0x80, 0xbf, 0x80, 0xbf, 0])
-  , assertEqual "3.1.6, " "\xfffd\xfffd\xfffd\xfffd\xfffd\0"
-                          (decode [0x80, 0xbf, 0x80, 0xbf, 0x80, 0])
-  , assertEqual "3.1.7, " "\xfffd\xfffd\xfffd\xfffd\xfffd\xfffd\0"
-                          (decode [0x80, 0xbf, 0x80, 0xbf, 0x80, 0xbf, 0])
-  , assertEqual "3.1.8, " "\xfffd\xfffd\xfffd\xfffd\xfffd\xfffd\xfffd\0"
-                          (decode [0x80, 0xbf, 0x80, 0xbf, 0x80, 0xbf, 0x80, 0])
-  , assertEqual "3.1.9, " (replicate 64 '\xfffd') (decode [0x80..0xbf])
-  ]
-
-test_3_2 = TestLabel "3.2 Lonely start characters" $
-  TestList $ map TestCase $
-  [ assertEqual "3.2.1, " (concat (replicate 32 "\xfffd "))
-                          (decode (concat [[x,0x20] | x <- [0xc0..0xdf]]))
-  , assertEqual "3.2.2, " (concat (replicate 16 "\xfffd "))
-                          (decode (concat [[x,0x20] | x <- [0xe0..0xef]]))
-  , assertEqual "3.2.3, " (concat (replicate 8 "\xfffd "))
-                          (decode (concat [[x,0x20] | x <- [0xf0..0xf7]]))
-  , assertEqual "3.2.4, " "\xfffd \xfffd \xfffd \xfffd "
-                          (decode (concat [[x,0x20] | x <- [0xf8..0xfb]]))
-  , assertEqual "3.2.5, " "\xfffd \xfffd " (decode [0xfc, 0x20, 0xfd, 0x20])
-  ]
-
-test_3_3 = TestLabel "3.3 Sequences with last continuation byte missing" $
-  TestList $ map TestCase $
-  [ assertEqual "3.3.1, " "\xfffd " (decode [0xc0, 0x20])
-  , assertEqual "3.3.2, " "\xfffd " (decode [0xe0, 0x80, 0x20])
-  , assertEqual "3.3.3, " "\xfffd " (decode [0xf0, 0x80, 0x80, 0x20])
-  , assertEqual "3.3.4, " "\xfffd " (decode [0xf8, 0x80, 0x80, 0x80, 0x20])
-  , assertEqual "3.3.5, " "\xfffd " (decode [0xfc, 0x80, 0x80, 0x80,0x80,0x20])
-  , assertEqual "3.3.6, " "\xfffd " (decode [0xdf, 0x20])
-  , assertEqual "3.3.7, " "\xfffd " (decode [0xef, 0xbf, 0x20])
-  , assertEqual "3.3.8, " "\xfffd " (decode [0xf7, 0xbf, 0xbf, 0x20])
-  , assertEqual "3.3.9, " "\xfffd " (decode [0xfb, 0xbf, 0xbf, 0xbf, 0x20])
-  , assertEqual "3.3.10, " "\xfffd " (decode [0xfd, 0xbf, 0xbf, 0xbf,0xbf,0x20])
-  ]
-
-test_3_4 = TestLabel "3.4 Concatenation of incomplete sequences" $
-  TestCase $ assertEqual "3.4, " 
-  (replicate 10 '\xfffd')
-  (decode [0xc0, 0xe0, 0x80, 0xf0, 0x80, 0x80, 0xf8, 0x80, 0x80, 0x80,
-   0xfc, 0x80, 0x80, 0x80,0x80, 0xdf, 0xef, 0xbf, 0xf7, 0xbf, 0xbf,
-   0xfb, 0xbf, 0xbf, 0xbf, 0xfd, 0xbf, 0xbf, 0xbf,0xbf])
-
-test_3_5 = TestLabel "3.5 Impossible bytes" $
-  TestList $ map TestCase $
-  [ assertEqual "3.5.1, " "\xfffd " (decode [0xfe, 0x20])
-  , assertEqual "3.5.2, " "\xfffd " (decode [0xff, 0x20])
-  , assertEqual "3.5.3, " "\xfffd\xfffd\xfffd\xfffd "
-                          (decode [0xfe, 0xfe, 0xff, 0xff, 0x20])
-  ]
-
-test_4 = TestLabel "4 Overlong sequences" $
-  TestList [test_4_1, test_4_2, test_4_3]
-
-test_4_1 = TestLabel "4.1" $ TestList $ map TestCase $
-  [ assertEqual "4.1.1, " "\xfffd " (decode [0xc0, 0xaf, 0x20])
-  , assertEqual "4.1.2, " "\xfffd " (decode [0xe0, 0x80, 0xaf, 0x20])
-  , assertEqual "4.1.3, " "\xfffd " (decode [0xf0, 0x80, 0x80, 0xaf, 0x20])
-  , assertEqual "4.1.4, " "\xfffd " (decode [0xf8, 0x80, 0x80,0x80,0xaf, 0x20])
-  , assertEqual "4.1.5, " "\xfffd " (decode[0xfc,0x80,0x80,0x80,0x80,0xaf,0x20])
-  ]
-
-test_4_2 = TestLabel "4.2 Maximum overlong sequences" $
-  TestList $ map TestCase $
-  [ assertEqual "4.2.1, " "\xfffd " (decode [0xc1, 0xbf, 0x20])
-  , assertEqual "4.2.2, " "\xfffd " (decode [0xe0, 0x9f, 0xbf, 0x20])
-  , assertEqual "4.2.3, " "\xfffd " (decode [0xf0, 0x8f, 0xbf, 0xbf, 0x20])
-  , assertEqual "4.2.4, " "\xfffd " (decode [0xf8, 0x87, 0xbf, 0xbf,0xbf,0x20])
-  , assertEqual "4.2.5, " "\xfffd "(decode[0xfc,0x83,0xbf,0xbf,0xbf,0xbf,0x20])
-  ]
-
-test_4_3 = TestLabel "4.2 Overlong NUL" $
-  TestList $ map TestCase $
-  [ assertEqual "4.3.1, " "\xfffd " (decode [0xc0, 0x80, 0x20])
-  , assertEqual "4.3.2, " "\xfffd " (decode [0xe0, 0x80, 0x80, 0x20])
-  , assertEqual "4.3.3, " "\xfffd " (decode [0xf0, 0x80, 0x80, 0x80, 0x20])
-  , assertEqual "4.3.4, " "\xfffd " (decode [0xf8, 0x80, 0x80, 0x80,0x80,0x20])
-  , assertEqual "4.3.5, " "\xfffd "(decode[0xfc,0x80,0x80,0x80,0x80,0x80,0x20])
-  ]
-
-test_5 = TestLabel "Illegal code positions" $
-  TestList [test_5_1, test_5_2, test_5_3]
-
-test_5_1 = TestLabel "5.1 Single UTF-16 surrogates" $
-  TestList $ map TestCase $
-  [ assertEqual "5.1.1, " "\xfffd " (decode [0xed,0xa0,0x80,0x20])
-  , assertEqual "5.1.2, " "\xfffd " (decode [0xed,0xad,0xbf,0x20])
-  , assertEqual "5.1.3, " "\xfffd " (decode [0xed,0xae,0x80,0x20])
-  , assertEqual "5.1.4, " "\xfffd " (decode [0xed,0xaf,0xbf,0x20])
-  , assertEqual "5.1.5, " "\xfffd " (decode [0xed,0xb0,0x80,0x20])
-  , assertEqual "5.1.6, " "\xfffd " (decode [0xed,0xbe,0x80,0x20])
-  , assertEqual "5.1.7, " "\xfffd " (decode [0xed,0xbf,0xbf,0x20])
-  ]
- 
-test_5_2 = TestLabel "5.2 Paired UTF-16 surrogates" $
-  TestList $ map TestCase $
-  [ assertEqual "5.2.1, " res (decode [0xed,0xa0,0x80,0xed,0xb0,0x80,0x20])
-  , assertEqual "5.2.2, " res (decode [0xed,0xa0,0x80,0xed,0xbf,0xbf,0x20])
-  , assertEqual "5.2.3, " res (decode [0xed,0xad,0xbf,0xed,0xb0,0x80,0x20])
-  , assertEqual "5.2.4, " res (decode [0xed,0xad,0xbf,0xed,0xbf,0xbf,0x20])
-  , assertEqual "5.2.5, " res (decode [0xed,0xae,0x80,0xed,0xb0,0x80,0x20])
-  , assertEqual "5.2.6, " res (decode [0xed,0xae,0x80,0xed,0xbf,0xbf,0x20])
-  , assertEqual "5.2.7, " res (decode [0xed,0xaf,0xbf,0xed,0xb0,0x80,0x20])
-  , assertEqual "5.2.8, " res (decode [0xed,0xaf,0xbf,0xed,0xbf,0xbf,0x20])
-  ]
-  where res = "\xfffd\xfffd "
- 
-test_5_3 = TestLabel "5.3 Other illegal code positions" $
-  TestList $ map TestCase $
-  [ assertEqual "5.3.1, " "\xfffd " (decode [0xef, 0xbf, 0xbe, 0x20])
-  , assertEqual "5.3.2, " "\xfffd " (decode [0xef, 0xbf, 0xbf, 0x20])
-  ]
-
-
---
--- test decode . encode == id for the class of chars we know that to be true of
---
-encodeDecodeTest :: [Char]
-encodeDecodeTest = filter (\x -> [x] /= decode (encode [x])) legal_codepoints ++
-                   filter (\x -> ['\xfffd'] /= decode (encode [x])) illegal_codepoints
-  where
-    legal_codepoints = ['\0'..'\xd7ff'] ++ ['\xe000'..'\xfffd'] ++ ['\x10000'..'\x10ffff']
-    illegal_codepoints = '\xffff' : '\xfffe' : ['\xd800'..'\xdfff']
-
-
diff --git a/utf8-string.cabal b/utf8-string.cabal
--- a/utf8-string.cabal
+++ b/utf8-string.cabal
@@ -1,5 +1,5 @@
 Name:               utf8-string
-Version:            0.3.1
+Version:            0.3.1.1
 Author:             Eric Mertens
 Maintainer:         emertens@galois.com
 License:            BSD3
@@ -11,12 +11,22 @@
                     strings to Word8 lists and back, and for reading and
                     writing UTF8 without truncation.
 Category:           Codec
-Build-depends:      base>=1.0, bytestring>=0.9
-Ghc-options:        -W -O2
 Build-type:         Simple
-Exposed-modules:    Codec.Binary.UTF8.String
-                    Codec.Binary.UTF8.Generic
-                    System.IO.UTF8
-                    Data.String.UTF8
-                    Data.ByteString.UTF8
-                    Data.ByteString.Lazy.UTF8
+cabal-version:      >= 1.2
+
+flag bytestring-in-base
+
+library
+  Ghc-options:        -W -O2
+
+  if flag(bytestring-in-base)
+    build-depends: base >= 2.0 && < 2.2
+  else
+    build-depends: base < 2.0 || >= 3, bytestring >= 0.9
+
+  Exposed-modules:    Codec.Binary.UTF8.String
+                      Codec.Binary.UTF8.Generic
+                      System.IO.UTF8
+                      Data.String.UTF8
+                      Data.ByteString.UTF8
+                      Data.ByteString.Lazy.UTF8
