diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -39,7 +39,40 @@
 
 	$ haskdogs
 
-Emacs users would probably want to add -e option to build Emacs-compatible TAGS.
+Emacs users would probably want to add -e hasktags option to build Emacs-compatible TAGS.
+
+
+
+    $ haskdogs --help
+    haskdogs - Recursive hasktags-based TAGS generator for a Haskell project
+
+    Usage: haskdogs [--version] [-d|--dir-list FILE] [-f|--file-list FILE]
+                    [--hasktags-args OPTS] [--ghc-pkg-args OPTS] [--use-stack ARG]
+                    [OPTS]
+
+    Available options:
+      -h,--help                Show this help text
+      --version                Show version number
+      -d,--dir-list FILE       File containing directory list to process
+      -f,--file-list FILE      File containing Haskell sources to process
+      --hasktags-args OPTS     Arguments to pass to hasktags. -c -x is the default
+      --ghc-pkg-args OPTS      Arguments to pass to ghc-pkgs
+      --use-stack ARG          Execute ghc-pkg via stack, arg is ON, OFF or AUTO
+                               (the default)
+      OPTS                     More hasktags options, use `--' to pass flags
+                               starting with `-'
+
+
+The following error could be caused by (over)strict Haskell policy regarding
+Unicode locale:
+
+    haskdogs: fd:5: hGetContents: invalid argument (invalid byte sequence)
+
+It usually happens when the program tries to print Unicode character to
+non-unicode console. In order to overcome, try the following setting:
+
+    export LANG=en_US.UTF8
+
 
 VIM HINT
 --------
diff --git a/haskdogs.cabal b/haskdogs.cabal
--- a/haskdogs.cabal
+++ b/haskdogs.cabal
@@ -1,5 +1,5 @@
 Name:                haskdogs
-Version:             0.4.2
+Version:             0.4.4
 Synopsis:            Generate tags file for Haskell project and its nearest deps
 Homepage:            http://github.com/grwlf/haskdogs
 License:             BSD3
@@ -30,6 +30,7 @@
 
 Executable haskdogs
   Default-language:    Haskell2010
+  other-modules:        Paths_haskdogs
   Hs-source-dirs:       src
   Main-is:              Main.hs
   Build-depends:        base >= 4.8 && < 5
@@ -39,6 +40,7 @@
                       , directory
                       , optparse-applicative
                       , process
+                      , containers
 
   Ghc-options:          -fwarn-tabs
 
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -11,9 +11,12 @@
 import System.Process (readProcess)
 import System.FilePath
 
+import Data.Set (Set)
+import qualified Data.Set as Set
 import Options.Applicative
 import qualified Options.Applicative as O
-import Data.Version
+import Data.Version (showVersion)
+import qualified Paths_haskdogs as Paths
 
 {-
   ___        _   _
@@ -30,13 +33,15 @@
   , cli_hasktags_args1 :: String
   , cli_ghc_pkgs_args :: String
   , cli_use_stack :: Tristate
-  , cli_use_sandbox :: Tristate
+  -- , cli_use_sandbox :: Tristate
   , cli_hasktags_args2 :: [String]
   } deriving(Show)
 
 data Tristate = ON | OFF | AUTO
   deriving(Eq, Ord, Show, Read)
 
+def_hasktags_args = words "-c -x"
+
 optsParser :: Parser Opts
 optsParser = Opts
   <$> strOption (
@@ -54,8 +59,8 @@
   <*> strOption (
         long "hasktags-args" <>
         metavar "OPTS" <>
-        value "-c -x" <>
-        help "Arguments to pass to hasktags")
+        value "" <>
+        help ("Arguments to pass to hasktags. " ++ unwords def_hasktags_args ++ " is the default"))
   <*> strOption (
         long "ghc-pkg-args" <>
         metavar "OPTS" <>
@@ -64,22 +69,21 @@
   <*> option auto (
         long "use-stack" <>
         value AUTO <>
-        help "Execute ghc-pkg via stack")
-  <*> option auto (
-        long "include-sandbox" <>
-        value AUTO <>
-        help "(!UNIMPLEMENTED!) Include .cabal-sandbox package databases")
-  <*> many (argument str (metavar "OPTS" <> help "More hasktags options"))
+        help "Execute ghc-pkg via stack, arg is ON, OFF or AUTO (the default)")
+  -- <*> option auto (
+  --       long "include-sandbox" <>
+  --       value AUTO <>
+  --       help "(!UNIMPLEMENTED!) Include .cabal-sandbox package databases")
+  <*> many (argument str (metavar "OPTS" <> help "More hasktags options, use `--' to pass flags starting with `-'"))
 
-exename, versionId :: String
+exename :: String
 exename = "haskdogs"
-versionId = "0.4.0"
 
-version :: Parser (a -> a)
-version = infoOption (exename ++ " version " ++ versionId)
+versionParser :: Parser (a -> a)
+versionParser = infoOption (exename ++ " version " ++ (showVersion Paths.version))
                      (long "version" <> help "Show version number")
 
-opts = info (helper <*> version <*> optsParser)
+opts = info (helper <*> versionParser <*> optsParser)
       ( fullDesc <> header (exename ++ " - Recursive hasktags-based TAGS generator for a Haskell project" ))
 
 {-
@@ -113,7 +117,7 @@
     eprint = hPutStrLn stderr
 
     runp nm args inp = do
-      vprint $ nm ++ " " ++ unwords args
+      vprint $ "> " ++ nm ++ " " ++ unwords args
       readProcess nm args inp
 
     -- Run GNU which tool
@@ -146,16 +150,16 @@
       | null cli_dirlist_file = return []
       | otherwise = readLinedFile cli_dirlist_file
 
-    readSourceFile :: IO [FilePath]
+    readSourceFile :: IO (Set FilePath)
     readSourceFile
-      | null cli_filelist_file = return []
-      | otherwise = readLinedFile cli_filelist_file
+      | null cli_filelist_file = return Set.empty
+      | otherwise = Set.fromList <$> readLinedFile cli_filelist_file
 
     cli_hasktags_args = (words cli_hasktags_args1) ++ cli_hasktags_args2
 
     runp_ghc_pkgs args = go cli_use_stack where
-      go ON = runp "stack" (["exec", "ghc-pkg", "--"] ++ args) []
-      go OFF = runp "ghc-pkg" args []
+      go ON = runp "stack" (["exec", "ghc-pkg", "--"] ++ (words cli_ghc_pkgs_args) ++ args) []
+      go OFF = runp "ghc-pkg" (words cli_ghc_pkgs_args ++ args) []
       go AUTO = if has_stack then go ON else go OFF
 
     cabal_or_stack = go cli_use_stack where
@@ -164,20 +168,21 @@
       go AUTO = if has_stack then go ON else go OFF
 
     -- Finds *hs in dirs, but filter-out Setup.hs
-    findSources :: [FilePath] -> IO [FilePath]
+    findSources :: [FilePath] -> IO (Set FilePath)
+    findSources [] = return Set.empty
     findSources dirs =
-      filter (not . isSuffixOf "Setup.hs") . lines <$>
+      Set.fromList . filter (not . isSuffixOf "Setup.hs") . lines <$>
       runp "find" (dirs ++ words "-type f -and ( -name *\\.hs -or -name *\\.lhs -or -name *\\.hsc )") []
 
     grepImports :: String -> Maybe String
     grepImports line = case words line of
-        ("import":"qualified":x:_) -> Just x
-        ("import":x:_) -> Just x
+        ("import":"qualified":x:_) -> Just (filter (/=';') x)
+        ("import":x:_) -> Just (filter (/=';') x)
         _ -> Nothing
 
     -- Produces list of imported modules for file.hs given
-    findModules :: [FilePath] -> IO [String]
-    findModules files = (catMaybes . map grepImports . lines) <$> runp "cat" files []
+    findModules :: Set FilePath -> IO [String]
+    findModules files = (catMaybes . map grepImports . lines) <$> runp "cat" (Set.toList files) []
 
     -- Maps import name to haskell package name
     iname2module :: String -> IO (Maybe String)
@@ -191,18 +196,19 @@
 
     -- Unapcks haskel package to the sourcedir
     unpackModule :: FilePath -> IO (Maybe FilePath)
-    unpackModule ((datadir</>) -> p) = do
-        exists <- doesDirectoryExist (datadir</>p)
+    unpackModule mod = do
+        let p = datadir</>mod
+        exists <- doesDirectoryExist p
         case exists of
           True ->  do
-            vprint $ "Already unpacked " ++ p
+            vprint $ "Already unpacked " ++ mod
             return (Just p)
           False -> do
             bracket_ (setCurrentDirectory datadir) (setCurrentDirectory cwd) $
-              ( runp cabal_or_stack ["unpack", p] [] >> return (Just p)
+              ( runp cabal_or_stack ["unpack", mod] [] >> return (Just p)
               ) `catch`
               (\(_ :: SomeException) ->
-                eprint ("Can't unpack " ++ p) >> return Nothing
+                eprint ("Can't unpack " ++ mod) >> return Nothing
               )
 
     unpackModules :: [FilePath] -> IO [FilePath]
@@ -213,12 +219,12 @@
       checkapp "hasktags"
       files <- do
         dirs <- readDirFile
-        ss_local <- (++) <$> readSourceFile <*> findSources dirs
+        ss_local <- Set.union <$> readSourceFile <*> findSources dirs
         when (null ss_local) $ do
           fail $ "Haskdogs were not able to find any sources in " <> (intercalate ", " dirs)
         ss_l1deps <- findModules ss_local >>= inames2modules >>= unpackModules >>= findSources
-        return $ ss_local ++ ss_l1deps
-      runp "hasktags" (cli_hasktags_args ++ files) []
+        return $ ss_local `mappend` ss_l1deps
+      runp "hasktags" ((if null cli_hasktags_args then def_hasktags_args else cli_hasktags_args) ++ Set.toList files) []
       putStrLn "\nSuccess"
 
   {- _real_main_ -}
