diff --git a/Control/Monad/Trans/Region.hs b/Control/Monad/Trans/Region.hs
--- a/Control/Monad/Trans/Region.hs
+++ b/Control/Monad/Trans/Region.hs
@@ -38,9 +38,9 @@
     , ParentOf
 
       -- * Handy functions for writing monadic instances
+    , liftCallCC
     , mapRegionT
     , liftCatch
-      -- | /TODO: define and export: /@liftCallCC@
     ) where
 
 import Control.Monad.Trans.Region.Internal
diff --git a/Control/Monad/Trans/Region/Internal.hs b/Control/Monad/Trans/Region/Internal.hs
--- a/Control/Monad/Trans/Region/Internal.hs
+++ b/Control/Monad/Trans/Region/Internal.hs
@@ -4,7 +4,6 @@
            , RankNTypes
            , ScopedTypeVariables
            , KindSignatures
-           , TypeFamilies
            , MultiParamTypeClasses
            , FunctionalDependencies
            , UndecidableInstances
@@ -33,14 +32,8 @@
 --------------------------------------------------------------------------------
 
 module Control.Monad.Trans.Region.Internal
-    ( -- * Scarce resources
-      Resource
-    , Handle
-    , openResource
-    , closeResource
-
-      -- * Regions
-    , RegionT
+    ( -- * Regions
+      RegionT
 
       -- * Running regions
     , runRegionT
@@ -54,7 +47,6 @@
     , RegionalHandle
 
     , internalHandle
-    , mapInternalHandle
 
     , open
     , with
@@ -64,9 +56,9 @@
     , dup
 
       -- * Handy functions for writing monadic instances
+    , liftCallCC
     , mapRegionT
     , liftCatch
-      -- | /TODO: define and export: /@liftCallCC@
 
       -- * Parent/child relationship between regions.
     , ParentOf
@@ -99,33 +91,21 @@
 -- from transformers:
 import Control.Monad.Trans   ( MonadTrans, lift, MonadIO, liftIO )
 
-import qualified Control.Monad.Trans.Reader as Reader ( liftCatch )
-import           Control.Monad.Trans.Reader ( ReaderT
-                                            , ask
-                                            , runReaderT, mapReaderT
-                                            )
+import qualified Control.Monad.Trans.Reader as R ( liftCallCC, liftCatch )
+import           Control.Monad.Trans.Reader      ( ReaderT
+                                                 , ask
+                                                 , runReaderT, mapReaderT
+                                                 )
 -- from base-unicode-symbols:
 import Data.Eq.Unicode       ( (≡) )
 import Data.Function.Unicode ( (∘) )
 
-
---------------------------------------------------------------------------------
--- * Scarce resources
---------------------------------------------------------------------------------
-
-{-| Class of /scarce/ resources. A scarce resource is a resource that only one
-user can use at a time. (like a file, memory pointer or USB device for
-example).
-
-Because of the scarcity, these resources need to be /opened/ to grant temporary
-sole access to the resource. When the resource is no longer needed it should be
-/closed/ a.s.a.p to grant others access to the resource.
--}
-class Resource resource where
-    data Handle resource ∷ *
-
-    openResource  ∷ resource → IO (Handle resource)
-    closeResource ∷ Handle resource → IO ()
+-- from ourselves:
+import Control.Resource ( Resource
+                        , Handle
+                        , openResource
+                        , closeResource
+                        )
 
 
 --------------------------------------------------------------------------------
@@ -186,14 +166,24 @@
 
       {-| Get the reference count from the given regional handle.
 
-      Handles are reference counted because they may be /duplicated/
-      to a parent region using 'dup'.
+      Normally a handle should be closed when its originating region
+      terminates. There are two exceptions to this rule:
 
+      * When a handle is /duplicated/ to a parent region using 'dup'
+        it should only be closed when the parent region terminates.
+
+      * When a region is executed in a new thread using 'forkTopRegion' all
+        handles that can be referenced in the originating region should also be
+        referenceable in the new forked region. Therefore those handles should only be
+        closed when the originating region or the new forked region terminates,
+        whichever comes /last/.
+
+      To implement this behaviour, handles are reference counted.
       The reference count is:
 
        * Initialized at 1 in 'open'.
 
-       * Incremented in 'dup'.
+       * Incremented in 'dup' and 'forkTopRegion'.
 
        * Decremented on termination of 'runRegionWith'
          (which is called by 'runRegionT' and 'forkTopRegion').
@@ -204,11 +194,6 @@
     , refCntIORef ∷ IORef Int
     }
 
--- | Modify the internal handle from the given regional handle.
-mapInternalHandle ∷ (Handle resource1 → Handle resource2)
-                  → (RegionalHandle resource1 r → RegionalHandle resource2 r)
-mapInternalHandle f rh = rh { internalHandle = f $ internalHandle rh }
-
 {-| Internally used function that atomically decrements the reference count that
 is stored in the given @IORef@. The function returns the decremented reference
 count.
@@ -478,12 +463,10 @@
 -- * Handy functions for writing monadic instances
 --------------------------------------------------------------------------------
 
--- TODO:
--- -- | Lift a @callCC@ operation to the new monad.
--- liftCallCC ∷ (((α → pr β) → pr α) → pr α)        -- ^ @callCC@ on the argument monad.
---            → ((α → RegionT s pr β) → RegionT s pr α)
---            → RegionT s pr α
--- liftCallCC callCC f = RegionT $ ???
+-- | Lift a @callCC@ operation to the new monad.
+liftCallCC ∷ (((α → pr β) → pr α) → pr α)
+           → (((α → RegionT s pr β) → RegionT s pr α) → RegionT s pr α)
+liftCallCC callCC f = RegionT $ R.liftCallCC callCC $ unRegionT ∘ f ∘ (RegionT ∘)
 
 -- | Transform the computation inside a region.
 mapRegionT ∷ (m α → n β) → RegionT s m α → RegionT s n β
@@ -494,7 +477,7 @@
           → RegionT s pr α             -- ^ Computation to attempt.
           → (e → RegionT s pr α)       -- ^ Exception handler.
           → RegionT s pr α
-liftCatch f m h = RegionT $ Reader.liftCatch f (unRegionT m) (unRegionT ∘ h)
+liftCatch f m h = RegionT $ R.liftCatch f (unRegionT m) (unRegionT ∘ h)
 
 
 --------------------------------------------------------------------------------
diff --git a/Control/Monad/Trans/Region/Unsafe.hs b/Control/Monad/Trans/Region/Unsafe.hs
--- a/Control/Monad/Trans/Region/Unsafe.hs
+++ b/Control/Monad/Trans/Region/Unsafe.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE UnicodeSyntax #-}
+
 -------------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.Trans.Region.Unsafe
@@ -10,29 +12,17 @@
 -- close the resource manually, which will defeat the safety-guarantees that
 -- this package provides!
 --
--- This module should /only/ be used by library authors wishing to allow their
--- end-users to open their resources in a region.
---
--- To create a module or library that allows your users to open your resources
--- in a region, the only thing you have to do is to define an instance for
--- 'Resource' for your type of resource.
---
--- Make sure not to re-export anything from this module. Either re-export things
--- from @Control.Monad.Trans.Region@ or tell your users to import that module
--- directly.
---
 --------------------------------------------------------------------------------
 
 module Control.Monad.Trans.Region.Unsafe
-    ( -- * Scarce resources
-      Resource
-    , Handle
-
-    , openResource
-    , closeResource
-
-    , internalHandle
+    ( internalHandle
     , mapInternalHandle
     ) where
 
-import Control.Monad.Trans.Region.Internal
+import Control.Monad.Trans.Region.Internal ( RegionalHandle, internalHandle )
+import Control.Resource ( Handle )
+
+-- | Modify the internal handle from the given regional handle.
+mapInternalHandle ∷ (Handle resource1 → Handle resource2)
+                  → (RegionalHandle resource1 r → RegionalHandle resource2 r)
+mapInternalHandle f rh = rh { internalHandle = f $ internalHandle rh }
diff --git a/Control/Resource.hs b/Control/Resource.hs
new file mode 100644
--- /dev/null
+++ b/Control/Resource.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE UnicodeSyntax, NoImplicitPrelude, TypeFamilies #-}
+
+-------------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Resource
+-- Copyright   :  (c) 2009 Bas van Dijk
+-- License     :  BSD3 (see the file LICENSE)
+-- Maintainer  :  Bas van Dijk <v.dijk.bas@gmail.com>
+--
+-- Unsafely opening and closing of scarce resources.
+--
+--------------------------------------------------------------------------------
+
+module Control.Resource
+    ( Resource
+    , Handle
+    , openResource
+    , closeResource
+    ) where
+
+import System.IO ( IO )
+
+{-| Class of /scarce/ resources. A scarce resource is a resource that only one
+user can use at a time. (like a file, memory pointer or USB device for
+example).
+
+Because of the scarcity, these resources need to be /opened/ to grant temporary
+sole access to the resource. When the resource is no longer needed it should be
+/closed/ a.s.a.p to grant others access to the resource.
+-}
+class Resource resource where
+    data Handle resource ∷ *
+
+    -- | Yield an @IO@ computation that opens the given resource and returns a
+    -- @Handle@ on it.
+    --
+    -- Think of a handle as your private session with the resource. As long as
+    -- you have it, other users can't use the resource. So don't forget to close
+    -- this session with the resource as soon as you're done with it.
+    openResource  ∷ resource → IO (Handle resource)
+
+    -- | Yield an @IO@ computation that closes the resource identified by the
+    -- given @Handle@.
+    --
+    -- /Warning/: Using the @Handle@ after the resource has been closed will
+    -- usually throw an exception or result in a program crash!
+    closeResource ∷ Handle resource → IO ()
diff --git a/Data/RegionRef.hs b/Data/RegionRef.hs
new file mode 100644
--- /dev/null
+++ b/Data/RegionRef.hs
@@ -0,0 +1,105 @@
+{-# LANGUAGE UnicodeSyntax, NoImplicitPrelude, KindSignatures #-}
+
+-------------------------------------------------------------------------------
+-- |
+-- Module      :  Data.RegionRef
+-- Copyright   :  (c) 2009 Bas van Dijk
+-- License     :  BSD3 (see the file LICENSE)
+-- Maintainer  :  Bas van Dijk <v.dijk.bas@gmail.com>
+--
+-- A mutable variable in the region monad that should provide a safer
+-- replacement for an 'IORef' because you can't use it outside the region in
+-- which it was created (unless you explicitly duplicate it).
+--
+--------------------------------------------------------------------------------
+
+module Data.RegionRef
+    ( RegionRef
+    , pureDup
+    , newRegionRef
+    , readRegionRef
+    , writeRegionRef
+    , modifyRegionRef
+    , atomicModifyRegionRef
+    ) where
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+-- from base:
+import Data.Function ( ($) )
+import Control.Monad ( liftM )
+import Data.Eq       ( Eq )
+import Data.IORef    ( IORef
+                     , newIORef
+                     , readIORef, writeIORef
+                     , modifyIORef, atomicModifyIORef
+                     )
+
+-- from base-unicode-symbols:
+import Data.Function.Unicode ( (∘) )
+
+-- from transformers:
+import Control.Monad.Trans ( MonadIO, liftIO )
+
+-- from ourselves:
+import Control.Monad.Trans.Region ( RegionT, ParentOf )
+
+
+--------------------------------------------------------------------------------
+-- Mutable references in the region monad
+--------------------------------------------------------------------------------
+
+-- | A mutable variable storing a value of type @&#945;@ which can only be used
+-- in region @r@, @r@'s children or @r@'s parent when you duplicate it using
+-- 'pureDup'.
+newtype RegionRef (r ∷ * → *) α = RegionRef { unRegionRef ∷ IORef α }
+    deriving ( Eq )
+
+-- | Transform the region type @r@ of the regional reference to @r@'s parent so
+-- that it can be used in that region.
+pureDup ∷ RegionRef (RegionT cs (RegionT ps ppr)) α
+        → RegionRef             (RegionT ps ppr)  α
+pureDup = RegionRef ∘ unRegionRef
+
+{-| Yield a regional computation that returns a new regional reference that
+stores the given value.
+
+Note that the reference is parameterized by the same region in which it was
+created. This ensures you can never use this reference outside that region and
+it allows you to use this reference in a child region of that region
+-}
+newRegionRef ∷ MonadIO pr
+             ⇒ α → RegionT s pr (RegionRef (RegionT s pr) α)
+newRegionRef = liftM RegionRef ∘ liftIO ∘ newIORef
+
+-- | Read the value of the given regional reference.
+readRegionRef ∷ (pr `ParentOf` cr, MonadIO cr)
+              ⇒ RegionRef pr α → cr α
+readRegionRef = liftIO ∘ readIORef ∘ unRegionRef
+
+-- | Write a new value into the given regional reference.
+writeRegionRef ∷ (pr `ParentOf` cr, MonadIO cr)
+               ⇒ RegionRef pr α → α → cr ()
+writeRegionRef ref x = liftIO $ writeIORef (unRegionRef ref) x
+
+-- | Mutate the contents of the given regional reference using the given
+-- function.
+modifyRegionRef ∷ (pr `ParentOf` cr, MonadIO cr)
+                ⇒ RegionRef pr α → (α → α) → cr ()
+modifyRegionRef ref f = liftIO $ modifyIORef (unRegionRef ref) f
+
+{-| Atomically modifies the contents of the given regional reference using the
+given function.
+
+This function is useful for using a regional reference in a safe way in a
+multithreaded program. If you only have one regional reference, then using
+@atomicModifyRegionRef@ to access and modify it will prevent race conditions.
+-}
+atomicModifyRegionRef ∷ (pr `ParentOf` cr, MonadIO cr)
+                      ⇒ RegionRef pr α → (α → (α, β)) → cr β
+atomicModifyRegionRef ref f = liftIO $ atomicModifyIORef (unRegionRef ref) f
+
+
+-- The End ---------------------------------------------------------------------
diff --git a/regions.cabal b/regions.cabal
--- a/regions.cabal
+++ b/regions.cabal
@@ -1,10 +1,10 @@
 name:          regions
-version:       0.3
+version:       0.4
 cabal-version: >=1.6
 build-type:    Simple
 license:       BSD3
 license-file:  LICENSE
-copyright:     2009 Bas van Dijk
+copyright:     2010 Bas van Dijk
 author:        Bas van Dijk
 maintainer:    Bas van Dijk <v.dijk.bas@gmail.com>
 stability:     experimental
@@ -31,28 +31,19 @@
 
   .
 
-  This package provides two modules:
-
-  .
-
-  * @Control.Monad.Trans.Region.Unsafe@ should only be used by library authors
-    wishing to allow their users to open their type of resources in a region. It
-    should /not/ be used by end-users directly!
-
-  .
-
-  * @Control.Monad.Trans.Region@ provides the public and safe interface to
-    regions which can be used by end-users.
+  Also see the @regions-monadsfd@ and @regions-monadstf@ packages which provide
+  instances for the classes in the respected monads packages.
 
   .
 
-  Also see the @regions-monadsfd@ and @regions-monadstf@ packages which provide
-  instances for the classes in the respected monads packages.
+  For an example on how to use this library see the @safer-file-handles@,
+  @usb-safe@ or @regional-pointers@ packages.
 
   .
 
-  For an example of how to use this library see the @safer-file-handles@ or
-  @usb-safe@ packages.
+  Note that if you want to open /your/ type of scarce resource in a region, the
+  only thing you have to do is define an instance for the @Resource@ class
+  (which you can find in: @Control.Resource@).
 
 source-repository head
   Type:     darcs
@@ -60,10 +51,12 @@
 
 Library
   GHC-Options: -Wall
-  build-depends: base                      >= 4 && < 4.3
-               , base-unicode-symbols      >= 0.1.1 && < 0.2
-               , transformers              >= 0.1.4 && < 0.2
-               , MonadCatchIO-transformers == 0.0.2.*
-  exposed-modules: Control.Monad.Trans.Region
-                 , Control.Monad.Trans.Region.Unsafe
+  build-depends: base                      >= 4       && < 4.3
+               , base-unicode-symbols      >= 0.1.1   && < 0.2
+               , transformers              >= 0.1.4   && < 0.2
+               , MonadCatchIO-transformers >= 0.0.2.0 && < 0.1
+  exposed-modules: Control.Resource
+                   Control.Monad.Trans.Region
+                   Control.Monad.Trans.Region.Unsafe
+                   Data.RegionRef
   other-modules:   Control.Monad.Trans.Region.Internal
