diff --git a/Distribution/Package/Debian.hs b/Distribution/Package/Debian.hs
new file mode 100644
--- /dev/null
+++ b/Distribution/Package/Debian.hs
@@ -0,0 +1,752 @@
+{-# LANGUAGE CPP, ScopedTypeVariables, TupleSections, TypeSynonymInstances #-}
+{-# OPTIONS -Wall -fno-warn-name-shadowing #-}
+
+-- |
+-- Module      :  Distribution.Package.Debian
+-- Copyright   :  David Fox 2008
+--
+-- Maintainer  :  David Fox <dsf@seereason.com>
+-- Stability   :  alpha
+-- Portability :  portable
+--
+-- Explanation: Support for generating Debianization from Cabal data.
+
+-- This software may be used and distributed according to the terms of
+-- the GNU General Public License, incorporated herein by reference.
+
+module Distribution.Package.Debian
+    ( debian
+    ) where
+
+-- import Debug.Trace
+
+import Codec.Binary.UTF8.String (decodeString)
+import Control.Arrow (second)
+import Control.Exception (SomeException, try, bracket, IOException)
+import Control.Monad (when,mplus)
+import Control.Monad.Reader (ReaderT(runReaderT), ask)
+import Control.Monad.Trans (lift)
+import Data.Char (isSpace)
+import Data.Either (partitionEithers)
+import Data.List
+import qualified Data.Map as Map
+import Data.Maybe
+import qualified Data.Set as Set
+import Data.Version (showVersion)
+import Debian.Control
+import qualified Debian.Relation as D
+import Debian.Release (parseReleaseName)
+import Debian.Changes (ChangeLogEntry(..), prettyEntry, parseLog)
+import Debian.Time (getCurrentLocalRFC822Time)
+import Debian.Version (DebianVersion, prettyDebianVersion)
+import Debian.Version.String
+import System.Cmd (system)
+import System.Directory
+import System.Exit (ExitCode(..))
+import System.FilePath ((</>), dropExtension)
+import System.IO (IOMode (ReadMode), hGetContents, hPutStrLn, hSetBinaryMode, openFile, stderr, withFile)
+import System.IO.Error (ioeGetFileName, isDoesNotExistError)
+import System.Posix.Files (setFileCreationMask)
+import System.Environment
+
+import Distribution.Text (display)
+import Distribution.Simple.Compiler (CompilerFlavor(..), compilerFlavor, Compiler(..), CompilerId(..))
+import Distribution.System (Platform(..), buildOS, buildArch)
+import Distribution.License (License(..))
+import Distribution.Package (Package(..), PackageIdentifier(..), PackageName(..), Dependency(..))
+import Distribution.Simple.Program (defaultProgramConfiguration)
+import Distribution.Simple.Configure (configCompiler)
+import Distribution.Simple.Utils (die, setupMessage)
+import Distribution.PackageDescription (GenericPackageDescription(..), PackageDescription(..), exeName)
+import Distribution.PackageDescription.Configuration (finalizePackageDescription)
+--import Distribution.ParseUtils (parseQuoted)
+import Distribution.Verbosity (Verbosity)
+import Distribution.Package.Debian.Dependencies (PackageType(..), debianExtraPackageName, debianUtilsPackageName, debianSourcePackageName, debianDocPackageName,
+                                                 {-DebianBinPackageName,-} debianDevPackageName, debianProfPackageName)
+import Distribution.Package.Debian.Relations (versionSplits)
+import Distribution.Package.Debian.Setup (Flags(..), DebAction(..), DebType(..))
+--import qualified Distribution.Compat.ReadP as ReadP
+--import Distribution.Text ( Text(parse) )
+import Text.PrettyPrint.HughesPJ
+
+import Distribution.Package.Debian.Relations (buildDependencies, docDependencies, allBuildDepends, cabalDependencies)
+
+{-
+_parsePackageId' :: ReadP.ReadP PackageIdentifier PackageIdentifier
+_parsePackageId' = parseQuoted parse ReadP.<++ parse
+-}
+
+type DebMap = Map.Map D.BinPkgName (Maybe DebianVersion)
+
+buildDebVersionMap :: IO DebMap
+buildDebVersionMap =
+    readFile "/var/lib/dpkg/status" >>=
+    return . either (const []) unControl . parseControl "/var/lib/dpkg/status" >>=
+    mapM (\ p -> case (lookupP "Package" p, lookupP "Version" p) of
+                   (Just (Field (_, name)), Just (Field (_, version))) ->
+                       return (Just (D.BinPkgName (D.PkgName (stripWS name)), Just (parseDebianVersion (stripWS version))))
+                   _ -> return Nothing) >>=
+    return . Map.fromList . catMaybes
+
+(!) :: DebMap -> D.BinPkgName -> DebianVersion
+m ! k = maybe (error ("No version number for " ++ (show . D.prettyBinPkgName $ k) ++ " in " ++ show (Map.map (maybe Nothing (Just . prettyDebianVersion)) m))) id (Map.findWithDefault Nothing k m)
+
+trim :: String -> String
+trim = dropWhile isSpace
+
+simplePackageDescription :: GenericPackageDescription -> Flags
+                         -> IO (Compiler, PackageDescription)
+simplePackageDescription genPkgDesc flags = do
+    (compiler', _) <- {- fchroot (buildRoot flags) -} (configCompiler (Just (rpmCompiler flags)) Nothing Nothing
+                                                               defaultProgramConfiguration
+                                                               (rpmVerbosity flags))
+    let compiler = case (rpmCompilerVersion flags, rpmCompiler flags) of
+                     (Just v, ghc) -> compiler' {compilerId = CompilerId ghc v}
+                     _ -> compiler'
+    --installed <- installedPackages
+    case finalizePackageDescription (rpmConfigurationsFlags flags)
+          (const True) (Platform buildArch buildOS) (compilerId compiler)
+          {- (Nothing :: Maybe PackageIndex) -}
+          [] genPkgDesc of
+      Left e -> die $ "finalize failed: " ++ show e
+      Right (pd, _) -> return (compiler, pd)
+    
+debian :: GenericPackageDescription	-- ^ info from the .cabal file
+       -> Flags				-- ^ command line flags
+       -> IO ()
+
+debian genPkgDesc flags =
+    case rpmCompiler flags of
+      GHC ->
+          do (compiler, pkgDesc) <- simplePackageDescription genPkgDesc flags
+             let verbose = rpmVerbosity flags
+             createDirectoryIfMissing True (debOutputDir flags)
+             --lbi <- localBuildInfo pkgDesc flags
+             debVersions <- buildDebVersionMap
+             cabalPackages <- libPaths compiler debVersions >>= return . Map.fromList . map (\ p -> (cabalName p, p))
+             bracket (setFileCreationMask 0o022) setFileCreationMask $ \ _ -> do
+               autoreconf verbose pkgDesc
+               case debAction flags of
+                 SubstVar name ->
+                     do control <- readFile "debian/control" >>= either (error . show) return . parseControl "debian/control"
+                        substvars flags pkgDesc compiler debVersions control cabalPackages name
+                 Debianize ->
+                     debianize True pkgDesc flags compiler (debOutputDir flags)
+                 UpdateDebianization ->
+                     updateDebianization True pkgDesc flags compiler (debOutputDir flags)
+                 Usage ->
+                     error "Unexpected debAction: usage"
+      c -> die ("the " ++ show c ++ " compiler is not yet supported")
+
+autoreconf :: Verbosity -> PackageDescription -> IO ()
+
+autoreconf verbose pkgDesc = do
+    ac <- doesFileExist "configure.ac"
+    when ac $ do
+        c <- doesFileExist "configure"
+        when (not c) $ do
+            setupMessage verbose "Running autoreconf" (packageId pkgDesc)
+            ret <- system "autoreconf"
+            case ret of
+              ExitSuccess -> return ()
+              ExitFailure n -> die ("autoreconf failed with status " ++ show n)
+
+data PackageInfo = PackageInfo { libDir :: FilePath
+                               , cabalName :: String
+                               , cabalVersion :: String
+                               , devDeb :: Maybe (D.BinPkgName, DebianVersion)
+                               , profDeb :: Maybe (D.BinPkgName, DebianVersion)
+                               , docDeb :: Maybe (D.BinPkgName, DebianVersion) }  
+
+-- |Each cabal package corresponds to a directory <name>-<version>,
+-- either in /usr/lib or in /usr/lib/haskell-packages/ghc/lib.
+-- In that directory is a compiler subdirectory such as ghc-6.8.2.
+-- In the ghc subdirectory is one or two library files of the form
+-- libHS<name>-<version>.a and libHS<name>-<version>_p.a.  We can
+-- determine the debian package names by running dpkg -S on these
+-- names, or examining the /var/lib/dpkg/info/\*.list files.  From
+-- these we can determine the source package name, and from that
+-- the documentation package name.
+substvars :: Flags
+          -> PackageDescription		-- ^info from the .cabal file
+          -> Compiler   		-- ^compiler details
+          -> DebMap
+          -> Control			-- ^The debian/control file
+          -> Map.Map String PackageInfo	-- ^The list of installed cabal packages
+          -> DebType			-- ^The type of deb we want to write substvars for
+          -> IO ()
+substvars flags pkgDesc _compiler _debVersions control cabalPackages debType =
+    case (missingBuildDeps, path) of
+      -- There should already be a .substvars file produced by dh_haskell_prep,
+      -- keep the relations listed there.  They will contain something like this:
+      -- libghc-cabal-debian-prof.substvars:
+      --    haskell:Depends=ghc-prof (<< 6.8.2-999), ghc-prof (>= 6.8.2), libghc-cabal-debian-dev (= 0.4)
+      -- libghc-cabal-debian-dev.substvars:
+      --    haskell:Depends=ghc (<< 6.8.2-999), ghc (>= 6.8.2)
+      -- haskell-cabal-debian-doc.substvars:
+      --    haskell:Depends=ghc-doc, haddock (>= 2.1.0), haddock (<< 2.1.0-999)
+      ([], Just path') ->
+          do old <- try (readFile path') >>= return . either (\ (_ :: SomeException) -> "") id
+             let new = addDeps old
+             hPutStrLn stderr (if new /= old
+                               then ("cabal-debian - Updated " ++ show path' ++ ":\n " ++ old ++ "\n   ->\n " ++ new)
+                               else ("cabal-debian - No updates found for " ++ show path'))
+             maybe (return ()) (\ _x -> replaceFile path' new) name
+      ([], Nothing) -> return ()
+      (missing, _) -> 
+          die ("These debian packages need to be added to the build dependency list so the required cabal packages are available:\n  " ++ intercalate "\n  " (map (show . D.prettyBinPkgName . fst) missing) ++
+               "\nIf this is an obsolete package you may need to withdraw the old versions from the\n" ++
+               "upstream repository, and uninstall and purge it from your local system.")
+    where
+      addDeps old =
+          case partition (isPrefixOf "haskell:Depends=") (lines old) of
+            ([], other) -> unlines (("haskell:Depends=" ++ showDeps deps) : other)
+            (hdeps, more) ->
+                case deps of
+                  [] -> unlines (hdeps ++ more)
+                  _ -> unlines (map (++ (", " ++ showDeps deps)) hdeps ++ more)
+      path = fmap (\ (D.BinPkgName (D.PkgName x)) -> "debian/" ++ x ++ ".substvars") name
+      name = case debType of Dev -> devDebName; Prof -> profDebName; Doc -> docDebName
+      deps = case debType of Dev -> devDeps; Prof -> profDeps; Doc -> docDeps
+      -- We must have build dependencies on the profiling and documentation packages
+      -- of all the cabal packages.
+      missingBuildDeps =
+          let requiredDebs =
+                  concat (map (\ (Dependency (PackageName name) _) ->
+                               case Map.lookup name cabalPackages :: Maybe PackageInfo of
+                                 Just info ->
+                                     let prof = maybe (devDeb info) Just (profDeb info) in
+                                     let doc = docDeb info in
+                                     catMaybes [prof, doc]
+                                 Nothing -> []) (cabalDependencies flags pkgDesc)) in
+          filter (not . (`elem` buildDepNames) . fst) requiredDebs
+      -- Make a list of the debian devel packages corresponding to cabal packages
+      -- which are build dependencies
+      devDeps :: D.Relations
+      devDeps =
+          catMaybes (map (\ (Dependency (PackageName name) _) ->
+                          case Map.lookup name cabalPackages :: Maybe PackageInfo of
+                            Just package -> maybe Nothing (\ (s, v) -> Just [D.Rel s (Just (D.GRE v)) Nothing]) (devDeb package)
+                            Nothing -> Nothing) (cabalDependencies flags pkgDesc))
+      profDeps :: D.Relations
+      profDeps =
+          maybe [] (\ name -> [[D.Rel name Nothing Nothing]]) devDebName ++
+          catMaybes (map (\ (Dependency (PackageName name) _) ->
+                          case Map.lookup name cabalPackages :: Maybe PackageInfo of
+                            Just package -> maybe Nothing (\ (s, v) -> Just [D.Rel s (Just (D.GRE v)) Nothing]) (profDeb package)
+                            Nothing -> Nothing) (cabalDependencies flags pkgDesc))
+      docDeps :: D.Relations
+      docDeps =
+          catMaybes (map (\ (Dependency (PackageName name) _) ->
+                              case Map.lookup name cabalPackages :: Maybe PackageInfo of
+                                Just package -> maybe Nothing (\ (s, v) -> Just [D.Rel s (Just (D.GRE v)) Nothing]) (docDeb package)
+                                Nothing -> Nothing) (cabalDependencies flags pkgDesc))
+      buildDepNames :: [D.BinPkgName]
+      buildDepNames = concat (map (map (\ (D.Rel s _ _) -> s)) buildDeps)
+      buildDeps :: D.Relations
+      buildDeps = (either (error . show) id . D.parseRelations $ bd) ++ (either (error . show) id . D.parseRelations $ bdi)
+      --sourceName = maybe (error "Invalid control file") (\ (Field (_, s)) -> stripWS s) (lookupP "Source" (head (unControl control)))
+      devDebName = fmap (D.BinPkgName . D.PkgName) $ listToMaybe (filter (isSuffixOf "-dev") debNames)
+      profDebName = fmap (D.BinPkgName . D.PkgName) $ listToMaybe (filter (isSuffixOf "-prof") debNames)
+      docDebName = fmap (D.BinPkgName . D.PkgName) $ listToMaybe (filter (isSuffixOf "-doc") debNames)
+      debNames = map (\ (Field (_, s)) -> stripWS s) (catMaybes (map (lookupP "Package") (tail (unControl control))))
+      bd = maybe "" (\ (Field (_a, b)) -> stripWS b) . lookupP "Build-Depends" . head . unControl $ control
+      bdi = maybe "" (\ (Field (_a, b)) -> stripWS b) . lookupP "Build-Depends-Indep" . head . unControl $ control
+
+-- |Write a file which we might still be reading from in
+-- order to compute the text argument.
+replaceFile :: FilePath -> String -> IO ()
+replaceFile path text =
+    try (removeFile back) >>= either chk1 return >>		-- This may not exist
+    try (renameFile path back) >>= either chk2 return >>	-- This may not exist
+    writeFile path text			-- This must succeed
+    where
+      back = path ++ "~"
+      chk1 :: IOException -> IO ()
+      chk1 e =
+          if ioeGetFileName e == Just back && isDoesNotExistError e
+          then return ()
+          else ioError e
+      chk2 :: IOException -> IO ()
+      chk2 e =
+          if ioeGetFileName e == Just path && isDoesNotExistError e
+          then return ()
+          else ioError e
+
+libPaths :: Compiler -> DebMap -> IO [PackageInfo]
+libPaths compiler debVersions
+    | compilerFlavor compiler == GHC =
+        do a <- getDirPaths "/usr/lib"
+           b <- getDirPaths "/usr/lib/haskell-packages/ghc/lib"
+           -- Build a map from names of installed debs to version numbers
+           dpkgFileMap >>= runReaderT (mapM (packageInfo compiler debVersions) (a ++ b)) >>= return . catMaybes
+    | True = error $ "Can't handle compiler flavor: " ++ show (compilerFlavor compiler)
+    where
+      getDirPaths path = try (getDirectoryContents path) >>= return . map (\ x -> (path, x)) . either (\ (_ :: SomeException) -> []) id
+
+packageInfo :: Compiler ->  DebMap -> (FilePath, String) -> ReaderT (Map.Map FilePath (Set.Set D.BinPkgName)) IO (Maybe PackageInfo)
+packageInfo compiler debVersions (d, f) =
+    case parseNameVersion f of
+      Nothing -> return Nothing
+      Just (p, v) -> lift (doesDirectoryExist (d </> f </> cdir)) >>= cond (return Nothing) (info (d, p, v))
+    where
+      cdir = display (compilerId compiler)
+      info (d, p, v) = 
+          do dev <- debOfFile ("^" ++ d </> p ++ "-" ++ v </> cdir </> "libHS" ++ p ++ "-" ++ v ++ ".a$")
+             prof <- debOfFile ("^" ++ d </> p ++ "-" ++ v </> cdir </> "libHS" ++ p ++ "-" ++ v ++ "_p.a$")
+             doc <- debOfFile ("/" ++ p ++ ".haddock$")
+             return (Just (PackageInfo { libDir = d
+                                       , cabalName = p
+                                       , cabalVersion = v
+                                       , devDeb = maybe Nothing (\ x -> Just (x, debVersions ! x)) dev
+                                       , profDeb = maybe Nothing (\ x -> Just (x, debVersions ! x)) prof
+                                       , docDeb = maybe Nothing (\ x -> Just (x, debVersions ! x)) doc }))
+      parseNameVersion s =
+          case (break (== '-') (reverse s)) of
+            (_a, "") -> Nothing
+            (a, b) -> Just (reverse (tail b), reverse a) 
+
+-- |Create a map from pathname to the names of the packages that contains that pathname.
+-- We need to make sure we consume all the files, so 
+dpkgFileMap :: IO (Map.Map FilePath (Set.Set D.BinPkgName))
+dpkgFileMap =
+    do
+      let fp = "/var/lib/dpkg/info"
+      names <- getDirectoryContents fp >>= return . filter (isSuffixOf ".list")
+      let paths = map (fp </>) names
+      files <- mapM (strictReadF lines) paths
+      return $ Map.fromList $ zip (map dropExtension names) (map (Set.fromList . map (D.BinPkgName . D.PkgName)) $ files)
+
+strictReadF :: (String -> r) -> FilePath -> IO r
+strictReadF f path = withFile path ReadMode (\h -> hGetContents h >>= (\x -> return $! f x))
+-- strictRead = strictReadF id
+
+-- |Given a path, return the name of the package that owns it.
+debOfFile :: FilePath -> ReaderT (Map.Map FilePath (Set.Set D.BinPkgName)) IO (Maybe D.BinPkgName)
+debOfFile path =
+    do mp <- ask
+       return $ testPath (Map.lookup path mp)
+    where
+      -- testPath :: Maybe (Set.Set FilePath) -> Maybe FilePath
+      testPath Nothing = Nothing
+      testPath (Just s) =
+          case Set.size s of
+            1 -> Just (Set.findMin s)
+            _ -> Nothing
+
+cond :: t -> t -> Bool -> t
+cond ifF _ifT False = ifF
+cond _ifF ifT True = ifT
+
+debianize :: Bool -> PackageDescription -> Flags -> Compiler -> FilePath -> IO ()
+debianize force pkgDesc flags compiler tgtPfx =
+    mapM_ removeIfExists ["debian/control"] >>
+    updateDebianization force pkgDesc flags compiler tgtPfx
+
+removeFileIfExists :: FilePath -> IO ()
+removeFileIfExists x = doesFileExist x >>= (`when` (removeFile x))
+
+removeDirectoryIfExists :: FilePath -> IO ()
+removeDirectoryIfExists x = doesDirectoryExist x >>= (`when` (removeDirectory x))
+
+removeIfExists :: FilePath -> IO ()
+removeIfExists x = removeFileIfExists x >> removeDirectoryIfExists x
+
+updateDebianization :: Bool                -- ^whether to forcibly create file
+                    -> PackageDescription  -- ^info from the .cabal file
+                    -> Flags		 -- ^command line flags
+                    -> Compiler            -- ^compiler details
+                    -> FilePath            -- ^directory in which to create files
+                    -> IO ()
+updateDebianization _force pkgDesc flags compiler tgtPfx =
+    do createDirectoryIfMissing True "debian"
+       createDirectoryIfMissing True "debian/source"
+       date <- getCurrentLocalRFC822Time
+       copyright <- try (readFile' (licenseFile pkgDesc)) >>=
+                    return . either (\ (_ :: SomeException) -> showLicense . license $ pkgDesc) id
+       debianMaintainer <- getDebianMaintainer flags >>= maybe (error "Missing value for --maintainer") return
+       controlUpdate (tgtPfx </> "control") flags compiler debianMaintainer pkgDesc
+       changelogUpdate flags (tgtPfx </> "changelog") debianMaintainer pkgDesc date
+       replaceFile (tgtPfx </> "rules") (cdbsRules pkgDesc)
+       getPermissions "debian/rules" >>= setPermissions "debian/rules" . (\ p -> p {executable = True})
+       replaceFile (tgtPfx </> "compat") "7" -- should this be hardcoded, or automatically read from /var/lib/dpkg/status?
+       replaceFile (tgtPfx </> "copyright") copyright
+       replaceFile (tgtPfx </> "source/format") (sourceFormat flags)
+       replaceFile (tgtPfx </> "watch") ("version=3\nopts=\"downloadurlmangle=s|archive/([\\w\\d_-]+)/([\\d\\.]+)/|archive/$1/$2/$1-$2.tar.gz|,\\\nfilenamemangle=s|(.*)/$|" ++ pkgname ++ "-$1.tar.gz|\" \\\n    http://hackage.haskell.org/packages/archive/" ++ pkgname ++ " \\\n    ([\\d\\.]*\\d)/\n")
+       -- The dev postinst and prerm files are generated by haskell-devscripts via cdbs.
+       return ()
+    where
+        PackageName pkgname = pkgName . package $ pkgDesc
+
+readFile' :: FilePath -> IO String
+readFile' path
+  = do
+    file <- openFile path ReadMode
+    hSetBinaryMode file True
+    hGetContents file
+
+{-
+Create a debian maintainer field from the environment variables:
+
+  DEBFULLNAME (preferred) or NAME
+  DEBEMAIL (preferred) or EMAIL
+
+More work could be done to match dch, but this is sufficient for
+now. Here is what the man page for dch has to say:
+
+ If the environment variable DEBFULLNAME is set, this will be used for
+ the maintainer full name; if not, then NAME will be checked.  If the
+ environment variable DEBEMAIL is set, this will be used for the email
+ address.  If this variable has the form "name <email>", then the
+ maintainer name will also be taken from here if neither DEBFULLNAME
+ nor NAME is set.  If this variable is not set, the same test is
+ performed on the environment variable EMAIL.  Next, if the full name
+ has still not been determined, then use getpwuid(3) to determine the
+ name from the pass‐word file.  If this fails, use the previous
+ changelog entry.  For the email address, if it has not been set from
+ DEBEMAIL or EMAIL, then look in /etc/mailname, then attempt to build
+ it from the username and FQDN, otherwise use the email address in the
+ previous changelog entry.  In other words, it’s a good idea to set
+ DEBEMAIL and DEBFULLNAME when using this script.
+
+-}
+getDebianMaintainer :: Flags -> IO (Maybe String)
+getDebianMaintainer flags =
+    case debMaintainer flags of
+      Nothing -> envMaintainer
+      maint -> return maint
+    where
+      envMaintainer :: IO (Maybe String)
+      envMaintainer =
+          do env <- map (second decodeString) `fmap` getEnvironment
+             return $ do fullname <- lookup "DEBFULLNAME" env `mplus` lookup "NAME" env
+                         email    <- lookup "DEBEMAIL" env `mplus` lookup "EMAIL" env
+                         return (fullname ++ " <" ++ email ++ ">")
+
+cdbsRules :: PackageDescription -> String
+cdbsRules pkgDesc =
+    unlines (intercalate [""] ([header, execs, comments] {- ++ devrules ++ profrules -} ))
+    where
+      header =
+          ["#!/usr/bin/make -f",
+           "",
+           "DEB_CABAL_PACKAGE = " ++ (show (D.prettyBinPkgName (debianExtraPackageName versionSplits (pkgName (package pkgDesc)) (Just (D.EEQ (parseDebianVersion (showVersion (pkgVersion (package pkgDesc))))))))),
+           "",
+           "include /usr/share/cdbs/1/rules/debhelper.mk",
+           "include /usr/share/cdbs/1/class/hlibrary.mk"]
+      execs =
+          case map exeName (executables pkgDesc) ++ dataFiles pkgDesc of
+            [] -> []
+{-
+            [e] ->
+                let exe = exeName e
+                    src = "dist-ghc/build/" ++ exe ++ "/" ++ exe
+                    dst = "debian/" ++ exeDeb e ++ "/usr/bin/" ++ exe in
+                [ -- Magic rule required to get binaries to build in packages that have no libraries
+                  "build/" ++ exeDeb e ++ ":: build-ghc-stamp"
+                , "binary-fixup/" ++ exeDeb e ++ "::"
+                , "\tinstall -m 755 -s -D " ++ src ++ " " ++ dst ++ " || true"]
+-}
+            _ ->
+                [ -- Magic rule required to get binaries to build in packages that have no libraries
+                  "build/" ++ (show . D.prettyBinPkgName $ utilsDeb) ++ ":: build-ghc-stamp"
+                , "binary-fixup/" ++ (show . D.prettyBinPkgName $ utilsDeb) ++ "::" ] ++
+                map (\ exe ->
+                         let src = "dist-ghc/build/" ++ exe ++ "/" ++ exe
+                             dst = "debian/" ++ (show . D.prettyBinPkgName $ utilsDeb) ++ "/usr/bin/" ++ exe in
+                         "\tinstall -m 755 -s -D " ++ src ++ " " ++ dst ++ " || true") (map exeName (executables pkgDesc)) ++
+                map (\ file ->
+                         let dst = "debian" </> (show . D.prettyBinPkgName $ utilsDeb) </> "usr/share" </> libDir </> file in
+                         "\tinstall -m 644 -D " ++ file ++ " " ++ dst ++ " || true") (dataFiles pkgDesc)
+      comments =
+          ["# How to install an extra file into the documentation package",
+           "#binary-fixup/" ++ (show . D.prettyBinPkgName $ docDeb) ++ "::",
+           "#\techo \"Some informative text\" > debian/" ++ (show . D.prettyBinPkgName $ docDeb) ++ "/usr/share/doc/" ++ (show . D.prettyBinPkgName $ docDeb) ++ "/AnExtraDocFile"]
+      p = pkgName . package $ pkgDesc
+      v = pkgVersion . package $ pkgDesc
+      libDir = unPackageName p ++ "-" ++ showVersion v
+      docDeb = debianDocPackageName versionSplits (pkgName (package pkgDesc)) (Just (D.EEQ (parseDebianVersion (showVersion (pkgVersion (package pkgDesc))))))
+      utilsDeb = debianUtilsPackageName versionSplits (pkgName (package pkgDesc)) (Just (D.EEQ (parseDebianVersion (showVersion (pkgVersion (package pkgDesc))))))
+      --exeDeb e = debianExtraPackageName (PackageName (exeName e)) Nothing
+
+list :: b -> ([a] -> b) -> [a] -> b
+list d f l = case l of [] -> d; _ -> f l
+
+controlUpdate :: FilePath -> Flags -> Compiler -> String -> PackageDescription -> IO ()
+controlUpdate path flags compiler debianMaintainer pkgDesc =
+    try (readFile path) >>=
+    either (\ (_ :: SomeException) -> writeFile path (show newCtl)) (\ s -> writeFile (path ++ ".new") $! show (merge newCtl (oldCtl s)))
+    where
+      newCtl = control flags compiler debianMaintainer pkgDesc
+      oldCtl s = either (const (Control [])) id (parseControl "debian/control" s)
+      merge (Control new) (Control old) =
+          case (new, old) of
+            (_newSource : _new', []) -> Control new
+            (newSource : new', oldSource : old') ->
+                Control (mergeParagraphs newSource oldSource : mergeOther new' old')
+      -- Merge a list of binary package paragraphs
+      mergeOther new old =
+          map mergePackages allNames
+          where
+            mergePackages name =
+                case (findPackage name new, findPackage name old) of
+                  (Just x, Nothing) -> x
+                  (Nothing, Just x) -> x
+                  (Just x, Just y) -> mergeParagraphs x y
+            findPackage name paras = listToMaybe (filter (hasName name) paras)
+                where hasName name para = lookupP "Package" para == Just name
+            allNames = newNames ++ (oldNames \\ newNames)
+            newNames = catMaybes $ map (lookupP "Package") new
+            oldNames = catMaybes $ map (lookupP "Package") old
+
+mergeParagraphs :: Paragraph' String -> Paragraph' String -> Paragraph' String
+mergeParagraphs new@(Paragraph newFields) old@(Paragraph oldFields) =
+    Paragraph (map mergeField fieldNames)
+    where
+      fieldNames = map fieldName oldFields ++ (map fieldName newFields \\ map fieldName oldFields)
+      fieldName (Field (name, _)) = name
+      mergeField :: String -> Field
+      mergeField name =
+          case (lookupP name new, lookupP name old) of
+            (Just (Field (_, x)), Nothing) -> Field (name, x)
+            (Nothing, Just (Field (_, x))) -> Field (name, x)
+            (Just (Field (_, x)), Just (Field (_, y))) -> Field (name, mergeValues name x y)
+            _ -> error $ "Internal error"
+      mergeValues :: String -> String -> String -> String
+      mergeValues "Build-Depends" x y =
+          " " ++ (showDeps' "Build-Depends:" $ mergeDeps (parseDeps x) (parseDeps y))
+      mergeValues "Depends" x y =
+          " " ++ (showDeps' "Depends:" $ mergeDeps (parseDeps x) (parseDeps y))
+      mergeValues _ x _ = x
+      parseDeps s = either (error . show) id (D.parseRelations s)
+
+mergeDeps :: D.Relations -> D.Relations -> D.Relations
+mergeDeps x y = 
+    -- foldr :: (a -> b -> b) -> b -> [a] -> b
+    nub $ foldr insertDep x y
+    where
+      insertDep :: [D.Relation] -> D.Relations -> D.Relations
+      insertDep ys xss =
+          case depPackageNames ys of
+            [name] -> case break (\ xs -> depPackageNames xs == [name]) xss of
+                        (a, b : c) -> a ++ [b, ys] ++ c
+                        (a, []) -> a ++ [ys]
+            _ -> xss ++ [ys]
+      depPackageNames xs = nub (map depPackageName xs)
+      depPackageName (D.Rel x _ _) = x
+
+control :: Flags -> Compiler -> String -> PackageDescription -> Control
+control flags compiler debianMaintainer pkgDesc =
+    -- trace ("allBuildDepends " ++ show flags ++ " -> " ++ show (allBuildDepends flags pkgDesc)) $
+    Control {unControl =
+             ([sourceSpec] ++
+              develLibrarySpecs ++
+              profileLibrarySpecs ++ 
+              docLibrarySpecs ++
+              (case map exeName (executables pkgDesc) ++ dataFiles pkgDesc of
+                 [] -> []
+                 -- [e] -> [utilsSpec (debianName Extra (PackageName (exeName e)) Nothing)]
+                 _ -> [utilsSpec (show . D.prettyBinPkgName $ debianUtilsPackageName versionSplits (pkgName (package pkgDesc)) (Just (D.EEQ (parseDebianVersion (showVersion (pkgVersion (package pkgDesc)))))))]))}
+    where
+      --buildDepsIndep = ""
+      sourceSpec =
+          Paragraph
+          ([Field ("Source", " " ++ (show . D.prettySrcPkgName $ debianSourcePackageName versionSplits (pkgName . package $ pkgDesc) (Just (D.EEQ (parseDebianVersion (showVersion (pkgVersion (package pkgDesc)))))))),
+            Field ("Priority", " " ++ "extra"),
+            Field ("Section", " " ++ "haskell"),
+            Field ("Maintainer", " " ++ debianMaintainer),
+            Field ("Build-Depends", " " ++ showDeps' "Build-Depends:" (debianBuildDeps ++ map rel (buildDeps flags))),
+            Field ("Build-Depends-Indep", " " ++ showDeps' "Build-Depends-Indep:" debianBuildDepsIndep),
+            --Field ("Build-Depends-Indep", " " ++ buildDepsIndep),
+            Field ("Standards-Version", " " ++ "3.9.3"),
+            Field ("Homepage",
+                   " " ++
+                   if homepage pkgDesc == ""
+                   then "http://hackage.haskell.org/package/" ++
+                        unPackageName (pkgName $ package pkgDesc)
+                   else homepage pkgDesc)])
+      rel x = [D.Rel (D.BinPkgName (D.PkgName x)) Nothing Nothing]
+      utilsSpec p =
+          Paragraph
+          [Field ("Package", " " ++ p),
+           Field ("Architecture", " " ++ "any"),
+           Field ("Section", " " ++ "misc"),
+           -- No telling what the dependencies of an executable might
+           -- be.  The developer will have to fill them in
+           Field ("Depends", " " ++ showDeps [[D.Rel (D.BinPkgName (D.PkgName "${shlibs:Depends}")) Nothing Nothing], 
+                                              [D.Rel (D.BinPkgName (D.PkgName "${haskell:Depends}")) Nothing Nothing],
+                                              [D.Rel (D.BinPkgName (D.PkgName "${misc:Depends}")) Nothing Nothing]]),
+           Field ("Description", " " ++ maybe debianDescription (const executableDescription) (library pkgDesc))]
+      develLibrarySpecs = if isJust (library pkgDesc) then [librarySpec "any" Development debianDevPackageName] else []
+      profileLibrarySpecs = if debLibProf flags && isJust  (library pkgDesc) then [librarySpec "any" Profiling debianProfPackageName] else []
+      docLibrarySpecs = if isJust (library pkgDesc) then [docSpecsParagraph] else []
+      docSpecsParagraph =
+          Paragraph
+          [Field ("Package", " " ++ (show . D.prettyBinPkgName $ debianDocPackageName versionSplits (pkgName (package pkgDesc)) (Just (D.EEQ (parseDebianVersion (showVersion (pkgVersion (package pkgDesc)))))))),
+           Field ("Architecture", " " ++ "all"),
+           Field ("Section", " " ++ "doc"),
+           Field ("Depends", " " ++ showDeps' "Depends:" [[D.Rel (D.BinPkgName (D.PkgName "${haskell:Depends}")) Nothing Nothing],
+                                                           [D.Rel (D.BinPkgName (D.PkgName "${misc:Depends}")) Nothing Nothing]]),
+           Field ("Recommends", " " ++ "${haskell:Recommends}"),
+           Field ("Suggests", " " ++ "${haskell:Suggests}"),
+           Field ("Description", " " ++ libraryDescription Documentation)]
+      librarySpec arch typ debianName =
+          Paragraph
+          [Field ("Package", " " ++ (show . D.prettyBinPkgName $ debianName versionSplits (pkgName (package pkgDesc)) (Just (D.EEQ (parseDebianVersion (showVersion (pkgVersion (package pkgDesc)))))))),
+           Field ("Architecture", " " ++ arch),
+           Field ("Depends", " " ++ showDeps' "Depends:" (
+                     (if typ == Development
+                      then [[D.Rel (D.BinPkgName (D.PkgName "${shlibs:Depends}")) Nothing Nothing]] ++ map (\ x -> [D.Rel (D.BinPkgName (D.PkgName x)) Nothing Nothing]) (extraDevDeps flags)
+                      else []) ++
+                     [[D.Rel (D.BinPkgName (D.PkgName "${haskell:Depends}")) Nothing Nothing],
+                      [D.Rel (D.BinPkgName (D.PkgName "${misc:Depends}")) Nothing Nothing]])),
+           Field ("Recommends", " " ++ "${haskell:Recommends}"),
+           Field ("Suggests", " " ++ "${haskell:Suggests}"),
+           Field ("Provides", " " ++ "${haskell:Provides}"),
+           Field ("Description", " " ++ libraryDescription typ)]
+      -- The haskell-cdbs package contains the hlibrary.mk file with
+      -- the rules for building haskell packages.
+      debianBuildDeps :: D.Relations
+      debianBuildDeps = 
+          nub $
+          [[D.Rel (D.BinPkgName (D.PkgName "debhelper")) (Just (D.GRE (parseDebianVersion "7.0"))) Nothing],
+           [D.Rel (D.BinPkgName (D.PkgName "haskell-devscripts")) (Just (D.GRE (parseDebianVersion "0.8"))) Nothing],
+           [D.Rel (D.BinPkgName (D.PkgName "cdbs")) Nothing Nothing],
+           [D.Rel (D.BinPkgName (D.PkgName "ghc")) Nothing Nothing]] ++
+          (if debLibProf flags then [[D.Rel (D.BinPkgName (D.PkgName "ghc-prof")) Nothing Nothing]] else []) ++
+          (concat . map (buildDependencies flags compiler) . allBuildDepends flags $ pkgDesc)
+      debianBuildDepsIndep :: D.Relations
+      debianBuildDepsIndep =
+          nub $
+          [[D.Rel (D.BinPkgName (D.PkgName "ghc-doc")) Nothing Nothing]] ++
+          (concat . map (docDependencies flags compiler) . allBuildDepends flags $ pkgDesc)
+      debianDescription = 
+          (unwords . words . synopsis $ pkgDesc) ++
+          case description pkgDesc of
+            "" -> ""
+            text ->
+                let text' = text ++ "\n" ++
+                            list "" ("\n Author: " ++) (author pkgDesc) ++
+                            list "" ("\n Upstream-Maintainer: " ++) (maintainer pkgDesc) ++
+                            list "" ("\n Url: " ++) (pkgUrl pkgDesc) in
+                "\n " ++ (trim . intercalate "\n " . map addDot . lines $ text')
+      addDot line = if all (flip elem " \t") line then "." else line
+      executableDescription = " " ++ "An executable built with the " ++ display (package pkgDesc) ++ " library."
+      libraryDescription Profiling = debianDescription ++ "\n .\n This package contains the libraries compiled with profiling enabled."
+      libraryDescription Development = debianDescription ++ "\n .\n This package contains the normal library files."
+      libraryDescription Documentation = debianDescription ++ "\n .\n This package contains the documentation files."
+      libraryDescription x = error $ "Unexpected library package name suffix: " ++ show x
+
+showDeps :: [[D.Relation]] -> String
+showDeps xss = intercalate ", " (map (intercalate " | " . map (show . D.prettyRelation)) xss)
+
+{-
+showDeps' :: [a] -> [[D.Relation]] -> String
+showDeps' prefix xss =
+    intercalate (",\n " ++ prefix') (map (intercalate " | " . map (show . D.prettyRelation)) xss)
+    where prefix' = map (\ _ -> ' ') prefix
+-}
+
+showDeps' :: [a] -> [[D.Relation]] -> String
+showDeps' prefix xss =
+    intercalate ("\n" ++ prefix' ++ " , ") (map (intercalate " | " . map (show . D.prettyRelation)) xss)
+    where prefix' = map (\ _ -> ' ') prefix
+
+changelogUpdate :: Flags -> FilePath -> String -> PackageDescription -> String -> IO ()
+changelogUpdate flags path debianMaintainer pkgDesc date =
+    read >>= replace
+    where
+      read :: IO ([[String]], [ChangeLogEntry])
+      read = try (readFile path) >>= return . either (\ (e :: SomeException) -> ([[show e]], [])) (partitionEithers . parseLog)
+      replace :: ([[String]], [ChangeLogEntry]) -> IO ()
+      replace (errs, entries) =
+          do when (not (null errs)) (hPutStrLn stderr (intercalate "\n " ("Errors reading changelog:" : concat errs)))
+             let entries' = dropWhile (\ entry -> logVersion entry >= logVersion log) entries
+             replaceFile path (intercalate "\n" (map (render . prettyEntry) (log : entries')))
+      log = changelog flags debianMaintainer pkgDesc date
+
+{-
+changelog :: Flags -> String -> PackageDescription -> String -> String
+changelog flags debianMaintainer pkgDesc date =
+    render . prettyEntry $ changelog' flags debianMaintainer pkgDesc date
+-}
+
+changelog :: Flags -> String -> PackageDescription -> String -> ChangeLogEntry
+changelog flags debianMaintainer pkgDesc date =
+    Entry { logPackage = (show . D.prettySrcPkgName $ debianSourcePackageName versionSplits (pkgName . package $ pkgDesc) (Just (D.EEQ (parseDebianVersion (showVersion (pkgVersion (package pkgDesc)))))))
+          , logVersion = updateOriginal f $ debianVersionNumber pkgDesc
+          , logDists = [parseReleaseName "unstable"]
+          , logUrgency = "low"
+          , logComments = "  * Debianization generated by cabal-debian\n\n"
+          , logWho = debianMaintainer
+          , logDate = date }
+    where
+      f s = maybe (g s) (\ d -> if older d s then error ("Version from --deb-version (" ++ show d ++ ") is older than hackage version (" ++ show s ++ "), maybe you need to unpin this package?") else d) (debVersion flags)
+      g s = maybe "" (\ n -> show n ++ ":") (Map.lookup (pkgName (package pkgDesc)) (epochMap flags)) ++ s ++ revision flags
+      older debv cabv = parseDebianVersion debv < parseDebianVersion cabv
+
+updateOriginal :: (String -> String) -> DebianVersion -> DebianVersion
+--updateOriginal f (DebianVersion str dv) = DebianVersion (f str) dv
+updateOriginal f v = parseDebianVersion . f . show . prettyDebianVersion $ v
+
+unPackageName :: PackageName -> String
+unPackageName (PackageName s) = s
+
+--debianDevelPackageName' (Dependency (PackageName name) _) = debianDevelPackageName name
+
+-- debianPackageName prefix name suffix = prefix ++ (map toLower name) ++ suffix
+
+debianVersionNumber :: PackageDescription -> DebianVersion
+debianVersionNumber pkgDesc = parseDebianVersion . showVersion . pkgVersion . package $ pkgDesc
+
+-- generated with:
+-- apt-cache show ghc \
+--   | grep ^Provides: \
+--   | cut -d\  -f2-
+--   | sed 's/, /\n/g' \
+--   | grep libghc- \
+--   | cut -d- -f2- \
+--   | grep dev$ \
+--   | sed 's/-dev//;s/$/",/;s/^/"/'
+
+{-
+base :: Set String
+base
+  = Data.Set.fromList
+    ["array",
+      "base",
+      "bin-package-db",
+      "bytestring",
+      "cabal",
+      "containers",
+      "directory",
+      "extensible-exceptions",
+      "filepath",
+      "ghc-binary",
+      "ghc-prim",
+      "haskell2010",
+      "haskell98",
+      "hpc",
+      "integer-gmp",
+      "old-locale",
+      "old-time",
+      "pretty",
+      "process",
+      "random",
+      "rts",
+      "template-haskell",
+      "time",
+      "unix"]
+-}
+
+-- | Convert from license to RPM-friendly description.  The strings are
+-- taken from TagsCheck.py in the rpmlint distribution.
+
+showLicense :: License -> String
+showLicense (GPL _) = "GPL"
+showLicense (LGPL _) = "LGPL"
+showLicense BSD3 = "BSD"
+showLicense BSD4 = "BSD-like"
+showLicense PublicDomain = "Public Domain"
+showLicense AllRightsReserved = "Proprietary"
+showLicense OtherLicense = "Non-distributable"
diff --git a/Distribution/Package/Debian/Bundled.hs b/Distribution/Package/Debian/Bundled.hs
new file mode 100644
--- /dev/null
+++ b/Distribution/Package/Debian/Bundled.hs
@@ -0,0 +1,323 @@
+-- |
+-- Module      :  Distribution.Package.Debian.Bundled
+-- Copyright   :  David Fox 2008
+--
+-- Maintainer  :  David Fox <dsf@seereason.com>
+-- Stability   :  alpha
+-- Portability :  portable
+--
+-- Determine whether a specific version of a Haskell package is
+-- bundled with into this particular version of the given compiler.
+
+-- This software may be used and distributed according to the terms of
+-- the GNU General Public License, incorporated herein by reference.
+{-# LANGUAGE StandaloneDeriving #-}
+module Distribution.Package.Debian.Bundled
+    ( ghcBuiltIn
+    ) where
+
+import qualified Data.Map as Map
+import Data.Set (fromList, member)
+import Data.Version (Version(..))
+import Debian.Relation.ByteString()
+import Distribution.Simple.Compiler (Compiler(..), CompilerId(..), CompilerFlavor(..), {-PackageDB(GlobalPackageDB), compilerFlavor-})
+import Distribution.Package (PackageIdentifier(..), PackageName(..) {-, Dependency(..)-})
+import System.Exit (ExitCode(..))
+
+type Bundled = (CompilerFlavor, Version, [PackageIdentifier])
+
+-- |Return a list of built in packages for the compiler in an environment.
+-- ghcBuiltIns :: FilePath -> IO [PackageIdentifier]
+-- ghcBuiltIns root =
+--     fchroot root (lazyProcess "ghc-pkg" ["list", "--simple-output"] Nothing Nothing empty) >>=
+--     return . map parsePackageIdentifier . words . unpack . fst . collectStdout
+--     where
+--       parsePackageIdentifier s =
+--           let (v', n') = break (== '-') (reverse s)
+--               (v, n) = (reverse (tail n'), reverse v') in
+--           PackageIdentifier (PackageName n) (Version (map read (filter (/= ".") (groupBy (\ a b -> (a == '.') == (b == '.')) v))) [])
+
+ghcBuiltIns :: Compiler -> Bundled
+ghcBuiltIns (Compiler {compilerId = CompilerId GHC compilerVersion}) =
+    case Map.lookup compilerVersion
+             (Map.fromList [ (Version [7,4,1] [], (GHC, Version [7,4,1] [], ghc741BuiltIns))
+                           , (Version [7,4,0,20111219] [], (GHC, Version [7,4,0,20111219] [], ghc740BuiltIns))
+                           , (Version [7,4,0,20120108] [], (GHC, Version [7,4,0,20120108] [], ghc740BuiltIns))
+                           , (Version [7,2,2] [], (GHC, Version [7,2,2] [], ghc721BuiltIns))
+                           , (Version [7,2,1] [], (GHC, Version [7,2,1] [], ghc721BuiltIns))
+                           , (Version [7,0,4] [], (GHC, Version [7,0,4] [], ghc701BuiltIns))
+                           , (Version [7,0,3] [], (GHC, Version [7,0,3] [], ghc701BuiltIns))
+                           , (Version [7,0,1] [], (GHC, Version [7,0,1] [], ghc701BuiltIns))
+                           , (Version [6,8,3] [], (GHC, Version [6,8,3] [], ghc683BuiltIns))
+                           , (Version [6,8,2] [], (GHC, Version [6,8,2] [], ghc682BuiltIns))
+                           , (Version [6,8,1] [], (GHC, Version [6,8,1] [], ghc681BuiltIns))
+                           , (Version [6,6,1] [], (GHC, Version [6,6,1] [], ghc661BuiltIns))
+                           , (Version [6,6] [], (GHC, Version [6,6] [], ghc66BuiltIns)) ]) of
+      Nothing -> error $ "cabal-debian: No bundled package list for ghc " ++ show compilerVersion
+      Just x -> x
+
+ghcBuiltIn :: Compiler -> PackageName -> Bool
+ghcBuiltIn compiler package =
+    Data.Set.member
+        package
+        (Data.Set.fromList
+             (let {- (Just (_, _, xs)) = unsafePerformIO (ghc6BuiltIns compiler) -}
+                  (_, _, xs) = ghcBuiltIns compiler in map pkgName xs))
+
+v :: String -> [Int] -> PackageIdentifier
+v n x = PackageIdentifier (PackageName n) (Version x [])
+
+-- | Packages bundled with 7.4.0.20111219-2.
+ghc741BuiltIns :: [PackageIdentifier]
+ghc741BuiltIns = [
+    v "Cabal" [1,14,0],
+    v "array" [0,4,0,0],
+    v "base" [4,5,0,0],
+    v "bin-package-db" [0,0,0,0],
+    v "binary" [0,5,1,0],
+    v "bytestring" [0,9,2,1],
+    v "containers" [0,4,2,1],
+    v "deepseq" [1,3,0,0],
+    v "directory" [1,1,0,2],
+    v "extensible-exceptions" [0,1,1,4],
+    v "filepath" [1,3,0,0],
+    v "ghc" [7,4,1],
+    v "ghc-prim" [0,2,0,0],
+    v "haskell2010" [1,1,0,1],
+    v "haskell98" [2,0,0,1],
+    v "hoopl" [3,8,7,2],
+    v "hpc" [0,5,1,1],
+    v "integer-gmp" [0,4,0,0],
+    v "old-locale" [1,0,0,4],
+    v "old-time" [1,1,0,0],
+    v "pretty" [1,1,1,0],
+    v "process" [1,1,0,1], 
+    v "rts" [1,0],
+    v "template-haskell" [2,7,0,0],
+    v "time" [1,4],
+    v "unix" [2,5,1,0] ]
+
+-- | Packages bundled with 7.4.0.20111219-2.
+ghc740BuiltIns :: [PackageIdentifier]
+ghc740BuiltIns = [
+    v "Cabal" [1,14,0],
+    v "array" [0,4,0,0],
+    v "base" [4,5,0,0],
+    v "bin-package-db" [0,0,0,0],
+    v "binary" [0,5,1,0],
+    v "bytestring" [0,9,2,1],
+    v "containers" [0,4,2,1],
+    v "deepseq" [1,3,0,0],
+    v "directory" [1,1,0,2],
+    v "extensible-exceptions" [0,1,1,4],
+    v "filepath" [1,3,0,0],
+    v "ghc" [7,4,0,20111219],
+    v "ghc-prim" [0,2,0,0],
+    v "haskell2010" [1,1,0,1],
+    v "haskell98" [2,0,0,1],
+    v "hoopl" [3,8,7,2],
+    v "hpc" [0,5,1,1],
+    v "integer-gmp" [0,4,0,0],
+    v "old-locale" [1,0,0,4],
+    v "old-time" [1,1,0,0],
+    v "pretty" [1,1,1,0],
+    v "process" [1,1,0,1], 
+    v "rts" [1,0],
+    v "template-haskell" [2,7,0,0],
+    v "time" [1,4],
+    v "unix" [2,5,1,0] ]
+
+ghc721BuiltIns :: [PackageIdentifier]
+ghc721BuiltIns = [
+    v "Cabal" [1,12,0],
+    v "array" [0,3,0,3],
+    v "base" [4,4,0,0],
+    v "bin-package-db" [0,0,0,0],
+    v "binary" [0,5,0,2],
+    v "bytestring" [0,9,2,0],
+    v "containers" [0,4,1,0],
+    v "directory" [1,1,0,1],
+    v "extensible-exceptions" [0,1,1,3],
+    v "filepath" [1,2,0,1],
+    v "ghc" [7,2,1],
+    -- ghc-binary renamed to binary
+    v "ghc-prim" [0,2,0,0],
+    v "haskell2010" [1,1,0,0],
+    v "haskell98" [2,0,0,0],
+    v "hoopl" [3,8,7,1], -- new
+    v "hpc" [0,5,1,0],
+    v "integer-gmp" [0,3,0,0],
+    v "old-locale" [1,0,0,3],
+    v "old-time" [1,0,0,7],
+    v "pretty" [1,1,0,0],
+    v "process" [1,1,0,0], 
+    -- random removed
+    v "rts" [1,0],
+    v "template-haskell" [2,6,0,0],
+    v "time" [1,2,0,5],
+    v "unix" [2,5,0,0] ]
+
+ghc701BuiltIns :: [PackageIdentifier]
+ghc701BuiltIns = [
+    v "Cabal" [1,10,0,0],
+    v "array" [0,3,0,2],
+    v "base" [4,3,0,0],
+    v "bin-package-db" [0,0,0,0],
+    v "bytestring" [0,9,1,8],
+    v "containers" [0,4,0,0],
+    v "directory" [1,1,0,0],
+    v "extensible-exceptions" [0,1,1,2],
+    v "filepath" [1,2,0,0],
+    v "ghc" [7,0,1],
+    v "ghc-binary" [0,5,0,2],
+    v "ghc-prim" [0,2,0,0],
+    v "haskell2010" [1,0,0,0],
+    v "haskell98" [1,1,0,0],
+    v "hpc" [0,5,0,6],
+    v "integer-gmp" [0,2,0,2],
+    v "old-locale" [1,0,0,2],
+    v "old-time" [1,0,0,6],
+    v "pretty" [1,0,1,2],
+    v "process" [1,0,1,4],
+    v "random" [1,0,0,3],
+    v "rts" [1,0],
+    v "template-haskell" [2,5,0,0],
+    v "time" [1,2,0,3],
+    v "unix" [2,4,1,0]
+  ]
+
+ghc683BuiltIns :: [PackageIdentifier]
+ghc683BuiltIns = ghc682BuiltIns
+
+ghc682BuiltIns :: [PackageIdentifier]
+ghc682BuiltIns = [
+    v "Cabal" [1,2,3,0],
+    v "array" [0,1,0,0],
+    v "base" [3,0,1,0],
+    v "bytestring" [0,9,0,1],
+    v "containers" [0,1,0,1],
+    v "directory" [1,0,0,0],
+    v "filepath" [1,1,0,0],
+    v "ghc" [6,8,2,0],
+    v "haskell98" [1,0,1,0],
+    v "hpc" [0,5,0,0],
+    v "old-locale" [1,0,0,0],
+    v "old-time" [1,0,0,0],
+    v "packedstring" [0,1,0,0],
+    v "pretty" [1,0,0,0],
+    v "process" [1,0,0,0],
+    v "random" [1,0,0,0],
+    v "readline" [1,0,1,0],
+    v "template-haskell" [2,2,0,0],
+    v "unix" [2,3,0,0]
+    ]
+
+ghc681BuiltIns :: [PackageIdentifier]
+ghc681BuiltIns = [
+    v "base" [3,0,0,0],
+    v "Cabal" [1,2,2,0],
+    v "GLUT" [2,1,1,1],
+    v "HGL" [3,2,0,0],
+    v "HUnit" [1,2,0,0],
+    v "OpenAL" [1,3,1,1],
+    v "OpenGL" [2,2,1,1],
+    v "QuickCheck" [1,1,0,0],
+    v "X11" [1,2,3,1],
+    v "array" [0,1,0,0],
+    v "bytestring" [0,9,0,1],
+    v "cgi" [3001,1,5,1],
+    v "containers" [0,1,0,0],
+    v "directory" [1,0,0,0],
+    v "fgl" [5,4,1,1],
+    v "filepatch" [1,1,0,0],
+    v "ghc" [6,8,1,0],
+    v "haskell-src" [1,0,1,1],
+    v "haskell98" [1,0,1,0],
+    v "hpc" [0,5,0,0],
+    v "html" [1,0,1,1],
+    v "mtl" [1,1,0,0],
+    v "network" [2,1,0,0],
+    v "old-locale" [1,0,0,0],
+    v "old-time" [1,0,0,0],
+    v "packedstring" [0,1,0,0],
+    v "parallel" [1,0,0,0],
+    v "parsec" [2,1,0,0],
+    v "pretty" [1,0,0,0],
+    v "process" [1,0,0,0],
+    v "random" [1,0,0,0],
+    v "readline" [1,0,1,0],
+    v "regex-base" [0,72,0,1],
+    v "regex-compat" [0,71,0,1],
+    v "regex-posix" [0,72,0,1],
+    v "stm" [2,1,1,0],
+    v "template-haskell" [2,2,0,0],
+    v "time" [1,1,2,0],
+    v "unix" [2,2,0,0],
+    v "xhtml" [3000,0,2,1]
+    ]
+
+ghc661BuiltIns :: [PackageIdentifier]
+ghc661BuiltIns = [
+    v "base" [2,1,1],
+    v "Cabal" [1,1,6,2],
+    v "cgi" [3001,1,1],
+    v "fgl" [5,4,1],
+    v "filepath" [1,0],
+    v "ghc" [6,6,1],
+    v "GLUT" [2,1,1],
+    v "haskell98" [1,0],
+    v "haskell-src" [1,0,1],
+    v "HGL" [3,1,1],
+    v "html" [1,0,1],
+    v "HUnit" [1,1,1],
+    v "mtl" [1,0,1],
+    v "network" [2,0,1],
+    v "OpenAL" [1,3,1],
+    v "OpenGL" [2,2,1],
+    v "parsec" [2,0],
+    v "QuickCheck" [1,0,1],
+    v "readline" [1,0],
+    v "regex-base" [0,72],
+    v "regex-compat" [0,71],
+    v "regex-posix" [0,71],
+    v "rts" [1,0],
+    v "stm" [2,0],
+    v "template-haskell" [2,1],
+    v "time" [1,1,1],
+    v "unix" [2,1],
+    v "X11" [1,2,1],
+    v "xhtml" [3000,0,2]
+    ]
+
+ghc66BuiltIns :: [PackageIdentifier]
+ghc66BuiltIns = [
+    v "base" [2,0],
+    v "Cabal" [1,1,6],
+    v "cgi" [2006,9,6],
+    v "fgl" [5,2],
+    v "ghc" [6,6],
+    v "GLUT" [2,0],
+    v "haskell98" [1,0],
+    v "haskell-src" [1,0],
+    v "HGL" [3,1],
+    v "html" [1,0],
+    v "HTTP" [2006,7,7],
+    v "HUnit" [1,1],
+    v "mtl" [1,0],
+    v "network" [2,0],
+    v "OpenAL" [1,3],
+    v "OpenGL" [2,1],
+    v "parsec" [2,0],
+    v "QuickCheck" [1,0],
+    v "readline" [1,0],
+    v "regex-base" [0,71],
+    v "regex-compat" [0,71],
+    v "regex-posix" [0,71],
+    v "rts" [1,0],
+    v "stm" [2,0],
+    v "template-haskell" [2,0],
+    v "time" [1,0],
+    v "unix" [1,0],
+    v "X11" [1,1],
+    v "xhtml" [2006,9,13]
+    ]
diff --git a/Distribution/Package/Debian/Dependencies.hs b/Distribution/Package/Debian/Dependencies.hs
new file mode 100644
--- /dev/null
+++ b/Distribution/Package/Debian/Dependencies.hs
@@ -0,0 +1,327 @@
+{-# LANGUAGE MultiParamTypeClasses, StandaloneDeriving #-}
+{-# OPTIONS -Wall -Wwarn -fno-warn-name-shadowing -fno-warn-orphans #-}
+module Distribution.Package.Debian.Dependencies
+    ( PackageType(..)
+    , VersionSplits(..)
+    , dependencies
+    , mkPkgName
+    , invertVersionRange
+    -- , debianName
+    , debianSourcePackageName
+    , DebianBinPackageName
+    , debianDevPackageName
+    , debianProfPackageName
+    , debianDocPackageName
+    , debianExtraPackageName
+    , debianUtilsPackageName
+    ) where
+
+import Data.Char (toLower)
+import Data.Function (on)
+import Data.List (intersperse, minimumBy)
+import qualified Data.Map as Map
+import Data.Maybe (catMaybes)
+import Data.Version (showVersion)
+import Debian.Relation (Relations, Relation, BinPkgName(BinPkgName), PkgName(PkgName), VersionReq(..), SrcPkgName(..))
+import qualified Debian.Relation as D
+import Debian.Version (DebianVersion, parseDebianVersion, prettyDebianVersion)
+import Distribution.Package (PackageName(PackageName))
+import Distribution.Package.Debian.Bundled (ghcBuiltIn)
+import Distribution.Package.Debian.Interspersed (Interspersed(..))
+import Distribution.Package.Debian.Setup (Flags(..))
+import Distribution.Simple.Compiler (Compiler(..))
+import Distribution.Version (Version(..), VersionRange(..), anyVersion, foldVersionRange', intersectVersionRanges, unionVersionRanges,
+                             laterVersion, orLaterVersion, earlierVersion, orEarlierVersion, fromVersionIntervals, toVersionIntervals, withinVersion,
+                             isNoVersion, asVersionIntervals, mkVersionIntervals, LowerBound(..), UpperBound(..), Bound(..))
+import Text.PrettyPrint (Doc, text, hcat , (<>), empty)
+
+data PackageType = Source | Development | Profiling | Documentation | Utilities | Extra deriving (Eq, Show)
+
+data VersionSplits
+    = VersionSplits {
+        packageName :: PackageName
+      , oldestPackage :: BinPkgName
+      , splits :: [(Version, BinPkgName)] -- Assumed to be in version number order
+      }
+
+instance Interspersed VersionSplits BinPkgName Version where
+    leftmost (VersionSplits {splits = []}) = error "Empty Interspersed instance"
+    leftmost (VersionSplits {oldestPackage = p}) = p
+    pairs (VersionSplits {splits = xs}) = xs
+
+-- | Turn a cabal dependency into debian dependencies.  The result
+-- needs to correspond to a single debian package to be installed,
+-- so we will return just an OrRelation.
+dependencies :: Flags -> Compiler -> (PackageType -> [VersionSplits]) -> PackageType -> Either BinPkgName PackageName -> VersionRange -> Relations
+dependencies flags compiler versionSplits typ (Left name) cabalRange = [[D.Rel name Nothing Nothing]]
+dependencies flags compiler versionSplits typ (Right name@(PackageName string)) cabalRange =
+    map doBundled $ convert' (canonical (Or (catMaybes (map convert alts))))
+    where
+
+      -- Compute a list of alternative debian dependencies for
+      -- satisfying a cabal dependency.  The only caveat is that
+      -- we may need to distribute any "and" dependencies implied
+      -- by a version range over these "or" dependences.
+      alts :: [(BinPkgName, VersionRange)]
+      alts = case Map.lookup name (packageSplits versionSplits typ) of
+               -- If there are no splits for this package just return the single dependency for the package
+               Nothing -> [(mkPkgName string typ, cabalRange')]
+               -- If there are splits create a list of (debian package name, VersionRange) pairs
+               Just splits -> packageRangesFromVersionSplits splits
+
+      convert :: (BinPkgName, VersionRange) -> Maybe (Rels Relation)
+      convert (dname, range) =
+          if isNoVersion range'''
+          then Nothing
+          else Just $
+               foldVersionRange'
+                 (Rel (D.Rel dname Nothing Nothing))
+                 (\ v -> Rel (D.Rel dname (Just (D.EEQ (dv v))) Nothing))
+                 (\ v -> Rel (D.Rel dname (Just (D.SGR (dv v))) Nothing))
+                 (\ v -> Rel (D.Rel dname (Just (D.SLT (dv v))) Nothing))
+                 (\ v -> Rel (D.Rel dname (Just (D.GRE (dv v))) Nothing))
+                 (\ v -> Rel (D.Rel dname (Just (D.LTE (dv v))) Nothing))
+                 (\ x y -> error "I don't think this ever gets called") -- And [Rel (D.Rel dname (Just (D.GRE (dv x))) Nothing), Rel (D.Rel dname (Just (D.LTE (dv y))) Nothing)])
+                 (\ x y -> Or [x, y])
+                 (\ x y -> And [x, y])
+                 id
+                 range'''
+          where 
+            -- Choose the simpler of the two
+            range''' = canon (simpler range' range'')
+            -- Unrestrict the range for versions that we know don't exist for this debian package
+            range'' = canon (unionVersionRanges range' (invertVersionRange range))
+            -- Restrict the range to the versions specified for this debian package
+            range' = intersectVersionRanges cabalRange' range
+            -- When we see a cabal equals dependency we need to turn it into
+            -- a wildcard because the resulting debian version numbers have
+            -- various suffixes added.
+      cabalRange' =
+          foldVersionRange'
+            anyVersion
+            withinVersion  -- <- Here we are turning equals into wildcard
+            laterVersion
+            earlierVersion
+            orLaterVersion
+            orEarlierVersion
+            (\ lb ub -> intersectVersionRanges (orLaterVersion lb) (earlierVersion ub))
+            unionVersionRanges
+            intersectVersionRanges
+            id
+            cabalRange
+      -- Convert a cabal version to a debian version, adding an epoch number if requested
+      dv v = parseDebianVersion (maybe "" (\ n -> show n ++ ":") (Map.lookup name (epochMap flags)) ++ showVersion v)
+      simpler v1 v2 = minimumBy (compare `on` (length . asVersionIntervals)) [v1, v2]
+      -- Simplify a VersionRange
+      canon = fromVersionIntervals . toVersionIntervals
+
+      -- If a package is bundled with the compiler we make the
+      -- compiler a substitute for that package.  If we were to
+      -- specify the virtual package (e.g. libghc-base-dev) we would
+      -- have to make sure not to specify a version number.
+      doBundled :: [D.Relation] -> [D.Relation]
+      doBundled rels | ghcBuiltIn compiler name = rels ++ [D.Rel (compilerPackageName typ) Nothing Nothing]
+      doBundled rels = rels
+
+      compilerPackageName Documentation = D.BinPkgName (D.PkgName "ghc-doc")
+      compilerPackageName Profiling = D.BinPkgName (D.PkgName "ghc-prof")
+      compilerPackageName Development = D.BinPkgName (D.PkgName "ghc")
+      compilerPackageName _ = D.BinPkgName (D.PkgName "ghc") -- whatevs
+
+data Rels a = And {unAnd :: [Rels a]} | Or {unOr :: [Rels a]} | Rel {unRel :: a} deriving Show
+
+-- | The intent of this class is to be similar to Show, but only one
+-- way, with no corresponding Read class.  To put something in a
+-- pretty printing class implies that there is only one way to pretty
+-- print it, which is not an assumption made by Text.PrettyPrint.  But
+-- in practice this is often good enough.
+class Pretty x where
+    pretty :: x -> Doc
+
+-- | return and of ors of rel
+canonical :: Rels a -> Rels a
+canonical (Rel rel) = And [Or [Rel rel]]
+canonical (And rels) = And $ concatMap (unAnd . canonical) rels
+canonical (Or rels) = And . map Or $ sequence $ map (concat . map unOr . unAnd . canonical) $ rels
+
+convert' :: Rels a -> [[a]]
+convert' = map (map unRel . unOr) . unAnd . canonical
+
+packageSplits :: (PackageType -> [VersionSplits]) -> PackageType -> Map.Map PackageName VersionSplits
+packageSplits versionSplits typ =
+    foldr (\ splits mp -> Map.insertWith multipleSplitsError (packageName splits) splits mp)
+          Map.empty
+          (versionSplits typ)
+    where
+      multipleSplitsError (VersionSplits {packageName = PackageName p}) _s2 =
+          error ("Multiple splits for package " ++ show p)
+
+packageRangesFromVersionSplits :: VersionSplits -> [(BinPkgName, VersionRange)]
+packageRangesFromVersionSplits splits =
+    foldInverted (\ older dname newer more ->
+                      (dname, intersectVersionRanges (maybe anyVersion orLaterVersion older) (maybe anyVersion earlierVersion newer)) : more)
+                 []
+                 splits
+
+-- | Build a debian package name from a cabal package name and a
+-- debian package type.
+mkPkgName :: String -> PackageType -> BinPkgName
+mkPkgName base typ =
+    BinPkgName . PkgName $ prefix typ ++ map toLower base ++ suffix typ
+    where
+      suffix Source = ""
+      suffix Documentation = "-doc"
+      suffix Development = "-dev"
+      suffix Profiling = "-prof"
+      suffix Utilities = "-utils"
+      suffix Extra = ""
+
+      prefix Source = "haskell-"
+      prefix Documentation = "libghc-"
+      prefix Development = "libghc-"
+      prefix Profiling = "libghc-"
+      prefix Utilities = "haskell-"
+      prefix Extra = ""
+
+instance Pretty VersionRange where
+    pretty range =
+        foldVersionRange'
+          (text "*")
+          (\ v -> text "=" <> pretty v)
+          (\ v -> text ">" <> pretty v)
+          (\ v -> text "<" <> pretty v)
+          (\ v -> text ">=" <> pretty v)
+          (\ v -> text "<=" <> pretty v)
+          (\ x _ -> text "=" <> pretty x <> text ".*") -- not exactly right
+          (\ x y -> text "(" <> x <> text " || " <> y <> text ")")
+          (\ x y -> text "(" <> x <> text " && " <> y <> text ")")
+          (\ x -> text "(" <> x <> text ")")
+          range
+
+instance Pretty Version where
+    pretty = text . showVersion
+
+instance Pretty a => Pretty [a] where
+    pretty xs = text "[" <> hcat (intersperse (text ", ") (map pretty xs)) <> text "]"
+
+instance (Pretty a, Pretty b) => Pretty (a, b) where
+    pretty (a, b) = text "(" <> pretty a <> text ", " <> pretty b <> text ")"
+
+instance Pretty D.BinPkgName where
+    pretty (D.BinPkgName p) = text "deb:" <> (pretty p)
+
+instance Pretty D.PkgName where
+    pretty (D.PkgName p) = text p
+
+instance Pretty D.Relation where
+    pretty (D.Rel name ver arch) =
+        pretty name <> maybe empty pretty ver <> maybe empty pretty arch
+
+instance Pretty D.VersionReq where
+    pretty (D.EEQ v) = text "=" <> pretty v
+    pretty (D.SLT v) = text "<" <> pretty v
+    pretty (D.LTE v) = text "<=" <> pretty v
+    pretty (D.GRE v) = text ">=" <> pretty v
+    pretty (D.SGR v) = text ">" <> pretty v
+
+instance Pretty D.ArchitectureReq where
+    pretty (D.ArchOnly ss) = text "[" <> hcat (intersperse (text ",") (map text ss)) <> text "]"
+    pretty (D.ArchExcept ss) = text "[!" <> hcat (intersperse (text ",") (map text ss)) <> text "]"
+
+instance Pretty DebianVersion where
+    pretty = text . show
+
+instance Show D.Relation where
+    show = show . pretty
+instance Show D.ArchitectureReq where
+    show = show . pretty
+
+invertVersionRange :: VersionRange -> VersionRange
+invertVersionRange = fromVersionIntervals . maybe (error "invertVersionRange") id . mkVersionIntervals . invertVersionIntervals . asVersionIntervals
+
+invertVersionIntervals :: [(LowerBound, UpperBound)] -> [(LowerBound, UpperBound)]
+invertVersionIntervals xs =
+    case xs of
+      [] -> [(lb0, NoUpperBound)]
+      ((LowerBound (Version {versionBranch = [0], versionTags = []}) InclusiveBound, ub) : more) ->
+          invertVersionIntervals' ub more
+      ((lb, ub) : more) ->
+          (lb0, invertLowerBound lb) : invertVersionIntervals' ub more
+    where
+      invertVersionIntervals' :: UpperBound -> [(LowerBound, UpperBound)] -> [(LowerBound, UpperBound)]
+      invertVersionIntervals' NoUpperBound [] = []
+      invertVersionIntervals' ub0 [] = [(invertUpperBound ub0, NoUpperBound)]
+      invertVersionIntervals' ub0 [(lb, NoUpperBound)] = [(invertUpperBound ub0, invertLowerBound lb)]
+      invertVersionIntervals' ub0 ((lb, ub1) : more) = (invertUpperBound ub0, invertLowerBound lb) : invertVersionIntervals' ub1 more
+
+      invertLowerBound :: LowerBound -> UpperBound
+      invertLowerBound (LowerBound v b) = UpperBound v (invertBound b)
+
+      invertUpperBound :: UpperBound -> LowerBound
+      invertUpperBound (UpperBound v b) = LowerBound v (invertBound b)
+      invertUpperBound NoUpperBound = error "NoUpperBound: unexpected"
+
+      invertBound :: Bound -> Bound
+      invertBound ExclusiveBound = InclusiveBound
+      invertBound InclusiveBound = ExclusiveBound
+
+      lb0 :: LowerBound
+      lb0 = LowerBound (Version {versionBranch = [0], versionTags = []}) InclusiveBound
+
+deriving instance Show VersionReq
+instance Show DebianVersion where
+    show = show . prettyDebianVersion
+
+debianSourcePackageName :: (PackageType -> [VersionSplits]) -> PackageName -> Maybe VersionReq -> SrcPkgName
+debianSourcePackageName versionSplits name version = SrcPkgName (D.unBinPkgName (debianName Source versionSplits name version))
+
+debianDevPackageName :: (PackageType -> [VersionSplits]) -> PackageName -> Maybe VersionReq -> BinPkgName
+debianDevPackageName versionSplits name version = debianName Development versionSplits name version
+
+debianProfPackageName :: (PackageType -> [VersionSplits]) -> PackageName -> Maybe VersionReq -> BinPkgName
+debianProfPackageName versionSplits name version = debianName Profiling versionSplits name version
+
+debianDocPackageName :: (PackageType -> [VersionSplits]) -> PackageName -> Maybe VersionReq -> BinPkgName
+debianDocPackageName versionSplits name version = debianName Documentation versionSplits name version
+
+type DebianBinPackageName = PackageName -> Maybe VersionReq -> BinPkgName
+
+debianExtraPackageName :: (PackageType -> [VersionSplits]) -> PackageName -> Maybe VersionReq -> BinPkgName
+debianExtraPackageName versionSplits name version = debianName Extra versionSplits name version
+
+debianUtilsPackageName :: (PackageType -> [VersionSplits]) -> PackageName -> Maybe VersionReq -> BinPkgName
+debianUtilsPackageName versionSplits name version = debianName Utilities versionSplits name version
+
+-- | Return the basename of the debian package for a given version
+-- relation.  If the version split happens at v, this will return the
+-- ltName is < v and the geName if the relation is >= v.  It also handles
+-- a special case for the name of the haskell-src-exts package.
+debianName :: PackageType -> (PackageType -> [VersionSplits]) -> PackageName -> Maybe VersionReq -> BinPkgName
+debianName typ versionSplits pname@(PackageName name) version =
+    case filter (\ x -> pname == packageName x) (versionSplits typ) of
+      [] -> def
+      [splits] ->
+          foldTriples' (\ ltName v geName debName ->
+                           if pname /= packageName splits
+                           then debName
+                           else let split = parseDebianVersion (showVersion v) in
+                                case version of
+                                  Nothing -> geName
+                                  Just (SLT v') | v' <= split -> ltName
+                                  -- Otherwise use ltName only when the split is below v'
+                                  Just (EEQ v') | v' < split -> ltName
+                                  Just (LTE v') | v' < split -> ltName
+                                  Just (GRE v') | v' < split -> ltName
+                                  Just (SGR v') | v' < split -> ltName
+                                  _ -> geName)
+                       def
+                       splits
+      _ -> error $ "Multiple splits for cabal package " ++ name
+    where
+      foldTriples' :: (BinPkgName -> Version -> BinPkgName -> BinPkgName -> BinPkgName) -> BinPkgName -> VersionSplits -> BinPkgName
+      foldTriples' = foldTriples
+      def = mkPkgName (map fixChar name) typ
+
+fixChar :: Char -> Char
+fixChar '_' = '-'
+fixChar c = toLower c
diff --git a/Distribution/Package/Debian/Interspersed.hs b/Distribution/Package/Debian/Interspersed.hs
new file mode 100644
--- /dev/null
+++ b/Distribution/Package/Debian/Interspersed.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE FlexibleInstances, FunctionalDependencies, MultiParamTypeClasses, StandaloneDeriving, TypeSynonymInstances #-}
+{-# OPTIONS_GHC -Wall -Werror #-}
+module Distribution.Package.Debian.Interspersed
+    ( Interspersed(..)
+    ) where
+
+import Debug.Trace
+
+-- | A class of Bs insterspersed with Cs.  Minimum implementation is a
+-- method to return the leftmost B, and another to return the
+-- following (C,B) pairs.  Its unfortunate to require lists in the
+-- implementation, a fold function would be better (though I find
+-- implementing such folds to be a pain in the you-know-what.)
+-- 
+-- The class provides implementations of three folds, each of which
+-- exposes slightly different views of the data.
+class Interspersed t around between | t -> around, t -> between where
+    leftmost :: t -> around
+    pairs :: t -> [(between, around)]
+
+    foldTriples :: (around -> between -> around -> r -> r) -> r -> t -> r
+    foldTriples f r0 x = snd $ foldl (\ (b1, r) (c, b2) -> (b2, f b1 c b2 r)) (leftmost x, r0) (pairs x)
+
+    -- Treat the b's as the centers and the c's as the things to their
+    -- left and right.  Use Maybe to make up for the missing c's at the
+    -- ends.
+    foldInverted :: (Maybe between -> around -> Maybe between -> r -> r) -> r -> t -> r
+    foldInverted f r0 x =
+        (\ (bn, an, r) -> f bn an Nothing r) $
+           foldl g (Nothing, leftmost x, r0) (pairs x)
+        where
+          g (b1, a1, r) (b2, a2) = (Just b2, a2, f b1 a1 (Just b2) r)
+
+    foldArounds :: (around -> around -> r -> r) -> r -> t -> r
+    foldArounds f r0 x = snd $ foldl (\ (a1, r) (_, a2) -> (a2, f a1 a2 r)) (leftmost x, r0) (pairs x)
+
+    foldBetweens :: (between -> r -> r) -> r -> t -> r
+    foldBetweens f r0 x = foldl (\ r (b, _) -> (f b r)) r0 (pairs x)
+
+-- | An example
+data Splits = Splits Double [(String, Double)] deriving Show
+
+instance Interspersed Splits Double String where
+    leftmost (Splits x _) = x
+    pairs (Splits _ x) = x
+
+_splits :: Splits
+_splits = Splits 1.0 [("between 1 and 2", 2.0), ("between 2 and 3", 3.0)]
+
+_test1 :: ()
+_test1 = foldTriples (\ l s r () -> trace ("l=" ++ show l ++ " s=" ++ show s ++ " r=" ++ show r) ()) () _splits
+
+_test2 :: ()
+_test2 = foldInverted (\ sl f sr () -> trace ("sl=" ++ show sl ++ " f=" ++ show f ++ " sr=" ++ show sr) ()) () _splits
diff --git a/Distribution/Package/Debian/Main.hs b/Distribution/Package/Debian/Main.hs
new file mode 100644
--- /dev/null
+++ b/Distribution/Package/Debian/Main.hs
@@ -0,0 +1,28 @@
+-- |
+-- Module      :  Distribution.Package.Debian.Main
+-- Copyright   :  David Fox 2008
+--
+-- Maintainer  :  David Fox <dsf@seereason.com>
+-- Stability   :  alpha
+-- Portability :  portable
+--
+-- Explanation: Main entry point for Debianizer of Cabal packages.
+
+-- This software may be used and distributed according to the terms of
+-- the GNU General Public License, incorporated herein by reference.
+
+module Distribution.Package.Debian.Main where
+
+import Distribution.PackageDescription.Parse (readPackageDescription)
+import Distribution.Package.Debian (debian)
+import Distribution.Package.Debian.Setup (Flags (..), parseArgs)
+import Distribution.Simple.Utils (defaultPackageDesc)
+import System.Environment (getArgs)
+
+main :: IO ()
+
+main = do opts <- getArgs >>= parseArgs
+          let verbosity = rpmVerbosity opts
+          descPath <- defaultPackageDesc verbosity
+          pkgDesc <- readPackageDescription verbosity descPath
+          debian pkgDesc opts
diff --git a/Distribution/Package/Debian/Relations.hs b/Distribution/Package/Debian/Relations.hs
new file mode 100644
--- /dev/null
+++ b/Distribution/Package/Debian/Relations.hs
@@ -0,0 +1,135 @@
+{-# LANGUAGE CPP, FlexibleInstances, MultiParamTypeClasses, PackageImports, ScopedTypeVariables,
+             StandaloneDeriving, TupleSections, TypeSynonymInstances #-}
+{-# OPTIONS -Wall -fno-warn-orphans #-}
+
+-- |
+-- Module      :  Distribution.Package.Debian
+-- Copyright   :  David Fox 2008
+--
+-- Maintainer  :  David Fox <dsf@seereason.com>
+-- Stability   :  alpha
+-- Portability :  portable
+--
+-- Explanation: Support for generating Debianization from Cabal data.
+
+-- This software may be used and distributed according to the terms of
+-- the GNU General Public License, incorporated herein by reference.
+
+module Distribution.Package.Debian.Relations
+    ( allBuildDepends
+    , buildDependencies
+    , docDependencies
+    , cabalDependencies
+    , versionSplits
+    ) where
+
+import Data.Char (isSpace)
+import Data.List
+import qualified Data.Map as Map
+import Data.Maybe
+import Data.Version (Version(Version))
+import qualified Debian.Relation as D
+import Distribution.Simple.Compiler (Compiler(..))
+import Distribution.Package (PackageName(..), Dependency(..))
+import Distribution.PackageDescription (PackageDescription(..),
+                                        allBuildInfo, buildTools, pkgconfigDepends,
+                                        extraLibs)
+import Distribution.Version (anyVersion)
+import Distribution.Package.Debian.Setup (Flags(..))
+import Distribution.Package.Debian.Dependencies (PackageType(..), VersionSplits(..), dependencies, mkPkgName)
+import System.Exit (ExitCode(ExitSuccess))
+import System.IO.Unsafe (unsafePerformIO)
+import System.Process (readProcessWithExitCode)
+
+cabalDependencies :: Flags -> PackageDescription -> [Dependency]
+cabalDependencies flags pkgDesc = catMaybes $ map unboxDependency $ allBuildDepends flags pkgDesc
+
+-- |Debian packages don't have per binary package build dependencies,
+-- so we just gather them all up here.
+allBuildDepends :: Flags -> PackageDescription -> [Dependency_]
+allBuildDepends flags pkgDesc =
+    nub $ map BuildDepends (buildDepends pkgDesc) ++
+          concat (map (map BuildTools . buildTools) (allBuildInfo pkgDesc) ++
+                  map
+                    (map PkgConfigDepends . pkgconfigDepends)
+                    (allBuildInfo pkgDesc) ++
+                  map (map ExtraLibs . (fixDeps . extraLibs)) (allBuildInfo pkgDesc))
+    where
+      fixDeps :: [String] -> [D.BinPkgName]
+      fixDeps xs = concatMap (\ cab -> fromMaybe [D.BinPkgName (D.PkgName ("lib" ++ cab ++ "-dev"))] (Map.lookup cab (depMap flags))) xs
+
+-- The build dependencies for a package include the profiling
+-- libraries and the documentation packages, used for creating cross
+-- references.
+buildDependencies :: Flags -> Compiler -> Dependency_ -> D.Relations
+buildDependencies flags compiler (BuildDepends (Dependency name ranges)) =
+    dependencies flags compiler versionSplits Development (Right name) ranges ++ dependencies flags compiler versionSplits Profiling (Right name) ranges
+buildDependencies flags compiler dep@(ExtraLibs _) =
+    concat (map (\ x -> dependencies flags compiler versionSplits Extra (Left x) anyVersion) $ adapt flags dep)
+buildDependencies flags compiler dep =
+    case unboxDependency dep of
+      Just (Dependency _name ranges) ->
+          concat (map (\ x -> dependencies flags compiler versionSplits Extra (Left x) ranges) $ adapt flags dep)
+      Nothing ->
+          []
+
+adapt :: Flags -> Dependency_ -> [D.BinPkgName]
+adapt flags (PkgConfigDepends (Dependency (PackageName pkg) _)) =
+    maybe (aptFile pkg) (: []) (Map.lookup pkg (execMap flags))
+adapt flags (BuildTools (Dependency (PackageName pkg) _)) =
+    maybe (aptFile pkg) (: []) (Map.lookup pkg (execMap flags))
+adapt _flags (ExtraLibs x) = [x]
+{-
+    maybe (error ("No mapping from library " ++ x ++ " to debian binary package name"))
+              (map (\ s -> PackageName ("lib" ++ s ++ "-dev"))) (Map.lookup x (depMap flags))
+-}
+adapt _flags (BuildDepends (Dependency (PackageName pkg) _)) = [D.BinPkgName (D.PkgName pkg)]
+
+-- |There are two reasons this may not work, or may work
+-- incorrectly: (1) the build environment may be a different
+-- distribution than the parent environment (the environment the
+-- autobuilder was run from), so the packages in that
+-- environment might have different names, and (2) the package
+-- we are looking for may not be installed in the parent
+-- environment.
+aptFile :: String -> [D.BinPkgName] -- Maybe would probably be more correct
+aptFile pkg =
+    unsafePerformIO $
+          do ret <- readProcessWithExitCode "apt-file" ["-l", "search", pkg ++ ".pc"] ""
+             return $ case ret of
+                        (ExitSuccess, out, _) -> [D.BinPkgName (D.PkgName (takeWhile (not . isSpace) out))]
+                        _ -> []
+
+-- The documentation dependencies for a package include the documentation
+-- package for any libraries which are build dependencies, so we have access
+-- to all the cross references.
+docDependencies :: Flags -> Compiler -> Dependency_ -> D.Relations
+docDependencies flags compiler (BuildDepends (Dependency name ranges)) =
+    dependencies flags compiler versionSplits Documentation (Right name) ranges
+docDependencies _ _ _ = []
+
+data Dependency_
+  = BuildDepends Dependency
+      | BuildTools Dependency
+      | PkgConfigDepends Dependency
+      | ExtraLibs D.BinPkgName
+    deriving (Eq, Show)
+
+unboxDependency :: Dependency_ -> Maybe Dependency
+unboxDependency (BuildDepends d) = Just d
+unboxDependency (BuildTools d) = Just d
+unboxDependency (PkgConfigDepends d) = Just d
+unboxDependency (ExtraLibs _) = Nothing -- Dependency (PackageName d) anyVersion
+
+-- | These are the instances of debian names changing that we know about.
+versionSplits :: PackageType -> [VersionSplits]
+versionSplits typ =
+    [ VersionSplits {
+        packageName = PackageName "parsec"
+      , oldestPackage = mkPkgName "parsec2" typ
+      , splits = [(Version [3] [], mkPkgName "parsec3" typ)] }
+    , VersionSplits {
+        packageName = PackageName "QuickCheck"
+      , oldestPackage = mkPkgName "quickcheck1" typ
+      , splits = [(Version [2] [], mkPkgName "quickcheck2" typ)] }
+    ]
diff --git a/Distribution/Package/Debian/Setup.hs b/Distribution/Package/Debian/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Distribution/Package/Debian/Setup.hs
@@ -0,0 +1,220 @@
+-- |
+-- Module      :  Distribution.Package.Debian.Setup
+-- Copyright   :  David Fox 2008
+--
+-- Maintainer  :  David Fox <dsf@seereason.com>
+-- Stability   :  alpha
+-- Portability :  portable
+--
+-- Explanation: Command line option processing for building RPM
+-- packages.
+
+-- This software may be used and distributed according to the terms of
+-- the GNU General Public License, incorporated herein by reference.
+
+module Distribution.Package.Debian.Setup (
+      Flags(..)
+    , DebAction(..)
+    , DebType(..)
+    , parseArgs
+    ) where
+
+import Control.Monad (when)
+import Data.Char (toLower, isDigit, ord)
+import qualified Data.Map as Map
+import Data.Version (Version, parseVersion)
+import Debian.Relation (PkgName(..), BinPkgName(..))
+import Distribution.Compiler (CompilerFlavor(..))
+import Distribution.ReadE (readEOrFail)
+import Distribution.PackageDescription (FlagName(..))
+import Distribution.Package (PackageName(..))
+import Distribution.Verbosity (Verbosity, flagToVerbosity, normal)
+import System.Console.GetOpt (ArgDescr (..), ArgOrder (..), OptDescr (..),
+                              usageInfo, getOpt')
+import System.Environment (getProgName)
+import System.Exit (exitWith, ExitCode (..))
+import System.IO (Handle, hPutStrLn, stderr, stdout)
+import Text.ParserCombinators.ReadP (readP_to_S)
+
+data Flags = Flags
+    {
+      rpmPrefix :: FilePath
+    , rpmCompiler :: CompilerFlavor
+    , rpmCompilerVersion :: Maybe Version
+    , rpmConfigurationsFlags :: [(FlagName, Bool)]
+    , rpmHaddock :: Bool
+    , rpmHelp :: Bool
+    , debLibProf :: Bool
+    , rpmName :: Maybe String
+    , rpmOptimisation :: Bool
+    , rpmRelease :: Maybe String
+    , rpmSplitObjs :: Bool
+    , debOutputDir :: FilePath
+    , buildRoot :: FilePath
+    , rpmVerbosity :: Verbosity
+    , rpmVersion :: Maybe String
+    , debMaintainer :: Maybe String
+    , debAction :: DebAction
+    , buildDeps :: [String]
+    , extraDevDeps :: [String]
+    -- , debName :: Maybe String
+    , debVersion :: Maybe String
+    , depMap :: Map.Map String [BinPkgName]
+    , epochMap :: Map.Map PackageName Int
+    , revision :: String
+    , execMap :: Map.Map String BinPkgName
+    , omitLTDeps :: Bool
+    , sourceFormat :: String
+    }
+    deriving (Eq, Show)
+
+data DebType = Dev| Prof | Doc deriving (Eq, Read, Show)
+
+data DebAction = Usage | Debianize | SubstVar DebType | UpdateDebianization deriving (Eq, Show)
+
+emptyFlags :: Flags
+
+emptyFlags = Flags
+    {
+      rpmPrefix = "/usr/lib/haskell-packages/ghc6"
+    , rpmCompiler = GHC
+    , rpmCompilerVersion = Nothing
+    , rpmConfigurationsFlags = []
+    , rpmHaddock = True
+    , rpmHelp = False
+    , debLibProf = True
+    , rpmName = Nothing
+    , rpmOptimisation = True
+    , rpmRelease = Nothing
+    , rpmSplitObjs = True
+    , debOutputDir = "./debian"
+    , buildRoot = "/"
+    , rpmVerbosity = normal
+    , rpmVersion = Nothing
+    , debMaintainer = Nothing
+    , debAction = Usage
+    , buildDeps = []
+    , extraDevDeps = []
+    , depMap = Map.empty
+    , epochMap = Map.empty
+    -- , debName = Nothing
+    , debVersion = Nothing
+    , revision = "-1~hackage1"
+    , execMap = Map.empty
+    , omitLTDeps = False
+    , sourceFormat = "3.0 (native)"
+    }
+
+options :: [OptDescr (Flags -> Flags)]
+
+options =
+    [
+      Option "" ["prefix"] (ReqArg (\ path x -> x { rpmPrefix = path }) "PATH")
+             "Pass this prefix if we need to configure the package",
+      Option "" ["ghc"] (NoArg (\x -> x { rpmCompiler = GHC }))
+             "Compile with GHC",
+      Option "" ["hugs"] (NoArg (\x -> x { rpmCompiler = Hugs }))
+             "Compile with Hugs",
+      Option "" ["jhc"] (NoArg (\x -> x { rpmCompiler = JHC }))
+             "Compile with JHC",
+      Option "" ["nhc"] (NoArg (\x -> x { rpmCompiler = NHC }))
+             "Compile with NHC",
+      Option "h?" ["help"] (NoArg (\x -> x { rpmHelp = True }))
+             "Show this help text",
+      Option "" ["ghc-version"] (ReqArg (\ ver x -> x { rpmCompilerVersion = Just (last (map fst (readP_to_S parseVersion ver)))}) "VERSION")
+             "Version of GHC in build environment",
+      Option "" ["name"] (ReqArg (\name x -> x { rpmName = Just name }) "NAME")
+             "Override the default package name",
+      Option "" ["disable-haddock"] (NoArg (\x -> x { rpmHaddock = False }))
+             "Don't generate API docs",
+      Option "" ["disable-library-profiling"] (NoArg (\x -> x { debLibProf = False }))
+             "Don't generate profiling libraries",
+      Option "" ["disable-optimization"] (NoArg (\x -> x { rpmOptimisation = False }))
+             "Don't generate optimised code",
+      Option "" ["disable-split-objs"] (NoArg (\x -> x { rpmSplitObjs = False }))
+             "Don't split object files to save space",
+      Option "f" ["flags"] (ReqArg (\flags x -> x { rpmConfigurationsFlags = rpmConfigurationsFlags x ++ flagList flags }) "FLAGS")
+             "Set given flags in Cabal conditionals",
+      Option "" ["release"] (ReqArg (\rel x -> x { rpmRelease = Just rel }) "RELEASE")
+             "Override the default package release",
+      Option "" ["debdir"] (ReqArg (\path x -> x { debOutputDir = path }) "DEBDIR")
+             ("Override the default output directory (" ++ show (debOutputDir emptyFlags) ++ ")"),
+      Option "" ["root"] (ReqArg (\ path x -> x { buildRoot = path }) "BUILDROOT")
+             "Use the compiler information in the given build environment.",
+      Option "v" ["verbose"] (ReqArg (\verb x -> x { rpmVerbosity = readEOrFail flagToVerbosity verb }) "n")
+             "Change build verbosity",
+      Option "" ["version"] (ReqArg (\vers x -> x { rpmVersion = Just vers }) "VERSION")
+             "Override the default package version",
+      Option "" ["maintainer"] (ReqArg (\maint x -> x { debMaintainer = Just maint }) "Maintainer Name <email addr>")
+             "Override the Maintainer name and email in $DEBEMAIL/$EMAIL/$DEBFULLNAME/$FULLNAME",
+      Option "" ["debianize"] (NoArg (\x -> x {debAction = Debianize}))
+             "Generate a new debianization, replacing any existing one.  One of --debianize, --substvar, or --update-debianization is required.",
+      Option "" ["build-dep"] (ReqArg (\ name x -> x {buildDeps = name : (buildDeps x)}) "Debian binary package name")
+             "Specify a package to add to the build dependency list in debian/control, e.g. '--build-dep libglib2.0-dev'.",
+      Option "" ["dev-dep"] (ReqArg (\ name x -> x {extraDevDeps = name : (extraDevDeps x)}) "Debian binary package name")
+             "Specify a package to add to the Depends: list of the -dev package, e.g. '--build-dep libssl-dev'.",
+      Option "" ["map-dep"] (ReqArg (\ pair x -> x {depMap = case break (== '=') pair of
+                                                               (cab, (_ : deb)) -> Map.insertWith (++) cab [BinPkgName (PkgName deb)] (depMap x)
+                                                               (_, "") -> error "usage: --dep-map CABALNAME=DEBIANNAME"}) "CABALNAME=DEBIANNAME")
+             "Specify a mapping from the name appearing in the Extra-Library field of the cabal file to a debian binary package name, e.g. --dep-map cryptopp=libcrypto-dev",
+      -- Option "" ["deb-name"] (ReqArg (\ name x -> x {debName = Just name}) "NAME")
+      --        "Specify the base name of the debian package, the part between 'libghc-' and '-dev'.  Normally this is the downcased cabal name.",
+      Option "" ["deb-version"] (ReqArg (\ version x -> x {debVersion = Just version}) "VERSION")
+             "Specify the version number for the debian package.  This will pin the version and should be considered dangerous.",
+      Option "" ["revision"] (ReqArg (\ rev x -> x {revision = rev}) "REVISION")
+             "Add this string to the cabal version to get the debian version number.  By default this is '-1~hackage1'.  Debian policy says this must either be empty (--revision '') or begin with a dash.",
+      Option "" ["epoch-map"] (ReqArg (\ pair x -> x {epochMap =
+                                                          case break (== '=') pair of
+                                                            (_, (_ : ['0'])) -> epochMap x
+                                                            (cab, (_ : [d])) | isDigit d -> Map.insert (PackageName cab) (ord d - ord '0') (epochMap x)
+                                                            _ -> error "usage: --epoch-map CABALNAME=DIGIT"}) "CABALNAME=DIGIT")
+             "Specify a mapping from the cabal package name to a digit to use as the debian package epoch number, e.g. --epoch-map HTTP=1",
+      Option "" ["substvar"] (ReqArg (\ name x -> x {debAction = SubstVar (read name)}) "Doc, Prof, or Dev")
+             (unlines ["Write out the list of dependencies required for the dev, prof or doc package depending",
+                       "on the argument.  This value can be added to the appropriate substvars file."]),
+      Option "" ["update-debianization"] (NoArg (\x -> x {debAction = UpdateDebianization}))
+             "Update an existing debianization, or generate a new one.",
+      Option "" ["exec-map"] (ReqArg (\ s x -> x {execMap = case break (== '=') s of
+                                                              (cab, (_ : deb)) -> Map.insert cab (BinPkgName (PkgName deb)) (execMap x)
+                                                              _ -> error "usage: --exec-map CABALNAME=DEBNAME"}) "EXECNAME=DEBIANNAME")
+             "Specify a mapping from the name appearing in the Build-Tool field of the cabal file to a debian binary package name, e.g. --exec-map trhsx=haskell-hsx-utils",
+      Option "" ["omit-lt-deps"] (NoArg (\x -> x { omitLTDeps = True }))
+             "Don't generate the << dependency when we see a cabal equals dependency.",
+      Option "" ["quilt"] (NoArg (\ x -> x {sourceFormat = "3.0 (quilt)"}))
+             "The package has an upstream tarball, write '3.0 (quilt)' into source/format."
+    ]
+
+-- Lifted from Distribution.Simple.Setup, since it's not exported.
+flagList :: String -> [(FlagName, Bool)]
+flagList = map tagWithValue . words
+  where tagWithValue ('-':name) = (FlagName (map toLower name), False)
+        tagWithValue name       = (FlagName (map toLower name), True)
+
+printHelp :: Handle -> IO ()
+
+printHelp h = do
+    progName <- getProgName
+    let info = "Usage: " ++ progName ++ " [FLAGS]\n"
+    hPutStrLn h (usageInfo info options)
+
+parseArgs :: [String] -> IO Flags
+
+parseArgs args = do
+     let (os, args', unknown, errs) = getOpt' RequireOrder options args
+         opts = foldl (flip ($)) emptyFlags os
+     when (rpmHelp opts || debAction opts == Usage) $ do
+       printHelp stdout
+       exitWith ExitSuccess
+     when (not (null errs)) $ do
+       hPutStrLn stderr "Errors:"
+       mapM_ (hPutStrLn stderr) errs
+       exitWith (ExitFailure 1)
+     when (not (null unknown)) $ do
+       hPutStrLn stderr "Unrecognised options:"
+       mapM_ (hPutStrLn stderr) unknown
+       exitWith (ExitFailure 1)
+     when (not (null args')) $ do
+       hPutStrLn stderr "Unrecognised arguments:"
+       mapM_ (hPutStrLn stderr) args'
+       exitWith (ExitFailure 1)
+     return opts
diff --git a/cabal-debian.cabal b/cabal-debian.cabal
--- a/cabal-debian.cabal
+++ b/cabal-debian.cabal
@@ -1,5 +1,5 @@
 Name:           cabal-debian
-Version:        1.23
+Version:        1.24
 License:        BSD3
 License-File:   debian/copyright
 Author:         David Fox <dsf@seereason.com>
@@ -12,7 +12,19 @@
 Description:
   A program which creates a debian subdirectory containing the required
   files to build a deb.
+Data-Files:
+  debian/cabal-debian.1,
+  debian/cabal-debian.manpages,
+  debian/changelog,
+  debian/compat,
+  debian/control,
+  debian/copyright,
+  debian/rules
 
+Source-Repository head
+  type: darcs
+  location: http://src.seereason.com/cabal-debian
+
 Flag cabal19
  Description: True if Cabal >= 1.9 is available
 
@@ -27,3 +39,11 @@
  else
    build-depends: Cabal >= 1.8
    cpp-options: -DCABAL18
+ Other-Modules:
+   Distribution.Package.Debian,
+   Distribution.Package.Debian.Bundled,
+   Distribution.Package.Debian.Dependencies,
+   Distribution.Package.Debian.Interspersed,
+   Distribution.Package.Debian.Main,
+   Distribution.Package.Debian.Relations,
+   Distribution.Package.Debian.Setup
diff --git a/debian/cabal-debian.1 b/debian/cabal-debian.1
new file mode 100644
--- /dev/null
+++ b/debian/cabal-debian.1
@@ -0,0 +1,120 @@
+.\"Original page generated by txt2man and then hacked extensively.
+.TH CABAL-DEBIAN 1  "May 10, 2010"
+
+.SH NAME
+cabal-debian \- create Debian package meta data from a Haskell cabal file.
+
+.SH SYNOPSIS
+.B cabal-debian
+.RI [flags]
+
+.SH DESCRIPTION
+cabal-debian will generated the Debian meta data for a Debian package from the
+cabal file of a Haskell package. The program expects to find the package's
+<pkgname>.cabal file in the directory from which it was run.
+
+.TP
+.B
+\fB--prefix=PATH\fP
+Pass this prefix if we need to configure the package
+
+.TP
+.B
+\fB--ghc\fP
+Compile with GHC.
+
+.TP
+.B
+\fB--hugs\fP
+Compile with HUGS.
+
+.TP
+.B
+\fB--jhc\fP
+Compile with JHC.
+
+.TP
+.B
+\fB--nhc\fP
+Compile with NHC.
+
+.TP
+.B
+\fB-h, -?, \-\-help\fP
+Show this help text.
+
+.TP
+.B
+\fB--name\fP=NAME
+Override the default package name.
+.TP
+.B
+\fB--disable-haddock\fP
+Don't generate API docs.
+.TP
+.B
+\fB--disable-library-profiling\fP
+Don't generate profiling libraries.
+.TP
+.B
+\fB--disable-optimization\fP
+Don't generate optimised code.
+
+.TP
+.B
+\fB--disable-split-objs\fP
+Don't split object files to save space.
+
+.TP
+.B
+\fB-f\fP FLAGS, \fB--flags\fP=FLAGS
+Set given flags in Cabal conditionals.
+
+.TP
+.B
+\fB--release\fP=RELEASE
+Override the default package release.
+
+.TP
+.B
+\fB--debdir\fP=DEBDIR
+Override the default output directory ("./debian").
+
+.TP
+.B
+\fB-v n,q \fB--verbose=n\fP
+Change build verbosity.
+
+.TP
+.B
+\fB--version\fP=VERSION
+Override the default package version.
+
+.TP
+.B
+\fB--maintainer\fP=Maintainer Name <email addr>
+Override the Maintainer name and email in $DEBEMAIL/$EMAIL/$DEBFULLNAME/$FULLNAME.
+
+.TP
+.B
+\fB--debianize\fP
+Generate a new debianization, replacing any existing one.  One of
+\fB--debianize\fP, \fB--substvar\fP, or \fB--update-debianization\fP is
+required.
+
+.TP
+.B
+\fB--substvar\fP=Doc, Prof, or Dev
+Write out the list of dependencies required for the dev, prof or doc package
+depending on the argument. This value can be added to the appropriate substvars
+file.
+
+.TP
+.B
+\fB--update-debianization\fP
+Update an existing debianization.
+
+.SH AUTHOR
+This manual page was originally written by Erik de Castro Lopo 
+<erikd@mega-nerd.com> for the Debian GNU/Linux system (but may be used by 
+others).
diff --git a/debian/cabal-debian.manpages b/debian/cabal-debian.manpages
new file mode 100644
--- /dev/null
+++ b/debian/cabal-debian.manpages
@@ -0,0 +1,1 @@
+debian/*.1
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,190 @@
+haskell-cabal-debian (1.24) unstable; urgency=low
+
+  * No wonder it doesn't build on hackage - none of the source
+    modules were shipped.
+
+ -- David Fox <dsf@seereason.com>  Thu, 14 Jun 2012 08:19:19 -0700
+
+haskell-cabal-debian (1.23) unstable; urgency=low
+
+  * Add a --quilt option to switch from native to quilt format.
+    Without this option the file debian/source/format will contain
+    '3.0 (native)', with it '3.0 (quilt)'.
+
+ -- David Fox <dsf@seereason.com>  Fri, 01 Jun 2012 05:53:36 -0700
+
+haskell-cabal-debian (1.22) unstable; urgency=low
+
+  * Bump version to make sure all changes are uploaded.
+
+ -- David Fox <dsf@seereason.com>  Wed, 23 May 2012 19:54:17 -0700
+
+haskell-cabal-debian (1.21) unstable; urgency=low
+
+  * fix conversion of wildcards into intersected ranges
+
+ -- David Fox <dsf@seereason.com>  Wed, 23 May 2012 19:51:34 -0700
+
+haskell-cabal-debian (1.20) unstable; urgency=low
+
+  * Fix generation of debian library dependencies from the Extra-Libraries
+    field of the cabal file.
+
+ -- David Fox <dsf@seereason.com>  Wed, 23 May 2012 19:50:39 -0700
+
+haskell-cabal-debian (1.19) unstable; urgency=low
+
+  * Handle cabal equals dependencies.
+
+ -- David Fox <dsf@seereason.com>  Tue, 20 Mar 2012 14:34:58 -0700
+
+haskell-cabal-debian (1.18) unstable; urgency=low
+
+  * High level of confidence this time.  Interesting new Interspersed
+    class, and an implementation of invertVersionRanges which should be
+    forwarded to the Cabal folks.
+  * Removes dependency on logic-classes
+
+ -- David Fox <dsf@seereason.com>  Tue, 20 Mar 2012 08:17:25 -0700
+
+haskell-cabal-debian (1.17) unstable; urgency=low
+
+  * Restore code to downcase cabal package name before using it as the
+    base of the debian package name.
+
+ -- David Fox <dsf@seereason.com>  Sun, 18 Mar 2012 15:32:04 -0700
+
+haskell-cabal-debian (1.16) unstable; urgency=low
+
+  * Remove code that implements a special case for the debian name of the
+    haskell-src-exts package.
+
+ -- David Fox <dsf@seereason.com>  Sun, 18 Mar 2012 14:11:21 -0700
+
+haskell-cabal-debian (1.15) unstable; urgency=low
+
+  * Yet another stab at fixing the code for converting cabal dependencies
+    to debian dependencies, with support for splitting version ranges of
+    cabal files among different debian packages.
+
+ -- David Fox <dsf@seereason.com>  Fri, 16 Mar 2012 17:59:28 -0700
+
+haskell-cabal-debian (1.14) unstable; urgency=low
+
+  * Don't try to strip data files
+  * Use permissions 644 for data files, not 755.
+
+ -- David Fox <dsf@seereason.com>  Wed, 07 Mar 2012 14:46:04 -0800
+
+haskell-cabal-debian (1.13) unstable; urgency=low
+
+  * Append the version number when constructing the directory for data
+    files.
+
+ -- David Fox <dsf@seereason.com>  Wed, 07 Mar 2012 08:56:39 -0800
+
+haskell-cabal-debian (1.12) unstable; urgency=low
+
+  * Include any files listed in the Data-Files field of the cabal file
+    in the utils package.
+
+ -- David Fox <dsf@seereason.com>  Tue, 06 Mar 2012 11:31:47 -0800
+
+haskell-cabal-debian (1.11) unstable; urgency=low
+
+  * Replace --epoch flag with --epoch-map, so we can specify epoch numbers
+    for both the package being built and for dependency packages.
+
+ -- David Fox <dsf@seereason.com>  Thu, 09 Feb 2012 07:01:19 -0800
+
+haskell-cabal-debian (1.10) unstable; urgency=low
+
+  * Add bundled package list for ghc 7.4.1.
+
+ -- David Fox <dsf@seereason.com>  Sat, 04 Feb 2012 14:44:33 -0800
+
+haskell-cabal-debian (1.9) unstable; urgency=low
+
+  * Add --dep-map flag to allow mapping of cabal package names to the base
+    of a debian package name.  This modifies the name to which the prefix
+    "lib" and the suffix "-dev" are added.
+  * Fix dependency generation bug introduced in 1.8.
+
+ -- David Fox <dsf@seereason.com>  Mon, 23 Jan 2012 14:13:05 -0800
+
+haskell-cabal-debian (1.8) unstable; urgency=low
+
+  * Add a --dev-dep flag to make one or more packages install dependencies
+    of the dev package.
+
+ -- David Fox <dsf@seereason.com>  Mon, 23 Jan 2012 05:00:46 -0800
+
+haskell-cabal-debian (1.7) unstable; urgency=low
+
+  * Add info about ghc 7.4.0 pre-release.
+
+ -- David Fox <dsf@seereason.com>  Wed, 11 Jan 2012 09:57:45 -0800
+
+haskell-cabal-debian (1.6) unstable; urgency=low
+
+  * Don't omit dependencies built into ghc, they should be satisfied by
+    the Provides in the compiler if they are not available in the
+    repository.  However, we do need to make ghc an alterantive to any
+    versioned dependencies that are bundled with the compiler, since the
+    built in dependencies are virtual packages and thus unversioned.
+
+ -- David Fox <dsf@seereason.com>  Wed, 07 Dec 2011 06:10:17 -0800
+
+haskell-cabal-debian (1.5) unstable; urgency=low
+
+  * Fix the generation of build dependency version ranges by using an
+    intermediate version range type.
+  * If the version range for the cabal file touches two different debian
+    package, don't try to write build dependencies that allow either one,
+    it can't really be done.  Just give the allowable versions of the
+    newer package (e.g. libghc-parsec3-dev rather than libghc-parsec2-dev.)
+
+ -- David Fox <dsf@seereason.com>  Sun, 04 Dec 2011 05:59:25 -0800
+
+haskell-cabal-debian (1.4) unstable; urgency=low
+
+  * Add a --revision <suffix> flag which appends a (perhaps empty) string
+    cabal version number to get the debian version number.  Without this
+    flag the string "-1~hackage1" is appended.
+  * Make it an error to specify a debian version via --deb-version that is
+    older than the current cabal version.
+
+ -- David Fox <dsf@seereason.com>  Sun, 20 Nov 2011 06:45:33 -0800
+
+haskell-cabal-debian (1.3) unstable; urgency=low
+
+  * Fix error message when compiler version is not in bundled package list.
+  * Add bundled package list for compiler 7.0.4 (same as 7.0.3.)
+
+ -- David Fox <dsf@seereason.com>  Sat, 08 Oct 2011 07:58:19 -0700
+
+haskell-cabal-debian (1.2) unstable; urgency=low
+
+  * When computing the debian name from a package's cabal name, if we
+    have no particular version number we are comparing to, use the name
+    from the version split that corresponds to newer version numbers.
+  * Add code to make the cabal package haskell-src-exts map to the debian
+    packages libghc-src-exts-dev etc.  Normally it would map to
+    libghc-haskell-src-exts-dev.
+
+ -- David Fox <dsf@seereason.com>  Thu, 06 Oct 2011 09:27:02 -0700
+
+haskell-cabal-debian (1.1) unstable; urgency=low
+
+  * Use propositional logic package to compute normal form for dependencies
+  * Make sure to correct format of cabal package synopsis before using as debian
+    package description.
+
+ -- David Fox <dsf@seereason.com>  Fri, 30 Sep 2011 06:16:34 -0700
+
+haskell-cabal-debian (1.0) unstable; urgency=low
+
+  * Debianization generated by cabal-debian
+
+ -- David Fox <dsf@seereason.com>  Sun, 18 Sep 2011 06:40:21 -0700
+
diff --git a/debian/compat b/debian/compat
new file mode 100644
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1,1 @@
+7
diff --git a/debian/control b/debian/control
new file mode 100644
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,40 @@
+Source: haskell-cabal-debian
+Priority: extra
+Section: haskell
+Maintainer: David Fox <dsf@seereason.com>
+Build-Depends: debhelper (>= 7.0),
+               haskell-devscripts (>= 0.8),
+               cdbs,
+               ghc,
+               ghc-prof,
+               libghc-unixutils-dev (>= 1.50),
+               libghc-unixutils-prof (>= 1.50),
+               libghc-debian-dev (>= 3.63),
+               libghc-debian-prof (>= 3.63),
+               libghc-mtl-dev,
+               libghc-mtl-prof,
+               libghc-parsec3-dev (>= 3),
+               libghc-parsec3-prof (>= 3),
+               libghc-regex-tdfa-dev,
+               libghc-regex-tdfa-prof,
+               libghc-utf8-string-dev,
+               libghc-utf8-string-prof
+Build-Depends-Indep: ghc-doc,
+                     libghc-unixutils-doc (>= 1.50),
+                     libghc-debian-doc (>= 3.63),
+                     libghc-mtl-doc,
+                     libghc-parsec3-doc (>= 3),
+                     libghc-regex-tdfa-doc,
+                     libghc-utf8-string-doc
+Standards-Version: 3.9.1
+Homepage: http://src.seereason.com/cabal-debian
+
+Package: cabal-debian
+Architecture: any
+Section: misc
+Depends: ${shlibs:Depends}, ${haskell:Depends}, ${misc:Depends}, apt-file
+Conflicts: haskell-debian-utils (<< 3.59)
+Description: Create a debianization for a cabal package
+ Tool for creating debianizations of Haskell packages based on the .cabal
+ file.  If apt-file is installed it will use it to discover what is the
+ debian package name of a C library.
diff --git a/debian/rules b/debian/rules
new file mode 100644
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,14 @@
+#!/usr/bin/make -f
+
+DEB_CABAL_PACKAGE = cabal-debian
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/hlibrary.mk
+
+build/cabal-debian:: build-ghc-stamp
+binary-fixup/cabal-debian::
+	install -m 755 -s -D dist-ghc/build/cabal-debian/cabal-debian debian/cabal-debian/usr/bin/cabal-debian || true
+
+# How to install an extra file into the documentation package
+#binary-fixup/libghc-cabal-debian-doc::
+#	echo "Some informative text" > debian/libghc-cabal-debian-doc/usr/share/doc/libghc-cabal-debian-doc/AnExtraDocFile
