diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,7 @@
+### 0.5.0.2
+
+- *nhm-tool*: get rid of dependency on package *extra* and other improvements.
+
 ### 0.5.0.1
 
 - More detailed help for *nhm-tool*.
diff --git a/ngx-export-distribution.cabal b/ngx-export-distribution.cabal
--- a/ngx-export-distribution.cabal
+++ b/ngx-export-distribution.cabal
@@ -1,5 +1,5 @@
 name:                       ngx-export-distribution
-version:                    0.5.0.1
+version:                    0.5.0.2
 synopsis:                   Build custom libraries for Nginx haskell module
 description:                Build custom libraries for
         <https://github.com/lyokha/nginx-haskell-module Nginx haskell module>.
@@ -38,7 +38,6 @@
                           , prettyprinter-ansi-terminal
                           , cabal-plan
                           , parsec
-                          , extra
 
   main-is:                  nhm-tool.hs
 
diff --git a/nhm-tool.hs b/nhm-tool.hs
--- a/nhm-tool.hs
+++ b/nhm-tool.hs
@@ -14,11 +14,9 @@
 import Data.Text (Text)
 import qualified Data.Map as M
 import qualified Data.Set as S
-import Data.Functor
 import Data.Maybe
 import Data.Char
 import Data.List
-import Data.List.Extra
 import Prettyprinter (pretty, annotate)
 import Prettyprinter.Render.Terminal
 import System.Environment
@@ -269,8 +267,8 @@
             lddOut <- getProgramOutput distDataOtherVerbosity
                 ldd' [distDataTargetLib]
             case parseLddOutput lddOut of
-                Left msg -> do
-                    hPrint stderr msg
+                Left err -> do
+                    hPutStrLn stderr $ show err ++ " in\n" ++ lddOut
                     exitFailure
                 Right recs -> do
                     (tar', _) <- requireProgram distDataOtherVerbosity
@@ -286,8 +284,8 @@
                   patchelfOut <- getProgramOutput distDataOtherVerbosity
                       patchelf' ["--print-rpath", distDataTargetLib]
                   case parsePatchelfRpathOutput patchelfOut of
-                      Left msg -> do
-                          hPrint stderr msg
+                      Left err -> do
+                          hPutStrLn stderr $ show err ++ " in\n" ++ patchelfOut
                           exitFailure
                       Right paths -> do
                           unless (distDataTargetDir `elem` paths) $
@@ -303,35 +301,31 @@
                                             ]
                           putStrLnTrim patchelfOut'
           collectLibs recs lddOut = do
-              let recsLibHS = filter (\case
-                                          LibHS _ _ -> True
-                                          _ -> False
-                                     ) recs
-              if null recsLibHS
+              let recsLibHS = M.fromList $
+                      mapMaybe (\case
+                                    LibHS name path -> Just (name, path)
+                                    _ -> Nothing
+                               ) recs
+              if M.null recsLibHS
                   then do
-                      hPutStrLn stderr
-                          "There were no Haskell libraries collected"
+                      hPutStrLn stderr $
+                          "No Haskell libraries were collected in\n" ++ lddOut
                       exitFailure
                   else do
-                      let recsLibHSNotFound =
-                              filter (\case
-                                          LibHS _ Nothing -> True
-                                          _ -> False
-                                     ) recsLibHS
-                      if null recsLibHSNotFound
+                      let (M.mapMaybe id -> recsLibHS', recsLibHSNotFound) =
+                              M.partition isJust recsLibHS
+                      if M.null recsLibHSNotFound
                           then do
                               createDirectoryIfMissing False distDataDir
-                              forM_ recsLibHS $ \case
-                                  LibHS _ (Just path) -> do
-                                      let dst = distDataDir </>
-                                                    takeFileName path
-                                      putStrLn' $ path ++ " -> " ++ dst
-                                      copyFile path dst
-                                  _ -> undefined
+                              forM_ (M.elems recsLibHS') $ \path -> do
+                                  let dst = distDataDir </> takeFileName path
+                                  putStrLn' $ path ++ " -> " ++ dst
+                                  copyFile path dst
                           else do
                               hPutStrLn stderr $
-                                 "There were missing Haskell libraries:\n" ++
-                                     lddOut
+                                 "Haskell libraries " ++
+                                     show (M.keys recsLibHSNotFound) ++
+                                         " were not found in\n" ++ lddOut
                               exitFailure
           archiveLibs tar' =
               unless (null distDataArchive) $ do
@@ -344,7 +338,12 @@
                       ]
                   putStrLnTrim tarOut
           putStrLn' = when (distDataOwnVerbosity == verbose) . putStrLn
-          putStrLnTrim = putStrLn' . fst . spanEnd (== '\n')
+          putStrLnTrim = putStrLn' . trimEnd '\n'
+          trimEnd end = fst . foldr (\v a@(vs, skipped) ->
+                                         if skipped || v /= end
+                                             then (v : vs, True)
+                                             else a
+                                    ) ("", False)
 
 parsePatchelfRpathOutput :: String -> Either ParseError [String]
 parsePatchelfRpathOutput =
@@ -353,23 +352,25 @@
 
 parseLddOutput :: String -> Either ParseError [LddRec]
 parseLddOutput = flip parse "ldd" $ many $
-    spaces >>
-    (try (do
-              lib <- manyTill anyChar' sep
-              path <- (char bs >> right <&> Just . (bs :))
-                      <|> (string "not found" >> return Nothing)
-              return $ if "libHS" `isPrefixOf` lib
-                           then LibHS lib path
-                           else LibOther lib path
+    spaces *>
+    (try (toLddRec <$>
+              manyTill anyChar' sep <*>
+                  ((Just .) . (:) <$> char '/' <*> right
+                   <|> Nothing <$ string "not found"
+                  )
          )
-     <|> (right <&> (`LibOther` Nothing))
+     -- FIXME: in some documents, vdso record has an arrow in the middle
+     --         linux-vdso.so.1 =>  (0x00007fffd33f2000)
+     -- this format is not supported here, not sure if it should be.
+     <|> (`LibOther` Nothing) <$> right
     )
-    where right = manyTill anyChar' (try $ spaces1 >> addr >> newline)
-          addr = string "(0x" >> many1 hexDigit >> char ')'
+    where toLddRec lib | "libHS" `isPrefixOf` lib = LibHS lib
+                       | otherwise = LibOther lib
+          right = manyTill anyChar' $ spaces1 *> addr *> newline
+          addr = string "(0x" *> many1 hexDigit *> char ')'
           anyChar' = satisfy (/= '\n')
-          sep = spaces1 >> string "=>" >> spaces1
+          sep = spaces1 *> string "=>" *> spaces1
           spaces1 = skipMany1 space
-          bs = '/'
 
 cmdDeps :: DepsData -> IO ()
 cmdDeps DepsData {..} = do
@@ -399,7 +400,7 @@
                 ,("Setup.hs", setupHs init', True)
                 ,(initDataProject ++ ".cabal", projectCabal init', True)
                 ,("Makefile", makefile init', True)
-                ,(replace "-" "_" initDataProject ++ ".hs"
+                ,(replace '-' '_' initDataProject ++ ".hs"
                   ,projectHs init'
                   ,False
                  )
@@ -418,7 +419,8 @@
                                      then useForceMsg name
                                      else existsMsg name
                     else T.writeFile name file
-    where printHeader header = do
+    where replace from to = foldr (\v -> ((if v == from then to else v) :)) ""
+          printHeader header = do
               isTerm <- isTerminal FD.stdout
               if isTerm
                   then putDoc $ annotate (color Blue <> underlined) $
