diff --git a/Debian/Dpkg.hs b/Debian/Dpkg.hs
new file mode 100644
--- /dev/null
+++ b/Debian/Dpkg.hs
@@ -0,0 +1,11 @@
+module Debian.Dpkg
+        ( module Debian.Dpkg.DB
+        , module Debian.Dpkg.Enums
+        , module Debian.Dpkg.Types
+        , module Debian.Dpkg.VersionRevision
+        ) where
+
+import Debian.Dpkg.DB
+import Debian.Dpkg.Enums
+import Debian.Dpkg.Types
+import Debian.Dpkg.VersionRevision
diff --git a/Debian/Dpkg/DB.hsc b/Debian/Dpkg/DB.hsc
--- a/Debian/Dpkg/DB.hsc
+++ b/Debian/Dpkg/DB.hsc
@@ -26,7 +26,9 @@
   , setDbDir
   , pkgDbFind
   , pkgList
-  , getConfigVersion
+  , parseVersion
+  , c'parseversion
+  , c'versioncompare
 ) where
 #strict_import
 
@@ -35,6 +37,7 @@
 import Foreign.Marshal.Utils (with)
 import Control.Monad (liftM, join)
 import Control.Monad.Loops (unfoldrM)
+import qualified Data.ByteString as BS
 import Debian.Dpkg.Types
 
 #include <dpkg/dpkg-db.h>
@@ -76,13 +79,22 @@
 pkgDbFind :: String -> IO C'pkginfo
 pkgDbFind p = withCString p c'pkg_db_find >>= peek
 
-getConfigVersion :: C'pkginfo -> IO String
-getConfigVersion p = do
-		v <- peekCString (c'versionrevision'version vr)
-		r <- peekCString (c'versionrevision'revision vr)
-		return $ nonZeroEpoch e ++ v ++ nonNativeRevision r
-	where
-		nonZeroEpoch e = if e == 0 then "" else (show e) ++ ":"
-		nonNativeRevision r = if r == "" then r else "-" ++ r
-		e = fromIntegral (c'versionrevision'epoch vr)
-		vr = c'pkginfo'configversion p
+#callconv parseversion , ccall unsafe , Ptr C'versionrevision -> CString -> Ptr C'dpkg_error -> IO CInt
+#callconv versioncompare , ccall unsafe , Ptr C'versionrevision -> Ptr C'versionrevision -> IO CInt
+
+parseVersion :: BS.ByteString -> IO (Either String C'versionrevision)
+parseVersion verstr = BS.useAsCString verstr $ \vercstr -> alloca $ \vrptr -> alloca $ \deptr -> do
+        i <- c'parseversion vrptr vercstr deptr
+        vr <- peek vrptr
+        if i == 0
+            then
+                return $ Right vr
+            else
+                do
+                    de <- peek deptr
+                    errmsg <- peekCString (c'dpkg_error'str de)
+                    if (c'dpkg_error'type de) == 1
+                        then
+                            return $ Right vr
+                        else
+                            return $ Left errmsg
diff --git a/Debian/Dpkg/Enums.chs b/Debian/Dpkg/Enums.chs
--- a/Debian/Dpkg/Enums.chs
+++ b/Debian/Dpkg/Enums.chs
@@ -22,6 +22,7 @@
 
 #include <dpkg/dpkg.h>
 #include <dpkg/dpkg-db.h>
+#include <dpkg/error.h>
 
 {# context lib="dpkg" #}
 
@@ -41,3 +42,5 @@
 {#enum pkgeflag as PkgEflag {upcaseFirstLetter} deriving (Eq,Show) #}
 {#enum pkgstatus as PkgStatus {upcaseFirstLetter} deriving (Eq,Show) #}
 {#enum pkgpriority as PkgPriority {upcaseFirstLetter} deriving (Eq,Show) #}
+
+{#enum dpkg_msg_type as DpkgMsgType {upcaseFirstLetter} deriving (Eq,Show) #}
diff --git a/Debian/Dpkg/Types.hsc b/Debian/Dpkg/Types.hsc
--- a/Debian/Dpkg/Types.hsc
+++ b/Debian/Dpkg/Types.hsc
@@ -24,7 +24,10 @@
 module Debian.Dpkg.Types where
 #strict_import
 
+import Data.ByteString as BS
+
 #include <dpkg/dpkg-db.h>
+#include <dpkg/error.h>
 
 #starttype struct versionrevision
 #field epoch , CInt
@@ -66,4 +69,11 @@
 #field installed , <pkgbin>
 #field available , <pkgbin>
 #field clientdata , Ptr <perpackagestate>
+#stoptype
+
+#integral_t enum dpkg_msg_type
+
+#starttype struct dpkg_error
+#field type , <dpkg_msg_type>
+#field str , CString
 #stoptype
diff --git a/Debian/Dpkg/VersionRevision.hs b/Debian/Dpkg/VersionRevision.hs
new file mode 100644
--- /dev/null
+++ b/Debian/Dpkg/VersionRevision.hs
@@ -0,0 +1,77 @@
+{-
+ VersionRevision.hs: Haskell bindings to libdpkg
+   Copyright (C) 2011 Clint Adams
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+-}
+
+module Debian.Dpkg.VersionRevision (
+    peekVersionRevision
+  , getConfigVersion
+  , VersionRevision(VersionRevision,vr_epoch,vr_version,vr_revision)
+) where
+
+import Data.ByteString.Char8 (unpack)
+import Foreign.Ptr (Ptr)
+import Foreign.Marshal.Utils (with)
+import System.IO.Unsafe (unsafePerformIO)
+
+import Debian.Dpkg.Types
+import Debian.Dpkg.DB (c'parseversion, c'versioncompare)
+
+import qualified Data.ByteString as BS
+
+-- #starttype struct versionrevision
+-- #field epoch , CInt
+-- #field version , CString
+-- #field revision , CString
+-- #stoptype
+
+peekVersionRevision :: C'versionrevision -> IO VersionRevision
+peekVersionRevision vr = do
+        v <- BS.packCString (c'versionrevision'version vr)
+        r <- BS.packCString (c'versionrevision'revision vr)
+        return $ VersionRevision (fromIntegral (c'versionrevision'epoch vr)) v r
+
+getConfigVersion :: C'pkginfo -> IO String
+getConfigVersion p = do
+		vr <- peekVersionRevision (c'pkginfo'configversion p)
+		let e = fromIntegral (vr_epoch vr)
+		let v = vr_version vr
+		let r = vr_revision vr
+		return $ nonZeroEpoch e ++ (unpack v) ++ nonNativeRevision r
+	where
+		nonZeroEpoch e = if e == 0 then "" else (show e) ++ ":"
+		nonNativeRevision r = if r == BS.empty then (unpack r) else "-" ++ (unpack r)
+
+data VersionRevision = VersionRevision {
+  vr_epoch :: Int,
+  vr_version :: BS.ByteString,
+  vr_revision :: BS.ByteString
+} deriving (Eq,Show)
+
+cvrpCompare :: Ptr C'versionrevision -> Ptr C'versionrevision -> IO Ordering
+cvrpCompare x y = do
+        r <- c'versioncompare x y
+        case r of
+                -1 -> return LT
+                0  -> return EQ
+                1  -> return GT
+
+cvrCompare :: C'versionrevision -> C'versionrevision -> Ordering
+cvrCompare = (unsafePerformIO .) . (. ((. cvrpCompare) . with)) . with
+
+instance Ord C'versionrevision where
+  compare = cvrCompare
diff --git a/dpkg.cabal b/dpkg.cabal
--- a/dpkg.cabal
+++ b/dpkg.cabal
@@ -1,5 +1,5 @@
 Name:                dpkg
-Version:             0.0.0
+Version:             0.0.1
 Synopsis:            libdpkg bindings
 Description:         Haskell bindings to the libdpkg API
 Copyright:           (C) 2011 Clint Adams
@@ -16,8 +16,13 @@
 Library
   build-depends:   base >= 4 && < 5
                  , bindings-DSL >= 1.0.7 && < 1.1
+                 , bytestring
                  , monad-loops
-  exposed-modules: Debian.Dpkg.DB, Debian.Dpkg.Types, Debian.Dpkg.Enums
+  exposed-modules: Debian.Dpkg
+                 , Debian.Dpkg.DB
+                 , Debian.Dpkg.Types
+                 , Debian.Dpkg.Enums
+                 , Debian.Dpkg.VersionRevision
   other-extensions: ForeignFunctionInterface
   pkgconfig-depends: libdpkg >= 1.16.1
   cpp-options: -DLIBDPKG_VOLATILE_API=1
@@ -26,7 +31,7 @@
 Test-Suite test
   type:       exitcode-stdio-1.0
   main-is:    test.hs
-  build-depends: base, HUnit, dpkg
+  build-depends: base, HUnit, dpkg, bytestring
   pkgconfig-depends: libdpkg >= 1.16.1
   extra-libraries: dpkg
   default-language: Haskell98
diff --git a/test.hs b/test.hs
--- a/test.hs
+++ b/test.hs
@@ -2,9 +2,12 @@
 import Debian.Dpkg.DB
 import Debian.Dpkg.Enums
 import Debian.Dpkg.Types
+import Debian.Dpkg.VersionRevision
 
 import Foreign.C.String (peekCString)
 import Foreign.Storable (peek)
+import qualified Data.ByteString as BS
+import Data.ByteString.Char8 (pack)
 
 test1 = TestCase (do
 	p <- pkgDbFind "testpkg"
@@ -34,6 +37,45 @@
 	assertEqual "configversion" "1.2.3-4" cv
         )
 
-tests = TestList [TestLabel "test1" test1, TestLabel "test2" test2]
+test3 = TestCase (do
+        cvr <- parseVersion (pack "9:8.7.6-5")
+        case cvr of
+             Left msg -> assertString msg
+             Right v  -> do
+                 vr <- peekVersionRevision v
+                 assertEqual "epoch" 9 (vr_epoch vr)
+                 assertEqual "version" (pack "8.7.6") (vr_version vr)
+                 assertEqual "revision" (pack "5") (vr_revision vr)
+        )
+
+test4 = TestCase (do
+        cvr <- parseVersion (BS.empty)
+        case cvr of
+             Left msg -> return ()
+             Right v  -> assertString "unexpected success"
+        )
+
+test5 = TestCase (do
+        cvr1 <- parseVersion (pack "9:8.7.6-5")
+        cvr2 <- parseVersion (pack "1:2.3.4-5")
+        case (cvr1,cvr2) of
+             (Right x, Right y) -> assertEqual "comparison" True (cvr1 > cvr2)
+             otherwise -> assertFailure"Failed to parse one of the versions"
+        )
+
+test6 = TestCase (do
+        cvr1 <- parseVersion (pack "1~1")
+        cvr2 <- parseVersion (pack "1")
+        case (cvr1,cvr2) of
+             (Right x, Right y) -> assertEqual "comparison" True (cvr1 < cvr2)
+             otherwise -> assertFailure"Failed to parse one of the versions"
+        )
+
+tests = TestList [TestLabel "pkgDbFind" test1
+                , TestLabel "pkgList" test2
+                , TestLabel "parseVersion good" test3
+                , TestLabel "parseVersion bad" test4
+                , TestLabel "parseVersion Ord" test5
+                , TestLabel "parseVersion Ord tilde" test6 ]
 
 main = setDbDir "./testdb" >> msdbInit >> runTestTT tests
