diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,10 @@
+# Version 0.11.1 (2016-01-11)
+
+* Fixes test dependencies that precluded tests from compiling
+
+# Version 0.11.0.0 (2015-11-23)
+
+* Minimize methods in `HasTemplates` and extract everything else into functions
+
+* Add `layoutObject` method that allows customizing the value passed to the
+  layout
diff --git a/simple.cabal b/simple.cabal
--- a/simple.cabal
+++ b/simple.cabal
@@ -1,5 +1,5 @@
 name:                simple
-version:             0.8.1.0
+version:             2.0.0
 synopsis: A minimalist web framework for the WAI server interface
 description:
 
@@ -33,6 +33,7 @@
 category:            Web
 build-type:          Simple
 cabal-version:       >=1.10
+extra-source-files:  LICENSE CHANGELOG.md
 
 data-files: template/*.tmpl
 
@@ -40,6 +41,7 @@
   hs-source-dirs: src
   Main-Is: smpl.hs
   ghc-options: -Wall -fno-warn-unused-do-bind
+  default-language: Haskell2010
   build-depends:
       base < 6
     , aeson
@@ -50,11 +52,12 @@
     , filepath
     , process
     , setenv
-    , simple-templates >= 0.7.0
+    , simple-templates >= 2.0.0
     , text
     , unordered-containers
     , vector
-  default-language: Haskell2010
+  other-modules:
+    Paths_simple
 
 library
   hs-source-dirs: src
@@ -62,19 +65,20 @@
       base < 6
     , aeson
     , base64-bytestring
+    , blaze-builder
     , bytestring
-    , conduit
     , directory
     , filepath
     , mime-types
-    , monad-peel
+    , monad-control >= 1.0.0.0
     , mtl
     , simple-templates >= 0.7.0
-    , wai >= 2.0
+    , wai >= 3.0
     , wai-extra
     , http-types
     , text
     , transformers
+    , transformers-base
     , unordered-containers
     , vector
 
@@ -84,6 +88,7 @@
     Web.Simple,
     Web.Simple.Auth,
     Web.Simple.Controller,
+    Web.Simple.Controller.Exception,
     Web.Simple.Controller.Trans,
     Web.Simple.Responses,
     Web.Simple.Static,
@@ -94,19 +99,35 @@
 
 test-suite test-simple
   type: exitcode-stdio-1.0
-  hs-source-dirs: test
+  hs-source-dirs: test, src
   main-is: Spec.hs
+  default-language: Haskell2010
   build-depends:
       base < 6
-    , hspec
-    , HUnit
-    , monad-peel
+    , aeson
+    , base64-bytestring
+    , blaze-builder
+    , bytestring
+    , directory
+    , filepath
+    , mime-types
+    , monad-control >= 1.0.0.0
     , mtl
-    , simple
+    , simple-templates >= 0.7.0
+    , wai >= 3.0
+    , wai-extra
+    , http-types
+    , hspec
+    , hspec-contrib
+    , text
     , transformers
-    , wai
+    , transformers-base
+    , unordered-containers
+    , vector
+  other-modules:
+    Web.Simple.Controller.Trans,
+    Web.Simple.Responses
 
 source-repository head
   type: git
   location: http://github.com/alevy/simple.git
-
diff --git a/src/Web/Frank.hs b/src/Web/Frank.hs
--- a/src/Web/Frank.hs
+++ b/src/Web/Frank.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE Safe #-}
 {- |
 Frank is a Sinatra-inspired DSL (see <http://www.sinatrarb.com>) for creating
 routes. It is composable with all 'ToApplication' types, but is designed to be used
@@ -11,11 +11,11 @@
   main = run 3000 $ controllerApp () $ do
     get \"\/\" $ do
       req <- request
-      return $ okHtml $ fromString $
+      respond $ okHtml $ fromString $
         \"Welcome Home \" ++ (show $ serverName req)
     get \"\/user\/:id\" $ do
       userId \<- queryParam \"id\" >>= fromMaybe \"\"
-      return $ ok \"text/json\" $ fromString $
+      respond $ ok \"text/json\" $ fromString $
         \"{\\\"myid\\\": \" ++ (show userId) ++ \"}\"
     put \"\/user\/:id\" $ do
       ...
@@ -26,6 +26,7 @@
   ( get
   , post
   , put
+  , patch
   , delete
   , options
   ) where
@@ -51,6 +52,10 @@
 -- | Matches the PUT method on the given URL pattern
 put :: Monad m => Text -> ControllerT s m a -> ControllerT s m ()
 put = frankMethod PUT
+
+-- | Matches the PATCH method on the given URL pattern
+patch :: Monad m => Text -> ControllerT s m a -> ControllerT s m ()
+patch = frankMethod PATCH
 
 -- | Matches the DELETE method on the given URL pattern
 delete :: Monad m => Text -> ControllerT s m a -> ControllerT s m ()
diff --git a/src/Web/REST.hs b/src/Web/REST.hs
--- a/src/Web/REST.hs
+++ b/src/Web/REST.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE Trustworthy, FlexibleInstances, OverloadedStrings #-}
+{-# LANGUAGE Safe, FlexibleInstances, OverloadedStrings #-}
 {- |
 
 REST is a DSL for creating routes using RESTful HTTP verbs.
diff --git a/src/Web/Simple.hs b/src/Web/Simple.hs
--- a/src/Web/Simple.hs
+++ b/src/Web/Simple.hs
@@ -16,6 +16,7 @@
 module Web.Simple (
     module Web.Simple.Responses
   , module Web.Simple.Controller
+  , module Web.Simple.Controller.Exception
   , module Web.Simple.Static
   , module Network.Wai
   -- * Overview
@@ -34,6 +35,7 @@
 import Network.Wai
 import Web.Simple.Responses
 import Web.Simple.Controller
+import Web.Simple.Controller.Exception
 import Web.Simple.Static
 
 {- $Overview
diff --git a/src/Web/Simple/Controller.hs b/src/Web/Simple/Controller.hs
--- a/src/Web/Simple/Controller.hs
+++ b/src/Web/Simple/Controller.hs
@@ -41,22 +41,17 @@
   , redirectBackOr
   -- * Exception handling
   , T.ControllerException
-  , module Control.Exception.Peel
-  -- * Integrating other WAI components
-  , fromApp
   -- * Low-level utilities
   , body
   , hoistEither
   ) where
 
-import           Control.Exception.Peel
 import           Control.Monad.IO.Class
+import           Blaze.ByteString.Builder
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Char8 as S8
 import qualified Data.ByteString.Lazy as L
 import qualified Data.ByteString.Lazy.Char8 as L8
-import           Data.Conduit
-import qualified Data.Conduit.List as CL
 import           Data.Text (Text)
 import           Network.HTTP.Types
 import           Network.Wai
@@ -92,7 +87,9 @@
 
 -- | Convert the controller into an 'Application'
 controllerApp :: s -> Controller s a -> Application
-controllerApp = T.controllerApp
+controllerApp s ctrl req responseFunc = do
+  resp <- T.controllerApp s ctrl req
+  responseFunc resp
 
 -- | Provide a response
 --
@@ -100,11 +97,6 @@
 respond :: Response -> Controller s a
 respond = T.respond
 
-
--- | Lift an application to a controller
-fromApp :: Application -> Controller s ()
-fromApp = T.fromApp
-
 -- | Matches on the hostname from the 'Request'. The route only succeeds on
 -- exact matches.
 routeHost :: S.ByteString -> Controller s a -> Controller s ()
@@ -220,8 +212,15 @@
 -- | Reads and returns the body of the HTTP request.
 body :: Controller s L8.ByteString
 body = do
-  req <- request
-  liftIO $ L8.fromChunks `fmap` (requestBody req $$ CL.consume)
+  bodyProducer <- getRequestBodyChunk `fmap` request
+  liftIO $ do
+    result <- consume mempty bodyProducer
+    return $ toLazyByteString result
+  where consume bldr prod = do
+          next <- prod
+          if S.null next then
+            return bldr
+            else consume (mappend bldr (fromByteString next)) prod
 
 -- | Returns the value of the given request header or 'Nothing' if it is not
 -- present in the HTTP request.
diff --git a/src/Web/Simple/Controller/Exception.hs b/src/Web/Simple/Controller/Exception.hs
new file mode 100644
--- /dev/null
+++ b/src/Web/Simple/Controller/Exception.hs
@@ -0,0 +1,30 @@
+module Web.Simple.Controller.Exception where
+
+import qualified Control.Exception as E
+import           Control.Monad.Trans.Control
+import           Web.Simple.Controller
+
+onException :: Controller s a -> Controller s b -> Controller s a
+onException act handler = control $ \runInM -> do
+  runInM act `E.onException` runInM handler
+
+finally :: Controller s a -> Controller s b -> Controller s a
+finally act next = control $ \runInM -> E.mask $ \restore -> do
+  r <- restore (runInM act) `E.onException` (runInM next)
+  _ <- runInM next
+  return r
+
+bracket :: Controller s a -> (a -> Controller s b)
+        -> (a -> Controller s c) -> Controller s c
+bracket aquire release act = control $ \runInM -> E.mask $ \restore -> do
+  let release' a = runInM $ restoreM a >>= release
+  a <- runInM aquire
+  r <- (restore $ runInM $ restoreM a >>= act) `E.onException` release' a
+  _ <- release' a
+  return r
+
+handle :: E.Exception e => (e -> Controller s a) -> Controller s a
+       -> Controller s a
+handle handler act = control $ \runInM -> do
+  E.handle (runInM . handler) $ runInM act
+
diff --git a/src/Web/Simple/Controller/Trans.hs b/src/Web/Simple/Controller/Trans.hs
--- a/src/Web/Simple/Controller/Trans.hs
+++ b/src/Web/Simple/Controller/Trans.hs
@@ -3,6 +3,7 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies #-}
 
 {- | 'ControllerT' provides a convenient syntax for writting 'Application'
   code as a Monadic action with access to an HTTP request as well as app
@@ -23,14 +24,15 @@
 -}
 module Web.Simple.Controller.Trans where
 
+import           Control.Exception
 import           Control.Monad hiding (guard)
+import           Control.Monad.Base
 import           Control.Monad.IO.Class
-import           Control.Monad.IO.Peel
 import           Control.Monad.Reader.Class
 import           Control.Monad.State.Class
 import           Control.Monad.Trans.Class
+import           Control.Monad.Trans.Control
 import           Control.Applicative
-import           Control.Exception.Peel
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Char8 as S8
 import           Data.List (find)
@@ -43,7 +45,6 @@
 import           Network.Wai
 import           Web.Simple.Responses
 
-
 -- | The ControllerT Monad is both a State-like monad which, when run, computes
 -- either a 'Response' or a result. Within the ControllerT Monad, the remainder
 -- of the computation can be short-circuited by 'respond'ing with a 'Response'.
@@ -59,11 +60,11 @@
                               Right result -> (Right $ f result, st)
 
 instance (Monad m, Functor m) => Applicative (ControllerT s m) where
-  pure = return
+  pure a = ControllerT $ \st _ -> return $ (Right a, st)
   (<*>) = ap
 
 instance Monad m => Monad (ControllerT s m) where
-  return a = ControllerT $ \st _ -> return $ (Right a, st)
+  return = pure
   (ControllerT act) >>= fn = ControllerT $ \st0 req -> do
     (eres, st) <- act st0 req
     case eres of
@@ -94,13 +95,18 @@
 instance MonadIO m => MonadIO (ControllerT s m) where
   liftIO = lift . liftIO
 
-instance MonadPeelIO (ControllerT s IO) where
-  peelIO = do
-    s <- controllerState
-    req <- request
-    return $ \ctrl -> do
-      res <- runController ctrl s req
-      return $ ControllerT $ \_ _ -> return res
+instance Monad m => MonadFail (ControllerT s m) where
+  fail = err
+
+instance (Applicative m, Monad m, MonadBase m m) => MonadBase m (ControllerT s m) where
+  liftBase = liftBaseDefault
+
+instance MonadBaseControl m m => MonadBaseControl m (ControllerT s m) where
+  type StM (ControllerT s m) a = (Either Response a, s)
+  liftBaseWith fn = ControllerT $ \st req -> do
+    res <- fn $ \act -> runController act st req
+    return (Right res, st)
+  restoreM (a, s) = ControllerT $ \_ _ -> return (a, s)
 
 hoistEither :: Monad m => Either Response a -> ControllerT s m a
 hoistEither eith = ControllerT $ \st _ -> return (eith, st)
diff --git a/src/Web/Simple/Responses.hs b/src/Web/Simple/Responses.hs
--- a/src/Web/Simple/Responses.hs
+++ b/src/Web/Simple/Responses.hs
@@ -3,7 +3,7 @@
 
 -- | This module defines some convenience functions for creating responses.
 module Web.Simple.Responses
-  ( ok, okHtml, okJson
+  ( ok, okHtml, okJson, okXml
   , movedTo, redirectTo
   , badRequest, requireBasicAuth, forbidden
   , notFound
@@ -39,6 +39,11 @@
 -- given resposne body
 okJson :: L8.ByteString -> Response
 okJson = ok (S8.pack "application/json")
+
+-- | Creates a 200 (OK) 'Response' with content-type \"application/xml\" and the
+-- given resposne body
+okXml :: L8.ByteString -> Response
+okXml = ok (S8.pack "application/xml")
 
 -- | Given a URL returns a 301 (Moved Permanently) 'Response' redirecting to
 -- that URL.
diff --git a/src/Web/Simple/Static.hs b/src/Web/Simple/Static.hs
--- a/src/Web/Simple/Static.hs
+++ b/src/Web/Simple/Static.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE OverloadedStrings #-}
 module Web.Simple.Static where
 
 import Control.Monad
@@ -19,4 +20,11 @@
     respond $ responseFile status200
       [(hContentType, defaultMimeLookup $ T.pack $ takeFileName fp)]
       fp Nothing
+  when (null $ takeExtension fp) $ do
+    let fpIdx = fp </> "index.html"
+    existsIdx <- liftIO $ doesFileExist fpIdx
+    when existsIdx $ do
+      respond $ responseFile status200
+        [(hContentType, "text/html")]
+        fpIdx Nothing
 
diff --git a/src/Web/Simple/Templates.hs b/src/Web/Simple/Templates.hs
--- a/src/Web/Simple/Templates.hs
+++ b/src/Web/Simple/Templates.hs
@@ -2,14 +2,15 @@
 {-# LANGUAGE OverloadedStrings, MultiParamTypeClasses #-}
 {-# LANGUAGE DefaultSignatures #-}
 module Web.Simple.Templates
-  ( HasTemplates(..)
-  , defaultGetTemplate, defaultRender, defaultFunctionMap
+  ( HasTemplates(..), render, renderPlain, renderLayout, renderLayoutTmpl
+  , defaultGetTemplate, defaultFunctionMap, defaultLayoutObject
   , H.fromList
   , Function(..), ToFunction(..), FunctionMap
   ) where
 
 import Control.Monad.IO.Class
 import Data.Aeson
+import qualified Data.Aeson.KeyMap as K
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Lazy as L
 import qualified Data.HashMap.Strict as H
@@ -54,40 +55,72 @@
   default getTemplate :: MonadIO m => FilePath -> ControllerT hs m Template
   getTemplate = defaultGetTemplate
 
-  -- | Renders a view template with the default layout and a global used to
-  -- evaluate variables in the template.
-  render :: ToJSON a => FilePath -> a -> ControllerT hs m ()
-  render = defaultRender
+  -- | The `Value` passed to a layout given the rendered view template and the
+  -- value originally passed to the view template. By default, produces an
+  -- `Object` with "yield", containing the rendered view, and "page", containing
+  -- the value originally passed to the view.
+  layoutObject :: (ToJSON pageContent, ToJSON pageVal)
+               => pageContent -> pageVal -> ControllerT hs m Value
+  layoutObject = defaultLayoutObject
 
-  -- | Same as 'render' but without a template.
-  renderPlain :: ToJSON a => FilePath -> a -> ControllerT hs m ()
-  renderPlain fp val = do
-    fm <- functionMap
-    dir <- viewDirectory
-    tmpl <- getTemplate (dir </> fp)
-    let pageContent =
-          L.fromChunks . (:[]) . encodeUtf8 $
-            renderTemplate tmpl fm $ toJSON val
-    let mime = defaultMimeLookup $ T.pack $ takeFileName fp
-    respond $ ok mime pageContent
+defaultLayoutObject :: (HasTemplates m hs, ToJSON pageContent, ToJSON pageVal)
+                    => pageContent -> pageVal -> ControllerT hs m Value
+defaultLayoutObject pageContent pageVal = return $
+    object ["yield" .= pageContent, "page" .= pageVal]
 
-  -- | Render a view using the layout named by the first argument.
-  renderLayout :: ToJSON a => FilePath -> FilePath -> a -> ControllerT hs m ()
-  renderLayout lfp fp val = do
-    layout <- getTemplate lfp
-    renderLayout' layout fp val
+-- | Render a view using the layout named by the first argument.
+renderLayout :: (HasTemplates m hs, ToJSON a)
+             => FilePath -> FilePath -> a -> ControllerT hs m ()
+renderLayout lfp fp val  = do
+  layout <- getTemplate lfp
+  viewDir <- viewDirectory
+  view <- getTemplate (viewDir </> fp)
+  let mime = defaultMimeLookup $ T.pack $ takeFileName fp
+  renderLayoutTmpl layout view val mime
 
-  -- | Same as 'renderLayout' but uses an already compiled layout.
-  renderLayout' :: ToJSON a => Template -> FilePath -> a -> ControllerT hs m ()
-  renderLayout' layout fp val = do
-    fm <- functionMap
-    dir <- viewDirectory
-    tmpl <- getTemplate (dir </> fp)
-    let pageContent = renderTemplate tmpl fm $ toJSON val
-    let mime = defaultMimeLookup $ T.pack $ takeFileName fp
-    respond $ ok mime $ L.fromChunks . (:[]) . encodeUtf8 $
-      renderTemplate layout fm $ object ["yield" .= pageContent, "page" .= val]
 
+-- | Same as 'renderLayout' but uses already compiled layouts.
+renderLayoutTmpl :: (HasTemplates m hs, ToJSON a)
+                 => Template -> Template -> a
+                 -> S.ByteString -> ControllerT hs m ()
+renderLayoutTmpl layout view val mime = do
+  fm <- functionMap
+  let pageContent = renderTemplate view fm $ toJSON val
+  value <- layoutObject pageContent val
+  let result = renderTemplate layout fm value
+  respond $ ok mime $ L.fromChunks . (:[]) . encodeUtf8 $ result
+
+-- | Renders a view template with the default layout and a global used to
+-- evaluate variables in the template.
+render :: (HasTemplates m hs , Monad m, ToJSON a)
+       => FilePath -- ^ Template to render
+       -> a -- ^ Aeson `Value` to pass to the template
+       -> ControllerT hs m ()
+render fp val = do
+  mlayout <- defaultLayout
+  case mlayout of
+    Nothing -> renderPlain fp val
+    Just layout -> do
+      viewDir <- viewDirectory
+      view <- getTemplate (viewDir </> fp)
+      let mime = defaultMimeLookup $ T.pack $ takeFileName fp
+      renderLayoutTmpl layout view val mime
+
+-- | Same as 'render' but without a template.
+renderPlain :: (HasTemplates m hs, ToJSON a)
+            => FilePath -- ^ Template to render
+            -> a -- ^ Aeson `Value` to pass to the template
+            -> ControllerT hs m ()
+renderPlain fp val = do
+  fm <- functionMap
+  dir <- viewDirectory
+  tmpl <- getTemplate (dir </> fp)
+  let pageContent =
+        L.fromChunks . (:[]) . encodeUtf8 $
+          renderTemplate tmpl fm $ toJSON val
+  let mime = defaultMimeLookup $ T.pack $ takeFileName fp
+  respond $ ok mime pageContent
+
 defaultGetTemplate :: (HasTemplates m hs, MonadIO m)
                    => FilePath -> ControllerT hs m Template
 defaultGetTemplate fp = do
@@ -96,14 +129,6 @@
     Left str -> fail str
     Right tmpl -> return tmpl
 
-defaultRender :: (HasTemplates m hs , Monad m, ToJSON a)
-              => FilePath -> a -> ControllerT hs m ()
-defaultRender fp val = do
-  mlayout <- defaultLayout
-  case mlayout of
-    Nothing -> renderPlain fp val
-    Just layout -> renderLayout' layout fp val
-
 defaultFunctionMap :: FunctionMap
 defaultFunctionMap = H.fromList
   [ ("length", toFunction valueLength)
@@ -111,14 +136,14 @@
 
 valueLength :: Value -> Value
 valueLength (Array arr) = toJSON $ V.length arr
-valueLength (Object obj) = toJSON $ H.size obj
+valueLength (Object obj) = toJSON $ K.size obj
 valueLength (String str) = toJSON $ T.length str
 valueLength Null = toJSON (0 :: Int)
 valueLength _ = error "length only valid for arrays, objects and strings"
 
 valueNull :: Value -> Value
 valueNull (Array arr) = toJSON $ V.null arr
-valueNull (Object obj) = toJSON $ H.null obj
+valueNull (Object obj) = toJSON $ K.null obj
 valueNull (String str) = toJSON $ T.null str
 valueNull Null = toJSON True
 valueNull _ = error "null only valid for arrays, objects and strings"
diff --git a/src/smpl.hs b/src/smpl.hs
--- a/src/smpl.hs
+++ b/src/smpl.hs
@@ -4,20 +4,18 @@
 module Main (main) where
 
 import Prelude hiding (writeFile, FilePath, all)
-import Control.Applicative
 import Control.Monad (when)
 import Data.Aeson
 import Data.Char
 import qualified Data.ByteString.Char8 as S8
 import qualified Data.Text.Encoding as T
-import Data.Monoid (mempty)
 import Data.Version
 import System.Console.CmdArgs
 import System.Directory
 import System.FilePath
-import System.Environment
+import System.Environment (getEnvironment)
+import System.SetEnv (setEnv)
 import System.Exit
-import System.SetEnv
 import System.Process
 import Web.Simple.Templates.Language
 
diff --git a/template/Common_hs.tmpl b/template/Common_hs.tmpl
--- a/template/Common_hs.tmpl
+++ b/template/Common_hs.tmpl
@@ -7,7 +7,7 @@
 $if(include_sessions)$import Web.Simple.Session$endif$
 $if(include_postgresql)$import Web.Simple.PostgreSQL$endif$
 
-data AppSettings = AppSettings { $if(include_postgresql)$appDB :: PostgreSQLConn$if(include_postgresql)$
+data AppSettings = AppSettings { $if(include_postgresql)$appDB :: PostgreSQLConn$if(include_sessions)$
                                , appSession :: Maybe Session$endif$$else$$if(include_sessions)$appSession :: Maybe Session$endif$$endif$ }
 
 newAppSettings :: IO AppSettings
diff --git a/template/package_cabal.tmpl b/template/package_cabal.tmpl
--- a/template/package_cabal.tmpl
+++ b/template/package_cabal.tmpl
@@ -1,4 +1,4 @@
-name:                $module$
+name:                $appname$
 version:             0.0.0.0
 --author:              YOUR NAME
 --maintainer:          your@email.com
@@ -16,5 +16,6 @@
     , wai-extra
     , warp$if(include_sessions)$
     , simple-session >= 0.8.0$endif$$if(include_postgresql)$
-    , simple-postgresql-orm >= 0.8.0$endif$
+    , simple-postgresql-orm >= 0.8.0
+    , postgresql-orm$endif$
 
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -3,10 +3,10 @@
 
 import Control.Monad
 import Control.Monad.IO.Class
-import Control.Monad.IO.Peel
 import Control.Monad.Trans
+import Control.Monad.Trans.Control
 import Test.Hspec
-import Test.Hspec.HUnit
+import Test.Hspec.Contrib.HUnit
 import Network.Wai
 import Web.Simple.Controller.Trans
 import Web.Simple.Responses
@@ -110,13 +110,14 @@
         defaultRequest { requestHeaderHost = Nothing }
       return ()
 
-  describe "MonadPeelIO instance" $ do
+  describe "MonadBaseControl instance" $ do
     it "Preserves state changes in inner block" $ do
       let expected = 1234
           ctrl = do
-                  k <- peelIO
-                  join $ liftIO $ k $ do
-                    putState expected
+                  putState 555
+                  res <- liftBaseWith $ \f -> do
+                      f $ putState expected
+                  restoreM res
       s <- snd `fmap` runController ctrl 0 defaultRequest
       s `shouldBe` expected
 
