diff --git a/Network/Hackage/CabalInstall/Fetch.hs b/Network/Hackage/CabalInstall/Fetch.hs
index 3256716e8811fe97471eb4a1494e7aee74379f7e..ab4292803a82acd8fd71434cbc388e13146518d8 100644
--- a/Network/Hackage/CabalInstall/Fetch.hs
+++ b/Network/Hackage/CabalInstall/Fetch.hs
@@ -21,7 +21,7 @@ module Network.Hackage.CabalInstall.Fetch
     , isFetched
     ) where
 
-import Network.URI (URI,parseURI)
+import Network.URI (URI,parseURI,uriScheme,uriPath)
 import Network.HTTP (ConnError(..), Request (..), simpleHTTP
                            , Response(..), RequestMethod (..))
 
@@ -35,6 +35,7 @@ import Network.Hackage.CabalInstall.Dependency (filterFetchables, resolveDepende
 
 import Distribution.Package (PackageIdentifier, showPackageId)
 import Distribution.Compat.FilePath (joinFileName)
+import System.Directory (copyFile)
 import Text.ParserCombinators.ReadP (readP_to_S)
 import Distribution.ParseUtils (parseDependency)
 
@@ -42,6 +43,9 @@ import Distribution.ParseUtils (parseDependency)
 downloadURI :: FilePath -- ^ Where to put it
             -> URI      -- ^ What to download
             -> IO (Maybe ConnError)
+downloadURI path uri | uriScheme uri == "file:" = do
+    copyFile (uriPath uri) path
+    return Nothing
 downloadURI path uri
     = do eitherResult <- simpleHTTP request
          case eitherResult of
diff --git a/Network/Hackage/CabalInstall/List.hs b/Network/Hackage/CabalInstall/List.hs
new file mode 100644
index 0000000000000000000000000000000000000000..f88ddded8f828f439097cb059d3205a23e65d0f1
--- /dev/null
+++ b/Network/Hackage/CabalInstall/List.hs
@@ -0,0 +1,146 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Network.Hackage.CabalInstall.Install
+-- Copyright   :  (c) David Himmelstrup 2005
+-- License     :  BSD-like
+--
+-- Maintainer  :  lemmih@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- High level interface to package installation.
+-----------------------------------------------------------------------------
+module Network.Hackage.CabalInstall.List
+    ( list    -- :: ConfigFlags -> [UnresolvedDependency] -> IO ()
+    , installPkg -- :: ConfigFlags -> (PackageIdentifier,[String],String) -> IO ()
+    ) where
+
+
+import Control.Exception (bracket_)
+
+import Network.Hackage.CabalInstall.Dependency (getPackages, resolveDependencies)
+import Network.Hackage.CabalInstall.Fetch (isFetched, packageFile, fetchPackage)
+import Network.Hackage.CabalInstall.Types (ConfigFlags(..), UnresolvedDependency(..)
+                                      ,OutputGen(..))
+import Network.Hackage.CabalInstall.TarUtils
+
+import Distribution.Simple.Configure (getInstalledPackages)
+import Distribution.Package (showPackageId, PackageIdentifier)
+import Distribution.Compat.FilePath (joinFileName, splitFileName)
+
+import Text.Printf (printf)
+import System.Directory (getTemporaryDirectory, createDirectoryIfMissing
+                        ,removeDirectoryRecursive, copyFile)
+import System.Process (runProcess, waitForProcess, terminateProcess)
+import System.Exit (ExitCode(..))
+import System.Posix.Signals
+
+-- |Installs the packages needed to satisfy a list of dependencies.
+list :: ConfigFlags -> [String] -> [UnresolvedDependency] -> IO ()
+list cfg globalArgs deps
+    = do ipkgs <- getInstalledPackages (configCompiler cfg) (configUser cfg) (configVerbose cfg)
+         apkgs <- fmap getPackages (resolveDependencies cfg ipkgs deps)
+         mapM_ (installPkg cfg globalArgs) apkgs
+
+-- Fetch a package and output nice messages.
+downloadPkg :: ConfigFlags -> PackageIdentifier -> String -> IO FilePath
+downloadPkg cfg pkg location
+    = do fetched <- isFetched cfg pkg
+         if fetched
+            then do pkgIsPresent (configOutputGen cfg) pkg
+                    return (packageFile cfg pkg)
+            else do downloadingPkg (configOutputGen cfg) pkg
+                    fetchPackage cfg pkg location
+
+whenFlag :: Bool -> String -> [String] -> [String]
+whenFlag True = (:)
+whenFlag False = flip const
+
+-- Attach the correct prefix flag to configure commands,
+-- correct --user flag to install commands and no options to other commands.
+mkPkgOps :: ConfigFlags -> String -> [String] -> [String]
+mkPkgOps cfg "configure" ops
+    = let ops' = whenFlag (configUser cfg) "--user" ops
+      in maybe id (\p -> (:) ("--prefix="++p)) (configPrefix cfg) ops'
+mkPkgOps cfg "install" _ops
+    | configUserIns cfg = return "--user"
+mkPkgOps _cfg _ _ops
+    = []
+
+{-|
+  Download, build and install a given package with some given flags.
+
+  The process is divided up in a few steps:
+
+    * The package is downloaded to {config-dir}\/packages\/{pkg-id} (if not already there).
+
+    * The fetched tarball is then moved to a temporary directory (\/tmp on linux) and unpacked.
+
+    * The lowest directory with a .cabal file is located and searched for a \'Setup.lhs\' or
+      \'Setup.hs\' file.
+
+    * \'runhaskell [Setup script] configure\' is called with the user specified options, \'--user\'
+      if the 'configUser' flag is @True@ and \'--prefix=[PREFIX]\' if 'configPrefix' is not @Nothing@.
+
+    * \'runhaskell [Setup script] build\' is called with no options.
+
+    * \'runhaskell [Setup script] install\' is called with the \'--user\' flag if 'configUserIns' is @True@.
+
+    * The installation finishes by deleting the unpacked tarball.
+-} 
+installPkg :: ConfigFlags
+           -> [String] -- ^Options which will be parse to every package.
+           -> (PackageIdentifier,[String],String) -- ^(Package, list of configure options, package location)
+           -> IO ()
+installPkg cfg globalArgs (pkg,ops,location)
+    = do pkgPath <- downloadPkg cfg pkg location
+         tmp <- getTemporaryDirectory
+         let tmpDirPath = tmp `joinFileName` printf "TMP%sTMP" (showPackageId pkg)
+             tmpPkgPath = tmpDirPath `joinFileName` printf "TAR%s.tgz" (showPackageId pkg)
+             setup setupScript cmd
+                 = let (path,script) = splitFileName setupScript
+                       cmdOps = mkPkgOps cfg cmd (globalArgs++ops)
+                   in do executingCmd output runHc (script:cmd:cmdOps)
+                         h <- runProcess runHc (script:cmd:cmdOps)
+                                                 (Just (tmpDirPath `joinFileName` path))
+                                                 Nothing Nothing (cmdStdout output) (cmdStderr output)
+                         oldHandler <- installHandler keyboardSignal (Catch (terminateProcess h)) Nothing
+                         e <- waitForProcess h
+                         installHandler keyboardSignal oldHandler Nothing 
+                         case e of
+                           ExitFailure err -> cmdFailed output cmd (script:cmd:cmdOps) err
+                           _ -> return ()
+         bracket_ (createDirectoryIfMissing True tmpDirPath)
+                  (removeDirectoryRecursive tmpDirPath)
+                  (do copyFile pkgPath tmpPkgPath
+                      extractTarFile tarProg tmpPkgPath
+                      installUnpackedPkg cfg pkg tmpPkgPath setup
+                      return ())
+    where runHc = configRunHc cfg
+          tarProg = configTarPath cfg
+          output = configOutputGen cfg
+
+installUnpackedPkg :: ConfigFlags -> PackageIdentifier -> FilePath
+                   -> (String -> String -> IO ()) -> IO ()
+installUnpackedPkg cfg pkgId tarFile setup
+    = do tarFiles <- tarballGetFiles tarProg tarFile
+         let cabalFile = locateFileExt tarFiles "cabal"
+         case cabalFile of
+           Just f -> let (path,_) = splitFileName f
+                         mbScript = locateFile tarFiles path ["Setup.lhs", "Setup.hs"]
+                     in case mbScript of
+                          Just script
+                              -> do buildingPkg output pkgId
+                                    stepConfigPkg output pkgId
+                                    setup script "configure"
+                                    stepBuildPkg output pkgId
+                                    setup script "build"
+                                    stepInstallPkg output pkgId
+                                    setup script "install"
+                                    stepFinishedPkg output pkgId
+                                    return ()
+                          Nothing
+                              -> noSetupScript output pkgId
+           Nothing -> noCabalFile output pkgId
+    where output = configOutputGen cfg
+          tarProg = configTarPath cfg
diff --git a/Network/Hackage/CabalInstall/Main.hs b/Network/Hackage/CabalInstall/Main.hs
index 7b215861457a75a439650f96b546da05e2b839bb..06720337a6c3bf6f0094056f129946d8199d311b 100644
--- a/Network/Hackage/CabalInstall/Main.hs
+++ b/Network/Hackage/CabalInstall/Main.hs
@@ -17,6 +17,7 @@ import Network.Hackage.CabalInstall.Types (Action (..))
 import Network.Hackage.CabalInstall.Setup (parseGlobalArgs, parseInstallArgs)
 import Network.Hackage.CabalInstall.Configure (mkConfigFlags)
 
+import Network.Hackage.CabalInstall.List (list)
 import Network.Hackage.CabalInstall.Install (install)
 import Network.Hackage.CabalInstall.Info (info)
 import Network.Hackage.CabalInstall.Update (update)
@@ -29,21 +30,14 @@ main :: IO ()
 main = do args <- getArgs
           (action, flags, args) <- parseGlobalArgs args
           config <- mkConfigFlags flags
+          let runCmd f = do (globalArgs, pkgs) <- parseInstallArgs args
+                            f config globalArgs pkgs
           case action of
-            InstallCmd
-                -> do (globalArgs, pkgs) <- parseInstallArgs args
-                      install config globalArgs pkgs
-            BuildDepCmd
-                -> do (globalArgs, pkgs) <- parseInstallArgs args
-                      buildDep config globalArgs pkgs
-            InfoCmd
-                -> do (globalArgs, pkgs) <- parseInstallArgs args
-                      info config globalArgs pkgs
-            UpdateCmd
-                -> update config
-            CleanCmd
-                -> clean config
-            FetchCmd
-                -> fetch config args
-            _ -> putStrLn "Unhandled command."
-
+            ListCmd     -> runCmd list
+            InstallCmd  -> runCmd install
+            BuildDepCmd -> runCmd buildDep
+            InfoCmd     -> runCmd info
+            UpdateCmd   -> update config
+            CleanCmd    -> clean config
+            FetchCmd    -> fetch config args
+            _           -> putStrLn "Unhandled command."
diff --git a/Network/Hackage/CabalInstall/Types.hs b/Network/Hackage/CabalInstall/Types.hs
index b1a0b5e083f283cd258fbd29b8fcaab81384be1b..24a4bc55c8fda932c69254bde2d870420ef94368 100644
--- a/Network/Hackage/CabalInstall/Types.hs
+++ b/Network/Hackage/CabalInstall/Types.hs
@@ -26,6 +26,7 @@ data Action
     | UpdateCmd
     | InfoCmd
     | HelpCmd
+    | ListCmd
 
 data TempFlags = TempFlags {
         tempHcFlavor    :: Maybe CompilerFlavor,
diff --git a/Network/Hackage/Client.hs b/Network/Hackage/Client.hs
index d6d5a46fce1379a1252d6b1b3e86d5bd177da8da..71d2ac516356098c0fd268d14ac6dcb177652de1 100644
--- a/Network/Hackage/Client.hs
+++ b/Network/Hackage/Client.hs
@@ -1,33 +1,70 @@
 module Network.Hackage.Client where
 
-import Network.XmlRpc.Client
-import Network.XmlRpc.Internals
-
 import Distribution.Package
+import Distribution.PackageDescription
 import Distribution.Version
 import Data.Version
 import Data.Maybe
+import Text.ParserCombinators.ReadP
+import Distribution.ParseUtils
+
+type PathName = String
 
-import Network.Hackage.Version
-import Network.Hackage.Interface
+-- Resolved dependency, pkg location and resolved dependencies of the dependency.
+data ResolvedDependency
+    = ResolvedDependency PackageIdentifier String [(Dependency,Maybe ResolvedDependency)]
+      deriving (Eq,Show)
+
+data Pkg = Pkg String [String] String
+    deriving (Show, Read)
 
 getPkgDescription :: String -> PackageIdentifier -> IO (Maybe String)
-getPkgDescription url = remote url "getPkgDescription"
+getPkgDescription url pkgId = do
+    fmap Just ( getFrom url (pathOf pkgId "cabal") )
 
 getPkgDescriptions :: String -> [PackageIdentifier] -> IO [Maybe String]
-getPkgDescriptions url = remote url "getPkgDescriptions"
+getPkgDescriptions url pkgIds = mapM (getPkgDescription url) pkgIds
 
 getDependencies :: String -> [Dependency] -> IO [(Dependency, Maybe ResolvedDependency)]
-getDependencies url = remote url "getDependencies"
+getDependencies _ _ = fail "getDependencies unimplemented" -- remote url "getDependencies"
 
 listPackages :: String -> IO [(PackageIdentifier,[Dependency],String)]
-listPackages url = remote url "listPackages"
+listPackages url = do
+    x    <- getFrom url "latest.txt" -- remote url "listPackages"
+    pkgs <- readIO x
+    return $ map parsePkg pkgs
+    where
+    parsePkg :: Pkg -> (PackageIdentifier,[Dependency],String)
+    parsePkg (Pkg ident deps _) = (pkgId, pkgDeps, pkgURL)
+        where
+        pkgId   = parseWith parsePackageId ident
+        pkgDeps = map (parseWith parseDependency) deps
+        pkgURL  = url ++ "/" ++ pathOf pkgId "tar.gz"
+
+pathOf :: PackageIdentifier -> String -> PathName
+pathOf pkgId ext = concat [pkgName pkgId, "/", showPackageId pkgId, ".", ext]
 
+parseWith :: Show a => ReadP a -> String -> a
+parseWith f s = case reverse (readP_to_S f s) of
+    ((x, _):_) -> x
+    _          -> error s
+
+-- XXX - check for existence?
 getPkgLocation :: String -> PackageIdentifier -> IO (Maybe String)
-getPkgLocation url = remote url "getPkgLocation"
+getPkgLocation url pkgId = return . Just $ url ++ "/" ++ pathOf pkgId "tar.gz"
 
 getServerVersion :: String -> IO Version
-getServerVersion url = remote url "getServerVersion"
+getServerVersion url = fail "getServerVersion not implemented" -- remote url "getServerVersion"
+
+
+getFrom :: String -> String -> IO String
+getFrom ('f':'i':'l':'e':':':'/':'/':base) path = do
+    readFile $ base ++ "/" ++ path
+getFrom base path = fail $ "Cannot handle " ++ base ++ "/" ++ path
+    
+
 
+{-
 isCompatible :: String -> IO Bool
 isCompatible = fmap ((==) clientVersion) . getServerVersion
+-}
diff --git a/dependencies/hackage-client-0.1.0/Network/Hackage/Client.hs b/dependencies/hackage-client-0.1.0/Network/Hackage/Client.hs
index d6d5a46fce1379a1252d6b1b3e86d5bd177da8da..47a954e3d4996175fb37374d0dde360ccfa11f89 100644
--- a/dependencies/hackage-client-0.1.0/Network/Hackage/Client.hs
+++ b/dependencies/hackage-client-0.1.0/Network/Hackage/Client.hs
@@ -11,6 +11,16 @@ import Data.Maybe
 import Network.Hackage.Version
 import Network.Hackage.Interface
 
+{-
+data ServerResource
+    = ResourceLocation URL
+    | UpdateLocation ServerResource URL
+    | PackageDescription PackageDescription
+    | AuthorDescription { email ... }
+    | ResourceBundle [ServerResource]
+    deriving (Show, Read, Typeable, Ord, Eq)
+-}
+
 getPkgDescription :: String -> PackageIdentifier -> IO (Maybe String)
 getPkgDescription url = remote url "getPkgDescription"
 
@@ -21,7 +31,7 @@ getDependencies :: String -> [Dependency] -> IO [(Dependency, Maybe ResolvedDepe
 getDependencies url = remote url "getDependencies"
 
 listPackages :: String -> IO [(PackageIdentifier,[Dependency],String)]
-listPackages url = remote url "listPackages"
+listPackages url = error "moose" -- remote url "listPackages"
 
 getPkgLocation :: String -> PackageIdentifier -> IO (Maybe String)
 getPkgLocation url = remote url "getPkgLocation"