diff --git a/Data/Conduit.hs b/Data/Conduit.hs
--- a/Data/Conduit.hs
+++ b/Data/Conduit.hs
@@ -37,6 +37,7 @@
     , ($$+)
     , ($$++)
     , ($$+-)
+    , unwrapResumable
 
       -- * Utility functions
     , transPipe
diff --git a/Data/Conduit/Internal.hs b/Data/Conduit/Internal.hs
--- a/Data/Conduit/Internal.hs
+++ b/Data/Conduit/Internal.hs
@@ -48,10 +48,11 @@
     , mapInput
     , sourceList
     , withUpstream
+    , unwrapResumable
     ) where
 
 import Control.Applicative (Applicative (..))
-import Control.Monad ((>=>), liftM, ap)
+import Control.Monad ((>=>), liftM, ap, when)
 import Control.Monad.Trans.Class (MonadTrans (lift))
 import Control.Monad.IO.Class (MonadIO (liftIO))
 import Control.Monad.Base (MonadBase (liftBase))
@@ -59,6 +60,7 @@
 import Data.Monoid (Monoid (mappend, mempty))
 import Control.Monad.Trans.Resource
 import qualified GHC.Exts
+import qualified Data.IORef as I
 
 -- | The underlying datatype for all the types in this package.  In has six
 -- type parameters:
@@ -540,3 +542,26 @@
         loop
       where
         loop = awaitE >>= either (\u -> return (u, r)) (\_ -> loop)
+
+-- | Unwraps a @ResumableSource@ into a @Source@ and a finalizer.
+--
+-- A @ResumableSource@ represents a @Source@ which has already been run, and
+-- therefore has a finalizer registered. As a result, if we want to turn it
+-- into a regular @Source@, we need to ensure that the finalizer will be run
+-- appropriately. By appropriately, I mean:
+--
+-- * If a new finalizer is registered, the old one should not be called.
+-- * If the old one is called, it should not be called again.
+--
+-- This function returns both a @Source@ and a finalizer which ensures that the
+-- above two conditions hold. Once you call that finalizer, the @Source@ is
+-- invalidated and cannot be used.
+--
+-- Since 0.5.2
+unwrapResumable :: MonadIO m => ResumableSource m o -> m (Source m o, m ())
+unwrapResumable (ResumableSource src final) = do
+    ref <- liftIO $ I.newIORef True
+    let final' = do
+            x <- liftIO $ I.readIORef ref
+            when x final
+    return (liftIO (I.writeIORef ref False) >> src, final')
diff --git a/conduit.cabal b/conduit.cabal
--- a/conduit.cabal
+++ b/conduit.cabal
@@ -1,5 +1,5 @@
 Name:                conduit
-Version:             0.5.1
+Version:             0.5.2
 Synopsis:            Streaming data processing library.
 Description:
     @conduit@ is a solution to the streaming data problem, allowing for production, transformation, and consumption of streams of data in constant memory. It is an alternative to lazy I\/O which guarantees deterministic resource handling, and fits in the same general solution space as @enumerator@/@iteratee@ and @pipes@. For a brief tutorial, please see the "Data.Conduit" module.
diff --git a/test/main.hs b/test/main.hs
--- a/test/main.hs
+++ b/test/main.hs
@@ -35,6 +35,7 @@
 
 main :: IO ()
 main = hspec $ do
+{-
     describe "data loss rules" $ do
         it "consumes the source to quickly" $ do
             x <- runResourceT $ CL.sourceList [1..10 :: Int] C.$$ do
@@ -688,6 +689,79 @@
         it' "works" $ do
             res <- CL.iterate (+ 1) (1 :: Int) C.$$ CL.isolate 10 C.=$ CL.fold (+) 0
             res @?= sum [1..10]
+            -}
+
+    describe "unwrapResumable" $ do
+        it' "works" $ do
+            ref <- I.newIORef (0 :: Int)
+            let src0 = do
+                    C.yieldOr () $ I.writeIORef ref 1
+                    C.yieldOr () $ I.writeIORef ref 2
+                    C.yieldOr () $ I.writeIORef ref 3
+            (rsrc0, Just ()) <- src0 C.$$+ CL.head
+
+            x0 <- I.readIORef ref
+            x0 @?= 0
+
+            (_, final) <- C.unwrapResumable rsrc0
+
+            x1 <- I.readIORef ref
+            x1 @?= 0
+
+            final
+
+            x2 <- I.readIORef ref
+            x2 @?= 1
+
+        it' "isn't called twice" $ do
+            ref <- I.newIORef (0 :: Int)
+            let src0 = do
+                    C.yieldOr () $ I.writeIORef ref 1
+                    C.yieldOr () $ I.writeIORef ref 2
+            (rsrc0, Just ()) <- src0 C.$$+ CL.head
+
+            x0 <- I.readIORef ref
+            x0 @?= 0
+
+            (src1, final) <- C.unwrapResumable rsrc0
+
+            x1 <- I.readIORef ref
+            x1 @?= 0
+
+            Just () <- src1 C.$$ CL.head
+
+            x2 <- I.readIORef ref
+            x2 @?= 2
+
+            final
+
+            x3 <- I.readIORef ref
+            x3 @?= 2
+
+        it' "source isn't used" $ do
+            ref <- I.newIORef (0 :: Int)
+            let src0 = do
+                    C.yieldOr () $ I.writeIORef ref 1
+                    C.yieldOr () $ I.writeIORef ref 2
+            (rsrc0, Just ()) <- src0 C.$$+ CL.head
+
+            x0 <- I.readIORef ref
+            x0 @?= 0
+
+            (src1, final) <- C.unwrapResumable rsrc0
+
+            x1 <- I.readIORef ref
+            x1 @?= 0
+
+            () <- src1 C.$$ return ()
+
+            x2 <- I.readIORef ref
+            x2 @?= 0
+
+            final
+
+            x3 <- I.readIORef ref
+            x3 @?= 1
 
 it' :: String -> IO () -> Spec
 it' = it
