diff --git a/README b/README
--- a/README
+++ b/README
@@ -70,22 +70,6 @@
       projects at some point in some way that makes sense.
 
 
-   - zip-archive on Hackage
-
-      I started out using zip-archive for this work but soon found that
-      it has problems with some poorly-made ePub files. Nearly 300 or 40%
-      of the books I have are unreadable at this time with zip-archive.
-
-      As ugly as it sounds, I found the most reliable solution right
-      now is to use the unzip shell utility to extract the relevant XML
-      documents from ePub books. This is why the dependency on HSH. I'm
-      not thrilled with this situation and would like to find time to
-      dig into the zip file spec and submit patches to zip-archive.
-
-      But also note that epub-meta is obscenely fast even with invoking
-      a shell for unzipping. Haskell FTW!
-
-
 -----
 A word about the version numbering scheme:
 
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -22,7 +22,7 @@
       -- convenience
       customPostBuild _ _ _ _ = do
          let binDir = "bin"
-         let binName = "epub-meta"
+         let binName = "epubmeta"
          let destPath = binDir </> binName
 
          createDirectoryIfMissing True binDir
diff --git a/epub-metadata.cabal b/epub-metadata.cabal
--- a/epub-metadata.cabal
+++ b/epub-metadata.cabal
@@ -1,5 +1,5 @@
 name:                epub-metadata
-version:             2.0.1
+version:             2.0.2
 cabal-version:       >= 1.2
 build-type:          Simple
 license:             BSD3
@@ -35,12 +35,12 @@
                      Codec.Epub.Opf.Package.Spine,
                      Codec.Epub.Opf.Parse
    hs-source-dirs:   src
-   build-depends:    base >= 3 && < 5, containers, hxt >= 9, mtl, 
-                     process, regex-compat
+   build-depends:    base >= 3 && < 5, containers, hxt >= 9, LibZip, 
+                     mtl, regex-compat
    ghc-options:      -Wall
 
-executable           epub-meta
-   main-is:          Codec/Epub/Opf/Cli/epub-meta.hs
+executable           epubmeta
+   main-is:          Codec/Epub/Opf/Cli/epubmeta.hs
    hs-source-dirs:   src
    build-depends:    base >= 3 && < 5
    ghc-options:      -Wall
diff --git a/src/Codec/Epub/IO.hs b/src/Codec/Epub/IO.hs
--- a/src/Codec/Epub/IO.hs
+++ b/src/Codec/Epub/IO.hs
@@ -13,11 +13,9 @@
    ( extractFileFromZip, opfPath )
    where
 
+import Codec.Archive.LibZip
 import Control.Arrow.ListArrows ( (>>>), deep )
 import Control.Monad.Error
-import System.Exit
-import System.Process
-import Text.Printf
 import Text.Regex
 import Text.XML.HXT.Arrow.XmlArrow ( getAttrValue, hasName, isElem )
 import Text.XML.HXT.Arrow.XmlState ( no, runX, withValidate )
@@ -36,36 +34,18 @@
    (mkRegexWithOpts "<!DOCTYPE [^>]*>" False True)) ""
 
 
-{- | GNU unzip has annoying non-zero exit codes that aren't fatal
-   so we need to check for those special.
--}
-handleEC :: (MonadIO m, MonadError String m)
-   => String -> ExitCode -> m ()
-handleEC msg (ExitFailure c)
-   | c > 2 = throwError $ printf "%s  status: %s]\n" msg (show c)
-   | otherwise = return ()
-handleEC _    ExitSuccess = return ()
-
-
 {- | Extract a file from a zipfile.
-   This is here because ePub files are really just zip files.
-
-   Yep, you saw right sports fans. This code is using the command-
-   line unzip utility. In the future I'd like to make it use a
-   library.
 -}
 extractFileFromZip :: (MonadIO m, MonadError String m)
    => FilePath    -- ^ path to zip file
    -> FilePath    -- ^ path within zip file to extract
    -> m String    -- ^ contents of expected file
 extractFileFromZip zipPath filePath = do
-   let dearchiver = "unzip"
-
-   (ec, output, _) <- liftIO $ readProcessWithExitCode
-      dearchiver ["-p", zipPath, filePath] ""
+   result <- liftIO $ catchZipError
+      (fmap Right $ withArchive [] zipPath $ fileContents [] filePath)
+      (return . Left)
 
-   handleEC (printf "[ERROR %s  zip file: %s  path in zip: %s"
-      dearchiver zipPath filePath) ec
+   output <- either (throwError . show) return result
 
    return . removeEncoding . removeDoctype $ output
 
diff --git a/src/Codec/Epub/Opf/Cli/Opts.hs b/src/Codec/Epub/Opf/Cli/Opts.hs
--- a/src/Codec/Epub/Opf/Cli/Opts.hs
+++ b/src/Codec/Epub/Opf/Cli/Opts.hs
@@ -46,11 +46,11 @@
 usageText = (usageInfo header options) ++ "\n" ++ footer
    where
       header = init $ unlines
-         [ "Usage: epub-meta [OPTIONS] EPUBFILE"
-         , "Examine ePub OPF package data"
+         [ "Usage: epubmeta [OPTIONS] EPUBFILE"
+         , "Examine EPUB OPF package data"
          , ""
          , "Options:"
          ]
       footer = init $ unlines
-         [ "Version 2.0.1  Dino Morelli <dino@ui3.info>"
+         [ "Version 2.0.2  Dino Morelli <dino@ui3.info>"
          ]
diff --git a/src/Codec/Epub/Opf/Cli/epub-meta.hs b/src/Codec/Epub/Opf/Cli/epub-meta.hs
deleted file mode 100644
--- a/src/Codec/Epub/Opf/Cli/epub-meta.hs
+++ /dev/null
@@ -1,25 +0,0 @@
--- Copyright: 2010, 2011 Dino Morelli
--- License: BSD3 (see LICENSE)
--- Author: Dino Morelli <dino@ui3.info>
-
-import Control.Monad.Error
-import System.Environment ( getArgs )
-import System.Exit
-
-import Codec.Epub.Opf.Cli.Opts
-import Codec.Epub.Opf.Format.Package
-import Codec.Epub.Opf.Parse
-
-
-main :: IO ()
-main = do
-   (opts, paths) <- getArgs >>= parseOpts
-
-   when ((optHelp opts) || (null paths)) $ do
-      putStrLn usageText
-      exitWith $ ExitFailure 1
-
-   let zipPath = head paths
-   result <- runErrorT $ parseEpubOpf zipPath
-
-   putStr $ either id (formatPackage (optVerbose opts)) result
diff --git a/src/Codec/Epub/Opf/Cli/epubmeta.hs b/src/Codec/Epub/Opf/Cli/epubmeta.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Epub/Opf/Cli/epubmeta.hs
@@ -0,0 +1,25 @@
+-- Copyright: 2010, 2011 Dino Morelli
+-- License: BSD3 (see LICENSE)
+-- Author: Dino Morelli <dino@ui3.info>
+
+import Control.Monad.Error
+import System.Environment ( getArgs )
+import System.Exit
+
+import Codec.Epub.Opf.Cli.Opts
+import Codec.Epub.Opf.Format.Package
+import Codec.Epub.Opf.Parse
+
+
+main :: IO ()
+main = do
+   (opts, paths) <- getArgs >>= parseOpts
+
+   when ((optHelp opts) || (null paths)) $ do
+      putStrLn usageText
+      exitWith $ ExitFailure 1
+
+   let zipPath = head paths
+   result <- runErrorT $ parseEpubOpf zipPath
+
+   putStr $ either id (formatPackage (optVerbose opts)) result
