diff --git a/Control/Continue.hs b/Control/Continue.hs
new file mode 100644
--- /dev/null
+++ b/Control/Continue.hs
@@ -0,0 +1,24 @@
+-- |
+-- Module:     Control.Continue
+-- Copyright:  (c) 2012 Ertugrul Soeylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Soeylemez <es@ertes.de>
+--
+-- Proxy to the various modules of the continue package.
+
+module Control.Continue
+    ( -- * Continue modules
+      module Control.Continue.Class,
+      module Control.Continue.Types,
+      module Control.Continue.Utils,
+
+      -- * Convenience reexports
+      Alt(..),
+      Plus(..)
+    )
+    where
+
+import Control.Continue.Class
+import Control.Continue.Types
+import Control.Continue.Utils
+import Data.Functor.Plus
diff --git a/Control/Continue/Class.hs b/Control/Continue/Class.hs
new file mode 100644
--- /dev/null
+++ b/Control/Continue/Class.hs
@@ -0,0 +1,77 @@
+-- |
+-- Module:     Control.Continue.Class
+-- Copyright:  (c) 2013 Ertugrul Soeylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Soeylemez <es@ertes.de>
+
+{-# LANGUAGE UndecidableInstances #-}
+
+module Control.Continue.Class
+    ( -- * Suspension
+      MonadContinue(..)
+    )
+    where
+
+import qualified Control.Monad.Trans.State.Strict as Ss
+import qualified Control.Monad.Trans.Writer.Strict as Ws
+import Control.Monad.Trans.Identity
+import Control.Monad.Trans.Maybe
+import Control.Monad.Trans.Reader
+import Control.Monad.Trans.State.Lazy
+import Control.Monad.Trans.Writer.Lazy
+import Data.Monoid
+import Data.Functor.Plus
+
+
+-- | Type class for monads that support suspension and continuation
+-- spots.
+
+class (Plus f, Monad m, Monoid e) => MonadContinue e f m | m -> e, m -> f where
+    -- | Add the given set of continuations and possibly suspend.
+    addCont ::
+        Either e a       -- ^ What to return now (left suspends).
+        -> f (m a)  -- ^ What to run and return when reentering.
+        -> m a
+
+instance (MonadContinue e f m) => MonadContinue e f (IdentityT m) where
+    addCont mx c = IdentityT $ addCont mx (fmap runIdentityT c)
+
+instance (MonadContinue e f m) => MonadContinue e f (MaybeT m) where
+    addCont mx c =
+        MaybeT $
+            addCont (fmap Just mx) (fmap runMaybeT c)
+
+instance (MonadContinue e f m) => MonadContinue e f (ReaderT r m) where
+    addCont mx c =
+        ReaderT $ \env ->
+            addCont mx (fmap (flip runReaderT env) c)
+
+-- | Time travel warning: Captures the current state, not the state at
+-- reentry!
+
+instance (MonadContinue e f m) => MonadContinue e f (StateT s m) where
+    addCont mx c =
+        StateT $ \s ->
+            addCont (fmap (flip (,) s) mx)
+                    (fmap (flip runStateT s) c)
+
+-- | Time travel warning: Captures the current state, not the state at
+-- reentry!
+
+instance (MonadContinue e f m) => MonadContinue e f (Ss.StateT s m) where
+    addCont mx c =
+        Ss.StateT $ \s ->
+            addCont (fmap (flip (,) s) mx)
+                    (fmap (flip Ss.runStateT s) c)
+
+instance (MonadContinue e f m, Monoid l) => MonadContinue e f (WriterT l m) where
+    addCont mx c =
+        WriterT $
+            addCont (fmap (flip (,) mempty) mx)
+                    (fmap runWriterT c)
+
+instance (MonadContinue e f m, Monoid l) => MonadContinue e f (Ws.WriterT l m) where
+    addCont mx c =
+        Ws.WriterT $
+            addCont (fmap (flip (,) mempty) mx)
+                    (fmap Ws.runWriterT c)
diff --git a/Control/Continue/Types.hs b/Control/Continue/Types.hs
new file mode 100644
--- /dev/null
+++ b/Control/Continue/Types.hs
@@ -0,0 +1,174 @@
+-- |
+-- Module:     Control.Continue.Types
+-- Copyright:  (c) 2012 Ertugrul Soeylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Soeylemez <es@ertes.de>
+--
+-- Types used in the continue library.
+
+{-# LANGUAGE UndecidableInstances #-}
+
+module Control.Continue.Types
+    ( -- * Suspendable computations
+      ContinueT(..),
+      Continue,
+
+      -- * Convenience types
+      LastEx
+    )
+    where
+
+import qualified Data.Bifunctor as Bi
+import Control.Applicative
+import Control.Arrow
+import Control.Continue.Class
+import Control.Exception (SomeException)
+import Control.Monad
+import Control.Monad.Base
+import Control.Monad.Error.Class
+import Control.Monad.Identity
+import Control.Monad.Reader.Class
+import Control.Monad.State.Class
+import Control.Monad.Trans
+import Control.Monad.Trans.Control
+import Control.Monad.Writer.Class
+import Data.Functor.Plus
+import Data.Monoid
+
+
+-- | This monad transformer adds continuations under @f@ and @e@-typed
+-- suspensions to @m@.
+
+newtype ContinueT e f m a =
+    ContinueT {
+      runContinueT :: m (Either e a, f (ContinueT e f m a))
+    }
+
+instance (Monad m, Monoid e, Plus f) => Alternative (ContinueT e f m) where
+    empty = ContinueT (return (Left mempty, zero))
+
+    ContinueT c1 <|> ContinueT c2 =
+        ContinueT $ do
+            (mx1, cf1) <- c1
+            (mx2, cf2) <- c2
+            let mx = either (\ex1 -> Bi.first (ex1 <>) mx2) Right mx1
+            return (mx, cf1 <!> cf2)
+
+instance (Monad m, Plus f) => Applicative (ContinueT e f m) where
+    pure x = ContinueT (return (Right x, zero))
+
+    ContinueT cf <*> rx@(ContinueT cx) =
+        ContinueT $ do
+            (mf, cff) <- cf
+            case mf of
+              Left ex -> return (Left ex, fmap (<*> rx) cff)
+              Right f -> do
+                  (mx, cfx) <- cx
+                  return (fmap f mx, fmap (fmap f) cfx)
+
+instance (Functor f, Monad m) => Functor (ContinueT e f m) where
+    fmap f (ContinueT c) = ContinueT (liftM (fmap f *** fmap (fmap f)) c)
+
+instance (Monad m, Monoid e, Plus f) => Monad (ContinueT e f m) where
+    return = pure
+
+    ContinueT c >>= f =
+        ContinueT $ do
+            (mx, cfx') <- c
+            let cfx = fmap (>>= f) cfx'
+            case mx of
+              Left ex -> return (Left ex, cfx)
+              Right x -> do
+                  (my, cfy) <- runContinueT (f x)
+                  return (my, cfx <!> cfy)
+
+    fail _ = ContinueT (return (Left mempty, zero))
+
+instance (MonadBase b m, Monoid e, Plus f) => MonadBase b (ContinueT e f m) where
+    liftBase = liftBaseDefault
+
+instance (MonadBaseControl b m, Monoid e, Plus f) => MonadBaseControl b (ContinueT e f m) where
+    data StM (ContinueT e f m) a =
+        StContinueT (StM m (Either e a, f (ContinueT e f m a)))
+
+    liftBaseWith k =
+        ContinueT $ do
+            x <-
+                liftBaseWith $ \runB ->
+                    k $ \(ContinueT c) ->
+                        liftM StContinueT (runB c)
+            return (Right x, zero)
+
+    restoreM (StContinueT s) = ContinueT (restoreM s)
+
+instance (Monad m, Monoid e, Plus f) => MonadContinue e f (ContinueT e f m) where
+    addCont mx cf = ContinueT (return (mx, cf))
+
+instance (Monad m, Monoid e, Plus f) => MonadError e (ContinueT e f m) where
+    throwError ex = ContinueT (return (Left ex, zero))
+    catchError (ContinueT c) h =
+        ContinueT $ do
+            (mx, cf) <- c
+            case mx of
+              Left ex -> do
+                  (mxh, cfh) <- runContinueT (h ex)
+                  return (mxh, cf <!> cfh)
+              Right _ -> return (mx, cf)
+
+-- | Warning:  If feedback is broken by suspension you get a run-time
+-- error.
+
+instance (MonadFix m, Monoid e, Plus f) => MonadFix (ContinueT e f m) where
+    mfix f =
+        ContinueT . mfix $ \ ~(mx, _) ->
+            runContinueT . f .
+            either (const $ error "Feedback broken by suspension") id $ mx
+
+instance (MonadIO m, Monoid e, Plus f) => MonadIO (ContinueT e f m) where
+    liftIO = ContinueT . liftM (\x -> (Right x, zero)) . liftIO
+
+instance (Monad m, Monoid e, Plus f) => MonadPlus (ContinueT e f m) where
+    mzero = empty
+    mplus = (<|>)
+
+instance (MonadReader r m, Monoid e, Plus f) => MonadReader r (ContinueT e f m) where
+    ask = lift ask
+    local f (ContinueT c) = ContinueT (local f c)
+    reader = ContinueT . liftM (\x -> (Right x, zero)) . reader
+
+instance (MonadState s m, Monoid e, Plus f) => MonadState s (ContinueT e f m) where
+    get = lift get
+    put = lift . put
+    state = lift . state
+
+instance (Plus f) => MonadTrans (ContinueT e f) where
+    lift = ContinueT . liftM (\x -> (Right x, zero))
+
+instance (MonadWriter l m, Monoid e, Plus f) => MonadWriter l (ContinueT e f m) where
+    listen (ContinueT c) =
+        ContinueT $ do
+            ((mx, cf), w) <- listen c
+            let addLog x = (x, w)
+            return (fmap addLog mx, fmap (fmap addLog) cf)
+
+    pass (ContinueT c) =
+        ContinueT . pass $ do
+            (mx, cf') <- c
+            let cf = fmap (fmap fst) cf'
+            case mx of
+              Left ex      -> return ((Left ex, cf), id)
+              Right (x, f) -> return ((Right x, cf), f)
+
+    tell = lift . tell
+    writer = lift . writer
+
+
+-- | 'ContinueT' over 'Identity'.
+
+type Continue e f = ContinueT e f Identity
+
+
+-- | Type alias for the common case of using @'Last' 'SomeException'@ as
+-- the suspension monoid.
+
+type LastEx = Last SomeException
diff --git a/Control/Continue/Utils.hs b/Control/Continue/Utils.hs
new file mode 100644
--- /dev/null
+++ b/Control/Continue/Utils.hs
@@ -0,0 +1,51 @@
+-- |
+-- Module:     Control.Continue.Utils
+-- Copyright:  (c) 2012 Ertugrul Soeylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Soeylemez <es@ertes.de>
+--
+-- Suspension/continuation utilities.
+
+module Control.Continue.Utils
+    ( -- * Basic utilities
+      addCont_,
+      continue,
+      continue_,
+      suspend
+    )
+    where
+
+import Control.Continue.Class
+import Data.Functor.Plus
+
+
+-- | Add the given set of continuations without suspending.
+
+addCont_ :: (MonadContinue e f m) => f (m ()) -> m ()
+addCont_ = addCont (Right ())
+
+
+-- | Allow to continue here with the given value.
+
+continue ::
+    (MonadContinue e f m)
+    => Either e a      -- ^ What to return now (left suspends).
+    -> f (Either e a)  -- ^ What to return when reentering (left suspends).
+    -> m a
+continue mx = addCont mx . fmap (\mx -> addCont mx zero)
+
+
+-- | Allow to continue here.
+
+continue_ ::
+    (MonadContinue e f m)
+    => f ()  -- ^ Reentering key.
+    -> m ()
+continue_ = addCont (Right ()) . fmap (const $ return ())
+
+
+-- | Suspend with the given value.  Does not register any continuation
+-- spots.  Note that @suspend mempty@ is equivalent to @empty@.
+
+suspend :: (MonadContinue e f m) => e -> m a
+suspend ex = addCont (Left ex) zero
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,32 @@
+continue license
+Copyright (c) 2012, Ertugrul Soeylemez
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+
+    * Neither the name of the author nor the names of any contributors
+      may be used to endorse or promote products derived from this
+      software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,95 @@
+The ContinueT monad transformer
+===============================
+
+Quickstart tutorial
+-------------------
+
+This monad transformer allows you to set continuation spots in a
+computation and reenter it at any of those spots possibly causing
+different behavior:
+
+    label name = continue_ (M.singleton name ())
+
+    myComp = do
+        label "first"
+        liftIO (putStrLn "Hello")
+        label "second"
+        liftIO (putStrLn "World!")
+
+This computation gives you two spots for reentry, "first" and "second".
+If you reenter at "first", the whole computation will be run again.  If
+you reenter at "second", only the second `putStrLn` computation will be
+run again.
+
+
+### Advanced reentering
+
+The most general way to reenter is to perform a computation when
+reentering:
+
+    addCont (Right False) . M.singleton "abc" $ do
+        liftIO (putStrLn "Reentered at spot abc.")
+        return True
+
+In the primary run this computation will just return `False`, but it
+will also register a continuation spot.  When you reenter the
+computation using that spot, it will return `True` instead.
+
+
+### Suspension
+
+A `ContinueT` monad also allows you to suspend a computation.  This
+basically means that the computation is aborted at some spot to be
+reentered somewhere else (or at the same spot) later.  You can do this
+with the `empty` combinator as well as the `suspend` function.  Examples
+TODO.
+
+
+ContinueT explained
+-------------------
+
+`ContinueT` takes four arguments:
+
+    newtype ContinueT e f m a
+
+To form a monad, *e* has to be a monoid, *f* has to be a `Plus` functor
+(as defined by the [semigroupoids] package) and *m* has to be a monad.
+
+
+### The reentry functor
+
+The most important parameter is the reentry functor *f*.  It represents
+the type for maps of reentry points.  Example:
+
+    ContinueT e (Map String) m a
+
+A computation of this type may register reentry points indexed by
+strings.  All registered reentry points are combined according to the
+functor's `Plus` instance.
+
+
+### The suspension monoid
+
+Computations may suspend, in which case control is returned to a
+controller, which may be the application loop or the `(<|>)` combinator:
+
+    c1 <|> c2
+
+This computation runs both `c1` and `c2` (note: even if neither
+suspends) and returns the result of the left-most computation that did
+not suspend.
+
+When a computation suspends it may do so with a value of type *e* that
+might communicate the reason for suspending.  This type must be a
+monoid, because multiple branches of a `(<|>)` composition may suspend,
+in which case the suspension values are combined according to the
+`Monoid` instance of *e*.
+
+A reasonable suspension monoid is `Last SomeException`, and since this
+will likely be a very common choice this library defines a shorthand for
+it:
+
+    type LastEx = Last SomeException
+
+
+[semigroupoids]: <http://hackage.haskell.org/package/semigroupoids>
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,12 @@
+continue setup script
+Copyright (C) 2012, Ertugrul Soeylemez
+
+Please see the LICENSE file for terms and conditions of use,
+modification and distribution of this package, including this file.
+
+> module Main where
+>
+> import Distribution.Simple
+>
+> main :: IO ()
+> main = defaultMain
diff --git a/continue.cabal b/continue.cabal
new file mode 100644
--- /dev/null
+++ b/continue.cabal
@@ -0,0 +1,62 @@
+Name:          continue
+Version:       0.1.0
+Category:      Continuation-based user interaction monad
+Synopsis:      Control
+Maintainer:    Ertugrul Söylemez <es@ertes.de>
+Author:        Ertugrul Söylemez <es@ertes.de>
+Copyright:     (c) 2012 Ertugrul Söylemez
+License:       BSD3
+License-file:  LICENSE
+Build-type:    Simple
+Stability:     experimental
+Cabal-version: >= 1.10
+Extra-source-files: README.md
+Description:
+    This library implements a monad transformer for suspendable
+    computations, similar and related to free comonads.  It allows to
+    write continuation-based web frameworks, command line applications
+    and similar interfaces.
+
+Source-repository head
+    type:     git
+    location: git://github.com/ertes/continue.git
+
+Library
+    Build-depends:
+        base              >= 4.5 && < 5,
+        bifunctors        >= 3.0 && < 4,
+        monad-control     >= 0.3 && < 1,
+        mtl               >= 2.0 && < 3,
+        semigroupoids     >= 3.0 && < 4,
+        transformers      >= 0.3 && < 1,
+        transformers-base >= 0.4 && < 1
+    Default-language: Haskell2010
+    Default-extensions:
+        FlexibleInstances
+        FunctionalDependencies
+        MultiParamTypeClasses
+        TypeFamilies
+    Other-extensions:
+        UndecidableInstances
+    GHC-Options: -W
+    Exposed-modules:
+        Control.Continue
+        Control.Continue.Class
+        Control.Continue.Types
+        Control.Continue.Utils
+
+-- Test-suite continue-test
+--     Type: exitcode-stdio-1.0
+--     Build-depends:
+--         base >= 4.5 && < 5,
+--         conduit,
+--         containers,
+--         continue,
+--         http-types,
+--         wai,
+--         warp
+--     Default-language: Haskell2010
+--     Default-extensions:
+--     GHC-Options: -threaded -rtsopts
+--     Hs-source-dirs: test
+--     Main-is: Main.hs
