diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c)2010, Sam Anklesaria
+
+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 Sam Anklesaria nor the names of other
+      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/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/WebCont.cabal b/WebCont.cabal
new file mode 100644
--- /dev/null
+++ b/WebCont.cabal
@@ -0,0 +1,61 @@
+Name:                WebCont
+
+-- The package version. See the Haskell package versioning policy
+-- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
+-- standards guiding when and how versions should be incremented.
+Version:             0.0.0
+
+-- A short (one-line) description of the package.
+Synopsis:            Continuation based web programming for Happstack
+
+-- A longer description of the package.
+-- Description:         
+
+-- URL for the project homepage or repository.
+Homepage:            http://patch-tag.com/r/salazar/webconts/snapshot/current/content/pretty
+
+-- The license under which the package is released.
+License:             BSD3
+
+-- The file containing the license text.
+License-file:        LICENSE
+
+-- The package author(s).
+Author:              Sam Anklesaria
+
+-- An email address to which users can send suggestions, bug reports,
+-- and patches.
+Maintainer:          amsay@amsay.net
+
+-- A copyright notice.
+-- Copyright:           
+
+Category:            Web
+
+Description:        WebCont allows continuation based web programming to be integrated with Happstack, allowing
+                    step based interfaces along with traditional handlers. It is based on <http://gist.github.com/260052>
+
+Build-type:          Simple
+
+-- Extra files to be distributed with the package, such as examples or
+-- a README.
+-- Extra-source-files:  
+
+-- Constraint on the version of Cabal needed to build this package.
+Cabal-version:       >=1.2
+
+
+Library
+  -- Modules exported by the library.
+  Exposed-modules:     WebCont
+  
+  -- Packages needed in order to build this package.
+  Build-depends:       happstack-server >= 0.5, happstack-state >= 0.5, happstack-util >= 0.5, mtl, concatenative >= 1, formlets < 1,
+                       utf8-string, containers, xhtml, applicative-extras, base >= 3 && < 5
+  
+  -- Modules not exported by this package.
+  -- Other-modules:       
+  
+  -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.
+  -- Build-tools:         
+  
diff --git a/WebCont.hs b/WebCont.hs
new file mode 100644
--- /dev/null
+++ b/WebCont.hs
@@ -0,0 +1,164 @@
+{-# LANGUAGE TypeSynonymInstances #-}
+{-| WebConts allow simple continuation based behavior in Happstack applications through the use of cookies
+    and an IntMap on the server mapping cookie names to continuations. 
+    It is based on the paste <http://gist.github.com/260052>. For the arc challenge:
+
+>    arc = do
+>        name <- doform' frm
+>        display $ samelink "click here"
+>        display $ "you said" ++ name
+
+    A more complicated example, creating a User datatype with a different page for each field:
+
+>   data User = User {age:: Int, name::String, dead::Bool} deriving (Show)
+>   makeUser = liftM3 User age name dead >>= (display . show) where
+>       age = doform' $ label "Age: " *> frm
+>       name = doform' $ label "Name: " *> frm
+>       dead = doform' $ label "Dead?: " *> frm
+
+    To run the continuations in Happstack, use 'runStateless' or 'runWithState', giving each continuation in a list
+    as a parameter, depending on whether you want MACID support enabled:
+
+>   runStateless nullConf [arc, makeUser] []
+
+-}
+module WebCont (
+    doform, doform', runWithState, runStateless, frm, display, samelink,
+    WebCont(..), Result(..), ContForm, DefaultForm, nullConf,
+) where
+import Happstack.Server.SimpleHTTP hiding (method)
+import Happstack.State hiding (dup)
+import Happstack.Util.Cron
+import Control.Monad
+import Control.Monad.Identity (Identity (..))
+import Control.Monad.Trans
+import Control.Monad.Reader
+import Control.Concurrent
+import Control.Exception hiding (catch)
+import Control.Concatenative
+import Control.Applicative
+import Control.Applicative.Error (Failing (..))
+import Text.Formlets
+import Text.XHtml.Strict.Formlets hiding (label)
+import Text.XHtml.Strict hiding (input, checkbox)
+import qualified Data.IntMap as Map
+import Data.IntMap (IntMap)
+import Data.Monoid
+import Data.ByteString.Lazy.UTF8 (toString)
+import qualified Happstack.Server.SimpleHTTP as H (ContentType(..))
+import qualified Text.Formlets as F (ContentType(..))
+
+data Result r a = Done a | Via r (WebCont r a) deriving Show
+
+-- | A WebCont is a function from 'Env' to a value of a,
+--   displaying a response of r. Both r and a must be
+--   Html for runnable continuations.
+newtype WebCont r a = WebCont {runWeb :: Env -> Result r a} deriving Show
+
+runWeb' :: Env -> (MVar Int, MVar ContTable) -> WebCont Html () -> ServerPartT IO Response
+runWeb' e t w = case runWeb w e of
+    Done _ -> expireCookie "cont" >> mzero
+    Via r w' -> serializeCont t w' >> ok (toResponse r)
+
+type ContForm a = XHtmlForm Identity a
+
+instance Monad (WebCont r) where
+    return = WebCont . const . Done
+    w >>= f = WebCont $ \e -> case (runWeb w e) of
+        Done a -> runWeb (f a) e
+        Via r w' -> Via r (w' >>= f)
+
+instance (Monoid r, Monoid a) => Monoid (WebCont r a) where
+    (WebCont f) `mappend` (WebCont g) = WebCont $ f &&. g >>@ c where
+        (Done _) `c` x@(Via _ _) = x
+        x@(Via _ _) `c` (Done _) = x
+        (Via v a) `c` (Via t b) = Via (v `mappend` t) (a `mappend` b) -- this instance seems flawed
+    mempty = WebCont . const . Done $ mempty
+
+-- | Lift a form into the WebCont monad using a function
+---  to modify its html, and a function to display errors
+doform :: (Html -> r) -> ([String] -> Html -> r) -> ContForm a -> WebCont r a
+doform l err f = WebCont . const $
+    Via (l (createForm [] f)) succPage where
+        succPage = WebCont $ dup >>. first parse >>@ formResult
+        parse env = x where (Identity x, _, _) = runFormState env f
+        formResult (Success a) _ = Done a
+        formResult (Failure faults) e = Via (err faults (createForm e f)) succPage
+        makeForm frm = form ! [method "POST"] << (frm +++ submit "submit" "submit")
+
+createForm :: Env -> ContForm a -> Html
+createForm env frm = form ! [method "POST"] << (xml +++ submit "submit" "Submit") where
+  (extractor, xml, endState) = runFormState env frm
+
+-- | Lift a form into the WebCont monad without embellishment, displaying errors inline
+doform' :: ContForm a -> WebCont Html a
+doform' = doform id $ curry (unlines **. id >>@ (+++))
+
+-- | Display a page, ignoring the value
+display :: HTML a => a -> WebCont Html ()
+display h = WebCont $ const $ Via (toHtml h) (return ())
+
+-- | Links to the same page, leading to the next step in a continuation
+samelink :: HTML a => a -> HotLink
+samelink a = hotlink "" (toHtml a)
+
+type ContTable = IntMap (WebCont Html ())
+
+runConts :: (MVar Int, MVar ContTable) -> ServerPartT IO Response
+runConts t = withDataFn (lookCookieValue "cont") $ \c-> do
+    w <- liftIO $ deserializeCont t c
+    case w of
+        Just w' -> do
+            d <- lookInputPairs
+            clearCont t c
+            runWeb' (maybe [] id d) t w'
+        Nothing -> mzero
+
+lookInputPairs :: ServerPartT IO (Maybe Env)
+lookInputPairs = getDataFn $ asks fst >>= (return . map f) where
+    f (k,Input v Nothing _) = (k,Left (toString v))
+    f (k,Input v (Just f) (H.ContentType t s p)) = (k,Right (File v f (F.ContentType t s p)))
+
+deserializeCont :: (MVar Int, MVar ContTable) -> String -> IO (Maybe (WebCont Html ()))
+deserializeCont (_,t) s = do
+    e <- readMVar t
+    let p = Map.lookup (read s :: Int) e
+    return p
+
+clearCont :: (MVar Int, MVar ContTable) -> String -> ServerPartT IO ()
+clearCont (_,t) s = liftIO (takeMVar t >>= (putMVar t . Map.delete (read s)))
+
+serializeCont :: (MVar Int, MVar ContTable) -> (WebCont Html ()) -> ServerPartT IO ()
+serializeCont (i,t) f = do
+    k <- liftIO $ takeMVar i
+    liftIO $ putMVar i (k+1)
+    liftIO $ takeMVar t >>= (putMVar t . Map.insert k f)
+    addCookie 600 (mkCookie "cont" (show k))
+
+-- | Entry point for the continuation server: sets up continuation table, MACID state,
+--   and a chron job to add a checkpoint daily
+runWithState :: (Methods a, Component a) => Conf -> Proxy a -> [WebCont Html ()] -> [ServerPartT IO Response] -> IO ()
+runWithState c p conts controller =
+    bracket (startSystemState p) (biM_ createCheckpoint shutdownSystem) $ \control->
+        do withThread (runStateless c conts controller) $ do
+           withThread (cron 86400 (createCheckpoint control)) $ waitForTermination
+        where withThread init action = bracket (forkIO $ init) (killThread) (const action)
+
+-- | Entry point for the continuation server: starts the server without MACID support
+runStateless :: Conf -> [WebCont Html ()] -> [ServerPartT IO Response] -> IO ()
+runStateless c conts controller = do
+    e <- newMVar Map.empty
+    counter <- newMVar (0 :: Int)
+    let env = (counter, e)
+    simpleHTTP c (runConts env `mplus` msum (map (runWeb' [] env) conts) `mplus` msum controller)
+
+-- | Defines a normal form style to use for a given type
+class DefaultForm i where frm :: Form Html Identity i
+instance DefaultForm String where frm = input Nothing
+instance DefaultForm Integer where frm = inputInteger Nothing
+instance DefaultForm Int where frm = fromInteger <$> (inputInteger Nothing)
+instance DefaultForm Bool where frm = checkbox Nothing
+instance (DefaultForm a, DefaultForm b) => DefaultForm (a,b) where 
+  frm = (,) <$> frm <*> frm
+instance HTML Integer where toHtml = toHtml . show
+instance Applicative Identity where pure = return; (<*>) = ap;
