diff --git a/CONTRIBUTORS b/CONTRIBUTORS
new file mode 100644
--- /dev/null
+++ b/CONTRIBUTORS
@@ -0,0 +1,6 @@
+* Oleg Kiselyov and Chung-chieh Shan
+  For coming up with the original idea of "lightweight monadic regions".
+
+* Ben Franksen
+  For rewriting the overly complicated ParentOf class and related instances
+  to something really clean and simple exploiting TypeFamilies.
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
@@ -1,9 +1,7 @@
-{-# LANGUAGE CPP #-}
-
 -------------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.Trans.Region
--- Copyright   :  (c) 2009-2010 Bas van Dijk
+-- Copyright   :  (c) 2009-2011 Bas van Dijk
 -- License     :  BSD3 (see the file LICENSE)
 -- Maintainer  :  Bas van Dijk <v.dijk.bas@gmail.com>
 --
@@ -21,25 +19,26 @@
       -- * Running regions
     , runRegionT
 
-    , TopRegion
-    , runTopRegion
+    , RegionControlIO
 
-      -- ** Forking /top-level/ regions
-    , forkIOTopRegion
-    , forkOSTopRegion
-#ifdef __GLASGOW_HASKELL__
-    , forkOnIOTopRegion
-#endif
       -- * Duplication
     , Dup(dup)
 
-    , module Control.Monad.Trans.Region.ParentOf
+      -- * Ancestor relation between regions
+    , AncestorRegion
 
-      -- * Handy functions for writing monadic instances
+      -- * Special regions
+      -- ** The root region
+    , RootRegion
+
+      -- ** Local regions
+    , LocalRegion, Local
+
+      -- * Utilities for writing monadic instances
     , liftCallCC
     , mapRegionT
     , liftCatch
     ) where
 
 import Control.Monad.Trans.Region.Internal
-import Control.Monad.Trans.Region.ParentOf
+
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
@@ -1,15 +1,21 @@
-{-# LANGUAGE CPP
-           , UnicodeSyntax
-           , NoImplicitPrelude
-           , GeneralizedNewtypeDeriving
-           , RankNTypes
-           , KindSignatures
+{-# LANGUAGE CPP                        -- For portability.
+           , UnicodeSyntax              -- Makes it look so nice.
+           , NoImplicitPrelude          -- I like to be fully explicit.
+           , GeneralizedNewtypeDeriving -- I'm lazy.
+           , RankNTypes                 -- Provides the essential type-safety.
+           , KindSignatures             -- To help the type-checker.
+           , EmptyDataDecls             -- For the RootRegion type.
+           , MultiParamTypeClasses      -- For the AncestorRegion class.
+           , UndecidableInstances       -- For the AncestorRegion instances.
+           , FlexibleInstances          -- ,,          ,,          ,,
+           , OverlappingInstances       -- ,,          ,,          ,,
+           , FlexibleContexts           -- For unsafeLiftControl
   #-}
 
 -------------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.Trans.Region.Internal
--- Copyright   :  (c) 2009-2010 Bas van Dijk
+-- Copyright   :  (c) 2009-2011 Bas van Dijk
 -- License     :  BSD3 (see the file LICENSE)
 -- Maintainer  :  Bas van Dijk <v.dijk.bas@gmail.com>
 --
@@ -27,28 +33,35 @@
     ( -- * Regions
       RegionT
 
-      -- * Close handles
-    , CloseAction
-    , CloseHandle
+      -- * Registering finalizers
+    , Finalizer
+    , FinalizerHandle
     , onExit
 
       -- * Running regions
     , runRegionT
 
-    , TopRegion
-    , runTopRegion
-
-      -- ** Forking /top-level/ regions
-    , forkIOTopRegion
-    , forkOSTopRegion
-#ifdef __GLASGOW_HASKELL__
-    , forkOnIOTopRegion
-#endif
-
       -- * Duplication
     , Dup(dup)
 
-      -- * Handy functions for writing monadic instances
+      -- * Ancestor relation between regions
+    , AncestorRegion
+
+      -- * Special regions
+      -- ** The root region
+    , RootRegion
+
+      -- ** Local regions
+    , LocalRegion, Local, unsafeStripLocal
+
+      -- * MonadTransControl & MonadControlIO
+    , RegionControlIO, unsafeLiftControlIO
+    , unsafeLiftControl
+    , unsafeControlIO
+    , unsafeLiftIOOp
+    , unsafeLiftIOOp_
+
+      -- * Utilities for writing monadic instances
     , liftCallCC
     , mapRegionT
     , liftCatch
@@ -60,13 +73,11 @@
 --------------------------------------------------------------------------------
 
 -- from base:
-import Prelude             ( (+), (-), seq, fromInteger )
+import Prelude             ( (+), (-), seq )
 import Control.Applicative ( Applicative, Alternative )
-import Control.Monad       ( Monad, return, (>>=), fail
-                           , (>>), when, forM_
-                           , MonadPlus
-                           )
+import Control.Monad       ( Monad, return, when, forM_, join, liftM, MonadPlus,  )
 import Control.Monad.Fix   ( MonadFix )
+import Control.Exception   ( bracket )
 import System.IO           ( IO )
 import Data.Function       ( ($) )
 import Data.Functor        ( Functor )
@@ -74,41 +85,46 @@
 import Data.IORef          ( IORef, newIORef
                            , readIORef, modifyIORef, atomicModifyIORef
                            )
-import Control.Concurrent  ( forkIO, forkOS, ThreadId )
-#ifdef __GLASGOW_HASKELL__
-import GHC.Conc            ( forkOnIO )
+#if __GLASGOW_HASKELL__ < 700
+import Prelude             ( fromInteger )
+import Control.Monad       ( (>>=), (>>), fail )
 #endif
 
--- from MonadCatchIO-transformers:
-import Control.Monad.CatchIO ( MonadCatchIO, block, bracket )
+-- from monad-control:
+import Control.Monad.Trans.Control ( Run, RunInBase, liftControl )
+import Control.Monad.IO.Control    ( MonadControlIO, liftControlIO )
 
 -- from transformers:
 import Control.Monad.Trans.Class ( MonadTrans, lift )
 import Control.Monad.IO.Class    ( MonadIO, liftIO )
 
 import qualified Control.Monad.Trans.Reader as R ( liftCallCC, liftCatch )
-import           Control.Monad.Trans.Reader      ( ReaderT(ReaderT)
-                                                 , runReaderT, mapReaderT
-                                                 )
+import Control.Monad.Trans.Reader ( ReaderT(ReaderT), runReaderT, mapReaderT )
+
 -- from base-unicode-symbols:
 import Data.Eq.Unicode       ( (≡) )
 import Data.Function.Unicode ( (∘) )
 
+-- Handling the new asynchronous exceptions API in base-4.3:
+#if MIN_VERSION_base(4,3,0)
+import Control.Exception ( mask_ )
+#else
+import Control.Exception ( block )
+mask_ ∷ IO α → IO α
+mask_ = block
+#endif
 
+
 --------------------------------------------------------------------------------
 -- * Regions
 --------------------------------------------------------------------------------
 
-{-| A monad transformer in which scarce resources can be opened
-which are automatically closed when the region terminates.
-
-Note that regions can be nested. @pr@ (for parent region) is a monad which is
-usually the region which is running this region. However when you are running a
-'TopRegion' the parent region will be 'IO'.
+{-| A monad transformer in which scarce resources can be opened. When the region
+terminates, all opened resources will be closed automatically. It's a type error
+to return an opened resource from the region. The latter ensures no I/O with
+closed resources is possible.
 -}
-newtype RegionT s (pr ∷ * → *) α = RegionT
-    { unRegionT ∷ ReaderT (IORef [Handle]) pr α }
-
+newtype RegionT s pr α = RegionT (ReaderT (IORef [RefCountedFinalizer]) pr α)
     deriving ( Functor
              , Applicative
              , Alternative
@@ -117,37 +133,62 @@
              , MonadFix
              , MonadTrans
              , MonadIO
-             , MonadCatchIO
              )
 
-data Handle = Handle !CloseAction !(IORef RefCnt)
+unRegionT ∷ RegionT s pr α → ReaderT (IORef [RefCountedFinalizer]) pr α
+unRegionT (RegionT r) = r
 
+-- | A 'Finalizer' paired with its reference count which defines how many times
+-- it has been registered in some region.
+data RefCountedFinalizer = RefCountedFinalizer !Finalizer !(IORef RefCnt)
+
 -- | An 'IO' computation that closes or finalizes a resource. For example
--- @hClose@ or @free@.
-type CloseAction = IO ()
+-- \"@hClose someHandle@\" or \"@free somePtr@\".
+type Finalizer = IO ()
 
 type RefCnt = Int
 
 
 --------------------------------------------------------------------------------
--- * Close handles
+-- * Registering finalizers
 --------------------------------------------------------------------------------
 
--- | A handle to a 'CloseAction' that allows you to duplicate the action to a
--- parent region using 'dup'.
-newtype CloseHandle (r ∷ * → *) = CloseHandle Handle
+{-| A handle to a 'Finalizer' that allows you to duplicate it to a parent region
+using 'dup'.
 
--- | Register the 'CloseAction' in the region. When the region terminates all
--- registered close actions will be perfomed if they're not duplicated to a
--- parent region.
-onExit ∷ MonadIO pr ⇒ CloseAction → RegionT s pr (CloseHandle (RegionT s pr))
-onExit closeAction = RegionT $ ReaderT $ \hsIORef → liftIO $ do
-                       refCntIORef ← newIORef 1
-                       let h = Handle closeAction refCntIORef
-                       modifyIORef hsIORef (h:)
-                       return $ CloseHandle h
+Duplicating a finalizer means that instead of it being performed when the
+current region terminates it is performed when the parent region terminates.
+-}
+newtype FinalizerHandle (r ∷ * → *) = FinalizerHandle RefCountedFinalizer
 
+{-| Register the 'Finalizer' in the region. When the region terminates all
+registered finalizers will be perfomed if they're not duplicated to a parent
+region.
 
+Note that finalizers are run in LIFO order (Last In First Out). So executing the following:
+
+@
+runRegionT $ do
+  _ <- onExit $ putStrLn \"finalizer 1\"
+  _ <- onExit $ putStrLn \"finalizer 2\"
+  return ()
+@
+
+yields:
+
+@
+finalizer 2
+finalizer 1
+@
+-}
+onExit ∷ MonadIO pr ⇒ Finalizer → RegionT s pr (FinalizerHandle (RegionT s pr))
+onExit finalizer = RegionT $ ReaderT $ \hsIORef → liftIO $ do
+                     refCntIORef ← newIORef 1
+                     let h = RefCountedFinalizer finalizer refCntIORef
+                     modifyIORef hsIORef (h:)
+                     return $ FinalizerHandle h
+
+
 --------------------------------------------------------------------------------
 -- * Running regions
 --------------------------------------------------------------------------------
@@ -167,111 +208,29 @@
 
 Note that it is possible to run a region inside another region.
 -}
-runRegionT ∷ MonadCatchIO pr ⇒ (∀ s. RegionT s pr α) → pr α
-runRegionT m = runRegionWith [] m
-
-{-| A region which has 'IO' as its parent region which enables it to be:
-
- * directly executed in 'IO' by 'runTopRegion',
-
- * concurrently executed in a new thread by 'forkIOTopRegion'.
--}
-type TopRegion s = RegionT s IO
-
-{-| Convenience funtion for running a /top-level/ region in 'IO'.
-
-Note that: @runTopRegion = 'runRegionT'@
--}
-runTopRegion ∷ (∀ s. TopRegion s α) → IO α
-runTopRegion = runRegionT
-
-
---------------------------------------------------------------------------------
--- ** Forking /top-level/ regions
---------------------------------------------------------------------------------
-
-{-| Return a region which executes the given /top-level/ region in a new thread.
-
-Note that the forked region has the same type variable @s@ as the resulting
-region. This means that all values which can be referenced in the resulting
-region can also be referenced in the forked region.
-
-For example the following is allowed:
-
-@
-'runRegionT' $ do
-  regionalHndl <- open resource
-  threadId <- 'forkIOTopRegion' $ doSomethingWith regionalHndl
-  doSomethingElseWith regionalHndl
-@
-
-Note that the @regionalHndl@ and all other resources opened in the current
-thread are closed only when the current thread or the forked thread terminates
-whichever comes /last/.
--}
-forkIOTopRegion ∷ MonadIO pr ⇒ TopRegion s () → RegionT s pr ThreadId
-forkIOTopRegion = forkTopRegion forkIO
-
--- | Like 'forkIOTopRegion' but internally uses 'forkOS'.
-forkOSTopRegion ∷ MonadIO pr ⇒ TopRegion s () → RegionT s pr ThreadId
-forkOSTopRegion = forkTopRegion forkOS
-
-#ifdef __GLASGOW_HASKELL__
--- | Like 'forkIOTopRegion' but internally uses 'forkOnIO'.
-forkOnIOTopRegion ∷ MonadIO pr ⇒ Int → TopRegion s () → RegionT s pr ThreadId
-forkOnIOTopRegion = forkTopRegion ∘ forkOnIO
-#endif
-
-forkTopRegion ∷ MonadIO pr
-              ⇒ (IO () → IO ThreadId)
-              → (TopRegion s () → RegionT s pr ThreadId)
-forkTopRegion doFork = \m →
-    RegionT $ ReaderT $ \hsIORef → liftIO $ do
-      hs ← readIORef hsIORef
-      block $ do
-        forM_ hs $ \(Handle _ refCntIORef) → increment refCntIORef
-        doFork $ runRegionWith hs m
-
---------------------------------------------------------------------------------
-
--- | Internally used function that actually runs the region on the given list of
--- opened resources.
-runRegionWith ∷ ∀ s pr α. MonadCatchIO pr
-              ⇒ [Handle] → RegionT s pr α → pr α
-runRegionWith hs r = bracket (liftIO before)
-                             (liftIO ∘ after)
-                             (runReaderT $ unRegionT r)
+runRegionT ∷ RegionControlIO pr ⇒ (∀ s. RegionT s pr α) → pr α
+runRegionT r = unsafeLiftIOOp (bracket before after) thing
     where
-      before = newIORef hs
+      before = newIORef []
+      thing hsIORef = runReaderT (unRegionT r) hsIORef
       after hsIORef = do
         hs' ← readIORef hsIORef
-        forM_ hs' $ \(Handle closeAction refCntIORef) → do
+        forM_ hs' $ \(RefCountedFinalizer finalizer refCntIORef) → do
           refCnt ← decrement refCntIORef
-          when (refCnt ≡ 0) closeAction
-
--- | Internally used function that atomically decrements the reference count
--- that is stored in the given @IORef@. The function returns the decremented
--- reference count.
-decrement ∷ IORef RefCnt → IO RefCnt
-decrement ioRef = do atomicModifyIORef ioRef $ \refCnt →
-                       let refCnt' = refCnt - 1
-                       in (refCnt', refCnt')
-
--- | Internally used function that atomically increments the reference count that
--- is stored in the given @IORef@.
-increment ∷ IORef RefCnt → IO ()
-increment ioRef = do refCnt' ← atomicModifyIORef ioRef $ \refCnt →
-                                 let refCnt' = refCnt + 1
-                                 in (refCnt', refCnt')
-                     refCnt' `seq` return ()
+          when (refCnt ≡ 0) finalizer
+          where
+            decrement ∷ IORef RefCnt → IO RefCnt
+            decrement ioRef = atomicModifyIORef ioRef $ \refCnt →
+                                let refCnt' = refCnt - 1
+                                in (refCnt', refCnt')
 
 
 --------------------------------------------------------------------------------
 -- * Duplication
 --------------------------------------------------------------------------------
 
-{-| Duplicate an @&#945;@ in the parent region. This @&#945;@ will usually be
-some type of regional handle.
+{-| Duplicate an @h@ in the parent region. This @h@ will usually be some type of
+regional handle.
 
 For example, suppose you run the following region:
 
@@ -313,22 +272,188 @@
 
 Back in the parent region you can safely operate on @r1hDup@.
 -}
-class Dup α where
-    dup ∷ MonadCatchIO ppr
-        ⇒ α (RegionT cs (RegionT ps ppr))
-        → RegionT cs (RegionT ps ppr)
-              (α (RegionT ps ppr))
+class Dup h where
+    dup ∷ MonadIO ppr
+        ⇒ h (RegionT cs (RegionT ps ppr))
+        →    RegionT cs (RegionT ps ppr)
+                     (h (RegionT ps ppr))
 
-instance Dup CloseHandle where
-    dup (CloseHandle h@(Handle _ refCntIORef)) =
-      lift $ RegionT $ ReaderT $ \hsIORef → liftIO $ block $ do
-        increment refCntIORef
-        modifyIORef hsIORef (h:)
-        return $ CloseHandle h
+instance Dup FinalizerHandle where
+    dup = lift ∘ copy
 
+copy ∷ MonadIO pr
+     ⇒ FinalizerHandle r
+     → RegionT s pr (FinalizerHandle (RegionT s pr))
+copy (FinalizerHandle h@(RefCountedFinalizer _ refCntIORef)) =
+  RegionT $ ReaderT $ \hsIORef → liftIO $ mask_ $ do
+    increment refCntIORef
+    modifyIORef hsIORef (h:)
+    return $ FinalizerHandle h
 
+increment ∷ IORef RefCnt → IO ()
+increment ioRef = do refCnt' ← atomicModifyIORef ioRef $ \refCnt →
+                                 let refCnt' = refCnt + 1
+                                 in (refCnt', refCnt')
+                     refCnt' `seq` return ()
+
+
 --------------------------------------------------------------------------------
--- * Handy functions for writing monadic instances
+-- * Ancestor relation between regions
+--------------------------------------------------------------------------------
+
+{-| The @AncestorRegion@ class is used to relate the region in which a resource
+was opened to the region in which it is used. Take the following operation from
+the @safer-file-handles@ package as an example:
+
+@hFileSize :: (pr \`AncestorRegion\` cr, MonadIO cr) => RegionalFileHandle ioMode pr -> cr Integer@
+
+The @AncestorRegion@ class defines the parent / child relationship between regions.
+The constraint
+
+@
+    pr \`AncestorRegion\` cr
+@
+
+is satisfied if and only if @cr@ is a sequence of zero or more \"@'RegionT' s@\"
+(with varying @s@) applied to @pr@, in other words, if @cr@ is an (improper)
+nested subregion of @pr@.
+
+The class constraint @InternalAncestorRegion pr cr@ serves two purposes. First, the
+instances of @InternalAncestorRegion@ do the type-level recursion that implements
+the relation specified above. Second, since it is not exported, user code cannot
+add new instances of 'AncestorRegion' (as these would have to be made instances of
+@InternalAncestorRegion@, too), effectively turning it into a /closed class/.
+-}
+
+-- The implementation uses type-level recursion, so it is no surprise we need
+-- UndecidableInstances.
+
+class (InternalAncestorRegion pr cr) ⇒ AncestorRegion pr cr
+
+instance (InternalAncestorRegion pr cr) ⇒ AncestorRegion pr cr
+
+class InternalAncestorRegion (pr ∷ * → *) (cr ∷ * → *)
+
+instance InternalAncestorRegion (RegionT s m) (RegionT s m)
+instance (InternalAncestorRegion pr cr) ⇒ InternalAncestorRegion pr (RegionT s cr)
+
+
+--------------------------------------------------------------------------------
+-- * The root region
+--------------------------------------------------------------------------------
+
+{-| The @RootRegion@ is the ancestor of any region.
+
+It's primary purpose is to tag regional handles which don't have an associated
+finalizer. For example the standard file handles @stdin@, @stdout@ and @stderr@
+which are opened on program startup and which shouldn't be closed when a region
+terminates. Another example is the @nullPtr@ which is a memory pointer which
+doesn't point to any allocated memory so doesn't need to be freed.
+-}
+data RootRegion α
+
+instance InternalAncestorRegion RootRegion (RegionT s m)
+
+
+--------------------------------------------------------------------------------
+-- * Local regions
+--------------------------------------------------------------------------------
+
+{-|
+A @LocalRegion@ is used to tag regional handles which are created locally.
+
+An example is the @LocalPtr@ in the @alloca@ function from the
+@regional-pointers@ package:
+
+@
+alloca :: (Storable a, MonadControlIO pr)
+       => (forall sl. LocalPtr a ('LocalRegion' sl s) -> RegionT ('Local' s) pr b)
+       -> RegionT s pr b
+@
+
+The finalisation of the @LocalPtr@ is not performed by the @regions@ library but
+is handled locally by @alloca@ instead.
+
+The type variable @sl@, which is only quantified over the continuation, ensures
+that locally opened resources don't escape.
+-}
+data LocalRegion sl s α
+
+{-|
+A type used to tag regions in which locally created handles (handles tagged with
+'LocalRegion') can be used.
+
+Note than any handle which is created in a @RegionT (Local s)@ can be used
+outside that region (@RegionT s@) and visa versa
+(except for 'LocalRegion'-tagged handles).
+-}
+data Local s
+
+instance InternalAncestorRegion (LocalRegion sf s) (RegionT (Local s) m)
+
+instance InternalAncestorRegion (RegionT        s  m) (RegionT (Local s) m)
+instance InternalAncestorRegion (RegionT (Local s) m) (RegionT        s  m)
+
+{-|
+Convert a 'Local' region to a regular region.
+
+This function is unsafe because it allows you to use a 'LocalRegion'-tagged
+handle outside its 'Local' region.
+-}
+unsafeStripLocal ∷ RegionT (Local s) pr α → RegionT s pr α
+unsafeStripLocal = RegionT ∘ unRegionT
+
+
+--------------------------------------------------------------------------------
+-- * MonadTransControl & MonadControlIO
+--------------------------------------------------------------------------------
+
+{-|
+Regions do not have an instance for 'MonadControlIO' since that would break the
+safety guarantees. (Think about lifting 'forkIO' into a region!)
+
+However 'runRegionT' and other operations on regions do need the ability to lift
+control operations. This is where the 'RegionControlIO' class comes in. This
+class is identical to `MonadControlIO` but its 'unsafeLiftControlIO' method is
+not exported by this module. So user can't accidentally break the safety.
+
+Note that a 'RegionT' is an instance of this class. For the rest there is a
+catch-all @instance 'MonadControlIO' m => 'RegionControlIO' m@.
+-}
+class MonadIO m ⇒ RegionControlIO m where
+    unsafeLiftControlIO ∷ (RunInBase m IO → IO α) → m α
+
+instance RegionControlIO pr ⇒ RegionControlIO (RegionT s pr) where
+    unsafeLiftControlIO f =
+        unsafeLiftControl $ \runInPr →
+          unsafeLiftControlIO $ \runInBase →
+            let run = liftM (join ∘ lift) ∘ runInBase ∘ runInPr
+            in f run
+
+instance MonadControlIO m ⇒ RegionControlIO m where
+    unsafeLiftControlIO = liftControlIO
+
+--------------------------------------------------------------------------------
+
+unsafeLiftControl ∷ Monad pr ⇒ (Run (RegionT s) → pr α) → RegionT s pr α
+unsafeLiftControl f = RegionT $ liftControl $ \runReader →
+                        f $ liftM RegionT ∘ runReader ∘ unRegionT
+
+unsafeControlIO ∷ RegionControlIO m ⇒ (RunInBase m IO → IO (m α)) → m α
+unsafeControlIO = join ∘ unsafeLiftControlIO
+
+unsafeLiftIOOp ∷ RegionControlIO m
+               ⇒ ((α → IO (m β)) → IO (m γ))
+               → ((α →     m β)  →     m γ)
+unsafeLiftIOOp f = \g → unsafeControlIO $ \runInIO → f $ runInIO ∘ g
+
+unsafeLiftIOOp_ ∷ RegionControlIO m
+                ⇒ (IO (m α) → IO (m β))
+                → (    m α →      m β)
+unsafeLiftIOOp_ f = \m → unsafeControlIO $ \runInIO → f $ runInIO m
+
+--------------------------------------------------------------------------------
+-- * Utilities for writing monadic instances
 --------------------------------------------------------------------------------
 
 -- | Lift a @callCC@ operation to the new monad.
diff --git a/Control/Monad/Trans/Region/OnExit.hs b/Control/Monad/Trans/Region/OnExit.hs
--- a/Control/Monad/Trans/Region/OnExit.hs
+++ b/Control/Monad/Trans/Region/OnExit.hs
@@ -1,9 +1,7 @@
-{-# LANGUAGE UnicodeSyntax #-}
-
 -------------------------------------------------------------------------------
 -- |
--- Module      :  Control.Monad.Trans.Region.Unsafe
--- Copyright   :  (c) 2009-2010 Bas van Dijk
+-- Module      :  Control.Monad.Trans.Region.OnExit
+-- Copyright   :  (c) 2009-2011 Bas van Dijk
 -- License     :  BSD3 (see the file LICENSE)
 -- Maintainer  :  Bas van Dijk <v.dijk.bas@gmail.com>
 --
@@ -12,12 +10,12 @@
 --
 --------------------------------------------------------------------------------
 
-module Control.Monad.Trans.Region.OnExit ( CloseAction
-                                         , CloseHandle
+module Control.Monad.Trans.Region.OnExit ( Finalizer
+                                         , FinalizerHandle
                                          , onExit
                                          ) where
 
-import Control.Monad.Trans.Region.Internal ( CloseAction
-                                           , CloseHandle
+import Control.Monad.Trans.Region.Internal ( Finalizer
+                                           , FinalizerHandle
                                            , onExit
                                            )
diff --git a/Control/Monad/Trans/Region/ParentOf.hs b/Control/Monad/Trans/Region/ParentOf.hs
deleted file mode 100644
--- a/Control/Monad/Trans/Region/ParentOf.hs
+++ /dev/null
@@ -1,70 +0,0 @@
-{-# LANGUAGE UnicodeSyntax
-           , NoImplicitPrelude
-           , KindSignatures
-           , MultiParamTypeClasses
-           , FunctionalDependencies
-           , UndecidableInstances
-           , FlexibleInstances
-           , OverlappingInstances
-  #-}
-
--------------------------------------------------------------------------------
--- |
--- Module      :  Control.Monad.Trans.Region.ParentOf
--- Copyright   :  (c) 2009-2010 Bas van Dijk
--- License     :  BSD3 (see the file LICENSE)
--- Maintainer  :  Bas van Dijk <v.dijk.bas@gmail.com>
---
---------------------------------------------------------------------------------
-
-module Control.Monad.Trans.Region.ParentOf ( ParentOf ) where
-
--- from base:
-import Control.Monad ( Monad )
-
--- from regions:
-import Control.Monad.Trans.Region.Internal ( RegionT )
-
-
-{-| The @ParentOf@ class declares the parent/child relationship between regions.
-
-A region is the parent of another region if they're either equivalent like:
-
-@
-RegionT ps pr  \`ParentOf\`  RegionT ps pr
-@
-
-or if it is the parent of the parent of the child like:
-
-@
-RegionT ps ppr \`ParentOf\` RegionT cs
-                              (RegionT pcs
-                                (RegionT ppcs
-                                  (RegionT ps ppr)))
-@
--}
-class (Monad pr, Monad cr) ⇒ pr `ParentOf` cr
-
-instance Monad r ⇒ ParentOf r r
-
-instance ( Monad cr
-         , cr `TypeCast2` RegionT s pcr
-         , pr `ParentOf` pcr
-         )
-         ⇒ ParentOf pr cr
-
-
---------------------------------------------------------------------------------
--- Type casting
---------------------------------------------------------------------------------
-
-class TypeCast2     (a ∷ * → *) (b ∷ * → *) |   a → b,   b → a
-class TypeCast2'  t (a ∷ * → *) (b ∷ * → *) | t a → b, t b → a
-class TypeCast2'' t (a ∷ * → *) (b ∷ * → *) | t a → b, t b → a
-
-instance TypeCast2'  () a b ⇒ TypeCast2    a b
-instance TypeCast2'' t  a b ⇒ TypeCast2' t a b
-instance TypeCast2'' () a a
-
-
--- The End ---------------------------------------------------------------------
diff --git a/Control/Monad/Trans/Region/Unsafe.hs b/Control/Monad/Trans/Region/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Trans/Region/Unsafe.hs
@@ -0,0 +1,23 @@
+-------------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.Trans.Region.Unsafe
+-- Copyright   :  (c) 2009-2011 Bas van Dijk
+-- License     :  BSD3 (see the file LICENSE)
+-- Maintainer  :  Bas van Dijk <v.dijk.bas@gmail.com>
+--
+--
+--------------------------------------------------------------------------------
+
+module Control.Monad.Trans.Region.Unsafe
+    ( -- * Local regions
+      unsafeStripLocal
+
+      -- * MonadTransControl & MonadControlIO
+    , unsafeLiftControlIO
+    , unsafeLiftControl
+    , unsafeControlIO
+    , unsafeLiftIOOp
+    , unsafeLiftIOOp_
+    ) where
+
+import Control.Monad.Trans.Region.Internal
diff --git a/Data/RegionRef.hs b/Data/RegionRef.hs
deleted file mode 100644
--- a/Data/RegionRef.hs
+++ /dev/null
@@ -1,105 +0,0 @@
-{-# LANGUAGE UnicodeSyntax, NoImplicitPrelude, KindSignatures #-}
-
--------------------------------------------------------------------------------
--- |
--- Module      :  Data.RegionRef
--- Copyright   :  (c) 2009-2010 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.IO.Class ( 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/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2009-2010 Bas van Dijk
+Copyright (c) 2009-2011 Bas van Dijk
 
 All rights reserved.
 
diff --git a/NEWS b/NEWS
new file mode 100644
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,154 @@
+0.9
+
+(Relased on: Wed Mar 9 12:20:05 UTC 2011)
+
+* Removed Control.Monad.Trans.Region.Concurrent
+  The fork functions contained bugs which could not be fixed.
+
+* Removed Data.RegionRef
+  I always considered this module a bit of a wart.
+
+* Switch from monad-peel to monad-control.
+
+* Added support for local regions
+  Primarily needed for the alloca functions from the regional-pointers package.
+
+
+0.8.1
+
+(Released on: Mon Jan 17 22:04:15 UTC 2011)
+
+* Fixed bug: Forked threads should have the same masked state has their parents.
+
+* Added forkIOUnmasked.
+
+* Derived MonadTransPeel instance for RegionT.
+
+
+0.8
+
+(Released on: Sat Nov 6 15:56:27 UTC 2010)
+
+* Released during BelHac 2010!
+
+* Replaced ParentOf class with the more understandable,
+  easier to implement and safer AncestorRegion class.
+  (Contributed by Ben Franksen)
+
+  Also moved the class from its own module to the main:
+  Control.Monad.Trans.Region module.
+
+* Exported fork*TopRegion functions from their own dedicated module:
+  Control.Monad.Trans.Region.Concurrent.
+
+* Use MonadPeelIO instead of MonadCatchIO.
+
+* Removed TopRegion and runTopRegion and
+  renamed the fork functions accordingly.
+
+* Renamed CloseAction to Finalizer and
+  CloseHandle to FinalizerHandle.
+
+* Added the RootRegion (empty) datatype which is defined as the
+  ancestor of any region.
+
+
+0.7.0.1
+
+(Released on: Sat Sep 11 14:17:48 UTC 2010)
+
+* Added strictness flags to the arguments of the Handle data constructor.
+
+* Fix haddock link.
+
+
+0.7
+
+(Released on: Wed Sep 1 20:11:41 UTC 2010)
+
+* Renamed forkTopRegion to forkIOTopRegion
+  Also added forkOSTopRegion and forkOnIOTopRegion.
+
+
+0.6.0.1
+
+(Released on: Wed Jun 16 13:45:27 UTC 2010)
+
+* Removed outdated documentation.
+
+
+0.6
+
+(Released on: Wed Jun 16 09:11:23 UTC 2010)
+
+* Major change: removed the Resource class in favor of the much
+  simpler 'onExit' function.
+
+* Renamed Control.Monad.Trans.Region.Close to
+  Control.Monad.Trans.Region.OnExit.
+
+
+0.5
+
+(Released on: Sun May 2 20:24:19 UTC 2010)
+
+* Renamed openResource and closeResource to open and close
+  respectively The intention is that Control.Resource should be
+  imported qualified.
+
+* Updated dependencies
+  transformers              >= 0.2   && < 0.3
+  MonadCatchIO-transformers >= 0.2   && < 0.3
+  base-unicode-symbols      >= 0.1.1 && < 0.3
+
+
+0.4
+
+(Released on: Thu Feb 4 10:17:47 UTC 2010)
+
+* Added Data.RegionRef.
+
+* Moved the Resource class to its own module Control.Resource.
+
+* Depend on more compatible versions of MonadCatchIO-transformers.
+
+* Defined and exported liftCallCC.
+
+
+0.3
+
+(Released on: Sat Jan 23 14:25:08 UTC 2010)
+
+* Add 'mapInternalHandle'.
+
+* Export the 'Dup' and 'ParentOf' classes from
+  'Control.Monad.Trans.Region'.
+
+
+0.2
+
+(Released on: Thu Jan 7 14:14:15 UTC 2010)
+
+* Renamed module Control.Monad.Trans.Region.Internal to
+  Control.Monad.Trans.Region.Unsafe.
+
+* Export only the unsafe things from Control.Monad.Trans.Region.Unsafe.
+
+* Removed resource type from RegionT which prevented opening different
+  types of resources in the same region.
+
+
+0.1.0.1
+
+(Released on: Wed Dec 23 13:42:48 UTC 2009)
+
+* Depend on base-unicode-symbols instead of unicode-symbols.
+
+* Tested with base 4.2.
+
+
+0.1
+
+(Released on: Mon Dec 21 09:46:51 UTC 2009)
+
+* Initial release.
diff --git a/README.markdown b/README.markdown
new file mode 100644
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,25 @@
+This package provides the region monad transformer. Scarce resources
+like files, memory pointers or USB devices for example can be opened
+in a region. When the region terminates, all opened resources will be
+automatically closed. The main advantage of regions is that the opened
+resources can not be returned from the region which ensures no I/O
+with closed resources is possible.
+
+The primary technique used in this package is called "Lightweight
+monadic regions" which was [invented][1] by Oleg Kiselyov and
+Chung-chieh Shan.
+
+Also see the [regions-mtl] and [regions-monadstf] packages which
+provide instances for the classes in the respected monad transformers
+packages.
+
+For an example on how to use this library see the
+[safer-file-handles], [usb-safe] or [regional-pointers] packages.
+
+[1]: http://okmij.org/ftp/Haskell/regions.html#light-weight
+
+[regions-mtl]:        http://hackage.haskell.org/package/regions-mtl
+[regions-monadstf]:   http://hackage.haskell.org/package/regions-monadstf
+[safer-file-handles]: http://hackage.haskell.org/package/safer-file-handles
+[usb-safe]:           http://hackage.haskell.org/package/usb-safe
+[regional-pointers]:  http://hackage.haskell.org/package/regional-pointers
diff --git a/regions.cabal b/regions.cabal
--- a/regions.cabal
+++ b/regions.cabal
@@ -1,12 +1,14 @@
 name:          regions
-version:       0.7.0.1
+version:       0.11
 cabal-version: >=1.6
 build-type:    Simple
 license:       BSD3
 license-file:  LICENSE
-copyright:     2009-2010 Bas van Dijk
+copyright:     2009-2011 Bas van Dijk
 author:        Bas van Dijk
 maintainer:    Bas van Dijk <v.dijk.bas@gmail.com>
+homepage:      https://github.com/basvandijk/regions/
+bug-reports:   https://github.com/basvandijk/regions/issues
 stability:     experimental
 category:      Control, Monadic Regions
 synopsis:      Provides the region monad for safely opening and working with
@@ -24,24 +26,25 @@
   .
   <http://okmij.org/ftp/Haskell/regions.html#light-weight>
   .
-  Also see the @regions-monadsfd@ and @regions-monadstf@ packages which provide
-  instances for the classes in the respected monads packages.
+  Also see the @regions-mtl@ and @regions-monadstf@ packages which provide
+  instances for the classes in the respected monad transformers packages.
   .
   For an example on how to use this library see the @safer-file-handles@,
   @usb-safe@ or @regional-pointers@ packages.
 
+extra-source-files: README.markdown, NEWS, CONTRIBUTORS
+
 source-repository head
-  Type:     darcs
-  Location: http://code.haskell.org/~basvandijk/code/regions
+  Type:     git
+  Location: git://github.com/basvandijk/regions.git
 
 Library
   GHC-Options: -Wall
-  build-depends: base                      >= 4       && < 4.3
-               , base-unicode-symbols      >= 0.1.1   && < 0.3
-               , transformers              >= 0.2     && < 0.3
-               , MonadCatchIO-transformers >= 0.2     && < 0.3
+  build-depends: base                      >= 4     && < 4.5
+               , base-unicode-symbols      >= 0.1.1 && < 0.3
+               , transformers              >= 0.2   && < 0.3
+               , monad-control             >= 0.2   && < 0.3
   exposed-modules: Control.Monad.Trans.Region
-                   Control.Monad.Trans.Region.ParentOf
                    Control.Monad.Trans.Region.OnExit
-                   Data.RegionRef
+                   Control.Monad.Trans.Region.Unsafe
   other-modules:   Control.Monad.Trans.Region.Internal
