diff --git a/System/Directory/Tree.hs b/System/Directory/Tree.hs
--- a/System/Directory/Tree.hs
+++ b/System/Directory/Tree.hs
@@ -69,6 +69,8 @@
        , sortDir
        , sortDirShape
        , filterDir
+       -- *** Low-level
+       , transformDir
        -- ** Navigation
        , dropTo
        -- ** Operators
@@ -248,9 +250,7 @@
 -- | same as readDirectory but allows us to, for example, use 
 -- ByteString.readFile to return a tree of ByteStrings.
 readDirectoryWith :: (FilePath -> IO a) -> FilePath -> IO (AnchoredDirTree a)
-readDirectoryWith f p = do (b:/t) <- buildWith' buildAtOnce' f p
-                           let t' = removeNonexistent t
-                           return ( b:/t') 
+readDirectoryWith f p = buildWith' buildAtOnce' f p
 
 
 -- | A "lazy" version of `readDirectoryWith` that does IO operations as needed
@@ -258,9 +258,7 @@
 -- /NOTE:/ This function uses unsafePerformIO under the hood. I believe our use
 -- here is safe, but this function is experimental in this release:
 readDirectoryWithL :: (FilePath -> IO a) -> FilePath -> IO (AnchoredDirTree a)
-readDirectoryWithL f p = do (b:/t) <- buildWith' buildLazilyUnsafe' f p
-                            let t' = removeNonexistent t
-                            return ( b:/t') 
+readDirectoryWithL f p = buildWith' buildLazilyUnsafe' f p
 
 
 -- | write a DirTree of strings to disk. Clobbers files of the same name. 
@@ -284,7 +282,6 @@
               do let bas = b'</>n
                  createDirectoryIfMissing True bas
                  Dir n <$> mapM (write' bas) cs
-           -- INTERESTING: have to rebuild Failed constr. to get to typecheck:
           write' _ (Failed n e) = return $ Failed n e
 
 
@@ -391,7 +388,7 @@
 
 -- | maps a function to convert Failed DirTrees to Files or Dirs
 failedMap :: (FileName -> IOException -> DirTree a) -> DirTree a -> DirTree a
-failedMap f = transform unFail
+failedMap f = transformDir unFail
     where unFail (Failed n e) = f n e
           unFail c            = c
                           
@@ -410,7 +407,7 @@
 
   -- HELPER:
 sortDirBy :: (DirTree a -> DirTree a -> Ordering) -> DirTree a -> DirTree a
-sortDirBy cf = transform sortD
+sortDirBy cf = transformDir sortD
     where sortD (Dir n cs) = Dir n (sortBy cf cs)
           sortD c          = c
 
@@ -477,7 +474,7 @@
 -- its children, of course) when the predicate returns False. The topmost 
 -- constructor will always be preserved:
 filterDir :: (DirTree a -> Bool) -> DirTree a -> DirTree a
-filterDir p = transform filterD
+filterDir p = transformDir filterD
     where filterD (Dir n cs) = Dir n $ filter p cs
           filterD c          = c
 
@@ -582,17 +579,17 @@
            isOkError = not . isDoesNotExistErrorType . ioeGetErrorType . err
 
 
----- THIS COULD BE USEFUL TO EXPORT:
-
--- at Dir constructor, apply transformation function to all of directory's
--- contents, then remove the Nothing's and recurse.
--- ALWAYS PRESERVES TOPMOST CONSTRUCTOR:
-transform :: (DirTree a -> DirTree a) -> DirTree a -> DirTree a
-transform f t = case f t of
-                     (Dir n cs) -> Dir n $ map (transform f) cs
+-- | At 'Dir' constructor, apply transformation function to all of directory's
+-- contents, then remove the Nothing's and recurse. This always preserves the
+-- topomst constructor.
+transformDir :: (DirTree a -> DirTree a) -> DirTree a -> DirTree a
+transformDir f t = case f t of
+                     (Dir n cs) -> Dir n $ map (transformDir f) cs
                      t'         -> t'
 
 -- Lenses, generated with TH from "lens" -----------
+-- TODO deprecate these? Pain in the ass to generate, and maybe it's intended
+--      for users to generate their own lenses.
 _contents :: 
             Applicative f =>
             ([DirTree a] -> f [DirTree a]) -> DirTree a -> f (DirTree a)
diff --git a/Test.hs b/Test.hs
new file mode 100644
--- /dev/null
+++ b/Test.hs
@@ -0,0 +1,107 @@
+module Main
+    where
+
+-- do a quick test for Darcs:
+
+import System.Directory.Tree
+import Control.Applicative
+import qualified Data.Foldable as F
+import System.Directory
+import System.Process
+import System.IO.Error(ioeGetErrorType,isPermissionErrorType)
+import Control.Monad(void)
+
+
+
+
+testDir :: FilePath
+testDir = "/tmp/TESTDIR-LKJHBAE"
+
+main :: IO ()
+main = do
+    putStrLn "-- The following tests will either fail with an error "
+    putStrLn "-- message or with an 'undefined' error"
+    -- write our testing directory structure to disk. We include Failed 
+    -- constructors which should be discarded:
+    _:/written <- writeDirectory testTree
+    putStrLn "OK"
+
+
+    if (fmap (const ()) (filterDir (not . failed) $dirTree testTree)) == 
+                                  filterDir (not . failed) written
+       then return ()
+       else error "writeDirectory returned a tree that didn't match"
+    putStrLn "OK"
+
+    -- make file farthest to the right unreadable:
+    (Dir _ [_,_,Dir "C" [_,_,File "G" p_unreadable]]) <- sortDir . dirTree <$> build testDir
+    setPermissions p_unreadable emptyPermissions{readable   = False,
+                                                   writable   = True,
+                                                   executable = True,
+                                                   searchable = True}
+    putStrLn "OK"
+
+
+    -- read with lazy and standard functions, compare for equality. Also test that our crazy
+    -- operator works correctly inline with <$>:
+    tL <- readDirectoryWithL readFile testDir
+    t@(_:/Dir _ [_,_,Dir "C" [unreadable_constr,_,_]]) <- sortDir </$> id <$> readDirectory testDir
+    if  t == tL  then return () else error "lazy read  /=  standard read"
+    putStrLn "OK"
+    
+    -- make sure the unreadable file left the correct error type in a Failed:
+    if isPermissionErrorType $ ioeGetErrorType $ err unreadable_constr 
+       then return ()
+       else error "wrong error type for Failed file read"
+    putStrLn "OK"
+    
+    
+    -- run lazy fold, concating file contents. compare for equality:
+    tL_again <- sortDir </$> readDirectoryWithL readFile testDir
+    let tL_concated = F.concat $ dirTree tL_again
+    if tL_concated == "abcdef" then return () else error "foldable broke"
+    putStrLn "OK"
+
+     -- get a lazy DirTree at root directory with lazy Directory traversal:
+    putStrLn "-- If lazy IO is not working, we should be stalled right now "
+    putStrLn "-- as we try to read in the whole root directory tree."
+    putStrLn "-- Go ahead and press CTRL-C if you've read this far"
+    mapM_ putStr =<< (map name . contents . dirTree) <$> readDirectoryWithL readFile "/"
+    putStrLn "\nOK"
+
+
+    let undefinedOrdFailed = Failed undefined undefined :: DirTree Char
+        undefinedOrdDir = Dir undefined undefined :: DirTree Char
+        undefinedOrdFile = File undefined undefined :: DirTree Char
+        -- simple equality and sorting
+    if Dir "d" [File "b" "b",File "a" "a"] == Dir "d" [File "a" "a", File "b" "b"] &&
+        -- recursive sort order, enforces non-recursive sorting of Dirs
+       Dir "d" [Dir "b" undefined,File "a" "a"] /= Dir "d" [File "a" "a", Dir "c" undefined] &&
+        -- check ordering of constructors:
+       undefinedOrdFailed < undefinedOrdDir  &&
+       undefinedOrdDir < undefinedOrdFile    &&
+        -- check ordering by dir contents list length:
+       Dir "d" [File "b" "b",File "a" "a"] > Dir "d" [File "a" "a"] &&
+        -- recursive ordering on contents:
+       Dir "d" [File "b" "b", Dir "c" [File "a" "b"]] > Dir "d" [File "b" "b", Dir "c" [File "a" "a"]] 
+        then putStrLn "OK"
+        else error "Ord/Eq instance is messed up"
+    
+    if Dir "d" [File "b" "b",File "a" "a"] `equalShape` Dir "d" [File "a" undefined, File "b" undefined]
+        then putStrLn "OK"
+        else error "equalShape or comparinghape functions broken"
+
+    -- clean up by removing the directory:
+    void $ system $ "rm -r " ++ testDir
+    putStrLn "SUCCESS"
+    
+
+
+testTree :: AnchoredDirTree String
+testTree = "" :/ Dir testDir [dA , dB , dC , Failed "FAAAIIILL" undefined]
+    where dA = Dir "A" [dA1 , dA2 , Failed "FAIL" undefined]
+          dA1    = Dir "A1" [File "A" "a", File "B" "b"]
+          dA2    = Dir "A2" [File "C" "c"]
+          dB = Dir "B" [File "D" "d"]
+          dC = Dir "C" [File "E" "e", File "F" "f", File "G" "g"]
+
diff --git a/directory-tree.cabal b/directory-tree.cabal
--- a/directory-tree.cabal
+++ b/directory-tree.cabal
@@ -1,5 +1,5 @@
 name:            directory-tree
-version:         0.11.0
+version:         0.12.0
 homepage:        http://brandon.si/code/directory-tree-module-released/
 synopsis:        A simple directory-like tree datatype, with useful IO functions 
 description:     A simple directory-like tree datatype, with useful IO functions and Foldable and Traversable instance  
@@ -51,15 +51,13 @@
  . 
  Any ideas or suggestions for improvements are most welcome :-)
  .
- /CHANGES/: from 0.10.1
- .
- - added records for AnchoredDirTree: 'anchor', 'dirTree'
+ /CHANGES/: from 0.11
  .
- - 'free' deprecated in favor of 'dirTree' 
+ - export 'System.Directory.Tree.transformDir' as requested
  .
- - added a new function 'dropTo'
+ - add test suite to cabal file
  .
- - implemented lenses compatible with "lens" package
+ - remove redundant @removeNonexistent@ (thanks to dmwit for patch)
  .
  
 category:        Data, System
@@ -68,9 +66,9 @@
 copyright:       (c) 2011, Brandon Simmons <brandon.m.simmons@gmail.com>
 author:          Brandon Simmons
 maintainer:      Brandon Simmons <brandon.m.simmons@gmail.com>
-cabal-version:   >= 1.6
+cabal-version:   >= 1.8
 build-type:      Simple
-tested-with:     GHC <=7.4.1
+tested-with:     GHC <=7.8.2
 extra-source-files: EXAMPLES/Examples.hs, EXAMPLES/LazyExamples.hs
 
 source-repository head   
@@ -81,3 +79,11 @@
     exposed-modules: System.Directory.Tree
     build-depends: base <5, filepath <2, directory <2
     ghc-options:       -Wall
+
+test-suite test
+    main-is: Test.hs
+    type: exitcode-stdio-1.0
+    build-depends: base <5, filepath <2, directory <2
+                 , process
+    ghc-options:       -Wall
+
