diff --git a/Control/Monad/Exception.hs b/Control/Monad/Exception.hs
--- a/Control/Monad/Exception.hs
+++ b/Control/Monad/Exception.hs
@@ -1,10 +1,8 @@
 {-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE ExistentialQuantification, ScopedTypeVariables #-}
 {-# LANGUAGE UndecidableInstances #-}
 {-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE OverlappingInstances #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE NamedFieldPuns #-}
 
 {-|
 A Monad Transformer for explicitly typed checked exceptions.
@@ -78,59 +76,86 @@
  * If your sets of exceptions are hierarchical then you need to
    teach 'Throws' about the hierarchy.
 
->                                                 --   TopException
->                                                 --         |
->   instance Throws MidException   TopException   --         |
->                                                 --   MidException
->   instance Throws ChildException MidException   --         |
->   instance Throws ChildException TopException   --         |
->                                                 --  ChildException
+>                                                            --   TopException
+>                                                            --         |
+>   instance Throws MidException   (Caught TopException l)   --         |
+>                                                            --   MidException
+>   instance Throws ChildException (Caught MidException l)   --         |
+>   instance Throws ChildException (Caught TopException l)   --         |
+           >                                                 --  ChildException
 
 
- * Stack traces are only provided for explicitly annotated program points.
-   For now there is the TH macro 'withLocTH' to help with this.
-   Eventually a preprocessor could be written to automatically insert calls
-   to 'withLoc' at every do statement.
+ * Stack traces are provided via the "MonadLoc" package.
+   All you need to do is add the following pragma at the top of your Haskell
+   source files and use do-notation:
 
->       f () = $withLocTH $ throw MyException
->       g a  = $withLocTH $ f a
+>  {-# OPTIONS_GHC -F -pgmF MonadLoc #-}
+
+   Only statements in do blocks appear in the stack trace.
+
+* Example:
+
+>       f () = do throw MyException
+>       g a  = do f a
 >
->       main = runEMT $ $withLocTH $ do
->       g () `catchWithSrcLoc` \loc (e::MyException) -> lift(putStrLn$ showExceptionWithTrace loc e)
+>       main = runEMT $ do
+>                g () `catchWithSrcLoc`
+>                        \loc (e::MyException) -> lift(putStrLn$ showExceptionWithTrace loc e)
 
 >        -- Running main produces the output:
 
 >       *Main> main
 >       MyException
->        in Main(example.hs): (12,6)
->           Main(example.hs): (11,7)
-
+>        in f, Main(example.hs): (1,6)
+>           g, Main(example.hs): (2,6)
+>           main, Main(example.hs): (5,9)
+>           main, Main(example.hs): (4,16)
 
 -}
 module Control.Monad.Exception (
+
+-- * The EM monad
     EM,  tryEM, runEM, runEMParanoid,
-    EMT, tryEMT, runEMT, runEMTParanoid,
-    WithSrcLoc(..), withLocTH,
-    MonadZeroException(..),
-    module Control.Monad.Exception.Class ) where
 
+-- * The EMT monad transformer
+    EMT, CallTrace, tryEMT, runEMT, runEMTParanoid,
+
+-- * Exception primitives
+    throw, rethrow, Control.Monad.Exception.catch, Control.Monad.Exception.catchWithSrcLoc,
+    finally, onException, bracket, wrapException,
+
+    showExceptionWithTrace,
+    FailException(..), MonadZeroException(..),
+
+-- * The Try class for absorbing other error monads
+    Try(..), NothingException(..),
+
+-- * Reexports
+    Exception(..), SomeException(..), Typeable(..),
+    MonadFailure(..),
+    Throws, Caught, UncaughtException,
+    withLoc, withLocTH,
+
+) where
+
 import Control.Applicative
+import qualified Control.Exception as CE
 import Control.Monad.Identity
-import Control.Monad.Exception.Class
+import Control.Monad.Exception.Catch
 import Control.Monad.Fix
 import Control.Monad.Trans
 import Control.Monad.Cont.Class
 import Control.Monad.RWS.Class
+import Control.Monad.Loc
+import Control.Monad.Failure
 import Data.Monoid
 import Data.Typeable
-import Language.Haskell.TH.Syntax hiding (lift)
 import Text.PrettyPrint
 import Prelude hiding (catch)
 
 -- | A monad of explicitly typed, checked exceptions
 type EM l = EMT l Identity
 
-
 mapLeft :: (a -> b) -> Either a r -> Either b r
 mapLeft f (Left x)  = Left (f x)
 mapLeft _ (Right x) = Right x
@@ -147,21 +172,21 @@
 runEMParanoid :: EM ParanoidMode a -> a
 runEMParanoid = runIdentity . runEMTParanoid
 
-data MonadZeroException = MonadZeroException deriving (Show, Typeable)
-instance Exception MonadZeroException
+type CallTrace = [String]
 
-newtype EMT l m a = EMT {unEMT :: m (Either ([String], WrapException l) a)}
+newtype EMT l m a = EMT {unEMT :: m (Either (CallTrace, CheckedException l) a)}
 
 type AnyException = Caught SomeException
 
 -- | Run a computation explicitly handling exceptions
 tryEMT :: Monad m => EMT (AnyException l) m a -> m (Either SomeException a)
-tryEMT (EMT m) = mapLeft (unwrapException.snd) `liftM` m
+tryEMT (EMT m) = mapLeft (checkedException.snd) `liftM` m
 
-runEMT_gen :: Monad m => EMT l m a -> m a
-runEMT_gen (EMT m) = liftM f m where
-  f (Right x) = x
-  f (Left (loc,e)) = error (showExceptionWithTrace loc (unwrapException e))
+runEMT_gen :: forall l m a . Monad m => EMT l m a -> m a
+runEMT_gen (EMT m) = m >>= \x ->
+                     case x of
+                       Right x -> return x
+                       Left (loc,e) -> error (showExceptionWithTrace loc (checkedException e))
 
 -- | Run a safe computation
 runEMT :: Monad m => EMT NoExceptions m a -> m a
@@ -180,6 +205,9 @@
 
 instance Monad m => Monad (EMT l m) where
   return = EMT . return . Right
+
+  fail s = EMT $ return $ Left ([], CheckedException $ toException $ FailException s)
+
   emt >>= f = EMT $ do
                 v <- unEMT emt
                 case v of
@@ -190,52 +218,77 @@
   pure  = return
   (<*>) = ap
 
-instance (Exception e, Throws e l, Monad m) => MonadThrow e (EMT l m) where
-  throw = EMT . return . (\e -> Left ([],e)) . WrapException . toException
+instance (Exception e, Throws e l, Monad m) => MonadFailure e (EMT l m) where
+  failure = throw
+
 instance (Exception e, Monad m) => MonadCatch e (EMT (Caught e l) m) (EMT l m) where
-  catchWithSrcLoc = catchEMT
-  catch emt h = catchEMT emt (\_ -> h)
+  catchWithSrcLoc = Control.Monad.Exception.catchWithSrcLoc
+  catch           = Control.Monad.Exception.catch
 
-catchEMT :: (Exception e, Monad m) => EMT (Caught e l) m a -> ([String] -> e -> EMT l m a) -> EMT l m a
-catchEMT emt h = EMT $ do
+instance Monad m => MonadLoc (EMT l m) where
+    withLoc loc (EMT emt) = EMT $ do
+                     current <- emt
+                     case current of
+                       (Left (tr, a)) -> return (Left (loc:tr, a))
+                       _              -> return current
+
+-- | The throw primitive
+throw :: (Exception e, Throws e l, Monad m) => e -> EMT l m a
+throw = EMT . return . (\e -> Left ([],e)) . CheckedException . toException
+
+-- | Rethrow an exception keeping the call trace
+rethrow :: (Throws e l, Monad m) => CallTrace -> e -> EMT l m a
+rethrow callt = EMT . return . (\e -> Left (callt,e)) . CheckedException . toException
+
+
+-- | The catch primitive
+catch :: (Exception e, Monad m) => EMT (Caught e l) m a -> (e -> EMT l m a) -> EMT l m a
+catch emt h = Control.Monad.Exception.catchWithSrcLoc emt (\_ -> h)
+
+-- | Like 'Control.Monad.Exception.catch' but makes the call trace available
+catchWithSrcLoc :: (Exception e, Monad m) => EMT (Caught e l) m a -> (CallTrace -> e -> EMT l m a) -> EMT l m a
+catchWithSrcLoc emt h = EMT $ do
                 v <- unEMT emt
                 case v of
                   Right x -> return (Right x)
-                  Left (trace, WrapException e) -> case fromException e of
-                               Nothing -> return (Left (trace,WrapException e))
+                  Left (trace, CheckedException e) -> case fromException e of
+                               Nothing -> return (Left (trace,CheckedException e))
                                Just e' -> unEMT (h trace e')
 
--- | 'withLocTH' is a convenient TH macro which expands to 'withLoc' @\<source location\>@
---   Usage:
---
---  > f x = $withLocTH $ do
-withLocTH :: Q Exp
-withLocTH = do
-  loc <- qLocation
-  let loc_msg = showLoc loc
-  [| withLoc loc_msg |]
- where
-   showLoc Loc{loc_module, loc_filename, loc_start} = render $
-                     {- text loc_package <> char '.' <> -}
-                     text loc_module <> parens (text loc_filename) <> colon <+> text (show loc_start)
 
--- | Generating stack traces for exceptions
-class WithSrcLoc a where
-  -- | 'withLoc' records the given source location in the exception stack trace
-  --   when used to wrap a EMT computation.
-  --
-  --   On any other monad or value, 'withLoc' is defined as the identity
-  withLoc :: String -> a -> a
+-- | Sequence two computations discarding the result of the second one.
+--   If the first computation rises an exception, the second computation is run
+--   and then the exception is rethrown.
+finally :: Monad m => EMT l m a -> EMT l m b -> EMT l m a
+finally m sequel = do { v <- m `onException` sequel; sequel; return v}
 
-instance WithSrcLoc a where withLoc _ = id
 
-instance Monad m => WithSrcLoc (EMT l m a) where
-    withLoc loc (EMT emt) = EMT $ do
-                     current <- emt
-                     case current of
-                       (Left (tr, a)) -> return (Left (loc:tr, a))
-                       _              -> return current
+-- | Like finally, but performs the second computation only when the first one
+--   rises an exception
+onException :: Monad m => EMT l m a -> EMT l m b -> EMT l m a
+onException (EMT m) (EMT sequel) = EMT $ do
+                                     ev <- m
+                                     case ev of
+                                       Left{}  -> do { sequel; return ev}
+                                       Right{} -> return ev
 
+bracket :: Monad m => EMT l m a        -- ^ acquire resource
+                   -> (a -> EMT l m b) -- ^ release resource
+                   -> (a -> EMT l m c) -- ^ computation
+                   -> EMT l m c
+bracket acquire release run = do { k <- acquire; run k `finally` release k }
+
+-- | Capture an exception e, wrap it, and rethrow.
+--   Keeps the original monadic call trace.
+wrapException :: (Exception e, Throws e' l, Monad m) => EMT (Caught e l) m a -> (e -> e') -> EMT l m a
+wrapException m mkE = m `Control.Monad.Exception.catchWithSrcLoc` \loc e -> rethrow loc (mkE e)
+
+showExceptionWithTrace :: Exception e => [String] -> e -> String
+showExceptionWithTrace [] e = show e
+showExceptionWithTrace trace e = render$
+             text (show e) $$
+             text " in" <+> (vcat (map text $ reverse trace))
+
 instance (Throws MonadZeroException l) => MonadPlus (EM l) where
   mzero = throw MonadZeroException
   mplus emt1 emt2 = EMT$ do
@@ -250,9 +303,42 @@
   mfix f = EMT $ mfix $ \a -> unEMT $ f $ case a of
                                              Right r -> r
                                              _       -> error "empty fix argument"
+instance UncaughtException SomeException
 
 instance (Throws SomeException l, MonadIO m) => MonadIO (EMT l m) where
-  liftIO = lift . liftIO
+  liftIO m = EMT (liftIO m') where
+      m' = liftM Right m
+            `CE.catch`
+           \(e::SomeException) -> return (Left ([], CheckedException e))
+
+
+-- -----------------------------------------------
+-- The Try class for absorbing other error monads
+-- -----------------------------------------------
+data NothingException = NothingException deriving (Typeable, Show)
+instance Exception NothingException
+
+class Try m l where try :: Monad m' => m a -> EMT l m' a
+instance Throws NothingException l => Try Maybe l where try = maybe (throw NothingException) return
+instance (Exception e, Throws e l) => Try (Either e) l where try = either throw return
+
+instance (Monad m, Try m l) => Try (EMT l m) l where try = join . fmap (EMT . return) .try . unEMT
+
+-- -----------
+-- Exceptions
+-- -----------
+
+-- | @FailException@ is thrown by Monad 'fail'
+data FailException = FailException String deriving (Show, Typeable)
+instance Exception FailException
+
+-- | @MonadZeroException@ is thrown by MonadPlus 'mzero'
+data MonadZeroException = MonadZeroException deriving (Show, Typeable)
+instance Exception MonadZeroException
+
+-- ------------------
+-- mtl boilerplate
+-- ------------------
 
 instance MonadCont m => MonadCont (EMT l m) where
   callCC f = EMT $ callCC $ \c -> unEMT (f (\a -> EMT $ c (Right a)))
diff --git a/Control/Monad/Exception/Catch.hs b/Control/Monad/Exception/Catch.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Exception/Catch.hs
@@ -0,0 +1,74 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE EmptyDataDecls #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE OverlappingInstances #-}
+
+
+{-| Defines the (not so useful anymore) 'MonadCatch' type class.
+-}
+
+module Control.Monad.Exception.Catch (
+       module Control.Monad,
+       module Control.Monad.Exception.Throws,
+       MonadCatch(..),
+       Exception(..), SomeException(..),
+       ) where
+
+import Control.Monad
+#if TRANSFORMERS
+import Control.Monad.Trans.Error
+import Control.Monad.Trans.List
+import Control.Monad.Trans.Reader
+import Control.Monad.Trans.State
+import Control.Monad.Trans.Writer
+import Control.Monad.Trans.RWS
+#else
+import Control.Monad.Error
+import Control.Monad.List
+import Control.Monad.Reader
+import Control.Monad.State
+import Control.Monad.Writer
+import Control.Monad.RWS
+#endif
+
+#if __GLASGOW_HASKELL__ < 610
+import Control.Exception.Extensible (Exception(..), SomeException)
+import qualified Control.Exception.Extensible as Control.Exception
+#else
+import Control.Exception (Exception(..), SomeException)
+import qualified Control.Exception
+#endif
+import Data.Monoid
+
+import Control.Monad.Exception.Throws
+
+import Prelude hiding (catch)
+
+class (Monad m, Monad m') => MonadCatch e m m' | e m -> m', e m' -> m where
+   catch   :: m a -> (e -> m' a) -> m' a
+   catchWithSrcLoc :: m a -> ([String] -> e -> m' a) -> m' a
+   catchWithSrcLoc m h = catch m (h [])
+
+instance Exception e => MonadCatch e IO IO where
+   catch   = Control.Exception.catch
+
+-- Throw and Catch instances for the Either and ErrorT monads
+-- -----------------------------------------------------------
+instance (Error e) => MonadCatch e (Either e) (Either e) where catch m h = either h Right m
+instance (Error e, Monad m) => MonadCatch e (ErrorT e m) (ErrorT e m) where catch = catchError
+
+
+-- Instances for transformers (requires undecidable instances in some cases)
+-- -------------------------------------------------------------------------
+instance MonadCatch e m m' => MonadCatch e (ListT m) (ListT m') where catch (ListT m) h = ListT (catch m (runListT . h))
+instance MonadCatch e m m' => MonadCatch e (ReaderT r m) (ReaderT r m') where catch (ReaderT m) h = ReaderT (\s -> catch (m s) ((`runReaderT` s) . h))
+
+instance (Monoid w, MonadCatch e m m') => MonadCatch e (WriterT w m) (WriterT w m') where catch (WriterT m) h = WriterT (catch m (runWriterT . h))
+
+instance MonadCatch e m m' => MonadCatch e (StateT s m) (StateT s m') where catch (StateT m) h = StateT (\s -> catch (m s) ((`runStateT` s) . h))
+
+instance (Monoid w, MonadCatch e m m') => MonadCatch e (RWST r w s m) (RWST r w s m') where catch (RWST m) h = RWST (\r s -> catch (m r s) ((\m -> runRWST m r s) . h))
diff --git a/Control/Monad/Exception/Class.hs b/Control/Monad/Exception/Class.hs
deleted file mode 100644
--- a/Control/Monad/Exception/Class.hs
+++ /dev/null
@@ -1,120 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE EmptyDataDecls #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE FunctionalDependencies #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE ExistentialQuantification #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE OverlappingInstances #-}
-
-
-{-| Defines 'MonadThrow' and 'MonadCatch' type classes and suitable instances for 'IO' and 'Either'.
--}
-
-module Control.Monad.Exception.Class (
-       module Control.Monad,
-       module Control.Monad.Exception.Throws,
-       MonadThrow(..), MonadCatch(..),
-       WrapException(..), Exception(..), SomeException(..),
-       showExceptionWithTrace, wrapException
-       ) where
-
-import Control.Monad
-#if TRANSFORMERS
-import Control.Monad.Trans
-import Control.Monad.Trans.Error
-import Control.Monad.Trans.List
-import Control.Monad.Trans.Reader
-import Control.Monad.Trans.State
-import Control.Monad.Trans.Writer
-import Control.Monad.Trans.RWS
-#else
-import Control.Monad.Error
-import Control.Monad.List
-import Control.Monad.Reader
-import Control.Monad.State
-import Control.Monad.Writer
-import Control.Monad.RWS
-#endif
-
-#if __GLASGOW_HASKELL__ < 610
-import Control.Exception.Extensible (Exception(..), SomeException)
-import qualified Control.Exception.Extensible as Control.Exception
-#else
-import Control.Exception (Exception(..), SomeException)
-import qualified Control.Exception
-#endif
-import Data.Monoid
-import Data.Typeable
-import Text.PrettyPrint
-
-import Control.Monad.Exception.Throws
-
-import Prelude hiding (catch)
-
-class Monad m => MonadThrow e m where
-    throw :: e -> m a
-    throwWithSrcLoc :: String -> e -> m a
-    throwWithSrcLoc _ = throw
-
-instance Exception e => MonadThrow e IO where
-   throw = Control.Exception.throw
-
-class (Monad m, Monad m') => MonadCatch e m m' | e m -> m', e m' -> m where
-   catch   :: m a -> (e -> m' a) -> m' a
-   catchWithSrcLoc :: m a -> ([String] -> e -> m' a) -> m' a
-   catchWithSrcLoc m h = catch m (h [])
-
-instance Exception e => MonadCatch e IO IO where
-   catch   = Control.Exception.catch
-
-wrapException ::
-     (MonadThrow e' m', MonadCatch e m m') =>
-     m a -> (e -> e') -> m' a
-wrapException m mkE = m `catch` (throw . mkE)
-
-{-| Given a list of source locations and an exception, @showExceptionWithTrace@ produces output of the form
-
->       <exception details>
->        in <module a>(<file a.hs>): (12,6)
->           <module b>(<file b.hs>): (11,7)
->           ...
-
--}
-showExceptionWithTrace :: Exception e => [String] -> e -> String
-showExceptionWithTrace trace e = render$
-             text (show e) $$
-             text " in" <+> (vcat (map text $ reverse trace))
-
--- Labelled SomeException
--- ------------------------
--- | @WrapException@ adds a phantom type parameter @l@ to @SomeException@
-newtype WrapException l = WrapException {unwrapException::SomeException} deriving (Typeable)
-instance Show (WrapException l) where show (WrapException e) = show e
-
--- Throw and Catch instances for the Either and ErrorT monads
--- -----------------------------------------------------------
-instance (Error e) => MonadThrow e (Either e) where throw = Left
-instance (Error e) => MonadCatch e (Either e) (Either e) where catch m h = either h Right m
-
-instance (Error e, Monad m) => MonadThrow e (ErrorT e m) where throw = throwError
-instance (Error e, Monad m) => MonadCatch e (ErrorT e m) (ErrorT e m) where catch = catchError
-
-
--- Instances for transformers (requires undecidable instances in some cases)
--- -------------------------------------------------------------------------
-instance MonadThrow e m    => MonadThrow e (ListT m)            where throw = lift . throw
-instance MonadCatch e m m' => MonadCatch e (ListT m) (ListT m') where catch (ListT m) h = ListT (catch m (runListT . h))
-
-instance MonadThrow e m    => MonadThrow e (ReaderT r m)                where throw = lift . throw
-instance MonadCatch e m m' => MonadCatch e (ReaderT r m) (ReaderT r m') where catch (ReaderT m) h = ReaderT (\s -> catch (m s) ((`runReaderT` s) . h))
-
-instance (Monoid w, MonadThrow e m)    => MonadThrow e (WriterT w  m)               where throw = lift . throw
-instance (Monoid w, MonadCatch e m m') => MonadCatch e (WriterT w m) (WriterT w m') where catch (WriterT m) h = WriterT (catch m (runWriterT . h))
-
-instance MonadThrow e m    => MonadThrow e (StateT s m)               where throw = lift . throw
-instance MonadCatch e m m' => MonadCatch e (StateT s m) (StateT s m') where catch (StateT m) h = StateT (\s -> catch (m s) ((`runStateT` s) . h))
-
-instance (Monoid w, MonadThrow e m)    => MonadThrow e (RWST r w s m)                 where throw = lift . throw
-instance (Monoid w, MonadCatch e m m') => MonadCatch e (RWST r w s m) (RWST r w s m') where catch (RWST m) h = RWST (\r s -> catch (m r s) ((\m -> runRWST m r s) . h))
diff --git a/Control/Monad/Exception/Throws.hs b/Control/Monad/Exception/Throws.hs
--- a/Control/Monad/Exception/Throws.hs
+++ b/Control/Monad/Exception/Throws.hs
@@ -2,19 +2,24 @@
 {-# LANGUAGE EmptyDataDecls #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE OverlappingInstances, FlexibleInstances #-}
+{-# LANGUAGE UndecidableInstances #-}
 
 {-|
 Defines the @Throws@ binary relationship between types.
 -}
 
-module Control.Monad.Exception.Throws (Throws, Caught, UncaughtException, NoExceptions, ParanoidMode) where
+module Control.Monad.Exception.Throws (
+    Throws, Caught,
+    CheckedException(..),
+    UncaughtException,
+    NoExceptions, ParanoidMode) where
 
 #if __GLASGOW_HASKELL__ < 610
 import Control.Exception.Extensible (Exception(..), SomeException)
 #else
 import Control.Exception (Exception(..), SomeException)
 #endif
-
+import Data.Typeable
 
 -- | A type level witness of a exception handler.
 data Caught e l
@@ -45,18 +50,17 @@
    'Throws' is not a transitive relation and every ancestor relation
    must be explicitly encoded.
 
->                                                 --   TopException
->                                                 --         |
->   instance Throws MidException   TopException   --         |
->                                                 --   MidException
->   instance Throws ChildException MidException   --         |
->   instance Throws ChildException TopException   --         |
->                                                 --  ChildException
+>                                                            --   TopException
+>                                                            --         |
+>   instance Throws MidException   (Caught TopException l)   --         |
+>                                                            --   MidException
+>   instance Throws ChildException (Caught MidException l)   --         |
+>   instance Throws ChildException (Caught TopException l)   --         |
+>                                                            --  ChildException
 
 'SomeException' is automatically
    an ancestor of every other exception type.
 
-
 -}
 
 class (Private l, Exception e) => Throws e l
@@ -68,17 +72,37 @@
 --   .
 --   Capturing SomeException captures every possible exception
 instance Exception e => Throws e (Caught SomeException l)
+instance Throws SomeException (Caught SomeException l) -- Disambiguation instance
 
 -- | Uncaught Exceptions model unchecked exceptions (a la RuntimeException in Java)
 --
---   In order to declare an unchecked exception @e@,
+--   In order to declare an unchecked exception @E@,
 --   all that is needed is to make @e@ an instance of @UncaughtException@
+--
+--  > instance UncaughtException E
+--
+--   Note that declaring an exception E as unchecked does not automatically
+--   turn its children as unchecked too. This is a shortcoming of the current encoding.
+{-
+--   If that is what you want, then
+--   declare E as unchecked using an instance of @Throws@:
+--
+--  > instance Throws E l
+--
+--  The shortcoming of this route is that runEMTParanoid won't be able to
+--  control exceptions declared unchecked this way.
+-}
 class Exception e => UncaughtException e
 instance UncaughtException e => Throws e NoExceptions
 
-
 data NoExceptions
 instance Private NoExceptions
 
 data ParanoidMode
 instance Private ParanoidMode
+
+-- Labelled SomeException
+-- ------------------------
+-- | @CheckedException@ adds a phantom type parameter @l@ to @SomeException@
+newtype CheckedException l = CheckedException {checkedException::SomeException} deriving (Typeable)
+instance Show (CheckedException l) where show (CheckedException e) = show e
diff --git a/control-monad-exception.cabal b/control-monad-exception.cabal
--- a/control-monad-exception.cabal
+++ b/control-monad-exception.cabal
@@ -1,5 +1,5 @@
 name: control-monad-exception
-version: 0.4.8
+version: 0.5
 Cabal-Version:  >= 1.2.3
 build-type: Simple
 license: PublicDomain
@@ -38,27 +38,29 @@
   > runEM(eval `catch` \ (e::SomeException) -> return (-1))  :: Expr -> Double
   .
   .
-  This package provides, among other things:
+  In addition to explicitly typed exceptions his package provides:
   .
     * Support for explicitly documented, unchecked exceptions (with 'tryEM').
   .
     * Support for selective unchecked exceptions (with 'UncaughtException').
   .
-    * Support for exception stack traces (experimental). /Example:/
+    * Support for exception call traces via 'Control.Monad.Loc.MonadLoc'. /Example:/
   .
-  >       f () = $withLocTH $ throw MyException
-  >       g a  = $withLocTH $ f a
   >
-  >       main = runEMT $ $withLocTH $ do
-  >       g () `catchWithSrcLoc` \loc (e::MyException) -> lift(putStrLn$ showExceptionWithTrace loc e)
-  .
-  >        -- Running main produces the output:
-  .
-  >       *Main> main
-  >       MyException
-  >        in Main(example.hs): (12,6)
-  >           Main(example.hs): (11,7)
-  .
+  > f () = do throw MyException
+  > g a  = do f a
+  >
+  > main = runEMT $ do g () `catchWithSrcLoc`
+  >                        \loc (e::MyException) -> lift(putStrLn$ showExceptionWithTrace loc e)
+  >
+  > -- Running main produces the output:
+  >
+  > *Main> main
+  >  MyException
+  >    in f, Main(example.hs): (1,6)
+  >       g, Main(example.hs): (2,6)
+  >       main, Main(example.hs): (5,9)
+  >       main, Main(example.hs): (4,16)
 
 synopsis: Explicitly typed, checked exceptions with stack traces
 category: Control, Monads
@@ -76,7 +78,9 @@
   default: False
 
 Library
-  buildable: True
+  buildable: True 
+  build-depends: control-monad-failure, monadloc, pretty
+
   if flag(extensibleExceptions)
     build-depends:
       extensible-exceptions >= 0.1 && <0.2,
@@ -99,9 +103,9 @@
                EmptyDataDecls,
                DeriveDataTypeable,
                UndecidableInstances
-  build-depends: pretty, template-haskell
+
   exposed-modules:
-     Control.Monad.Exception.Class
+     Control.Monad.Exception.Catch
      Control.Monad.Exception.Throws
      Control.Monad.Exception
-  ghc-options: -Wall -fno-warn-name-shadowing
+  ghc-options: -Wall -fno-warn-name-shadowing -fno-warn-orphans
