diff --git a/Data/Conduit/Cereal.hs b/Data/Conduit/Cereal.hs
--- a/Data/Conduit/Cereal.hs
+++ b/Data/Conduit/Cereal.hs
@@ -1,45 +1,31 @@
-{-# LANGUAGE DeriveDataTypeable #-}
 -- | Turn a 'Get' into a 'Sink' and a 'Put' into a 'Source'
+
 module Data.Conduit.Cereal where
 
 import qualified Data.ByteString as BS
 import qualified Data.ByteString.Lazy as LBS
-import Data.Typeable (Typeable)
-import Control.Exception (Exception)
-import Control.Monad.Trans
-import qualified Data.Conduit as DC
-import Data.Conduit.List (sourceList)
-import Data.Serialize.Get
-import Data.Serialize.Put
-import Control.Exception (throw)
-
-data GetException = GetException String
-                  | GetDoesntConsumeInput
-  deriving (Show, Typeable)
-
-instance Exception GetException
+import qualified Data.Conduit as C
+import           Data.Conduit.List (sourceList)
+import           Data.Serialize
 
 -- | Convert a 'Get' into a 'Sink'. The 'Get' will be streamed bytes until it returns 'Done' or 'Fail'.
 --
--- If the 'Get' fails, a GetException will be thrown with 'resourceThrow'. This function itself can also throw a GetException.
-sinkGet :: DC.ResourceThrow m => Get output -> DC.Sink BS.ByteString m output
-sinkGet get = case runGetPartial get BS.empty of
-                Fail s -> throw $ GetException s
-                Partial f -> DC.SinkData { DC.sinkPush = push f
-                                         , DC.sinkClose = close f
-                                         }
-                Done _ _ -> throw GetDoesntConsumeInput
+-- If 'Get' succeed it will return the data read and unconsumed part of the input stream.
+-- If the 'Get' fails it will return message describing the error. 
+sinkGet :: Monad m => Get output -> C.Sink BS.ByteString m (Either String output)
+sinkGet get = consume (runGetPartial get) BS.empty
   where push f input
-          | BS.null input = return $ DC.Processing (push f) (close f)
-          | otherwise = case f input of
-              Fail s -> lift $ DC.resourceThrow $ GetException s
-              Partial f' -> return $ DC.Processing (push f') (close f')
-              Done r rest -> return $ DC.Done (if BS.null rest
-                                                 then Nothing
-                                                 else Just rest
-                                              ) r
-        close f = let Fail s = f BS.empty in lift $ DC.resourceThrow $ GetException s
+          | BS.null input = C.NeedInput (push f) (close f)
+          | otherwise = consume f input
+        consume f s = case f s of
+          Fail msg   -> C.Done (streamToMaybe s) (Left msg)
+          Partial f' -> C.NeedInput (push f') (close f')
+          Done r s'  -> C.Done (streamToMaybe s') (Right r)
+        close f = let Fail r = f BS.empty in C.Done Nothing (Left r)
+        streamToMaybe s = if BS.null s
+                            then Nothing
+                            else Just s
 
 -- | Convert a 'Put' into a 'Source'. Runs in constant memory.
-sourcePut :: DC.Resource m => Put -> DC.Source m BS.ByteString
+sourcePut :: Monad m => Put -> C.Source m BS.ByteString
 sourcePut put = sourceList $ LBS.toChunks $ runPutLazy put
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
 The following license covers this documentation, and the source code, except
 where otherwise indicated.
 
-Copyright 2010, Michael Snoyman. All rights reserved.
+Copyright 2012, Myles C. Maxfield. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
diff --git a/Test/CerealConduit.hs b/Test/CerealConduit.hs
new file mode 100644
--- /dev/null
+++ b/Test/CerealConduit.hs
@@ -0,0 +1,45 @@
+module Test.CerealConduit (tests) where
+
+import Control.Monad.Identity
+import Test.HUnit
+import qualified Data.Conduit as C
+import Data.Conduit.Cereal
+import Data.Conduit.List
+import Data.Serialize
+import qualified Data.ByteString as BS
+import Test.Framework.Providers.HUnit
+import System.Exit
+
+test1 :: Test
+test1 = TestCase (assertEqual "Handles starting with empty bytestring"
+  (Right 1)
+  (runIdentity $ (sourceList [BS.pack [], BS.pack [1]]) C.$$ (sinkGet getWord8)))
+
+test2 :: Test
+test2 = TestCase (assertEqual "Handles empty bytestring in middle"
+  (Right [1, 3])
+  (runIdentity $ (sourceList [BS.pack [1], BS.pack [], BS.pack [3]]) C.$$ (sinkGet (do
+    x <- getWord8
+    y <- getWord8
+    return [x, y]))))
+
+test3 :: Test
+test3 = TestCase (assertBool "Handles no data"
+  (case (runIdentity $ (sourceList []) C.$$ (sinkGet getWord8)) of
+    Right _ -> False
+    Left _ -> True))
+
+test4 :: Test
+test4 = TestCase (assertEqual "Consumes no data"
+  (Right ())
+  (runIdentity $ (sourceList [BS.pack [1]]) C.$$ (sinkGet $ return ())))
+
+hunittests = TestList [test1, test2, test3, test4]
+
+tests = hUnitTestToTests hunittests
+
+main = do
+  counts <- runTestTT hunittests
+  if errors counts == 0 && failures counts == 0
+    then exitSuccess
+    else exitFailure
diff --git a/cereal-conduit.cabal b/cereal-conduit.cabal
--- a/cereal-conduit.cabal
+++ b/cereal-conduit.cabal
@@ -1,5 +1,5 @@
 name:            cereal-conduit
-version:         0.0.3
+version:         0.0.4
 license:         BSD3
 license-file:    LICENSE
 author:          Myles C. Maxfield <myles.maxfield@gmail.com>
@@ -14,13 +14,22 @@
 
 library
     build-depends: base     >= 4       && < 5
-                 , conduit  >= 0.2.0
+                 , conduit  >= 0.4.0   && < 0.5.0
                  , cereal   >= 0.3.1.0
                  , mtl
                  , bytestring
     exposed-modules: Data.Conduit.Cereal
     ghc-options:     -Wall
 
+Test-Suite test-cereal-conduit
+    type: exitcode-stdio-1.0
+    main-is: Test/CerealConduit.hs
+    build-depends: base >= 4 && < 5
+                 , conduit >= 0.4.0 && < 0.5.0
+                 , cereal >= 0.3.1.0
+                 , mtl
+                 , bytestring
+                 , test-framework-hunit
 
 source-repository head
   type:     git
