diff --git a/Bundled/Posix.hsc b/Bundled/Posix.hsc
--- a/Bundled/Posix.hsc
+++ b/Bundled/Posix.hsc
@@ -70,9 +70,14 @@
 
 #include <sys/stat.h>
 
+-- lstat is broken on win32 with at least GHC 6.10.3
 getSymbolicLinkStatus :: FilePath -> IO FileStatus
+##if mingw32_HOST_OS
+getSymbolicLinkStatus = getFileStatus
+##else
 getSymbolicLinkStatus fp =
   do_stat (\p -> (fp `withCString` (`lstat` p)))
+##endif
 
 getFileStatus :: FilePath -> IO FileStatus
 getFileStatus fp =
diff --git a/Bundled/SHA256.hs b/Bundled/SHA256.hs
--- a/Bundled/SHA256.hs
+++ b/Bundled/SHA256.hs
@@ -43,5 +43,5 @@
 
 -- void sha256sum(const unsigned char *d, size_t n, unsigned char *md);
 --
-foreign import ccall unsafe "sha2.h sha256" c_sha256
+foreign import ccall unsafe "sha2.h hashed_storage_sha256" c_sha256
     :: Ptr CChar -> CSize -> Ptr Word8 -> IO ()
diff --git a/Bundled/sha2.c b/Bundled/sha2.c
--- a/Bundled/sha2.c
+++ b/Bundled/sha2.c
@@ -127,27 +127,27 @@
     wv[h] = t1 + t2;                                        \
 }
 
-uint32 sha224_h0[8] =
+static uint32 sha224_h0[8] =
             {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
              0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
 
-uint32 sha256_h0[8] =
+static uint32 sha256_h0[8] =
             {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
              0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
 
-uint64 sha384_h0[8] =
+static uint64 sha384_h0[8] =
             {0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL,
              0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL,
              0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
              0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL};
 
-uint64 sha512_h0[8] =
+static uint64 sha512_h0[8] =
             {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
              0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
              0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
              0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};
 
-uint32 sha256_k[64] =
+static uint32 sha256_k[64] =
             {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
              0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
              0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
@@ -165,7 +165,7 @@
              0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
              0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
 
-uint64 sha512_k[80] =
+static uint64 sha512_k[80] =
             {0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
              0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
              0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
@@ -209,8 +209,8 @@
 
 /* SHA-256 functions */
 
-void sha256_transf(sha256_ctx *ctx, const unsigned char *message,
-                   unsigned int block_nb)
+static void sha256_transf(sha256_ctx *ctx, const unsigned char *message,
+                          unsigned int block_nb)
 {
     uint32 w[64];
     uint32 wv[8];
@@ -324,16 +324,7 @@
     }
 }
 
-void sha256(const unsigned char *message, unsigned int len, unsigned char *digest)
-{
-    sha256_ctx ctx;
-
-    sha256_init(&ctx);
-    sha256_update(&ctx, message, len);
-    sha256_final(&ctx, digest);
-}
-
-void sha256_init(sha256_ctx *ctx)
+static void sha256_init(sha256_ctx *ctx)
 {
 #ifndef UNROLL_LOOPS
     int i;
@@ -351,8 +342,8 @@
     ctx->tot_len = 0;
 }
 
-void sha256_update(sha256_ctx *ctx, const unsigned char *message,
-                   unsigned int len)
+static void sha256_update(sha256_ctx *ctx, const unsigned char *message,
+                          unsigned int len)
 {
     unsigned int block_nb;
     unsigned int new_len, rem_len, tmp_len;
@@ -385,7 +376,7 @@
     ctx->tot_len += (block_nb + 1) << 6;
 }
 
-void sha256_final(sha256_ctx *ctx, unsigned char *digest)
+static void sha256_final(sha256_ctx *ctx, unsigned char *digest)
 {
     unsigned int block_nb;
     unsigned int pm_len;
@@ -423,10 +414,19 @@
 #endif /* !UNROLL_LOOPS */
 }
 
+void hashed_storage_sha256(const unsigned char *message, unsigned int len, unsigned char *digest)
+{
+    sha256_ctx ctx;
+
+    sha256_init(&ctx);
+    sha256_update(&ctx, message, len);
+    sha256_final(&ctx, digest);
+}
+
 /* SHA-512 functions */
 
-void sha512_transf(sha512_ctx *ctx, const unsigned char *message,
-                   unsigned int block_nb)
+static void sha512_transf(sha512_ctx *ctx, const unsigned char *message,
+                          unsigned int block_nb)
 {
     uint64 w[80];
     uint64 wv[8];
@@ -520,17 +520,7 @@
     }
 }
 
-void sha512(const unsigned char *message, unsigned int len,
-            unsigned char *digest)
-{
-    sha512_ctx ctx;
-
-    sha512_init(&ctx);
-    sha512_update(&ctx, message, len);
-    sha512_final(&ctx, digest);
-}
-
-void sha512_init(sha512_ctx *ctx)
+static void sha512_init(sha512_ctx *ctx)
 {
 #ifndef UNROLL_LOOPS
     int i;
@@ -548,8 +538,8 @@
     ctx->tot_len = 0;
 }
 
-void sha512_update(sha512_ctx *ctx, const unsigned char *message,
-                   unsigned int len)
+static void sha512_update(sha512_ctx *ctx, const unsigned char *message,
+                          unsigned int len)
 {
     unsigned int block_nb;
     unsigned int new_len, rem_len, tmp_len;
@@ -582,7 +572,7 @@
     ctx->tot_len += (block_nb + 1) << 7;
 }
 
-void sha512_final(sha512_ctx *ctx, unsigned char *digest)
+static void sha512_final(sha512_ctx *ctx, unsigned char *digest)
 {
     unsigned int block_nb;
     unsigned int pm_len;
@@ -620,19 +610,19 @@
 #endif /* !UNROLL_LOOPS */
 }
 
-/* SHA-384 functions */
-
-void sha384(const unsigned char *message, unsigned int len,
+void hashed_storage_sha512(const unsigned char *message, unsigned int len,
             unsigned char *digest)
 {
-    sha384_ctx ctx;
+    sha512_ctx ctx;
 
-    sha384_init(&ctx);
-    sha384_update(&ctx, message, len);
-    sha384_final(&ctx, digest);
+    sha512_init(&ctx);
+    sha512_update(&ctx, message, len);
+    sha512_final(&ctx, digest);
 }
 
-void sha384_init(sha384_ctx *ctx)
+/* SHA-384 functions */
+
+static void sha384_init(sha384_ctx *ctx)
 {
 #ifndef UNROLL_LOOPS
     int i;
@@ -650,8 +640,8 @@
     ctx->tot_len = 0;
 }
 
-void sha384_update(sha384_ctx *ctx, const unsigned char *message,
-                   unsigned int len)
+static void sha384_update(sha384_ctx *ctx, const unsigned char *message,
+                          unsigned int len)
 {
     unsigned int block_nb;
     unsigned int new_len, rem_len, tmp_len;
@@ -684,7 +674,7 @@
     ctx->tot_len += (block_nb + 1) << 7;
 }
 
-void sha384_final(sha384_ctx *ctx, unsigned char *digest)
+static void sha384_final(sha384_ctx *ctx, unsigned char *digest)
 {
     unsigned int block_nb;
     unsigned int pm_len;
@@ -720,19 +710,19 @@
 #endif /* !UNROLL_LOOPS */
 }
 
-/* SHA-224 functions */
-
-void sha224(const unsigned char *message, unsigned int len,
+void hashed_storage_sha384(const unsigned char *message, unsigned int len,
             unsigned char *digest)
 {
-    sha224_ctx ctx;
+    sha384_ctx ctx;
 
-    sha224_init(&ctx);
-    sha224_update(&ctx, message, len);
-    sha224_final(&ctx, digest);
+    sha384_init(&ctx);
+    sha384_update(&ctx, message, len);
+    sha384_final(&ctx, digest);
 }
 
-void sha224_init(sha224_ctx *ctx)
+/* SHA-224 functions */
+
+static void sha224_init(sha224_ctx *ctx)
 {
 #ifndef UNROLL_LOOPS
     int i;
@@ -750,8 +740,8 @@
     ctx->tot_len = 0;
 }
 
-void sha224_update(sha224_ctx *ctx, const unsigned char *message,
-                   unsigned int len)
+static void sha224_update(sha224_ctx *ctx, const unsigned char *message,
+                          unsigned int len)
 {
     unsigned int block_nb;
     unsigned int new_len, rem_len, tmp_len;
@@ -784,7 +774,7 @@
     ctx->tot_len += (block_nb + 1) << 6;
 }
 
-void sha224_final(sha224_ctx *ctx, unsigned char *digest)
+static void sha224_final(sha224_ctx *ctx, unsigned char *digest)
 {
     unsigned int block_nb;
     unsigned int pm_len;
@@ -819,6 +809,16 @@
    UNPACK32(ctx->h[5], &digest[20]);
    UNPACK32(ctx->h[6], &digest[24]);
 #endif /* !UNROLL_LOOPS */
+}
+
+void hashed_storage_sha224(const unsigned char *message, unsigned int len,
+            unsigned char *digest)
+{
+    sha224_ctx ctx;
+
+    sha224_init(&ctx);
+    sha224_update(&ctx, message, len);
+    sha224_final(&ctx, digest);
 }
 
 #ifdef TEST_VECTORS
diff --git a/Bundled/sha2.h b/Bundled/sha2.h
--- a/Bundled/sha2.h
+++ b/Bundled/sha2.h
@@ -72,33 +72,14 @@
 typedef sha512_ctx sha384_ctx;
 typedef sha256_ctx sha224_ctx;
 
-void sha224_init(sha224_ctx *ctx);
-void sha224_update(sha224_ctx *ctx, const unsigned char *message,
-                   unsigned int len);
-void sha224_final(sha224_ctx *ctx, unsigned char *digest);
-void sha224(const unsigned char *message, unsigned int len,
-            unsigned char *digest);
-
-void sha256_init(sha256_ctx * ctx);
-void sha256_update(sha256_ctx *ctx, const unsigned char *message,
-                   unsigned int len);
-void sha256_final(sha256_ctx *ctx, unsigned char *digest);
-void sha256(const unsigned char *message, unsigned int len,
-            unsigned char *digest);
-
-void sha384_init(sha384_ctx *ctx);
-void sha384_update(sha384_ctx *ctx, const unsigned char *message,
-                   unsigned int len);
-void sha384_final(sha384_ctx *ctx, unsigned char *digest);
-void sha384(const unsigned char *message, unsigned int len,
-            unsigned char *digest);
-
-void sha512_init(sha512_ctx *ctx);
-void sha512_update(sha512_ctx *ctx, const unsigned char *message,
-                   unsigned int len);
-void sha512_final(sha512_ctx *ctx, unsigned char *digest);
-void sha512(const unsigned char *message, unsigned int len,
-            unsigned char *digest);
+void hashed_storage_sha224(const unsigned char *message, unsigned int len,
+                           unsigned char *digest);
+void hashed_storage_sha256(const unsigned char *message, unsigned int len,
+                           unsigned char *digest);
+void hashed_storage_sha384(const unsigned char *message, unsigned int len,
+                           unsigned char *digest);
+void hashed_storage_sha512(const unsigned char *message, unsigned int len,
+                           unsigned char *digest);
 
 #ifdef __cplusplus
 }
diff --git a/Storage/Hashed.hs b/Storage/Hashed.hs
--- a/Storage/Hashed.hs
+++ b/Storage/Hashed.hs
@@ -98,7 +98,7 @@
 -- and with a given @hash@.
 readDarcsHashedDir :: FilePath -> Hash -> IO [(ItemType, Name, Hash)]
 readDarcsHashedDir dir h = do
-  compressed <- BL.readFile (dir </> BS.unpack (darcsFormatHash h))
+  compressed <- readSegment (dir </> BS.unpack (darcsFormatHash h), Nothing)
   let content = decompress compressed
       lines = BL.split '\n' content
   return $ if BL.null compressed
diff --git a/Storage/Hashed/AnchoredPath.hs b/Storage/Hashed/AnchoredPath.hs
--- a/Storage/Hashed/AnchoredPath.hs
+++ b/Storage/Hashed/AnchoredPath.hs
@@ -62,6 +62,7 @@
 floatBS = AnchoredPath . map Name . takeWhile (not . BS.null) . BS.split '/'
 
 flatten :: AnchoredPath -> BS.ByteString
+flatten (AnchoredPath []) = BS.singleton '.'
 flatten (AnchoredPath p) = BS.intercalate (BS.singleton '/')
                                            [ n | (Name n) <- p ]
 
diff --git a/Storage/Hashed/Index.hs b/Storage/Hashed/Index.hs
--- a/Storage/Hashed/Index.hs
+++ b/Storage/Hashed/Index.hs
@@ -9,7 +9,7 @@
 -- your validity tracking code, you also check for format validity (see
 -- "indexFormatValid") and scrap and re-create index when needed.
 --
--- The index is a binary file that overlays a hashed tree over the working
+-- The index is a binary file, that overlays a hashed tree over the working
 -- copy. This means that every working file and directory has an entry in the
 -- index, that contains its path and hash and validity data. The validity data
 -- is a "last seen" timestamp plus the file size. The file hashes are sha256's
@@ -97,6 +97,9 @@
 itemIsDir :: Item -> Bool
 itemIsDir i = BS.last (iPath i) == '/'
 
+noslashpath :: Item -> FilePath
+noslashpath i = BS.unpack $ itemIsDir i ? (BS.init $ iPath i, iPath i)
+
 -- xlatePeek32 = fmap xlate32 . peek
 xlatePeek64 :: (Storable a, Bits a) => Ptr a -> IO a
 xlatePeek64 = fmap xlate64 . peek
@@ -207,7 +210,7 @@
       readDir :: AnchoredPath -> Item -> Int -> Int -> IO (Maybe TreeItem)
       readDir parent_path item off dl =
           do dirend <- xlatePeek64 $ iAux item
-             st <- getFileStatusBS (iPath item)
+             st <- getFileStatus (noslashpath item)
              let this_path = parent_path `appendPath` (Name $ iName item)
                  nl = BS.length (iName item)
                  dl' = dl + (nl == 0) ? (0, 1 + nl)
@@ -256,7 +259,7 @@
                 then return $ Just $ File (Blob readblob $ Just hash)
                 else return Nothing
   if mmap_size > 0 then
-      do (_, Just (Stub root h)) <- readItem (AnchoredPath []) 4 0
+      do (_, Just (Stub root h)) <- readItem (AnchoredPath []) 4 (-2)
          tree <- root
          return (tree { treeHash = h }, item_map)
     else return (emptyTree, item_map)
@@ -312,7 +315,7 @@
                   return lastOff
            create (Stub _ _) path _ =
                fail $ "Cannot create index from stubbed Tree at " ++ show path
-       pokeBS magic (BS.pack "HSI0")
+       pokeBS magic (BS.pack "HSI1")
        create (SubTree reference) (AnchoredPath []) 4
        readIndex indexpath hashtree
 
@@ -324,7 +327,7 @@
   magic <- sequence [ hGetChar fd | _ <- [1..4] :: [Int] ]
   hClose fd
   return $ case magic of
-             "HSI0" -> True
+             "HSI1" -> True
              _ -> False
 
 -- | DEPRECATED! Read index (just like readIndex). However, also check that the
diff --git a/Storage/Hashed/Monad.hs b/Storage/Hashed/Monad.hs
--- a/Storage/Hashed/Monad.hs
+++ b/Storage/Hashed/Monad.hs
@@ -9,7 +9,7 @@
 module Storage.Hashed.Monad
     ( hashedTreeIO, plainTreeIO, virtualTreeIO
     , readFile, writeFile, createDirectory, rename, unlink
-    , fileExists, exists
+    , fileExists, directoryExists, exists
     , tree, cwd, TreeState, TreeIO
     ) where
 
@@ -20,6 +20,8 @@
 import Storage.Hashed.Utils
 import Storage.Hashed.Darcs
 
+import Control.Exception.Extensible( catch, SomeException(..) )
+
 import System.Directory( createDirectoryIfMissing, doesFileExist )
 import System.FilePath( (</>) )
 import Data.List( inits )
@@ -91,7 +93,7 @@
 
 expandTo :: AnchoredPath -> TreeIO ()
 expandTo p = do t <- gets tree
-                t' <- liftIO $ expandPath t p
+                t' <- liftIO $ expandPath t p `catch` \(_::SomeException) -> return t
                 modify $ \st -> st { tree = t' }
 
 -- | Run a 'TreeIO' @action@ in a hashed setting. The @initial@ tree is assumed
@@ -165,6 +167,11 @@
 fileExists p = do expandTo p
                   (isJust . (flip findFile p)) `fmap` gets tree
 
+-- | Check for existence of a directory.
+directoryExists :: AnchoredPath -> TreeIO Bool
+directoryExists p = do expandTo p
+                       (isJust . (flip findTree p)) `fmap` gets tree
+
 -- | Check for existence of a node (file or directory, doesn't matter).
 exists :: AnchoredPath -> TreeIO Bool
 exists p = do expandTo p
@@ -196,17 +203,20 @@
 -- flushed to disk, but might be buffered for some time.
 writeFile :: AnchoredPath -> BL.ByteString -> TreeIO ()
 writeFile p con =
-    do replaceItem p (Just blob)
+    do expandTo p
+       replaceItem p (Just blob)
        markChanged p
        maybeSync
     where blob = File $ Blob (return con) hash
           hash = Just $ hashSetSize (sha256 con) (BL.length con)
 
 createDirectory :: AnchoredPath -> TreeIO ()
-createDirectory p = replaceItem p $ Just $ SubTree emptyTree
+createDirectory p = do expandTo p
+                       replaceItem p $ Just $ SubTree emptyTree
 
 unlink :: AnchoredPath -> TreeIO ()
-unlink p = replaceItem p Nothing
+unlink p = do expandTo p
+              replaceItem p Nothing
 
 rename :: AnchoredPath -> AnchoredPath -> TreeIO ()
 rename from to = do expandTo from
diff --git a/Storage/Hashed/Test.hs b/Storage/Hashed/Test.hs
--- a/Storage/Hashed/Test.hs
+++ b/Storage/Hashed/Test.hs
@@ -17,7 +17,10 @@
 import Storage.Hashed.Utils
 import Storage.Hashed.Darcs
 import System.IO.Unsafe( unsafePerformIO )
+import System.Mem( performGC )
 
+import Bundled.Posix( getFileStatus, getSymbolicLinkStatus, fileSize, fileExists )
+
 import Test.HUnit
 import Test.Framework( testGroup )
 import Test.QuickCheck
@@ -29,11 +32,16 @@
 -- Test Data
 --
 
-files = [ floatPath "foo_a"
-        , floatPath "foo_dir/foo_a"
-        , floatPath "foo_dir/foo_b"
-        , floatPath "foo_dir/foo_subdir/foo_a" ]
+blobs = [ (floatPath "foo_a", BL.pack "a\n")
+        , (floatPath "foo_dir/foo_a", BL.pack "a\n")
+        , (floatPath "foo_dir/foo_b", BL.pack "b\n")
+        , (floatPath "foo_dir/foo_subdir/foo_a", BL.pack "a\n") ]
 
+files = map fst blobs
+
+dirs = [ floatPath "foo_dir"
+       , floatPath "foo_dir/foo_subdir" ]
+
 emptyStub = Stub (return emptyTree) Nothing
 
 testTree =
@@ -50,7 +58,8 @@
 -- Test list
 --
 
-tests = [ testGroup "darcs" darcs
+tests = [ testGroup "Bundled.Posix" posix
+        , testGroup "Storage.Hashed" hashed
         , testGroup "Storage.Hashed.Index" index
         , testGroup "Storage.Hashed.Tree" tree
         , testGroup "Storage.Hashed.Utils" utils ]
@@ -59,35 +68,29 @@
 -- Tests
 --
 
-darcs = [ testCase "specific files" have_files
-        , testCase "pristine files" have_pristine_files
-        , testCase "list == darcs show manifest" darcs_manifest
-        , testCase "content == darcs show contents" darcs_contents ]
+hashed = [ testCase "plain has all files" have_files
+         , testCase "pristine has all files" have_pristine_files
+         , testCase "pristine has no extras" pristine_no_extra
+         , testCase "pristine file contents match" pristine_contents ]
     where
       check_file t f = assertBool
-                       ("path " ++ show f ++ " is in tree")
+                       ("path " ++ show f ++ " is missing in tree")
                        (isJust $ find t f)
       check_files = forM_ files . check_file
+      pristine_no_extra = do
+        t <- readDarcsPristine "." >>= expand
+        forM_ (list t) $ \(path,_) -> assertBool (show path ++ " is extraneous in tree")
+                                                 (path `elem` (dirs ++ files))
       have_files = readPlainTree "." >>= expand >>= check_files
       have_pristine_files =
          readDarcsPristine "." >>= expand >>= check_files
 
-      -- NB. When hashed-storage replace slurpies in darcs, the following 2
-      -- tests become useless, since they just check our code against darcs.
-      darcs_manifest = do
-        f <- lines `fmap` readProcess "darcs" ["show", "files" ] ""
-        t <- readDarcsPristine "." >>= expand
-        forM_ (f \\ ["."]) (\x -> check_file t (floatPath x))
-        forM_ (list t)
-              (\x -> assertBool (show (fst x) ++ " is in darcs show files") $
-                     anchorPath "." (fst x) `elem` f)
-      darcs_contents = do
+      pristine_contents = do
         t <- readDarcsPristine "." >>= expand
         sequence_ [
-          do our <- read b
-             darcs <- readProcess "darcs" [ "show", "contents",
-                                            anchorPath "." p ] ""
-             assertEqual "contents match" (BL.unpack our) darcs
+          do ours <- read b
+             let Just stored = Prelude.lookup p blobs
+             assertEqual "contents match" ours stored
          | (p, File b) <- list t ]
 
 index = [ testCase "index listing" check_index
@@ -97,6 +100,7 @@
           build_index =
             do x <- pristine
                exist <- doesFileExist "_darcs/index"
+               performGC -- required in win32 to trigger file close
                when exist $ removeFile "_darcs/index"
                idx <- updateIndexFrom "_darcs/index" darcsTreeHash x >>= expand
                return (x, idx)
@@ -113,7 +117,8 @@
                x <- sequence $ zipCommonFiles check_blob_pair plain idx
                assertBool "files match" (length x > 0)
           check_index_versions =
-            do writeFile "_darcs/index" "nonsense index... do not crash!"
+            do performGC -- required in win32 to trigger file close
+               writeFile "_darcs/index" "nonsense index... do not crash!"
                pris <- pristine
                idx <- expand =<<
                         readOrUpgradeIndex "_darcs/index" darcsTreeHash pristine
@@ -175,6 +180,19 @@
         , testProperty "xlate64" prop_xlate64 ]
     where prop_xlate32 x = (xlate32 . xlate32) x == x where types = x :: Word32
           prop_xlate64 x = (xlate64 . xlate64) x == x where types = x :: Word64
+
+posix = [ testCase "getFileStatus" $ check_stat getFileStatus
+        , testCase "getSymbolicLinkStatus" $ check_stat getSymbolicLinkStatus ]
+    where check_stat fun = do
+            x <- fileSize `fmap` fun "foo_a"
+            writeFile "test_empty" ""
+            y <- fileSize `fmap` fun "test_empty"
+            exist_nonexistent <- fileExists `fmap` fun "test_does_not_exist"
+            exist_existent <- fileExists `fmap` fun "test_empty"
+            assertEqual "file size" x 2
+            assertEqual "file size" y 0
+            assertBool "existence check" $ not exist_nonexistent
+            assertBool "existence check" exist_existent
 
 instance Arbitrary Word32 where
     arbitrary = do x <- arbitrary :: Gen Int
diff --git a/hashed-storage.cabal b/hashed-storage.cabal
--- a/hashed-storage.cabal
+++ b/hashed-storage.cabal
@@ -1,5 +1,5 @@
 name:          hashed-storage
-version:       0.3.5
+version:       0.3.6
 synopsis:      Hashed file storage support code.
 
 description:   Support code for reading and manipulating hashed file storage
@@ -27,11 +27,17 @@
 flag diff
     default: False
 
+flag hpc
+    default: False
+
 library
     if impl(ghc >= 6.8)
       ghc-options: -fwarn-tabs
+
     ghc-options:   -Wall -O2
     ghc-prof-options: -prof -auto-all -O2
+    if flag(hpc)
+      ghc-prof-options: -fhpc
 
 
     exposed-modules:
@@ -53,7 +59,7 @@
         Storage.Hashed.Utils
 
     build-depends: base >= 3 && < 5, directory, filepath, bytestring, zlib,
-                   containers, mtl, extensible-exceptions, mmap
+                   containers, mtl, extensible-exceptions, mmap >= 0.4
 
     c-sources: Bundled/sha2.c
 
@@ -63,8 +69,10 @@
     if impl(ghc >= 6.8)
       ghc-options: -fwarn-tabs
     ghc-options:   -Wall -O2
-
     ghc-prof-options: -prof -auto-all -O2
+
+    if flag(hpc)
+      ghc-prof-options: -fhpc
 
     main-is: test.hs
     other-modules: Bundled.Posix
