diff --git a/Debian/Apt/Dependencies.hs b/Debian/Apt/Dependencies.hs
--- a/Debian/Apt/Dependencies.hs
+++ b/Debian/Apt/Dependencies.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# OPTIONS -fno-warn-missing-signatures #-}
 module Debian.Apt.Dependencies
 {-
     ( solve
@@ -13,13 +14,12 @@
 -- test gutsyPackages "libc6" (\csp -> bt csp)
 
 import Control.Arrow (second)
-import qualified Data.ByteString.Char8 as BS
 import qualified Data.ByteString.Char8 as C
-import Data.List((++), foldr, concat, filter, map, any, elem, null, reverse, take, zipWith, find, union)
-import Data.Maybe(Maybe(..))
+import Data.List as List (find, union)
 import Data.Tree(Tree(rootLabel, Node))
 import Debian.Apt.Package(PackageNameMap, packageNameMap, lookupPackageByRel)
-import Debian.Control.ByteString(ControlFunctions(stripWS, lookupP, parseControlFromFile), Field'(Field), Control'(Control), Paragraph, Control)
+import Debian.Control.ByteString(ControlFunctions(stripWS, lookupP, parseControlFromFile),
+                                 Field'(Field, Comment), Control'(Control), Paragraph, Control)
 import Debian.Relation (BinPkgName(..))
 import Debian.Relation.ByteString(ParseRelations(..), Relation(..), OrRelation, AndRelation, Relations, checkVersionReq)
 import Debian.Version(DebianVersion, parseDebianVersion, prettyDebianVersion)
@@ -50,28 +50,32 @@
 
 -- |TODO addProvides -- see DQL.Exec
 controlCSP :: Control -> Relations -> (Paragraph -> Relations) -> CSP Paragraph
-controlCSP (Control paragraphs) rels depF =
+controlCSP (Control paragraphs) rels depF' =
     CSP { pnm = packageNameMap getName paragraphs
         , relations = rels
-        , depFunction = depF
+        , depFunction = depF'
         , conflicts = conflicts'
         , packageVersion = packageVersionParagraph
         }
     where
       getName :: Paragraph -> BinPkgName
-      getName p = case lookupP "Package" p of Nothing -> error "Missing Package field" ; (Just (Field (_,n))) -> BinPkgName (C.unpack (stripWS n))
+      getName p = case lookupP "Package" p of
+                    Nothing -> error "Missing Package field"
+                    Just (Field (_,n)) -> BinPkgName (C.unpack (stripWS n))
+                    Just (Comment _) -> error "controlCSP"
       conflicts' :: Paragraph -> Relations
       conflicts' p =
           case lookupP "Conflicts" p of
             Nothing -> []
             Just (Field (_, c)) -> either (error . show) id (parseRelations c)
+            Just (Comment _) -> error "controlCSP"
 
 testCSP :: FilePath -> (Paragraph -> Relations) -> String -> (CSP Paragraph -> IO a) -> IO a
 testCSP controlFile depf relationStr cspf =
     do c' <- parseControlFromFile controlFile
        case c' of
          Left e -> error (show e)
-         Right control@(Control paragraphs) ->
+         Right control@(Control _) ->
              case parseRelations relationStr of
                Left e -> error (show e)
                Right r ->
@@ -84,11 +88,13 @@
               Nothing -> []
               Just (Field (_,pd)) -> 
                   either (error . show) id (parseRelations pd)
+              Just (Comment _) -> error "depF"
         depends =
             case lookupP "Depends" p of
               Nothing -> []
               Just (Field (_,pd)) -> 
                   either (error . show) id (parseRelations pd)
+              Just (Comment _) -> error "depF"
     in
       preDepends ++ depends
 
@@ -107,6 +113,8 @@
           case lookupP "Version" p of
             Nothing -> error $ "Paragraph missing Version field"
             (Just (Field (_, version))) -> (BinPkgName (C.unpack (stripWS name)), parseDebianVersion (C.unpack version))
+            (Just (Comment _)) -> error "packageVersionParagraph"
+      (Just (Comment _)) -> error "packageVersionParagraph"
 
 
 
@@ -175,11 +183,11 @@
       andRelation :: ([a],AndRelation) -> AndRelation -> [Tree (State a)]
       andRelation (candidates,[]) [] = [Node (Complete, candidates) []]
       andRelation (candidates,remaining) [] = andRelation (candidates, []) remaining
-      andRelation (candidates, remaining) (or:ors) =
-          orRelation (candidates, ors ++ remaining) or
+      andRelation (candidates, remaining) (x:xs) =
+          orRelation (candidates, xs ++ remaining) x
       orRelation :: ([a],AndRelation) -> OrRelation -> [Tree (State a)]
-      orRelation acc or =
-          concat (fmap (relation acc) or)
+      orRelation acc x =
+          concat (fmap (relation acc) x)
       relation :: ([a],AndRelation) -> Relation -> [Tree (State a)]
       relation acc@(candidates,_) rel =
           let packages = lookupPackageByRel (pnm csp) (packageVersion csp) rel in
@@ -187,12 +195,12 @@
             [] -> [Node (MissingDep rel, candidates) []]
             _ -> map (package acc) packages
       package :: ([a],AndRelation) -> a -> Tree (State a)
-      package (candidates, remaining) package =
-          if ((packageVersion csp) package) `elem` (map (packageVersion csp) candidates)
+      package (candidates, remaining) p =
+          if ((packageVersion csp) p) `elem` (map (packageVersion csp) candidates)
           then if null remaining
                then Node (Complete, candidates) []
                else Node (Remaining remaining, candidates) (andRelation (candidates, []) remaining)
-          else Node (Remaining remaining, (package : candidates)) (andRelation ((package : candidates), remaining) ((depFunction csp) package))
+          else Node (Remaining remaining, (p : candidates)) (andRelation ((p : candidates), remaining) ((depFunction csp) p))
 
 
 -- |earliestInconsistency does what it sounds like
diff --git a/Debian/Apt/Index.hs b/Debian/Apt/Index.hs
--- a/Debian/Apt/Index.hs
+++ b/Debian/Apt/Index.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveDataTypeable, OverloadedStrings, ScopedTypeVariables #-}
 {-# OPTIONS_GHC -fno-warn-name-shadowing -fno-warn-orphans #-}
 module Debian.Apt.Index
     ( update
@@ -24,11 +24,14 @@
 import Data.Function
 import Data.List
 import qualified Data.Map as M
+import Data.Monoid ((<>))
+import qualified Data.Text as T (Text, unpack, concat, lines, null, words)
 import Data.Time
 import Debian.Apt.Methods
 import Debian.Control (formatControl)
 import Debian.Control.ByteString
 import Debian.Control.Common
+import Debian.Control.Text (decodeControl)
 --import Debian.Repo.Types
 import Debian.Release
 import Debian.Sources
@@ -166,23 +169,23 @@
             maybeOfString s = Just s
 
             wordsBy :: Eq a => (a -> Bool) -> [a] -> [[a]]
-            wordsBy p s = 
+            wordsBy p s =
                 case (break p s) of
                   (s, []) -> [s]
                   (h, t) -> h : wordsBy p (drop 1 t)
 
 -- |Parse a possibly compressed index file.
-controlFromIndex :: Compression -> FilePath -> L.ByteString -> Either ParseError (Control' B.ByteString)
-controlFromIndex GZ path s = parseControl path . B.concat . L.toChunks . GZip.decompress $ s
-controlFromIndex BZ2 path s = parseControl path . B.concat . L.toChunks . BZip.decompress $ s
-controlFromIndex Uncompressed path s = parseControl path . B.concat . L.toChunks $ s
+controlFromIndex :: Compression -> FilePath -> L.ByteString -> Either ParseError (Control' T.Text)
+controlFromIndex GZ path s = either Left (Right . decodeControl) . parseControl path . B.concat . L.toChunks . GZip.decompress $ s
+controlFromIndex BZ2 path s = either Left (Right . decodeControl) . parseControl path . B.concat . L.toChunks . BZip.decompress $ s
+controlFromIndex Uncompressed path s = either Left (Right . decodeControl) . parseControl path . B.concat . L.toChunks $ s
 
--- |parse an index possibly compressed file 
-controlFromIndex' :: Compression -> FilePath -> IO (Either ParseError (Control' B.ByteString))
+-- |parse an index possibly compressed file
+controlFromIndex' :: Compression -> FilePath -> IO (Either ParseError (Control' T.Text))
 controlFromIndex' compression path = L.readFile path >>= return . controlFromIndex compression path
 
 type Size = Integer
-type FileTuple = (CheckSums, Size, FilePath) 
+type FileTuple = (CheckSums, Size, FilePath)
 
 -- |A release file contains a list of indexes (Packages\/Sources). Each
 -- Package or Source index may appear multiple times because it may be
@@ -264,7 +267,7 @@
           | otherwise            = (fp, Uncompressed)
 
 indexesInRelease :: (FilePath -> Bool)
-                 -> Control -- ^ A release file
+                 -> Control' T.Text -- ^ A release file
                  -> [(CheckSums, Integer, FilePath)] -- ^ 
 indexesInRelease filterp (Control [p]) =
     let md5sums =
@@ -272,12 +275,12 @@
               (Just md5) -> md5
               Nothing -> error $ "Did not find MD5Sum field."
     in
-      filter (\(_,_,fp) -> filterp fp) $ map (makeTuple . B.words) $ filter (not . B.null) (B.lines md5sums)
+      filter (\(_,_,fp) -> filterp fp) $ map (makeTuple . T.words) $ filter (not . T.null) (T.lines md5sums)
     where
-      makeTuple :: [B.ByteString] -> (CheckSums, Integer, FilePath)
-      makeTuple [md5sum, size, fp] = (CheckSums { md5sum = Just (B.unpack md5sum), sha1 = Nothing, sha256 = Nothing }, read (B.unpack size), B.unpack fp)
+      makeTuple :: [T.Text] -> (CheckSums, Integer, FilePath)
+      makeTuple [md5sum, size, fp] = (CheckSums { md5sum = Just (T.unpack md5sum), sha1 = Nothing, sha256 = Nothing }, read (T.unpack size), T.unpack fp)
       makeTuple x = error $ "Invalid line in release file: " ++ show x
-indexesInRelease _ x = error $ "Invalid release file: " ++ B.unpack (B.concat (formatControl x))
+indexesInRelease _ x = error $ "Invalid release file: " <> T.unpack (T.concat (formatControl x))
 
 -- |make a FileTuple for a file found on the local disk
 -- returns 'Nothing' if the file does not exist.
diff --git a/Debian/Apt/Methods.hs b/Debian/Apt/Methods.hs
--- a/Debian/Apt/Methods.hs
+++ b/Debian/Apt/Methods.hs
@@ -71,7 +71,7 @@
     | MediaFailure Media Drive
       deriving (Show, Eq)
 
-data Hashes 
+data Hashes
     = Hashes { md5 :: Maybe String
              , sha1 :: Maybe String
              , sha256 :: Maybe String
@@ -104,14 +104,14 @@
 -- |whichMethodBinary - find the method executable associated with a URI
 -- throws an exception on failure
 whichMethodPath :: URI -> IO (Maybe FilePath)
-whichMethodPath uri = 
+whichMethodPath uri =
     let scheme = init (uriScheme uri)
         path = "/usr/lib/apt/methods/" ++ scheme
     in
       doesFileExist path >>= return . bool Nothing (Just path)
 
 {-
-The flow of messages starts with the method sending out a 
+The flow of messages starts with the method sending out a
 100 Capabilities and APT sending out a 601 Configuration.
 
 The flow is largely unsynchronized, but our function may have to
@@ -122,6 +122,7 @@
 -}
 
 parseStatus :: [String] -> Status
+parseStatus [] = error "parseStatus"
 parseStatus (code' : headers') =
     parseStatus' (take 3 code') (map parseHeader headers')
     where
@@ -138,10 +139,10 @@
                         | a == "Needs-Cleanup"   = c { needsCleanup = parseTrueFalse v }
                         | a == "Local-Only"	 = c { localOnly = parseTrueFalse v }
                         | otherwise = error $ "unknown capability: " ++ show (a,v)
-                    defaultCapabilities = 
+                    defaultCapabilities =
                         Capabilities { version = ""
                                      , singleInstance = False
-                                     , preScan 	      = False 
+                                     , preScan 	      = False
                                      , pipeline	      = False
                                      , sendConfig     = False
                                      , needsCleanup   = False
@@ -151,6 +152,7 @@
           | code == logMsg =
               case headers of
                 [("Message", msg)] -> LogMsg msg
+                _ -> error "parseStatus'"
           | code == status =
                 Status (fromJust $ parseURI $ fromJust $ lookup "URI" headers) (fromJust $ lookup "Message" headers)
           | code == uriStart =
@@ -161,6 +163,7 @@
                         | a == "Size" = u { size = Just (read v) }
                         | a == "Last-Modified" = u { lastModified = parseTimeRFC822 v } -- if the date is unparseable, we silently truncate. Is that bad ?
                         | a == "Resume-Point" = u { resumePoint = Just (read v) }
+                    updateUriStart _ _ = error "updateUriStart"
       parseStatus' code headers
           | code == uriDone =
               foldr updateUriDone (URIDone undefined Nothing Nothing Nothing Nothing emptyHashes False) headers
@@ -182,11 +185,11 @@
               URIFailure (fromJust $ parseURI $ fromJust $ lookup "URI" headers) (fromJust $ lookup "Message" headers)
           | code == generalFailure =
               GeneralFailure (fromJust $ lookup "Message" headers)
-          | code == authorizationRequired = 
+          | code == authorizationRequired =
               AuthorizationRequired (fromJust $ lookup "Site" headers)
           | code == mediaFailure =
               MediaFailure (fromJust $ lookup "Media" headers) (fromJust $ lookup "Drive" headers)
-
+      parseStatus' _ _ = error "parseStatus'"
 
 formatCommand :: Command -> [String]
 formatCommand (URIAcquire uri filepath mLastModified) =
@@ -195,7 +198,7 @@
     , "FileName: " ++ filepath
     ] ++ maybe [] (\lm -> ["Last-Modified: " ++ formatTimeRFC822 lm ]) mLastModified
 formatCommand (Configuration configItems) =
-    (configuration ++ " Configuration") : (map formatConfigItem configItems) 
+    (configuration ++ " Configuration") : (map formatConfigItem configItems)
     where
       formatConfigItem (a,v) = concat ["Config-Item: ", a, "=", v]
 formatCommand (AuthorizationCredentials site user passwd) =
@@ -208,8 +211,8 @@
     [ mediaChanged ++ " Media Changed"
     , "Media: " ++ media
     ] ++ maybe [] (\b -> ["Fail: " ++ case b of True -> "true" ; False -> "false"]) mFail
-      
 
+
 parseTrueFalse :: String -> Bool
 parseTrueFalse "true" = True
 parseTrueFalse "false" = False
@@ -227,9 +230,9 @@
 parseHeader str =
     let (a, r) = span (/= ':') str
         v = dropWhile (flip elem ": \t") r
-    in 
+    in
       (a, v)
-       
+
 openMethod :: FilePath -> IO MethodHandle
 openMethod methodBinary =
     do
@@ -245,7 +248,7 @@
       hPutStrLn pIn ""
       hFlush pIn
     where
-      put line = 
+      put line =
           do
             -- hPutStrLn stderr ("  " ++ line)
             hPutStrLn pIn line
@@ -270,19 +273,19 @@
             line <- hGetLine pOut
             case line of
               "" -> return []
-              line -> 
+              line ->
                   do
                     -- hPutStrLn stderr ("  " ++ line)
                     tail <- readTillEmptyLine pOut
                     return $ line : tail
 {-
-The flow of messages starts with the method sending out a 
+The flow of messages starts with the method sending out a
 <em>100 Capabilities</> and APT sending out a <em>601 Configuration</>.
 
 The flow is largely unsynchronized, but our function may have to
 respond to things like authorization requests. Perhaps we do a
 recvContents and then mapM_ over that ? Not all incoming messages
-require a response. 
+require a response.
 
 We probably also need to track state, for example, if we are
 pipelining multiple downloads and want to show seperate progress bars
@@ -336,7 +339,7 @@
 
 -}
 
-data FetchCallbacks 
+data FetchCallbacks
     = FetchCallbacks { logCB :: Message ->  IO ()
                      , statusCB :: URI -> Message -> IO ()
                      , uriStartCB :: URI -> Maybe Integer -> Maybe UTCTime -> Maybe Integer -> IO ()
@@ -370,24 +373,24 @@
                Capabilities {} ->
                    do unless (null configItems) (sendCommand' mh (Configuration configItems))
                       loop mh
-               LogMsg m -> 
+               LogMsg m ->
                    do logCB cb m
                       loop mh
-               Status uri m -> 
+               Status uri m ->
                    do statusCB cb uri m
                       loop mh
-               URIStart uri size lastModified resumePoint -> 
+               URIStart uri size lastModified resumePoint ->
                    uriStartCB cb uri size lastModified resumePoint >> loop mh
                URIDone uri size lastModified resumePoint filename hashes imsHit ->
                    uriDoneCB cb uri size lastModified resumePoint filename hashes imsHit >> return True
                URIFailure uri message ->
                    uriFailureCB cb uri message >> return False
                GeneralFailure m -> generalFailureCB cb m >> return False
-               AuthorizationRequired site -> 
+               AuthorizationRequired site ->
                    do mCredentials <- authorizationRequiredCB cb site
                       case mCredentials of
                         Nothing -> return False -- FIXME: do we need a force close option for closeMethod ?
-                        Just (user, passwd) -> 
+                        Just (user, passwd) ->
                             do sendCommand' mh (AuthorizationCredentials site user passwd)
                                loop mh
                MediaFailure media drive ->
@@ -430,7 +433,7 @@
 {-
     FetchCallbacks { logCB = \m -> hPutStrLn stderr m
                    , statusCB = \uri m -> putStrLn (show uri ++" : "++ m)
-                   , uriStartCB = \uri 
+                   , uriStartCB = \uri
                    }
 
 defaultAuthenticate site =
@@ -445,8 +448,8 @@
 {-
     let itemsByHost = groupOn (regName . fst) items
     in
-      do totalQSem <- newQSem 16 -- max number of streams allowed for 
-         forkIO 
+      do totalQSem <- newQSem 16 -- max number of streams allowed for
+         forkIO
     where
       regName = fmap uriRegName . uriAuthority
       withQSem :: QSem -> IO a -> IO a
@@ -457,7 +460,7 @@
                                  , "ssh://jeremy:aoeu@n-heptane.com"
                                  , "cdrom:/one"
                                  ]
--}    
+-}
 
 -- * Misc Helper Functions
 
diff --git a/Debian/Apt/Package.hs b/Debian/Apt/Package.hs
--- a/Debian/Apt/Package.hs
+++ b/Debian/Apt/Package.hs
@@ -32,9 +32,9 @@
 
 -- |'findProvides'
 findProvides :: forall p. (p -> [BinPkgName]) -> [p] -> [(BinPkgName, p)]
-findProvides providesf packages = foldl addProvides [] packages
-    where addProvides :: [(BinPkgName, p)] -> p -> [(BinPkgName, p)]
-          addProvides providesList package =
+findProvides providesf packages = foldl addProvides' [] packages
+    where addProvides' :: [(BinPkgName, p)] -> p -> [(BinPkgName, p)]
+          addProvides' providesList package =
               foldl (\pl pkgName -> (pkgName, package): pl) providesList (providesf package)
 
 -- |'lookupPackageByRel' returns all the packages that satisfy the specified relation
diff --git a/Debian/Arch.hs b/Debian/Arch.hs
new file mode 100644
--- /dev/null
+++ b/Debian/Arch.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+module Debian.Arch
+    ( Arch(..)
+    , ArchOS(..)
+    , ArchCPU(..)
+    , prettyArch
+    , parseArch
+    ) where
+
+import Data.Data (Data)
+import Data.Monoid ((<>))
+import Data.Typeable (Typeable)
+import Text.PrettyPrint.ANSI.Leijen (Doc, text)
+
+data ArchOS = ArchOS String | ArchOSAny deriving (Eq, Ord, Read, Show, Data, Typeable)
+
+prettyOS :: ArchOS -> Doc
+prettyOS (ArchOS s) = text s
+prettyOS ArchOSAny = text "any"
+
+parseOS :: String -> ArchOS
+parseOS "any" = ArchOSAny
+parseOS s = ArchOS s
+
+data ArchCPU = ArchCPU String | ArchCPUAny deriving (Eq, Ord, Read, Show, Data, Typeable)
+
+prettyCPU :: ArchCPU -> Doc
+prettyCPU (ArchCPU s) = text s
+prettyCPU ArchCPUAny = text "any"
+
+parseCPU :: String -> ArchCPU
+parseCPU "any" = ArchCPUAny
+parseCPU s = ArchCPU s
+
+data Arch
+    = Source
+    | All
+    | Binary ArchOS ArchCPU
+    deriving (Eq, Ord, Read, Show, Data, Typeable)
+
+prettyArch :: Arch -> Doc
+prettyArch Source = text "source"
+prettyArch All = text "all"
+prettyArch (Binary (ArchOS "linux") cpu) = prettyCPU cpu
+prettyArch (Binary os cpu) = prettyOS os <> text "-" <> prettyCPU cpu
+
+parseArch :: String -> Arch
+parseArch s =
+    case span (/= '-') s of
+      ("source", "") -> Source
+      ("all", "") -> All
+      (cpu, "") -> Binary (ArchOS "linux") (parseCPU cpu)
+      (os, '-' : cpu) -> Binary (parseOS os) (parseCPU cpu)
+      _ -> error "parseArch: internal error"
diff --git a/Debian/Changes.hs b/Debian/Changes.hs
--- a/Debian/Changes.hs
+++ b/Debian/Changes.hs
@@ -14,7 +14,8 @@
 
 import Data.Either (partitionEithers)
 import Data.List (intercalate, intersperse)
-import Data.Text (pack, unpack, strip)
+import Data.Text (Text, pack, unpack, strip)
+import Debian.Arch (Arch, prettyArch)
 import qualified Debian.Control.String as S
 import Debian.Release
 import Debian.URI()
@@ -31,7 +32,7 @@
             , changeVersion :: DebianVersion	-- ^ The version number parsed from the .changes file name
             , changeRelease :: ReleaseName	-- ^ The Distribution field of the .changes file
             , changeArch :: Arch		-- ^ The architecture parsed from the .changes file name
-            , changeInfo :: S.Paragraph		-- ^ The contents of the .changes file
+            , changeInfo :: S.Paragraph' Text	-- ^ The contents of the .changes file
             , changeEntry :: ChangeLogEntry	-- ^ The value of the Changes field of the .changes file
             , changeFiles :: [ChangedFileSpec]	-- ^ The parsed value of the Files attribute
             } deriving (Eq)
@@ -69,7 +70,7 @@
 
 changesFileName :: ChangesFile -> String
 changesFileName changes =
-    changePackage changes ++ "_" ++ show (prettyDebianVersion (changeVersion changes)) ++ "_" ++ archName (changeArch changes) ++ ".changes"
+    changePackage changes ++ "_" ++ show (prettyDebianVersion (changeVersion changes) <> text "_" <> prettyArch (changeArch changes) <> text ".changes")
 
 instance Pretty ChangesFile where
     pretty = text . changesFileName
@@ -89,6 +90,7 @@
              , text ("  " ++ unpack (strip (pack details)))
              , empty
              , text (" -- " ++ who ++ "  " ++ date) ]
+    pretty (WhiteSpace _) = error "instance Pretty ChangeLogEntry"
 
 instance Pretty ChangeLog where
     pretty (ChangeLog xs) = vcat (intersperse empty (map pretty xs)) <> text "\n"
@@ -97,6 +99,7 @@
 _showHeader :: ChangeLogEntry -> Doc
 _showHeader (Entry package ver dists urgency _ _ _) =
     text (package ++ " (" ++ show (prettyDebianVersion ver) ++ ") " ++ intercalate " " (map releaseName' dists) ++ "; urgency=" ++ urgency ++ "...")
+_showHeader (WhiteSpace _) = error "_showHeader"
 
 {-
 format is a series of entries like this:
@@ -233,9 +236,9 @@
 
 -- |Parse the changelog information that shows up in the .changes
 -- file, i.e. a changelog entry with no signature.
-parseChanges :: String -> Maybe ChangeLogEntry
+parseChanges :: Text -> Maybe ChangeLogEntry
 parseChanges text =
-    case text =~ changesRE :: MatchResult String of
+    case unpack text =~ changesRE :: MatchResult String of
       MR {mrSubList = []} -> Nothing
       MR {mrSubList = [_, name, ver, dists, urgency, _, details]} ->
           Just $ Entry name
@@ -262,7 +265,7 @@
 bol = "^"
 
 -- This can be used for tests
-_s1 = intercalate "\n" 
+_s1 = unlines
      ["haskell-regex-compat (0.92-3+seereason1~jaunty4) jaunty-seereason; urgency=low",
       "",
       "  [ Joachim Breitner ]",
@@ -335,6 +338,4 @@
       "  * Initial release (used to be part of ghc6).",
       "  * Using \"Generic Haskell cabal library packaging files v9\".",
       "  ",
-      " -- Ian Lynagh (wibble) <igloo@debian.org>  Wed, 21 Nov 2007 01:26:57 +0000",
-      "  ",
-      ""]
+      " -- Ian Lynagh (wibble) <igloo@debian.org>  Wed, 21 Nov 2007 01:26:57 +0000"]
diff --git a/Debian/Control.hs b/Debian/Control.hs
--- a/Debian/Control.hs
+++ b/Debian/Control.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE OverloadedStrings #-}
 -- |A module for working with Debian control files <http://www.debian.org/doc/debian-policy/ch-controlfields.html>
 module Debian.Control 
     ( -- * Types
@@ -31,25 +32,27 @@
 --import Data.List
 --import Text.ParserCombinators.Parsec
 --import System.IO
+import Debian.Control.Common
 import Debian.Control.String
 import Data.List
-import qualified Debian.Control.ByteString as B
+import Data.Text as T (Text, pack, concat)
+import qualified Debian.Control.Text as T
+import qualified Debian.Control.ByteString as B ()
 import qualified Debian.Control.String as S
-import qualified Data.ByteString.Char8 as B
 
-packParagraph :: S.Paragraph -> B.Paragraph
-packParagraph (S.Paragraph s) = B.Paragraph (map packField s)
+packParagraph :: S.Paragraph -> T.Paragraph
+packParagraph (S.Paragraph s) = T.Paragraph (map packField s)
 
-packField :: Field' String -> Field' B.ByteString
-packField (S.Field (name, value)) = B.Field (B.pack name, B.pack value)
-packField (S.Comment s) = B.Comment (B.pack s)
+packField :: Field' String -> Field' Text
+packField (S.Field (name, value)) = T.Field (T.pack name, T.pack value)
+packField (S.Comment s) = T.Comment (T.pack s)
 
-formatControl :: Control' B.ByteString -> [B.ByteString]
-formatControl (B.Control paragraphs) = intersperse (B.pack "\n") . map formatParagraph $ paragraphs
+formatControl :: Control' Text -> [Text]
+formatControl (T.Control paragraphs) = intersperse (T.pack "\n") . map formatParagraph $ paragraphs
 
-formatParagraph :: Paragraph' B.ByteString -> B.ByteString
-formatParagraph (B.Paragraph fields) = B.concat . map formatField $ fields
+formatParagraph :: Paragraph' Text -> Text
+formatParagraph (T.Paragraph fields) = T.concat . map formatField $ fields
 
-formatField :: Field' B.ByteString -> B.ByteString
-formatField (B.Field (name, value)) = B.concat [name, B.pack ":", value, B.pack "\n"]
-formatField (B.Comment s) = s
+formatField :: Field' Text -> Text
+formatField (T.Field (name, value)) = T.concat [name, T.pack ":", value, T.pack "\n"]
+formatField (T.Comment s) = s
diff --git a/Debian/Control/Common.hs b/Debian/Control/Common.hs
--- a/Debian/Control/Common.hs
+++ b/Debian/Control/Common.hs
@@ -17,11 +17,11 @@
     )
     where
 
-import Text.ParserCombinators.Parsec
-import System.Exit
-import System.IO
-import System.Process
-import Data.List
+import Text.ParserCombinators.Parsec (ParseError)
+import System.Exit (ExitCode(ExitSuccess, ExitFailure))
+import System.IO (Handle)
+import System.Process (runInteractiveCommand, waitForProcess)
+import Data.List (partition)
 
 newtype Control' a
     = Control { unControl :: [Paragraph' a] }
diff --git a/Debian/Control/PrettyPrint.hs b/Debian/Control/PrettyPrint.hs
--- a/Debian/Control/PrettyPrint.hs
+++ b/Debian/Control/PrettyPrint.hs
@@ -2,6 +2,7 @@
 module Debian.Control.PrettyPrint where
 
 import qualified Data.ByteString.Char8 as C
+import Data.Text as T (Text, unpack)
 import Text.PrettyPrint.ANSI.Leijen
 
 import Debian.Control.Common
@@ -26,3 +27,6 @@
 
 instance ToText C.ByteString where
     totext = text . C.unpack
+
+instance ToText Text where
+    totext = text . T.unpack
diff --git a/Debian/Control/String.hs b/Debian/Control/String.hs
--- a/Debian/Control/String.hs
+++ b/Debian/Control/String.hs
@@ -25,10 +25,13 @@
 
 import qualified Control.Exception as E
 import Data.Char (toLower)
-import Data.List
-import Text.ParserCombinators.Parsec
-import System.IO
-import Debian.Control.Common
+import Data.List (find)
+import Text.ParserCombinators.Parsec (CharParser, parse, parseFromFile, sepEndBy, satisfy, oneOf, string, lookAhead, try, many, many1, (<|>), noneOf, char, eof)
+import System.IO (hGetContents)
+import Debian.Control.Common (ControlFunctions(parseControlFromFile, parseControlFromHandle, parseControl, lookupP, stripWS, asString),
+                              Control'(Control), Paragraph'(Paragraph), Field'(Field, Comment),
+                              mergeControls, fieldValue, removeField, prependFields, appendFields,
+                              renameField, modifyField, raiseFields)
 import Text.PrettyPrint.ANSI.Leijen (Pretty(pretty), text, vcat, empty)
 
 -- |This may have bad performance issues (why?)
diff --git a/Debian/Control/Text.hs b/Debian/Control/Text.hs
new file mode 100644
--- /dev/null
+++ b/Debian/Control/Text.hs
@@ -0,0 +1,165 @@
+{-# LANGUAGE FlexibleInstances, OverloadedStrings, ScopedTypeVariables, TypeSynonymInstances #-}
+{-# OPTIONS_GHC -fno-warn-orphans -fno-warn-name-shadowing -fno-warn-unused-do-bind #-}
+module Debian.Control.Text
+    ( -- * Types
+      Control'(..)
+    , Paragraph'(..)
+    , Field'(..)
+    , Control
+    , Paragraph
+    , Field
+    -- , ControlParser
+    , ControlFunctions(..)
+    -- * Control File Parser
+    -- , pControl
+    -- * Helper Functions
+    , mergeControls
+    , fieldValue
+    , removeField
+    , prependFields
+    , appendFields
+    , renameField
+    , modifyField
+    , raiseFields
+    , decodeControl
+    , decodeParagraph
+    , decodeField
+    ) where
+
+import qualified Data.ByteString.Char8 as B
+import Data.Char (toLower, chr)
+import Data.List (find)
+import Data.Monoid ((<>))
+import qualified Data.Text as T (Text, pack, unpack, map, strip, reverse)
+import Data.Text.Encoding (decodeUtf8With, encodeUtf8)
+--import Data.Text.IO as T (readFile)
+import qualified Debian.Control.ByteString as B
+--import Text.Parsec.Error (ParseError)
+--import Text.Parsec.Text (Parser)
+--import Text.Parsec.Prim (runP)
+import Debian.Control.Common (ControlFunctions(parseControlFromFile, parseControlFromHandle, parseControl, lookupP, stripWS, asString),
+                              Control'(Control), Paragraph'(Paragraph), Field'(Field, Comment),
+                              mergeControls, fieldValue, removeField, prependFields, appendFields,
+                              renameField, modifyField, raiseFields)
+import Text.PrettyPrint.ANSI.Leijen (Pretty(pretty), text, vcat, empty)
+
+-- | @parseFromFile p filePath@ runs a string parser @p@ on the
+-- input read from @filePath@ using 'Prelude.readFile'. Returns either a 'ParseError'
+-- ('Left') or a value of type @a@ ('Right').
+--
+-- >  main    = do{ result <- parseFromFile numbers "digits.txt"
+-- >              ; case result of
+-- >                  Left err  -> print err
+-- >                  Right xs  -> print (sum xs)
+-- >              }
+{-
+parseFromFile :: Parser a -> String -> IO (Either ParseError a)
+parseFromFile p fname
+    = do input <- T.readFile fname `E.catch` (\ (_ :: E.SomeException) -> B.readFile fname >>= return . decode)
+         return (runP p () fname input)
+-}
+
+-- |This may have bad performance issues (why?)
+instance Pretty (Control' T.Text) where
+    pretty (Control paragraphs) = vcat (map (\ p -> pretty p) paragraphs)
+instance Pretty (Paragraph' T.Text) where
+    pretty (Paragraph fields) = vcat (map pretty fields ++ [empty])
+
+instance Pretty (Field' T.Text) where
+    pretty (Field (name,value)) = text . T.unpack $ name <>":"<> value
+    pretty (Comment s) = text (T.unpack s)
+
+type Field = Field' T.Text
+type Control = Control' T.Text
+type Paragraph = Paragraph' T.Text
+
+decodeControl :: B.Control -> Control
+decodeControl (B.Control paragraphs) = Control (map decodeParagraph paragraphs)
+
+decodeParagraph :: B.Paragraph -> Paragraph
+decodeParagraph (B.Paragraph s) = B.Paragraph (map decodeField s)
+
+decodeField :: Field' B.ByteString -> Field' T.Text
+decodeField (B.Field (name, value)) = Field (decode name, decode value)
+decodeField (B.Comment s) = Comment (decode s)
+
+decode :: B.ByteString -> T.Text
+decode = decodeUtf8With (\ _ w -> fmap (chr . fromIntegral) w)
+
+-- * ControlFunctions
+
+instance ControlFunctions T.Text where
+    parseControlFromFile filepath =
+        -- The ByteString parser is far more efficient than the Text
+        -- parser.  By calling decodeControl we tell the compiler to
+        -- use it instead.
+        parseControlFromFile filepath >>= return . either Left (Right . decodeControl)
+    parseControlFromHandle sourceName handle =
+        parseControlFromHandle sourceName handle >>= return . either Left (Right . decodeControl)
+    parseControl sourceName c =
+        -- Warning: This is very slow, it does a utf8 round trip
+        either Left (Right . decodeControl) (parseControl sourceName (encodeUtf8 c))
+    lookupP fieldName (Paragraph paragraph) =
+        find (hasFieldName (map toLower fieldName)) paragraph
+        where hasFieldName :: String -> Field' T.Text -> Bool
+              hasFieldName name (Field (fieldName',_)) = T.pack name == T.map toLower fieldName'
+              hasFieldName _ _ = False
+    stripWS = T.reverse . T.strip . T.reverse . T.strip
+    asString = T.unpack
+
+-- * Control File Parser
+{-
+-- type ControlParser = GenParser T.Text
+type ControlParser a = Parsec T.Text () a
+
+-- |A parser for debian control file. This parser handles control files
+-- that end without a newline as well as ones that have several blank
+-- lines at the end. It is very liberal and does not attempt validate
+-- the fields in any way. All trailing, leading, and folded whitespace
+-- is preserved in the field values. See 'stripWS'.
+pControl :: ControlParser Control
+pControl =
+    do many $ char '\n'
+       sepEndBy pParagraph pBlanks >>= return . Control
+
+pParagraph :: ControlParser Paragraph
+pParagraph = many1 (pComment <|> pField) >>= return . Paragraph
+
+-- |We are liberal in that we allow *any* field to have folded white
+-- space, even though the specific restricts that to a few fields.
+pField :: ControlParser Field
+pField =
+    do c1 <- noneOf "#\n"
+       fieldName <-  many1 $ noneOf ":\n"
+       char ':'
+       fieldValue <- many fcharfws
+       (char '\n' >> return ()) <|> eof
+       return $ Field (T.cons c1 (T.pack fieldName), T.pack fieldValue)
+
+pComment :: ControlParser Field
+pComment =
+    do char '#'
+       text <- many (satisfy (not . ((==) '\n')))
+       char '\n'
+       return $ Comment (T.pack ("#" <> text <> "\n"))
+
+fcharfws :: ControlParser Char
+fcharfws = fchar <|> (try $ lookAhead (string "\n ") >> char '\n') <|> (try $ lookAhead (string "\n\t") >> char '\n') <|> (try $ lookAhead (string "\n#") >> char '\n')
+
+fchar :: ControlParser Char
+fchar = satisfy (/='\n')
+
+_fws :: ControlParser T.Text
+_fws =
+    try $ do char '\n'
+             ws <- many1 (char ' ')
+             c <- many1 (satisfy (not . ((==) '\n')))
+             return $ T.cons '\n' (T.pack ws <> T.pack c)
+
+-- |We go with the assumption that 'blank lines' mean lines that
+-- consist of entirely of zero or more whitespace characters.
+pBlanks :: ControlParser T.Text
+pBlanks =
+    do s <- many1 (oneOf " \n")
+       return . T.pack $ s
+-}
diff --git a/Debian/GenBuildDeps.hs b/Debian/GenBuildDeps.hs
--- a/Debian/GenBuildDeps.hs
+++ b/Debian/GenBuildDeps.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE RecordWildCards, ScopedTypeVariables #-}
+{-# LANGUAGE OverloadedStrings, RecordWildCards, ScopedTypeVariables #-}
 -- |Figure out the dependency relation between debianized source
 -- directories.  The code to actually solve these dependency relations
 -- for a particular set of binary packages is in Debian.Repo.Dependency.
@@ -24,12 +24,14 @@
 import		 Control.Monad (filterM)
 import		 Debian.Control
 import           Data.Either
-import		 Data.Graph (Graph,buildG,topSort,reachable, transposeG, vertices, edges)
+import		 Data.Graph (Graph, Edge, buildG, topSort, reachable, transposeG, vertices, edges)
 import		 Data.List
 import qualified Data.Map as Map
 import		 Data.Maybe
 import qualified Data.Set as Set
+import           Data.Text (Text, unpack)
 import		 Debian.Relation
+import		 Debian.Relation.Text ()
 import		 System.Directory (getDirectoryContents, doesFileExist)
 
 -- | This type describes the build dependencies of a source package.
@@ -50,12 +52,12 @@
 -- |Return the dependency info for a source package with the given dependency relaxation.
 -- |According to debian policy, only the first paragraph in debian\/control can be a source package
 -- <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-sourcecontrolfiles>
-buildDependencies :: Control -> Either String DepInfo
+buildDependencies :: Control' Text -> Either String DepInfo
 buildDependencies (Control []) = error "Control file seems to be empty"
 buildDependencies (Control (source:binaries)) =
-    either (Left . concat) (\ deps -> Right (DepInfo {sourceName = sourcePackage, relations = deps, binaryNames = bins})) deps
+    either (Left . concat) (\ rels -> Right (DepInfo {sourceName = sourcePackage, relations = rels, binaryNames = bins})) deps
     where
-      sourcePackage = maybe (error "First Paragraph in control file lacks a Source field") SrcPkgName $ assoc "Source" source
+      sourcePackage = maybe (error "First Paragraph in control file lacks a Source field") (SrcPkgName . unpack) $ assoc "Source" source
       -- The raw list of build dependencies for this package
       deps = either Left (Right . concat) (concatEithers [buildDeps, buildDepsIndep])
       buildDeps =
@@ -67,8 +69,8 @@
             (Just v) -> either (\ e -> Left ("Error parsing Build-Depends-Indep for" ++ show sourcePackage ++ ": " ++ show e)) Right (parseRelations v)
             _ -> Right []
       bins = mapMaybe lookupPkgName binaries
-      lookupPkgName :: Paragraph -> Maybe BinPkgName
-      lookupPkgName p = maybe Nothing (Just . BinPkgName) (assoc "Package" p)
+      lookupPkgName :: Paragraph' Text -> Maybe BinPkgName
+      lookupPkgName p = maybe Nothing (Just . BinPkgName . unpack) (assoc "Package" p)
 
 -- |Specifies build dependencies that should be ignored during the build
 -- decision.  If the pair is (BINARY, Nothing) it means the binary package
@@ -85,8 +87,8 @@
 -- OldRelaxInfo.)
 type RelaxInfo = SrcPkgName -> BinPkgName -> Bool
 
-makeRelaxInfo :: OldRelaxInfo -> RelaxInfo
-makeRelaxInfo (RelaxInfo xs) srcPkgName binPkgName =
+_makeRelaxInfo :: OldRelaxInfo -> RelaxInfo
+_makeRelaxInfo (RelaxInfo xs) srcPkgName binPkgName =
     Set.member binPkgName global || maybe False (Set.member binPkgName) (Map.lookup srcPkgName mp)
     where
       (global :: Set.Set BinPkgName, mp :: Map.Map SrcPkgName (Set.Set BinPkgName)) =
@@ -168,13 +170,13 @@
           (ofVertex thisReady, map ofVertex directlyBlocked, map ofVertex (otherReady ++ otherBlocked))
       --allDeps x = (ofVertex x, map ofVertex (filter (/= x) (reachable hasDep x)))
       isDep = buildG (0, length packages - 1) edges'
-      edges' = map (\ (a, b) -> (b, a)) edges
-      hasDep = buildG (0, length packages - 1) edges
-      edges :: [(Int, Int)]
-      edges =
+      edges' = map (\ (a, b) -> (b, a)) edges''
+      hasDep = buildG (0, length packages - 1) edges''
+      edges'' :: [(Int, Int)]
+      edges'' =
           nub (foldr f [] (tails vertPairs))
-          where f [] edges = edges
-                f (x : xs) edges = catMaybes (map (toEdge x) xs) ++ edges
+          where f [] es = es
+                f (x : xs) es = catMaybes (map (toEdge x) xs) ++ es
                 toEdge (xv, xa) (yv, ya) =
                     case cmp xa ya of
                       EQ -> Nothing
@@ -186,21 +188,22 @@
       verts = map fst vertPairs
       vertPairs = zip [0..] packages
 
+cycleEdges :: Graph -> [Edge]
 cycleEdges g =
     filter (`elem` (edges g))
                (Set.toList (Set.intersection
                             (Set.fromList (closure g))
                             (Set.fromList (closure (transposeG g)))))
     where
-      closure g = concat (map (\ v -> (map (\ u -> (v, u)) (reachable g v))) (vertices g))
+      closure g' = concat (map (\ v -> (map (\ u -> (v, u)) (reachable g' v))) (vertices g'))
       --self (a, b) = a == b
       --distrib = concat . map (\ (n, ms) -> map (\ m -> (n, m)) ms) 
       --swap (a, b) = (b, a)
 
 -- | Remove any packages which can't be built given that a package has failed.
 failPackage :: Eq a => (a -> a -> Ordering) -> a -> [a] -> ([a], [a])
-failPackage compare failed packages =
-    let graph = buildGraph compare packages in
+failPackage cmp failed packages =
+    let graph = buildGraph cmp packages in
     let root = elemIndex failed packages in
     let victims = maybe [] (map (fromJust . vertex) . reachable graph) root in
     partition (\ x -> not . elem x $ victims) packages
@@ -212,28 +215,28 @@
 -- build dependencies so that the first element doesn't depend on any
 -- of the other packages.
 orderSource :: (a -> a -> Ordering) -> [a] -> [a]
-orderSource compare packages =
+orderSource cmp packages =
     map (fromJust . vertex) (topSort graph)
     where
-      graph = buildGraph compare packages
+      graph = buildGraph cmp packages
       vertex n = Map.findWithDefault Nothing n vertexMap
       vertexMap = Map.fromList (zip [0..] (map Just packages))
 
 -- | Build a graph with the list of packages as its nodes and the
 -- build dependencies as its edges.
 buildGraph :: (a -> a -> Ordering) -> [a] -> Graph
-buildGraph compare packages =
-    let edges = someEdges (zip packages [0..]) in
-    buildG (0, length packages - 1) edges
+buildGraph cmp packages =
+    let es = someEdges (zip packages [0..]) in
+    buildG (0, length packages - 1) es
     where
       someEdges [] = []
       someEdges (a : etc) = aEdges a etc ++ someEdges etc
       aEdges (ap, an) etc =
           concat (map (\ (bp, bn) ->
-                           case compare ap bp of
-                                       LT -> [(an, bn)]
-                                       GT -> [(bn, an)]
-                                       EQ -> []) etc)
+                           case cmp ap bp of
+                             LT -> [(an, bn)]
+                             GT -> [(bn, an)]
+                             EQ -> []) etc)
 
 -- |This is a nice start. It ignores circular build depends and takes
 -- a pretty simplistic approach to 'or' build depends. However, I
@@ -276,5 +279,5 @@
           filterM doesFileExist
 
 
-assoc :: String -> Paragraph -> Maybe String
+assoc :: String -> Paragraph' Text -> Maybe Text
 assoc name fields = maybe Nothing (\ (Field (_, v)) -> Just (stripWS v)) (lookupP name fields)
diff --git a/Debian/Relation.hs b/Debian/Relation.hs
--- a/Debian/Relation.hs
+++ b/Debian/Relation.hs
@@ -11,6 +11,9 @@
     , prettyRelations
     , Relation(..)
     , ArchitectureReq(..)
+    , Arch(..)
+    , ArchOS(..)
+    , ArchCPU(..)
     , VersionReq(..)
     -- * Helper Functions
     , checkVersionReq
@@ -19,5 +22,6 @@
     , ParseRelations(..)
     ) where 
 
+import Debian.Arch (Arch(..), ArchOS(..), ArchCPU(..))
 import Debian.Relation.Common (SrcPkgName(..), BinPkgName(..), PkgName(pkgNameFromString), prettyOrRelation, prettyRelations)
 import Debian.Relation.String
diff --git a/Debian/Relation/ByteString.hs b/Debian/Relation/ByteString.hs
--- a/Debian/Relation/ByteString.hs
+++ b/Debian/Relation/ByteString.hs
@@ -1,3 +1,4 @@
+{-# OPTIONS -fno-warn-orphans #-}
 -- |A module for working with debian relationships <http://www.debian.org/doc/debian-policy/ch-relationships.html>
 module Debian.Relation.ByteString
     ( -- * Types
diff --git a/Debian/Relation/Common.hs b/Debian/Relation/Common.hs
--- a/Debian/Relation/Common.hs
+++ b/Debian/Relation/Common.hs
@@ -3,9 +3,12 @@
 
 -- Standard GHC Modules
 
-import Data.List
+import Data.List as List (map, intersperse)
 import Data.Monoid (mconcat)
 import Data.Function
+import Data.Set as Set (Set, toList)
+import Debian.Arch (Arch, prettyArch)
+import Prelude hiding (map)
 import Text.ParserCombinators.Parsec
 import Text.PrettyPrint.ANSI.Leijen (Pretty(pretty), Doc, text, empty, (<>))
 
@@ -19,7 +22,7 @@
 type AndRelation = [OrRelation]
 type OrRelation = [Relation]
 
-data Relation = Rel BinPkgName (Maybe VersionReq) (Maybe ArchitectureReq) deriving Eq
+data Relation = Rel BinPkgName (Maybe VersionReq) (Maybe ArchitectureReq) deriving (Eq, Show)
 
 newtype SrcPkgName = SrcPkgName {unSrcPkgName :: String} deriving (Show, Eq, Ord)
 newtype BinPkgName = BinPkgName {unBinPkgName :: String} deriving (Show, Eq, Ord)
@@ -41,10 +44,10 @@
 
 -- | This needs to be indented for use in a control file: intercalate "\n     " . lines . show
 prettyRelations :: [[Relation]] -> Doc
-prettyRelations xss = mconcat . intersperse (text "\n, ") . map prettyOrRelation $ xss
+prettyRelations xss = mconcat . intersperse (text "\n, ") . List.map prettyOrRelation $ xss
 
 prettyOrRelation :: [Relation] -> Doc
-prettyOrRelation xs = mconcat . intersperse (text " | ") . map prettyRelation $ xs
+prettyOrRelation xs = mconcat . intersperse (text " | ") . List.map prettyRelation $ xs
 
 prettyRelation :: Relation -> Doc
 prettyRelation (Rel name ver arch) =
@@ -58,13 +61,13 @@
 	     EQ -> compare mVerReq1 mVerReq2
 
 data ArchitectureReq
-    = ArchOnly [String]
-    | ArchExcept [String]
-      deriving Eq
+    = ArchOnly (Set Arch)
+    | ArchExcept (Set Arch)
+    deriving (Eq, Ord, Show)
 
 prettyArchitectureReq :: ArchitectureReq -> Doc
-prettyArchitectureReq (ArchOnly arch) = text $ " [" ++ intercalate " " arch ++ "]"
-prettyArchitectureReq (ArchExcept arch) = text $ " [!" ++ intercalate " !" arch ++ "]"
+prettyArchitectureReq (ArchOnly arch) = text " [" <> mconcat (List.map prettyArch (toList arch)) <> text "]"
+prettyArchitectureReq (ArchExcept arch) = text " [" <> mconcat (List.map ((text "!") <>) (List.map prettyArch (toList arch))) <> text "]"
 
 data VersionReq
     = SLT DebianVersion
@@ -72,7 +75,7 @@
     | EEQ  DebianVersion
     | GRE  DebianVersion
     | SGR DebianVersion
-      deriving Eq
+      deriving (Eq, Show)
 
 prettyVersionReq :: VersionReq -> Doc
 prettyVersionReq (SLT v) = text $ " (<< " ++ show (prettyDebianVersion v) ++ ")"
@@ -85,11 +88,11 @@
 -- relation, sorting in the order <<, <= , ==, >= , >>
 instance Ord VersionReq where
     compare = compare `on` extr
-      where extr (SLT v) = (v,0)
-            extr (LTE v) = (v,1)
-            extr (EEQ v) = (v,2)
-            extr (GRE v) = (v,3)
-            extr (SGR v) = (v,4)
+      where extr (SLT v) = (v,0 :: Int)
+            extr (LTE v) = (v,1 :: Int)
+            extr (EEQ v) = (v,2 :: Int)
+            extr (GRE v) = (v,3 :: Int)
+            extr (SGR v) = (v,4 :: Int)
 
 -- |Check if a version number satisfies a version requirement.
 checkVersionReq :: Maybe VersionReq -> Maybe DebianVersion -> Bool
diff --git a/Debian/Relation/String.hs b/Debian/Relation/String.hs
--- a/Debian/Relation/String.hs
+++ b/Debian/Relation/String.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
+{-# OPTIONS -fno-warn-unused-do-bind -fno-warn-orphans #-}
 -- |A module for working with debian relationships <http://www.debian.org/doc/debian-policy/ch-relationships.html>
 module Debian.Relation.String
     ( -- * Types
@@ -14,14 +15,18 @@
     , RelParser
     , ParseRelations(..)
     , pRelations
-    ) where 
+    ) where
 
 -- Standard GHC Modules
 
+import Control.Monad.Identity (Identity)
+import Data.Set (fromList)
 import Text.ParserCombinators.Parsec
+import Text.Parsec.Prim (ParsecT)
 
 -- Local Modules
 
+import Debian.Arch (Arch, parseArch)
 import Debian.Relation.Common
 import Debian.Version
 
@@ -57,6 +62,7 @@
                  skipMany (char ',' <|> whiteChar)
                  return rel
 
+whiteChar :: ParsecT String u Identity Char
 whiteChar = oneOf [' ','\t','\n']
 
 pRelation :: RelParser Relation
@@ -75,13 +81,14 @@
        skipMany whiteChar
        op <- pVerReq
        skipMany whiteChar
-       version <- many1 (noneOf [' ',')','\t','\n'])
+       ver <- many1 (noneOf [' ',')','\t','\n'])
        skipMany whiteChar
        char ')'
-       return $ Just (op (parseDebianVersion version))
+       return $ Just (op (parseDebianVersion ver))
     <|>
     do return $ Nothing
 
+pVerReq :: ParsecT [Char] u Identity (DebianVersion -> VersionReq)
 pVerReq =
     do char '<'
        (do char '<' <|> char ' ' <|> char '\t'
@@ -106,12 +113,12 @@
        (do archs <- pArchExcept
 	   char ']'
            skipMany whiteChar
-	   return (Just (ArchExcept archs))
+	   return (Just (ArchExcept (fromList . map parseArchExcept $ archs)))
 	<|>
 	do archs <- pArchOnly
 	   char ']'
            skipMany whiteChar
-	   return (Just (ArchOnly archs))
+	   return (Just (ArchOnly (fromList . map parseArch $ archs)))
 	)
     <|>
     return Nothing
@@ -124,3 +131,9 @@
 
 pArchOnly :: RelParser [String]
 pArchOnly = sepBy (many1 (noneOf [']',' '])) (skipMany1 whiteChar)
+
+-- | Ignore the ! if it is present, we already know this list has at
+-- least one, and the rest are implicit.
+parseArchExcept :: String -> Arch
+parseArchExcept ('!' : s) = parseArch s
+parseArchExcept s = parseArch s
diff --git a/Debian/Relation/Text.hs b/Debian/Relation/Text.hs
new file mode 100644
--- /dev/null
+++ b/Debian/Relation/Text.hs
@@ -0,0 +1,30 @@
+{-# OPTIONS -fno-warn-orphans #-}
+-- |A module for working with debian relationships <http://www.debian.org/doc/debian-policy/ch-relationships.html>
+module Debian.Relation.Text
+    ( -- * Types
+      AndRelation
+    , OrRelation
+    , Relations
+    , Relation(..)
+    , ArchitectureReq(..)
+    , VersionReq(..)
+    -- * Helper Functions
+    , checkVersionReq
+    -- * Relation Parser
+    , RelParser
+    , ParseRelations(..)
+    ) where 
+
+import qualified Data.Text as T
+
+-- Local Modules
+
+--import Debian.Relation.Common
+import Debian.Relation.String
+--import Debian.Version
+
+-- * ParseRelations
+
+-- For now we just wrap the string version
+instance ParseRelations T.Text where
+    parseRelations text = parseRelations (T.unpack text)
diff --git a/Debian/Release.hs b/Debian/Release.hs
--- a/Debian/Release.hs
+++ b/Debian/Release.hs
@@ -3,8 +3,6 @@
     ( ReleaseName(..)
     , parseReleaseName
     , releaseName'
-    , Arch(..)
-    , archName
     , Section(..)
     , SubSection(..)
     , sectionName
@@ -16,7 +14,7 @@
 
 import Data.Data (Data)
 import Data.Typeable (Typeable)
-import Debian.URI
+import Network.URI (unEscapeString, escapeURIString, isAllowedInURI)
 
 -- |A distribution (aka release) name.  This type is expected to refer
 -- to a subdirectory of the dists directory which is at the top level
@@ -28,14 +26,6 @@
 
 releaseName' :: ReleaseName -> String
 releaseName' (ReleaseName {relName = s}) = escapeURIString isAllowedInURI s
-
--- |The types of architecture that a package can have, either Source
--- or some type of binary architecture.
-data Arch = Source | Binary String deriving (Read, Show, Eq, Ord, Data, Typeable)
-
-archName :: Arch -> String
-archName Source = "source"
-archName (Binary arch) = arch
 
 -- |A section of a repository such as main, contrib, non-free,
 -- restricted.  The indexes for a section are located below the
diff --git a/Debian/Report.hs b/Debian/Report.hs
--- a/Debian/Report.hs
+++ b/Debian/Report.hs
@@ -1,14 +1,15 @@
 module Debian.Report where
 
 import Debian.Apt.Index (Fetcher, Compression(..), update, controlFromIndex')
-import Debian.Control.ByteString
+import Debian.Control.Common (unControl)
+import Debian.Control.Text
 import Debian.Sources
 import Debian.Version
 
 import Data.Maybe
 import qualified Data.Map as M
-import qualified Data.ByteString.Char8 as B
-import Text.XML.HaXml
+import qualified Data.Text as T
+import Text.XML.HaXml (CFilter, mkElem, cdata)
 import Text.XML.HaXml.Posn
 
 -- * General Package Map Builders
@@ -20,7 +21,7 @@
 -- time to avoid having all the control files loaded in memory at
 -- once. However, I am not sure that property is actually occuring
 -- anyway. So, this should be revisited.
-makePackageMap :: (Paragraph -> a) -> (a -> a -> a) -> [(FilePath, Compression)] -> IO (M.Map B.ByteString a)
+makePackageMap :: (Paragraph -> a) -> (a -> a -> a) -> [(FilePath, Compression)] -> IO (M.Map T.Text a)
 makePackageMap _ _ [] = return M.empty
 makePackageMap extractValue resolveConflict ((path, compression):is) =
     do r <- controlFromIndex' compression path
@@ -32,7 +33,7 @@
                 return $ M.unionWith resolveConflict pm pms
 
 -- |create a map of (package name, max version) from a single control file
-packageMap :: (Paragraph -> a) -> (a -> a -> a) -> Control -> M.Map B.ByteString a
+packageMap :: (Paragraph -> a) -> (a -> a -> a) -> Control' T.Text -> M.Map T.Text a
 packageMap extractValue resolveConflict control =
     M.fromListWith resolveConflict (map packageTuple (unControl control))
     where
@@ -40,7 +41,7 @@
 
 -- |extract the version number from a control paragraph
 extractVersion :: Paragraph -> Maybe DebianVersion
-extractVersion paragraph = fmap (parseDebianVersion . B.unpack)  $ fieldValue "Version" paragraph
+extractVersion paragraph = fmap (parseDebianVersion . T.unpack)  $ fieldValue "Version" paragraph
 
 -- * Trump Report
 
@@ -51,7 +52,7 @@
         -> String -- ^ binary architecture 
         -> [DebSource] -- ^ sources.list a
         -> [DebSource] -- ^ sources.list b
-        -> IO (M.Map B.ByteString (DebianVersion, DebianVersion)) -- ^ a map of trumped package names to (version a, version b)
+        -> IO (M.Map T.Text (DebianVersion, DebianVersion)) -- ^ a map of trumped package names to (version a, version b)
 trumped fetcher cacheDir arch sourcesA sourcesB =
     do indexesA <- update fetcher cacheDir arch (filter isDebSrc sourcesA)
        pmA <- makePackageMap (fromJust . extractVersion) max (map fromJust indexesA)
@@ -62,9 +63,9 @@
       isDebSrc ds = sourceType ds == DebSrc
 
 -- |calculate all the trumped packages
-trumpedMap :: M.Map B.ByteString DebianVersion -- ^ package map a
-           -> M.Map B.ByteString DebianVersion -- ^ package map b
-           -> M.Map B.ByteString (DebianVersion, DebianVersion) -- ^ trumped packages (version a, version b)
+trumpedMap :: M.Map T.Text DebianVersion -- ^ package map a
+           -> M.Map T.Text DebianVersion -- ^ package map b
+           -> M.Map T.Text (DebianVersion, DebianVersion) -- ^ trumped packages (version a, version b)
 trumpedMap pmA pmB =
     M.foldWithKey (checkTrumped pmB) M.empty pmA
     where
@@ -75,13 +76,13 @@
             _ -> trumpedPM
 
 -- |create <trumped /> XML element and children from a trumped Map
-trumpedXML :: M.Map B.ByteString (DebianVersion, DebianVersion) -> CFilter Posn
+trumpedXML :: M.Map T.Text (DebianVersion, DebianVersion) -> CFilter Posn
 trumpedXML trumpedMap' =
     mkElem "trumped" (map mkTrumpedPackage (M.toAscList trumpedMap' ))
     where
       mkTrumpedPackage (package, (oldVersion, newVersion)) =
           mkElem "trumpedPackage"
-                     [ mkElem "package" [ cdata (B.unpack package) ]
+                     [ mkElem "package" [ cdata (T.unpack package) ]
                      , mkElem "oldVersion" [ cdata (show (prettyDebianVersion oldVersion)) ]
                      , mkElem "newVersion" [ cdata (show (prettyDebianVersion newVersion)) ]
                      ]
diff --git a/Debian/Sources.hs b/Debian/Sources.hs
--- a/Debian/Sources.hs
+++ b/Debian/Sources.hs
@@ -3,7 +3,7 @@
 
 import Data.List (intercalate)
 import Debian.Release
-import Debian.URI
+import Network.URI (URI, uriToString, parseURI, unEscapeString, escapeURIString, isAllowedInURI)
 import Text.PrettyPrint.ANSI.Leijen (Pretty(pretty), text)
 
 data SourceType
diff --git a/Debian/URI.hs b/Debian/URI.hs
--- a/Debian/URI.hs
+++ b/Debian/URI.hs
@@ -1,7 +1,11 @@
+{-# LANGUAGE PackageImports #-}
 {-# OPTIONS -fno-warn-orphans #-}
 module Debian.URI
     ( module Network.URI
-    , URIString
+    , URI'
+    , toURI'
+    , fromURI'
+    , readURI'
     , uriToString'
     , fileFromURI
     , fileFromURIStrict
@@ -9,47 +13,61 @@
     ) where
 
 import Control.Exception (SomeException, try)
+import Data.ByteString.Lazy.UTF8 as L
 import qualified Data.ByteString.Lazy.Char8 as L
-import Data.ByteString.UTF8 as B
-import qualified Data.ByteString as B
-import Data.Maybe (catMaybes)
-import Network.URI
+import Data.Maybe (catMaybes, fromJust)
+import Network.URI (URI(..), URIAuth(..), parseURI, uriToString)
 import System.Directory (getDirectoryContents)
-import System.Process.ByteString (readProcessWithExitCode)
+-- import System.Process.ByteString (readProcessWithExitCode)
+import "process-listlike" System.Process.ByteString.Lazy (readProcessWithExitCode)
 import Text.Regex (mkRegex, matchRegex)
 
+-- | A wrapper around a String containing a known parsable URI.  Not
+-- absolutely safe, because you could say read "URI' \"bogus string\""
+-- :: URI'.  But enough to save me from myself.
+newtype URI' = URI' String deriving (Read, Show, Eq, Ord)
+
+readURI' :: String -> Maybe URI'
+readURI' s = maybe Nothing (const (Just (URI' s))) (parseURI s)
+
+fromURI' :: URI' -> URI
+fromURI' (URI' s) = fromJust (parseURI s)
+
+-- | Using the bogus Show instance of URI here.  If it ever gets fixed
+-- this will stop working.  Worth noting that show will obscure any
+-- password info embedded in the URI, so that's nice.
+toURI' :: URI -> URI'
+toURI' = URI' . show
+
 uriToString' :: URI -> String
 uriToString' uri = uriToString id uri ""
 
--- |If the URI type could be read and showed this wouldn't be necessary.
-type URIString = String
-
 fileFromURI :: URI -> IO (Either SomeException L.ByteString)
-fileFromURI uri = fileFromURIStrict uri >>= either (return . Left) (return . Right . L.fromChunks . (: []))
+fileFromURI uri = fileFromURIStrict uri
 
-fileFromURIStrict :: URI -> IO (Either SomeException B.ByteString)
+fileFromURIStrict :: URI -> IO (Either SomeException L.ByteString)
 fileFromURIStrict uri = try $
     case (uriScheme uri, uriAuthority uri) of
-      ("file:", Nothing) -> B.readFile (uriPath uri)
+      ("file:", Nothing) -> L.readFile (uriPath uri)
       -- ("ssh:", Just auth) -> cmdOutputStrict ("ssh " ++ uriUserInfo auth ++ uriRegName auth ++ uriPort auth ++ " cat " ++ show (uriPath uri))
       ("ssh:", Just auth) -> do
           let cmd = "ssh"
               args = [uriUserInfo auth ++ uriRegName auth ++ uriPort auth, "cat", uriPath uri]
-          (_code, out, _err) <- readProcessWithExitCode cmd args B.empty
+          (_code, out, _err) <- readProcessWithExitCode cmd args L.empty
           return out
       _ -> do
           let cmd = "curl"
               args = ["-s", "-g", uriToString' uri]
-          (_code, out, _err) <- readProcessWithExitCode cmd args B.empty
+          (_code, out, _err) <- readProcessWithExitCode cmd args L.empty
           return out
 
 -- | Parse the text returned when a directory is listed by a web
 -- server.  This is currently only known to work with Apache.
 -- NOTE: there is a second copy of this function in
 -- Extra:Extra.Net. Please update both locations if you make changes.
-webServerDirectoryContents :: B.ByteString -> [String]
+webServerDirectoryContents :: L.ByteString -> [String]
 webServerDirectoryContents text =
-    catMaybes . map (second . matchRegex re) . Prelude.lines . B.toString $ text
+    catMaybes . map (second . matchRegex re) . Prelude.lines . L.toString $ text
     where
       re = mkRegex "( <A HREF|<a href)=\"([^/][^\"]*)/\""
       second (Just [_, b]) = Just b
@@ -63,10 +81,10 @@
       ("ssh:", Just auth) ->
           do let cmd = "ssh"
                  args = [uriUserInfo auth ++ uriRegName auth ++ uriPort auth, "ls", "-1", uriPath uri]
-             (_code, out, _err) <- readProcessWithExitCode cmd args B.empty
-             return . Prelude.lines . B.toString $ out
+             (_code, out, _err) <- readProcessWithExitCode cmd args L.empty
+             return . Prelude.lines . L.toString $ out
       _ ->
           do let cmd = "curl"
                  args = ["-s", "-g", uriToString' uri]
-             (_code, out, _err) <- readProcessWithExitCode cmd args B.empty
+             (_code, out, _err) <- readProcessWithExitCode cmd args L.empty
              return . webServerDirectoryContents $ out
diff --git a/Debian/UTF8.hs b/Debian/UTF8.hs
new file mode 100644
--- /dev/null
+++ b/Debian/UTF8.hs
@@ -0,0 +1,26 @@
+-- | There are old index files that have funky characters like 'ø'
+-- that are not properly UTF8 encoded.  As far as I can tell, these
+-- files are otherwise plain ascii, so just naivelyinsert the
+-- character into the output stream.
+module Debian.UTF8
+    ( decode
+    , readFile
+    ) where
+
+import Control.Applicative ((<$>))
+import qualified Data.ByteString.Char8 as B (concat)
+import qualified Data.ByteString.Lazy.Char8 as L (ByteString, readFile, toChunks)
+import Data.Char (chr)
+import Data.Text as T
+import Data.Text.Encoding (decodeUtf8With)
+import Data.Word (Word8)
+import Prelude hiding (readFile)
+
+decode :: L.ByteString -> T.Text
+decode b = decodeUtf8With e (B.concat (L.toChunks b))
+    where
+      e :: String -> Maybe Word8 -> Maybe Char
+      e _description w = fmap (chr . fromIntegral) w
+
+readFile :: FilePath -> IO T.Text
+readFile path = decode <$> L.readFile path
diff --git a/Debian/Util/FakeChanges.hs b/Debian/Util/FakeChanges.hs
--- a/Debian/Util/FakeChanges.hs
+++ b/Debian/Util/FakeChanges.hs
@@ -6,8 +6,8 @@
 import Control.Monad hiding (mapM)
 import qualified Data.ByteString.Lazy.Char8 as L
 import qualified Data.Digest.Pure.MD5 as MD5
-import Data.Foldable
-import Data.List hiding (concat, foldr, all)
+import Data.Foldable (concat, all, foldr)
+import Data.List as List (intercalate, nub, partition, isSuffixOf)
 import Data.Maybe 
 --import Data.Typeable
 import Data.Data (Data, Typeable)
@@ -17,7 +17,7 @@
 import System.FilePath
 import System.Posix.Files
 import Text.Regex.TDFA
-import Prelude hiding (catch, concat, foldr, all, mapM)
+import Prelude hiding (concat, foldr, all, mapM, sum)
 import Network.BSD
 import Text.PrettyPrint.ANSI.Leijen (pretty)
 
@@ -163,7 +163,7 @@
       if singleton binArch
          then head binArch
          else case (filter (/= "all") binArch) of
-                [binArch] -> binArch
+                [b] -> b
                 _ -> error $ "Could not uniquely determine binary architecture: " ++ show binArch
 
 mkFileLine :: FilePath -> IO String
@@ -200,30 +200,30 @@
 
 loadFiles :: [FilePath] -> IO Files
 loadFiles files =
-       let (dscs, files'') = partition (isSuffixOf ".dsc") files'
-           (debs, files') = partition (isSuffixOf ".deb") files
-           (tars, files''') = partition (isSuffixOf ".tar.gz") files''
-           (diffs, rest) = partition (isSuffixOf ".diff.gz") files'''
-           errors = concat [ if (length debs  < 1) then [NoDebs] else []
-                           , if (length dscs  > 1) then [TooManyDscs dscs]   else []
-                           , if (length tars  > 1) then [TooManyTars tars]   else []
-                           , if (length diffs > 1) then [TooManyDiffs diffs] else []
+       let (dscs', files'') = partition (isSuffixOf ".dsc") files'
+           (debs', files') = partition (isSuffixOf ".deb") files
+           (tars', files''') = partition (isSuffixOf ".tar.gz") files''
+           (diffs', rest) = partition (isSuffixOf ".diff.gz") files'''
+           errors = concat [ if (length debs'  < 1) then [NoDebs] else []
+                           , if (length dscs'  > 1) then [TooManyDscs dscs']   else []
+                           , if (length tars'  > 1) then [TooManyTars tars']   else []
+                           , if (length diffs' > 1) then [TooManyDiffs diffs'] else []
                            , if (length rest  > 0) then [UnknownFiles rest]  else []
                            ]
        in
          do when (not . null $ errors) (error $ show errors)
-            dsc <- mapM loadDsc (listToMaybe dscs)
-            debs <- mapM loadDeb debs
-            return $ Files { dsc = dsc, debs = debs, tar = listToMaybe tars, diff = listToMaybe diffs }
+            dsc' <- mapM loadDsc (listToMaybe dscs')
+            debs'' <- mapM loadDeb debs'
+            return $ Files { dsc = dsc', debs = debs'', tar = listToMaybe tars', diff = listToMaybe diffs' }
          -- if (not . null $ errors) then throwDyn errors else return (debs, listToMaybe dscs, listToMaybe tars, listToMaybe diffs)
     where
       loadDsc :: FilePath -> IO (FilePath, Paragraph)
-      loadDsc dsc = 
-          do res <- parseControlFromFile dsc
+      loadDsc dsc' = 
+          do res <- parseControlFromFile dsc'
              case  res of
-               (Left e) -> error $ "Error parsing " ++ dsc ++ "\n" ++ show e
-               (Right (Control [p])) -> return (dsc, p)
-               (Right c) -> error $ dsc ++ " did not have exactly one paragraph: " ++ show (pretty c)
+               (Left e) -> error $ "Error parsing " ++ dsc' ++ "\n" ++ show e
+               (Right (Control [p])) -> return (dsc', p)
+               (Right c) -> error $ dsc' ++ " did not have exactly one paragraph: " ++ show (pretty c)
       loadDeb :: FilePath -> IO (FilePath, Paragraph)
       loadDeb deb =
           do res <- Deb.fields deb
@@ -239,8 +239,8 @@
               case dfn of
                 (Right n) -> return n
                 (Left (_ :: SomeException)) ->
-                    do dfn <-try (getEnv "USER")
-                       case dfn of
+                    do dfn' <-try (getEnv "USER")
+                       case dfn' of
                          (Right n) -> return n
                          (Left (_ :: SomeException)) -> error $ "Could not determine user name, neither DEBFULLNAME nor USER enviroment variables were set."
        emailAddr <-
@@ -248,8 +248,8 @@
               case eml of 
                 (Right e) -> return e
                 (Left (_ :: SomeException)) ->
-                    do eml <- try (getEnv "EMAIL")
-                       case eml of
+                    do eml' <- try (getEnv "EMAIL")
+                       case eml' of
                          (Right e) -> return e
                          (Left (_ :: SomeException)) -> getHostName -- FIXME: this is not a FQDN
        return $ debFullName ++ " <" ++ emailAddr ++ ">"
diff --git a/Debian/Version/Common.hs b/Debian/Version/Common.hs
--- a/Debian/Version/Common.hs
+++ b/Debian/Version/Common.hs
@@ -1,6 +1,6 @@
 -- |A module for parsing, comparing, and (eventually) modifying debian version
 -- numbers. <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version>
-{-# OPTIONS -fno-warn-orphans -fno-warn-unused-do-bind -Wall #-}
+{-# OPTIONS -fno-warn-orphans -fno-warn-unused-do-bind #-}
 module Debian.Version.Common
     (DebianVersion -- |Exported abstract because the internal representation is likely to change 
     , prettyDebianVersion
diff --git a/Debian/Version/Text.hs b/Debian/Version/Text.hs
new file mode 100644
--- /dev/null
+++ b/Debian/Version/Text.hs
@@ -0,0 +1,18 @@
+{-# OPTIONS -fno-warn-orphans #-}
+module Debian.Version.Text
+    ( ParseDebianVersion(..)
+    ) where
+
+import Text.ParserCombinators.Parsec
+
+import qualified Data.Text as T
+
+import Debian.Version.Common
+import Debian.Version.Internal
+    
+instance ParseDebianVersion T.Text where
+    parseDebianVersion text =
+        let str = T.unpack text in
+        case parse parseDV str str of
+          Left e -> error (show e)
+          Right dv -> DebianVersion str dv
diff --git a/Test/Changes.hs b/Test/Changes.hs
--- a/Test/Changes.hs
+++ b/Test/Changes.hs
@@ -1,11 +1,11 @@
 {-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS -fno-warn-missing-signatures -fno-warn-orphans #-}
 module Test.Changes where
 
 import Test.HUnit
-import Data.List (intercalate)
 import Debian.Changes
 import Debian.Release (ReleaseName(ReleaseName, relName))
-import Debian.Version (DebianVersion, prettyDebianVersion, parseDebianVersion)
+import Debian.Version (parseDebianVersion)
 import Text.PrettyPrint.ANSI.Leijen
 
 deriving instance Show ChangeLogEntry
diff --git a/Test/Control.hs b/Test/Control.hs
--- a/Test/Control.hs
+++ b/Test/Control.hs
@@ -1,33 +1,37 @@
-{-# LANGUAGE FlexibleInstances, StandaloneDeriving #-}
+{-# LANGUAGE FlexibleInstances, OverloadedStrings, StandaloneDeriving #-}
 module Test.Control where
 
 import Test.HUnit
 import Data.List (intercalate)
+import Data.Monoid ((<>))
+import Data.Text as T (Text, pack, intercalate)
 import Debian.Control
+import Debian.Control.Common (unControl)
 import Debian.Control.PrettyPrint (ppControl, ppParagraph)
-import Debian.Control.String ({- Pretty instances -})
+import Debian.Control.Text ({- Pretty instances -})
 import Text.PrettyPrint.ANSI.Leijen (pretty)
 
-deriving instance Eq (Control' String)
-deriving instance Show (Control' String)
-deriving instance Show (Paragraph' String)
-deriving instance Show (Field' String)
+deriving instance Eq (Control' Text)
+deriving instance Show (Control' Text)
+deriving instance Show (Paragraph' Text)
+deriving instance Show (Field' Text)
 
 -- Additional tests of the results of parsing additional
 -- inter-paragraph newlines, or missing terminating newlines, would be
 -- good.
 controlTests =
     [ TestCase (assertEqual "pretty1" control (either (error "parser failed") id (parseControl "debian/control" sample)))
-    , TestCase (assertEqual "pretty2" sample (show (ppControl control)))
-    , TestCase (assertEqual "pretty3" (head paragraphs ++ "\n") (show (ppParagraph (head (unControl control)))))
+    , TestCase (assertEqual "pretty2" sample (pack (show (ppControl control))))
+    , TestCase (assertEqual "pretty3" (head paragraphs <> "\n") (pack (show (ppParagraph (head (unControl control))))))
     -- The Pretty class instances are distinct implementations from
     -- those in Debian.Control.PrettyPrint.  Not sure why, there is a
     -- terse note about performance concerns.
-    , TestCase (assertEqual "pretty4" sample (show (pretty control)))
-    , TestCase (assertEqual "pretty5" (head paragraphs ++ "\n") (show (pretty (head (unControl control)))))  ]
+    , TestCase (assertEqual "pretty4" sample (pack (show (pretty control))))
+    , TestCase (assertEqual "pretty5" (head paragraphs <> "\n") (pack (show (pretty (head (unControl control))))))  ]
 
 -- | These paragraphs have no terminating newlines.  They are added
 -- where appropriate to the expected test results.
+paragraphs :: [Text]
 paragraphs =
     [ "Source: haskell-debian\nSection: haskell\nPriority: extra\nMaintainer: Debian Haskell Group <pkg-haskell-maintainers@lists.alioth.debian.org>\nUploaders: Joachim Breitner <nomeata@debian.org>\nBuild-Depends: debhelper (>= 7)\n  , cdbs\n  , haskell-devscripts (>= 0.7)\n  , ghc\n  , ghc-prof\n  , libghc-hunit-dev\n  , libghc-hunit-prof\n  , libghc-mtl-dev\n  , libghc-mtl-prof\n  , libghc-parsec3-dev\n  , libghc-parsec3-prof\n  , libghc-pretty-class-dev\n  , libghc-pretty-class-prof\n  , libghc-process-extras-dev (>= 0.4)\n  , libghc-process-extras-prof (>= 0.4)\n  , libghc-regex-compat-dev\n  , libghc-regex-compat-prof\n  , libghc-regex-tdfa-dev (>= 1.1.3)\n  , libghc-regex-tdfa-prof\n  , libghc-bzlib-dev (>= 0.5.0.0-4)\n  , libghc-bzlib-prof\n  , libghc-haxml-prof (>= 1:1.20)\n  , libghc-unixutils-dev (>= 1.50)\n  , libghc-unixutils-prof (>= 1.50)\n  , libghc-zlib-dev\n  , libghc-zlib-prof\n  , libghc-network-dev (>= 2.4)\n  , libghc-network-prof (>= 2.4)\n  , libghc-utf8-string-dev\n  , libghc-utf8-string-prof,\n  , libcrypto++-dev\nBuild-Depends-Indep: ghc-doc\n  , libghc-hunit-doc\n  , libghc-mtl-doc\n  , libghc-parsec3-doc\n  , libghc-pretty-class-doc\n  , libghc-process-extras-doc (>= 0.4)\n  , libghc-regex-compat-doc\n  , libghc-regex-tdfa-doc\n  , libghc-bzlib-doc\n  , libghc-haxml-doc (>= 1:1.20)\n  , libghc-unixutils-doc (>= 1.50)\n  , libghc-zlib-doc\n  , libghc-network-doc (>= 2.4)\n  , libghc-utf8-string-doc\nStandards-Version: 3.9.2\nHomepage: http://hackage.haskell.org/package/debian\nVcs-Darcs: http://darcs.debian.org/pkg-haskell/haskell-debian\nVcs-Browser: http://darcs.debian.org/cgi-bin/darcsweb.cgi?r=pkg-haskell/haskell-debian",
       "Package: libghc-debian-dev\nArchitecture: any\nDepends: ${haskell:Depends}\n  , ${shlibs:Depends}\n  , ${misc:Depends}\nRecommends: ${haskell:Recommends}\nSuggests: ${haskell:Suggests}\nProvides: ${haskell:Provides}\nDescription: Haskell library for working with the Debian package system\n This package provides a library for the Haskell programming language.\n See http://www.haskell.org/ for more information on Haskell.\n .\n This library includes modules covering almost every aspect of the Debian\n packaging system, including low level data types such as version numbers\n and dependency relations, on up to the types necessary for computing and\n installing build dependencies, building source and binary packages,\n and inserting them into a repository.\n .\n This package contains the libraries compiled for GHC 6.",
@@ -35,8 +39,8 @@
       "Package: libghc-debian-doc\nSection: doc\nArchitecture: all\nDepends: ${misc:Depends}, ${haskell:Depends}\nRecommends: ${haskell:Recommends}\nSuggests: ${haskell:Suggests}\nDescription: Documentation for Debian package system library\n This package provides the documentation for a library for the Haskell\n programming language.\n See http://www.haskell.org/ for more information on Haskell.\n .\n This library includes modules covering almost every aspect of the Debian\n packaging system, including low level data types such as version numbers\n and dependency relations, on up to the types necessary for computing and\n installing build dependencies, building source and binary packages,\n and inserting them into a repository.\n .\n This package contains the library documentation.",
       "Package: haskell-debian-utils\nSection: devel\nArchitecture: any\nDepends: ghc, ${misc:Depends}, ${shlibs:Depends}\nRecommends: apt-file\nDescription: Various helpers to work with Debian packages\n This package contains tools shipped with the Haskell library \8220debian\8221:\n .\n   * fakechanges:\n     Sometimes you have the .debs, .dsc, .tar.gz, .diff.gz, etc from a package\n     build, but not the .changes file. This package lets you create a fake\n     .changes file in case you need one.\n .\n   * debian-report:\n     Analyze Debian repositories and generate reports about their contents and\n     relations. For example, a list of all packages in a distribution that are\n     trumped by another distribution.\n .\n   * cabal-debian:\n     Tool for creating debianizations of Haskell packages based on the .cabal\n     file.  If apt-file is installed it will use it to discover what is the\n     debian package name of a C library.\n .\n   * apt-get-build-depends:\n     Tool which will parse the Build-Depends{-Indep} lines from debian/control\n     and apt-get install the required packages" ]
 
-sample :: String
-sample = intercalate "\n\n" paragraphs ++ "\n"
+sample :: Text
+sample = T.intercalate "\n\n" paragraphs <> "\n"
 
 -- | The expecte result of parsing the sample control file.
 control =
diff --git a/Test/Dependencies.hs b/Test/Dependencies.hs
--- a/Test/Dependencies.hs
+++ b/Test/Dependencies.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS -fno-warn-missing-signatures -fno-warn-orphans #-}
 module Test.Dependencies where
 
 import Control.Arrow
@@ -93,10 +94,10 @@
       (Just v) -> either (error . show) id (parseRelations v)
 
 mkCSP :: [[(String, String)]] -> String -> ([(String, String)] -> Relations) -> CSP [(String, String)]
-mkCSP paragraphs relStr depF =
+mkCSP paragraphs relStr depF' =
     CSP { pnm = addProvides providesF paragraphs $ packageNameMap getName paragraphs
         , relations = either (error . show) id (parseRelations relStr)
-        , depFunction = depF
+        , depFunction = depF'
         , conflicts = conflicts'
         , packageVersion = packageVersionParagraph
         }
@@ -134,9 +135,9 @@
 mapSnd f = map (second f)
 
 deriving instance Show Status
-deriving instance Show Relation
-deriving instance Show VersionReq
-deriving instance Show ArchitectureReq
+-- deriving instance Show Relation
+-- deriving instance Show VersionReq
+-- deriving instance Show ArchitectureReq
 
 test1 =
     let csp = mkCSP control "a" depends
diff --git a/Test/Versions.hs b/Test/Versions.hs
--- a/Test/Versions.hs
+++ b/Test/Versions.hs
@@ -1,3 +1,4 @@
+{-# OPTIONS -fno-warn-missing-signatures -fno-warn-orphans #-}
 module Test.Versions where
 
 import Test.HUnit
diff --git a/debian.cabal b/debian.cabal
--- a/debian.cabal
+++ b/debian.cabal
@@ -1,5 +1,5 @@
 Name:           debian
-Version:        3.70.1
+Version:        3.79.1
 License:        BSD3
 License-File:   debian/copyright
 Author:         David Fox <dsf@seereason.com>, Jeremy Shaw <jeremy@seereason.com>, Clifford Beshers <beshers@seereason.com>
@@ -14,7 +14,7 @@
   the Debian policy manual - version numbers, control file syntax, etc.
 extra-source-files:
   Test/Main.hs, Test/Changes.hs, Test/Dependencies.hs,
-  Test/SourcesList.hs, Test/VersionPolicy.hs, Test/Versions.hs, Test/Control.hs, debian/changelog
+  Test/SourcesList.hs, Test/VersionPolicy.hs, Test/Versions.hs, Test/Control.hs, debian/changelog, debian/changelog.pre-debian
 
 Flag cabal19
  Description: True if Cabal >= 1.9 is available
@@ -36,7 +36,7 @@
    parsec >= 2 && <4,
    pretty,
    process,
-   process-extras,
+   process-listlike,
    pureMD5,
    regex-compat,
    regex-tdfa,
@@ -46,7 +46,7 @@
    Unixutils >= 1.50,
    utf8-string,
    zlib
- ghc-options: -W -Wall -O2
+ ghc-options: -Wall -O2
  if flag(cabal19)
    build-depends: Cabal >= 1.9
    cpp-options: -DCABAL19
@@ -59,12 +59,14 @@
         Debian.Apt.Index,
         Debian.Apt.Methods,
         Debian.Apt.Package,
+        Debian.Arch,
         Debian.Changes,
         Debian.Control,
         Debian.Control.Common,
         Debian.Control.PrettyPrint,
         Debian.Control.ByteString,
         Debian.Control.String,
+        Debian.Control.Text,
         Debian.Deb,
         Debian.Extra.Files,
         Debian.GenBuildDeps,
@@ -72,15 +74,18 @@
         Debian.Relation.ByteString,
         Debian.Relation.Common,
         Debian.Relation.String,
+        Debian.Relation.Text,
         Debian.Release,
         Debian.Sources,
         Debian.Version,
+        Debian.Version.ByteString,
         Debian.Version.Common,
         Debian.Version.String,
-        Debian.Version.ByteString,
+        Debian.Version.Text,
         Debian.Report,
         Debian.Time,
         Debian.URI,
+        Debian.UTF8,
         Debian.Util.FakeChanges
  other-modules:
         Debian.Version.Internal,
@@ -127,4 +132,4 @@
 
 source-repository head
   type:     darcs
-  location: http://src.seereason.com/darcs/haskell-debian
+  location: http://src.seereason.com/haskell-debian
diff --git a/debian/changelog b/debian/changelog
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,77 @@
+haskell-debian (3.79.1) unstable; urgency=low
+
+  * Switch from using package process-extras to process-listlike.
+
+ -- David Fox <dsf@seereason.com>  Wed, 05 Jun 2013 06:22:26 -0700
+
+haskell-debian (3.79) unstable; urgency=low
+
+  * Efficiency fix for the Text instance of Debian.Control.
+  * Get rid of the Data.Text parser, instead parse the ByteString and
+    then decode the resulting control file.  Much faster I think.
+
+ -- David Fox <dsf@seereason.com>  Mon, 29 Apr 2013 21:33:55 -0700
+
+haskell-debian (3.78) unstable; urgency=low
+
+  * Change URI' to simplify its Read and Show instances, it is now just a
+    private constructor applied to a string for which parseURI was known
+    to succeed.
+  * Add changelog.pre-debian to the source file list
+
+ -- David Fox <dsf@seereason.com>  Sun, 28 Apr 2013 12:51:11 -0700
+
+haskell-debian (3.77) unstable; urgency=low
+
+  * Add a URI' type that is a wrapper around URI with working Read and
+    Show instances.
+
+ -- David Fox <dsf@seereason.com>  Fri, 26 Apr 2013 11:00:10 -0700
+
+haskell-debian (3.76) unstable; urgency=low
+
+  * Add Debian.UTF, with support for reading and decoding "almost-utf8" files
+
+ -- David Fox <dsf@seereason.com>  Thu, 25 Apr 2013 07:56:45 -0700
+
+haskell-debian (3.75) unstable; urgency=low
+
+  * If we get a UTF8 decoding error just insert the offending character
+    into the output stream.  There is an
+
+ -- David Fox <dsf@seereason.com>  Wed, 24 Apr 2013 15:30:30 -0700
+
+haskell-debian (3.74) unstable; urgency=low
+
+  * Add Debian.Relation.Text and Debian.Version.Text.
+
+ -- David Fox <dsf@seereason.com>  Tue, 23 Apr 2013 18:11:00 -0700
+
+haskell-debian (3.73) unstable; urgency=low
+
+  * Use Text instead of ByteString in the functions exported
+    by Debian.Control.
+
+ -- David Fox <dsf@seereason.com>  Tue, 23 Apr 2013 17:59:21 -0700
+
+haskell-debian (3.72) unstable; urgency=low
+
+  * Add Debian.Control.Text, Data.Text support for control files.
+
+ -- David Fox <dsf@seereason.com>  Tue, 23 Apr 2013 17:19:22 -0700
+
+haskell-debian (3.71) unstable; urgency=low
+
+  * Refine the ArchitectureReq type to parse things like !linux-any.
+
+ -- David Fox <dsf@seereason.com>  Sat, 13 Apr 2013 15:55:27 -0700
+
+haskell-debian (3.70.2) unstable; urgency=low
+
+  * Fix source repository location in cabal file.
+
+ -- David Fox <dsf@seereason.com>  Sat, 13 Apr 2013 11:11:45 -0700
+
 haskell-debian (3.70.1) unstable; urgency=low
 
   * Add Show and Read instances for DebianVersion.
diff --git a/debian/changelog.pre-debian b/debian/changelog.pre-debian
new file mode 100644
--- /dev/null
+++ b/debian/changelog.pre-debian
@@ -0,0 +1,625 @@
+haskell-debian (3.53) unstable; urgency=low
+
+  * Changes for unixutils-1.30
+  * Changes for unixutils-1.31
+
+ -- David Fox <dsf@seereason.com>  Sun, 26 Dec 2010 09:12:20 -0800
+
+haskell-debian (3.52) unstable; urgency=low
+
+  * Update to work with Cabal 1.10, shipped with ghc7.
+
+ -- David Fox <dsf@seereason.com>  Sat, 20 Nov 2010 07:54:52 -0800
+
+haskell-debian (3.51) unstable; urgency=low
+
+  * Remove dependency on haskell-utils, it is no longer in the repository.
+  * Change the doc package prefix generated by cabal-debian from haskell-
+    to libghc6-, this is the prefix chosen by the Debian packaging team.
+    and I believe that if haskell- is used the documentation ends up in
+    a directory in /usr/share/doc with the libghc6- prefix anyway.
+
+ -- David Fox <dsf@seereason.com>  Mon, 19 Jul 2010 10:37:39 -0700
+
+haskell-debian (3.50) unstable; urgency=low
+
+  * Switch back to regex-tdfa, regex-posix can't match extended ASCII
+    like "\250" =~ "[\249\250]"
+
+ -- David Fox <dsf@seereason.com>  Sun, 18 Jul 2010 22:34:13 +0100
+
+haskell-debian (3.49) unstable; urgency=low
+
+  * Add Show instances.
+
+ -- David Fox <dsf@seereason.com>  Fri, 16 Jul 2010 14:35:15 -0700
+
+haskell-debian (3.48) unstable; urgency=low
+
+  * Switch from regex-tdfa to regex-posix to avoid this failure, which
+    seems to have appeared going from 1.1.2 to 1.1.3:
+    "Explict error in module Text.Regex.TDFA.NewDFA : compressOrbit,1"
+
+ -- David Fox <dsf@seereason.com>  Fri, 16 Jul 2010 10:43:13 -0700
+
+haskell-debian (3.47) unstable; urgency=low
+
+  * require HaXml < 1.14
+
+ -- Jeremy Shaw <jeremy@seereason.com>  Wed, 05 May 2010 14:23:26 -0500
+
+haskell-debian (3.46) unstable; urgency=low
+
+  * Relax the Cabal >= 1.9 requirement by conditionalizing the code
+    that is affected by the change.
+  * Remove the applicative-extras dependency, instead of Failing a
+    use Either [String] a.
+  * Include Joachim Breitner's fixes for the Relation Ord instance.
+  * Do case insensitive field name comparisons in Debian.Control.
+
+ -- David Fox <dsf@seereason.com>  Tue, 04 May 2010 11:55:24 -0700
+
+haskell-debian (3.45) unstable; urgency=low
+
+  * Don't require targets to be Show instance in GenBuildDeps.buildable.
+  * Eliminate use of OldException.
+
+ -- David Fox <dsf@seereason.com>  Fri, 19 Feb 2010 06:47:04 -0800
+
+haskell-debian (3.44) unstable; urgency=low
+
+  * Add a rule to debian/rules to install the executables.
+
+ -- David Fox <dsf@seereason.com>  Thu, 18 Feb 2010 12:16:18 -0800
+
+haskell-debian (3.43) unstable; urgency=low
+
+  * Add a strict version of fileFromURI.
+  * Catch errors thrown by hGetContents when reading control files
+
+ -- David Fox <dsf@seereason.com>  Sat, 02 Jan 2010 12:29:45 -0800
+
+haskell-debian (3.42) unstable; urgency=low
+
+  * Fix signature regex so we always split at the first pair of spaces.
+
+ -- David Fox <dsf@seereason.com>  Tue, 29 Dec 2009 19:25:27 -0800
+
+haskell-debian (3.41) unstable; urgency=low
+
+  * Use Text.Regex.TDFA for parsing changelog instead of Text.Regex.Compat, it
+    can handle Unicode.
+  * Run unit tests during build, add some changelog unit tests.
+
+ -- David Fox <dsf@seereason.com>  Tue, 29 Dec 2009 12:22:40 -0800
+
+haskell-debian (3.40) unstable; urgency=low
+
+  * Remove the now unused Extra.CIO and Debian.Extra.CIO modules
+
+ -- David Fox <dsf@seereason.com>  Mon, 14 Sep 2009 09:41:52 -0700
+
+haskell-debian (3.39) unstable; urgency=low
+
+  * Remove dependency on Extra
+  * Remove debian directory from .cabal
+
+ -- Jeremy Shaw <jeremy@seereason.com>  Wed, 09 Sep 2009 11:57:03 -0500
+
+haskell-debian (3.38) unstable; urgency=low
+
+  * Use parsec 3
+
+ -- Jeremy Shaw <jeremy@seereason.com>  Tue, 28 Jul 2009 19:12:03 -0500
+
+haskell-debian (3.37) unstable; urgency=low
+
+  * Escape the vendor tag before embedding it in a regular expression.
+    (I wrote an escapeForRegex that only escapes +, the character I want
+    to use right now.  This function should be available somewhere in the
+    haskell standard libraries, right?)
+  * Moved the VersionPolicy module to haskell-debian-repo.
+
+ -- David Fox <dsf@seereason.com>  Thu, 23 Jul 2009 07:38:00 -0700
+
+haskell-debian (3.36) unstable; urgency=low
+
+  * Make the changelog parser more liberal, allow a tab character at
+    the beginning of a text line instead of two spaces.  This parses
+    the new changelog entry for hscolour.
+
+ -- David Fox <dsf@seereason.com>  Tue, 21 Jul 2009 06:45:24 -0700
+
+haskell-debian (3.35) unstable; urgency=low
+
+  * removed dependencies on Extra.HaXml
+  * Updated to base >= 4 && < 5
+  * Fixed test suite
+
+ -- Jeremy Shaw <jeremy@seereason.com>  Wed, 01 Jul 2009 09:48:00 -0500
+
+haskell-debian (3.34) unstable; urgency=low
+
+  * cabal-debian: move -doc packages to Build-Depends-Indep
+  * cabal-debian: properly nub Build-Depends and Build-Depends-Indep
+
+ -- Jeremy Shaw <jeremy@seereason.com>  Sun, 03 May 2009 12:15:52 -0500
+
+haskell-debian (3.33) unstable; urgency=low
+
+  * cabal-debian: Setion: libdevel -> haskell
+
+ -- Jeremy Shaw <jeremy@seereason.com>  Thu, 16 Apr 2009 16:22:35 -0500
+
+haskell-debian (3.32) unstable; urgency=low
+
+  * Add fields to Debian.Changes.ChangedFileSpec for SHA1 and SHA256
+    checksums.
+
+ -- David Fox <dsf@seereason.com>  Fri, 03 Apr 2009 07:14:59 -0700
+
+haskell-debian (3.31) unstable; urgency=low
+
+  * update to use newer haskell-devscripts which includes hlibrary.mk
+  * change libghc6-*-doc to haskell-*-doc
+  * move haskell-*-doc to Section: doc
+  * build haskell-*-doc for Architecture 'all' instead of 'any'
+  * make ghc6-doc and haddock Build-Depends-Indep
+  * update Standards-Version to 3.8.1
+  * depend on cdbs and haskell-devscripts instead of haskell-cdbs
+  * only use one space at the beginning of lines in the long description
+  * add ${misc:Depends} to Depends lines
+
+ -- Jeremy Shaw <jeremy@seereason.com>  Mon, 23 Mar 2009 20:18:41 -0500
+
+haskell-debian (3.30) unstable; urgency=low
+
+  * Move the modules for dealing with the repository into a new package
+    named haskell-debian-repo.  The cabal-debian tool remains in this
+    package, so this split means that the repo package can change without
+    triggering massive rebuilding due to build dependencies on
+    cabal-debian.
+
+ -- David Fox <dsf@seereason.com>  Wed, 18 Feb 2009 06:36:25 -0800
+
+haskell-debian (3.29) unstable; urgency=low
+
+  * Add System.Chroot to list of exported modules
+  * Reduce number of modules loaded by CabalDebian.
+
+ -- David Fox <dsf@seereason.com>  Tue, 10 Feb 2009 17:06:47 -0800
+
+haskell-debian (3.28) unstable; urgency=low
+
+  * Add System.Chroot.useEnv, and use it to allow contact with the ssh
+    agent from inside of changeroots.
+
+ -- David Fox <dsf@seereason.com>  Mon, 09 Feb 2009 11:18:59 -0800
+
+haskell-debian (3.27) unstable; urgency=low
+
+  * Added apt-get-build-deps. not librarized yet :(
+
+ -- Jeremy Shaw <jeremy@seereason.com>  Fri, 06 Feb 2009 18:52:36 -0600
+
+haskell-debian (3.26) unstable; urgency=low
+
+  * Improve the code that decides whether the sources.list has changed,
+    to avoid recreating the build environment as often.
+
+ -- David Fox <dsf@seereason.com>  Thu, 05 Feb 2009 08:56:32 -0800
+
+haskell-debian (3.25) unstable; urgency=low
+
+  * Use State monad instead of RWS monad for AptIO
+  * Rename IOState to AptState
+
+ -- David Fox <dsf@seereason.com>  Wed, 04 Feb 2009 09:34:24 -0800
+
+haskell-debian (3.24) unstable; urgency=low
+
+  * Use Data.Time instead of System.Time
+  * Fix code to compute the elapsed time for the dpkg-buildpackage.
+  * Restore some generated dependencies that got dropped out of
+    cabal-debian.
+
+ -- David Fox <dsf@seereason.com>  Sat, 31 Jan 2009 08:45:51 -0800
+
+haskell-debian (3.23) unstable; urgency=low
+
+  * Eliminate the use of EnvPath in most places, just use a regular
+    path instead.  There were very few places where we actually were
+    inside a changeroot.
+
+ -- David Fox <dsf@seereason.com>  Thu, 29 Jan 2009 16:48:23 -0800
+
+haskell-debian (3.22) unstable; urgency=low
+
+  * cabal-debian now has autodetection of ghc6 bundled packages
+
+ -- Jeremy Shaw <jeremy@seereason.com>  Thu, 29 Jan 2009 15:26:25 -0600
+
+haskell-debian (3.21) unstable; urgency=low
+
+  * Don't write out postinst and postrm for the doc package, they are
+    now automatically added by haskell-cdbs.
+
+ -- David Fox <dsf@seereason.com>  Tue, 27 Jan 2009 10:14:20 -0800
+
+haskell-debian (3.20) unstable; urgency=low
+
+  * Modify the buildable function in GenBuildDeps so it returns more
+    info about the ready packages and what packages each one blocks.
+
+ -- David Fox <dsf@seereason.com>  Tue, 27 Jan 2009 06:55:39 -0800
+
+haskell-debian (3.19) unstable; urgency=low
+
+  * Make cabal-debian depend on haskell-cdbs, it used to be the opposite.
+
+ -- David Fox <dsf@seereason.com>  Sun, 25 Jan 2009 15:22:41 -0800
+
+haskell-debian (3.18) unstable; urgency=low
+
+  * Modify cabal-debian to it creates debianizations that use the new
+    haskell-cdbs package instead of our modified haskell-devscripts with
+    the cdbs file hlibrary.mk added in.
+  * Have cabal-debian explain what changes it is making to the dependency
+    list.
+
+ -- David Fox <dsf@seereason.com>  Sat, 24 Jan 2009 07:27:47 -0800
+
+haskell-debian (3.17) unstable; urgency=low
+
+  * Have cabal-debian --substvar print its result to stderr.
+
+ -- David Fox <dsf@seereason.com>  Fri, 23 Jan 2009 10:33:48 -0800
+
+haskell-debian (3.16) unstable; urgency=low
+
+  * Back out register/unregister stuff, just have cabal-debian die if the
+    package doesn't have a library section.
+
+ -- David Fox <dsf@seereason.com>  Thu, 22 Jan 2009 15:33:43 -0800
+
+haskell-debian (3.15) unstable; urgency=low
+
+  * Don't leave package registered after computing lbi.
+
+ -- David Fox <dsf@seereason.com>  Thu, 22 Jan 2009 14:19:23 -0800
+
+haskell-debian (3.14) unstable; urgency=low
+
+  * Fix a bug that resulted in a fromJust Nothing error.
+
+ -- David Fox <dsf@seereason.com>  Thu, 22 Jan 2009 09:59:16 -0800
+
+haskell-debian (3.13) unstable; urgency=low
+
+  * Add the cabal-debian executable to this package to ease bootstrapping.
+
+ -- David Fox <dsf@seereason.com>  Fri, 16 Jan 2009 06:41:40 -0800
+
+haskell-debian (3.12) unstable; urgency=low
+
+  * Export some functions and types from Debian.Apt.Index that were
+    already being used by other applications
+  * Allow relation parser to skip empty relations like such as: a, ,c
+
+ -- Jeremy Shaw <jeremy@n-heptane.com>  Fri, 09 Jan 2009 18:22:09 -0600
+
+haskell-debian (3.11) unstable; urgency=low
+
+  * Gather code to retrieve the text an URI points to into the Debian.URI
+    module.
+
+ -- David Fox <dsf@seereason.com>  Tue, 04 Nov 2008 13:53:33 -0800
+
+haskell-debian (3.10) unstable; urgency=low
+
+  * Change name and arch of doc package.
+
+ -- David Fox <dsf@seereason.com>  Sat, 20 Sep 2008 12:07:38 -0700
+
+haskell-debian (3.9) unstable; urgency=low
+
+  * Compute exactly which packages participate in dependency cycles.
+
+ -- David Fox <dsf@seereason.com>  Mon, 18 Aug 2008 12:42:56 -0700
+
+haskell-debian (3.8) unstable; urgency=low
+
+  * Don't add an extra newline at the end of the Files section when
+    editing the .changes file.
+
+ -- David Fox <dsf@seereason.com>  Mon, 21 Jul 2008 10:57:49 -0700
+
+haskell-debian (3.7) unstable; urgency=low
+
+  * Eliminate all direct uses of TIO, we always use CIO m => so
+    that all functions can be called from the regular IO monad.
+
+ -- David Fox <dsf@seereason.com>  Sat, 19 Jul 2008 10:27:49 -0700
+
+haskell-debian (3.6) unstable; urgency=low
+
+  * Remove useless arguments from insertRelease.
+  * Replace debianization
+
+ -- David Fox <dsf@seereason.com>  Tue, 01 Jul 2008 10:41:22 -0700
+
+haskell-debian (3.5) unstable; urgency=low
+
+  * Debianization generated by cabal-debian
+
+ -- David Fox <dsf@seereason.com>  Sat, 28 Jun 2008 15:49:07 -0700
+
+haskell-debian (3.4) unstable; urgency=low
+
+  * Even correcter code for doing Relax-Depends.  The relaxDeps function
+    is now seperate from the other build depenency functions, which makes
+    things a bit simpler and easier to document.
+
+ -- David Fox <dsf@seereason.com>  Wed, 18 Jun 2008 21:00:36 +0000
+
+haskell-debian (3.3) unstable; urgency=low
+
+  * Add code to correctly implement Relax-Depends for non-global
+    dependencies.
+
+ -- David Fox <dsf@seereason.com>  Sat, 31 May 2008 07:31:15 +0000
+
+haskell-debian (3.2) unstable; urgency=low
+
+  * Redo the buildable function in GenBuildDeps.
+  * Improve message from OSImage.updateLists.
+
+ -- David Fox <dsf@seereason.com>  Sat, 24 May 2008 13:06:09 +0000
+
+haskell-debian (3.1-1) unstable; urgency=low
+
+  * Version number follies.
+
+ -- David Fox <dsf@seereason.com>  Thu, 22 May 2008 16:18:47 -0700
+
+haskell-debian (3.1) unstable; urgency=low
+
+  * Re-worked the build dependency computation
+
+ -- David Fox <dsf@seereason.com>  Thu, 22 May 2008 10:59:22 -0700
+
+haskell-debian (3.0) unstable; urgency=low
+
+  * Re-organization of module heirarchy.
+
+ -- David Fox <dsf@seereason.com>  Mon, 19 May 2008 12:47:25 -0700
+
+haskell-debian (2.28) unstable; urgency=low
+
+  * Eliminate use of haskell-ugly library.
+
+ -- David Fox <dsf@seereason.com>  Wed, 14 May 2008 12:30:40 -0700
+
+haskell-debian (2.27) unstable; urgency=low
+
+  * Changes for switch to lazy bytestrings in haskell-unixutils.
+
+ -- David Fox <dsf@seereason.com>  Tue, 06 May 2008 05:52:51 -0700
+
+haskell-debian (2.26) unstable; urgency=low
+
+  * Improve error report from "Missing control file or changelog"
+
+ -- David Fox <dsf@seereason.com>  Mon, 05 May 2008 05:59:27 -0700
+
+haskell-debian (2.25) unstable; urgency=low
+
+  * Packaging changes for haskell-devscripts 0.6.10.
+
+ -- David Fox <dsf@seereason.com>  Sat, 29 Mar 2008 10:25:54 -0700
+
+haskell-debian (2.24) unstable; urgency=low
+
+  * New version of dupload reads both /etc/dupload.conf and ~/.dupload.conf, so
+    we have to explicitly unset $preupload in ~/.dupload.conf.
+
+ -- David Fox <dsf@seereason.com>  Tue, 25 Mar 2008 05:49:08 -0700
+
+haskell-debian (2.23) unstable; urgency=low
+
+  * Fix a divide by zero error in Debian.Shell.  This should also improve
+    the behavior of the code that outputs one dot per 128 characters of
+    shell command output.
+
+ -- David Fox <dsf@seereason.com>  Wed, 12 Mar 2008 16:55:59 +0000
+
+haskell-debian (2.22) unstable; urgency=low
+
+  * Add a chars/dot argument to Shell.dotOutput
+  * Moved some functions from Shell to haskell-unixutils
+  * Moved TIO module to haskell-extra
+
+ -- David Fox <dsf@seereason.com>  Sun, 02 Mar 2008 10:14:13 -0800
+
+haskell-debian (2.21) unstable; urgency=low
+
+  * Change some writeFile calls to avoid lazyness in evaluating the
+    second argument, which appears to lead to locked file errors.
+
+ -- David Fox <dsf@seereason.com>  Sun, 24 Feb 2008 11:06:53 -0800
+
+haskell-debian (2.20) unstable; urgency=low
+
+  * Message Improvements
+  * Discard duplicate dependency relations
+  * Fix rfc822DateFormat
+
+ -- Jeremy Shaw <jeremy@n-heptane.com>  Wed, 20 Feb 2008 13:34:34 -0800
+
+haskell-debian (2.19) unstable; urgency=low
+
+  * Added more functions for working with index files
+
+ -- Jeremy Shaw <jeremy@n-heptane.com>  Tue, 19 Feb 2008 16:07:46 -0800
+
+haskell-debian (2.18) unstable; urgency=low
+
+  * Hack: Debian.Local.Insert.addPackagesToIndexes work-around for optimizer bug
+  * Debian.Package: use controlFromIndex instead of calling zcat
+
+ -- Jeremy Shaw <jeremy@n-heptane.com>  Mon, 11 Feb 2008 23:08:30 -0800
+
+haskell-debian (2.17) unstable; urgency=low
+
+  * TIO module fixes and cleanups.
+
+ -- David Fox <dsf@seereason.com>  Thu, 07 Feb 2008 05:45:00 -0800
+
+haskell-debian (2.16) unstable; urgency=low
+
+  * Add setRepoMap to install cached repository info
+  * Print more info about what happened when a repository appears not to exist.
+
+ -- David Fox <ddssff@gmail.com>  Wed, 06 Feb 2008 16:00:45 -0800
+
+haskell-debian (2.15) unstable; urgency=low
+
+  * Fix bug in Debian.VersionPolicy
+  * Split a simple TIO monad out of the AptIO monad.
+  * Simplify Repository type, eliminate parameterized Release etc.
+  * Improve type safety of the SourcesList related types
+
+ -- David Fox <ddssff@gmail.com>  Wed, 06 Feb 2008 05:38:12 -0800
+
+haskell-debian (2.14) unstable; urgency=low
+
+  * Rewrite of Debian.VersionPolicy.
+  * Run unit tests during build
+
+ -- David Fox <ddssff@gmail.com>  Mon, 28 Jan 2008 13:07:00 -0800
+
+haskell-debian (2.13) unstable; urgency=low
+
+  * Improvements in code currently used to compute the build dependencies.
+    This allows builds of packages which previously caused an combinatoric
+    explosion in memory and time use.  The specific modifications are to
+    avoid making a huge list of all the solution candidates that failed,
+    and to put the relations into a normal form which only involves equals
+    dependencies on packages that are actually available for installation.
+    Finally, a bug in handling of architecture specific dependencies was
+    fixed which might have been causing the extremely long and fruitless
+    searches for some packages' build dependencies.
+
+ -- David Fox <ddssff@gmail.com>  Sat, 19 Jan 2008 19:28:32 +0000
+
+haskell-debian (2.12) unstable; urgency=low
+
+  * Add Debian.Apt.Dependecies and Debian.Apt.Package to debian.cabal
+
+ -- Jeremy Shaw <jeremy.shaw@linspireinc.com>  Fri, 18 Jan 2008 17:13:24 -0800
+
+haskell-debian (2.11) unstable; urgency=low
+
+  * Added trump detector
+  * Added code to find parents and siblings of a binary package from the
+    Packages/Sources files
+  * Packaging updates
+
+ -- Jeremy Shaw <jeremy.shaw@linspireinc.com>  Fri, 14 Dec 2007 13:55:20 -0800
+
+haskell-debian (2.10) unstable; urgency=low
+
+  * Added new interface, Apt.Debian.Methods.fetch which allows the UI
+    portion of fetching (status, authentication), to be controlled by
+    providing a set of callback functions.
+
+ -- Jeremy Shaw <jeremy.shaw@linspireinc.com>  Tue, 20 Nov 2007 14:07:43 -0800
+
+haskell-debian (2.9) unstable; urgency=low
+
+  * Add caching of loaded package indexes based on the path and the
+    file status of the cached index file.  Also splits Debian.Types
+    into several modules.
+
+ -- David Fox <dsf@seereason.org>  Fri,  9 Nov 2007 11:05:11 -0800
+
+haskell-debian (2.8) unstable; urgency=low
+
+  * Last version had bogus dependencies due to an unknown build error.
+    Make loading of package indexes less lazy in an attempt to reduce
+    memory usage.
+
+ -- David Fox <dsf@seereason.org>  Wed,  7 Nov 2007 10:54:27 -0800
+
+haskell-debian (2.7) unstable; urgency=low
+
+  * Make loading of package indexes lazy.
+
+ -- David Fox <dsf@seereason.org>  Mon, 22 Oct 2007 11:11:34 -0700
+
+haskell-debian (2.6) unstable; urgency=low
+
+  * Pass --immediate-configure-false to build-env so we can create
+    environments for gutsy, lenny, and sid.
+
+ -- David Fox <dsf@seereason.org>  Sat, 20 Oct 2007 16:17:59 -0700
+
+haskell-debian (2.5) unstable; urgency=low
+
+  * Reduce amount of apt-get updating that occurs.
+
+ -- David Fox <ddssff@gmail.com>  Sat, 20 Oct 2007 13:50:25 +0000
+
+haskell-debian (2.4) unstable; urgency=low
+
+  * Fix parsing of version tags in VersionPolicy.  It was always failing
+    and therefore not understanding versions we had generated.
+
+ -- David Fox <ddssff@gmail.com>  Sat, 13 Oct 2007 04:44:39 -0700
+
+haskell-debian (2.3) unstable; urgency=low
+
+  * The EnvPath and EnvRoot types had show methods that were not
+    invertable by read.  Now they use deriving Show, and use rootPath
+    and the new outsidePath to convert EnvRoot and EnvPath to the
+    FilePath type.  This is a big looking change, but safe.
+  * Replace code that looked at the "Package" and "Version" fields
+    of a parsed control file with calls to packageName and
+    packageVersion, which just returns values already computed and
+    saved in the Package object.
+  * Use EnvPath instead of FilePath in places where it makes sense, such
+    as the copyDebianBuildTree and other places in Debian.SourceTree.
+    This change propagated down in various places, and the cutoff may be
+    a little out of whack in some places, but it is all typesafe (and
+    therefore wonderful?)
+
+ -- David Fox <ddssff@gmail.com>  Thu, 11 Oct 2007 15:43:03 +0000
+
+haskell-debian (2.2) unstable; urgency=low
+
+  * Fix a bug in parsing of dependency relations when there is
+    whitespace after a right square brace.
+
+ -- David Fox <ddssff@gmail.com>  Tue,  9 Oct 2007 21:00:24 +0000
+
+haskell-debian (2.1) unstable; urgency=low
+
+  * Fix show method of SliceList, the elements need to be
+    terminated by newlines.
+
+ -- David Fox <ddssff@gmail.com>  Fri,  5 Oct 2007 00:11:33 -0700
+
+haskell-debian (2.0) unstable; urgency=low
+
+  * Change Apt. to Debian.
+  * Added Debian.Apt.Methods
+  * Added Debian.Deb
+  * Added Debian.Time
+
+ -- Jeremy Shaw <jeremy.shaw@linspire.com>  Wed, 19 Sep 2007 15:14:10 -0700
+
+haskell-apt (1.0) unstable; urgency=low
+
+  * Initial Debian package.
+
+ -- David Fox <ddssff@gmail.com>  Tue, 18 Sep 2007 09:33:24 -0700
