diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -4,35 +4,15 @@
 -- License: BSD3 (see LICENSE)
 -- Author: Dino Morelli <dino@ui3.info>
 
-import Control.Monad ( unless )
 import Distribution.Simple
 import System.Cmd ( system )
-import System.Directory ( createDirectoryIfMissing )
-import System.FilePath
-import System.Posix.Files ( createSymbolicLink, fileExist )
 
 
 main = defaultMainWithHooks (simpleUserHooks 
-   { postBuild = customPostBuild
-   , runTests = testRunner
+   { runTests = testRunner
    } )
 
    where
-      -- Create symlink to the binary after build for developer 
-      -- convenience
-      customPostBuild _ _ _ _ = do
-         let binDir = "bin"
-         let binName = "epubmeta"
-         let destPath = binDir </> binName
-
-         createDirectoryIfMissing True binDir
-
-         linkExists <- fileExist destPath
-         unless linkExists $ do
-            createSymbolicLink
-               (".." </> "dist" </> "build" </> binName </> binName)
-               destPath
-
       -- Target for running all unit tests
       testRunner _ _ _ _ = do
          system $ "runhaskell -isrc testsuite/runtests.hs"
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.2
+version:             2.1.0
 cabal-version:       >= 1.2
 build-type:          Simple
 license:             BSD3
@@ -17,7 +17,7 @@
                      utility to dump OPF package data to stdout in a 
                      human-readable form.
 category:            Codec, Text
-tested-with:         GHC>=6.12.1
+tested-with:         GHC >= 6.12.3
 
 library
    exposed-modules:  Codec.Epub.IO,
@@ -35,8 +35,8 @@
                      Codec.Epub.Opf.Package.Spine,
                      Codec.Epub.Opf.Parse
    hs-source-dirs:   src
-   build-depends:    base >= 3 && < 5, containers, hxt >= 9, LibZip, 
-                     mtl, regex-compat
+   build-depends:    base >= 3 && < 5, bytestring, containers,
+                     hxt >= 9, mtl, regex-compat, zip-archive
    ghc-options:      -Wall
 
 executable           epubmeta
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
@@ -5,17 +5,15 @@
 {-# LANGUAGE FlexibleContexts #-}
 
 {- | Functions for doing some disk IO with ePub documents
-
-   Note that these functions do their work by using the external 
-   unzip utility.
 -}
 module Codec.Epub.IO
-   ( extractFileFromZip, opfPath )
+   ( opfContents )
    where
 
-import Codec.Archive.LibZip
+import Codec.Archive.Zip
 import Control.Arrow.ListArrows ( (>>>), deep )
 import Control.Monad.Error
+import qualified Data.ByteString.Lazy.Char8 as B
 import Text.Regex
 import Text.XML.HXT.Arrow.XmlArrow ( getAttrValue, hasName, isElem )
 import Text.XML.HXT.Arrow.XmlState ( no, runX, withValidate )
@@ -34,37 +32,43 @@
    (mkRegexWithOpts "<!DOCTYPE [^>]*>" False True)) ""
 
 
-{- | Extract a file from a zipfile.
--}
-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
-   result <- liftIO $ catchZipError
-      (fmap Right $ withArchive [] zipPath $ fileContents [] filePath)
-      (return . Left)
-
-   output <- either (throwError . show) return result
-
-   return . removeEncoding . removeDoctype $ output
+-- | Extract a file from a zip archive throwing an error on failure
+fileFromArchive :: MonadError String m =>
+   FilePath -> Archive -> m String
+fileFromArchive filePath archive = do
+   let mbEntry = findEntryByPath filePath archive
+   maybe
+      (throwError $ "Unable to locate file " ++ filePath)
+      (return . B.unpack . fromEntry) mbEntry
 
 
--- | Get the path within an ePub file to the OPF Package Document
-opfPath :: (MonadError String m, MonadIO m)
+-- | Get the contents of the OPF Package Document from an ePub file
+opfContents :: (MonadError String m, MonadIO m)
    => FilePath    -- ^ path to ePub zip file
-   -> m String    -- ^ path within ePub to the OPF Package Document
-opfPath zipPath = do
-   containerContents <- extractFileFromZip zipPath
-      "META-INF/container.xml"
+   -> m String    -- ^ contents of the OPF Package Document
+opfContents zipPath = do
+   {- We need to first extract the container.xml file
+      It's required to have a certain path and name in the epub
+      and contains the path to what we really want, the .opf file.
+   -}
+   zipFileBytes <- liftIO $ B.readFile zipPath
+   let archive = toArchive zipFileBytes
 
+   let containerPath = "META-INF/container.xml"
+   containerDoc <- fileFromArchive containerPath archive
+
    result <- liftIO $ runX (
-      readString [withValidate no] containerContents
+      readString [withValidate no] containerDoc
       >>> deep (isElem >>> hasName "rootfile")
       >>> getAttrValue "full-path"
       )
 
-   case result of
+   rootPath <- case result of
       (p : []) -> return p
-      _        -> throwError
-         "ERROR: rootfile full-path missing from META-INF/container.xml"
+      _        -> throwError $
+         "ERROR: rootfile full-path missing from " ++ containerPath
+
+   -- Now that we have the path to the .opf file, extract it
+   rootDoc <- fileFromArchive rootPath archive
+
+   return . removeEncoding . removeDoctype $ rootDoc
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
@@ -52,5 +52,5 @@
          , "Options:"
          ]
       footer = init $ unlines
-         [ "Version 2.0.2  Dino Morelli <dino@ui3.info>"
+         [ "Version 2.1.0  Dino Morelli <dino@ui3.info>"
          ]
diff --git a/src/Codec/Epub/Opf/Parse.hs b/src/Codec/Epub/Opf/Parse.hs
--- a/src/Codec/Epub/Opf/Parse.hs
+++ b/src/Codec/Epub/Opf/Parse.hs
@@ -251,9 +251,9 @@
    XML string
 -}
 parseXmlToOpf :: (MonadIO m) => String -> m [Package]
-parseXmlToOpf opfContents =
+parseXmlToOpf contents =
    liftIO $ runX (
-      readString [withValidate no] opfContents
+      readString [withValidate no] contents
       >>> propagateNamespaces
       >>> getBookData
       )
@@ -263,8 +263,7 @@
 parseEpubOpf :: (MonadIO m, MonadError String m) =>
    FilePath -> m Package
 parseEpubOpf zipPath = do
-   opfContents <- extractFileFromZip zipPath =<< opfPath zipPath
-   result <- parseXmlToOpf opfContents
+   result <- opfContents zipPath >>= parseXmlToOpf
 
    case result of
       (em : []) -> return em
