diff --git a/Chatty/Commands.hs b/Chatty/Commands.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Commands.hs
@@ -0,0 +1,62 @@
+{-# LANGUAGE FlexibleInstances #-}
+
+module Chatty.Commands where
+
+import Chatty.Printer
+import Chatty.Scanner
+import Chatty.Interactor
+import Chatty.Finalizer
+import Chatty.Expansion
+import Control.Monad
+import Control.Monad.Trans.Class
+import Control.Monad.IO.Class
+import System.IO
+import System.Directory
+import System.Posix.Files
+
+cat :: (MonadScanner m, MonadPrinter m, MonadIO m,Functor m,MonadFinalizer m) => [String] -> m ()
+cat [] = mscanL >>= mprint
+cat [f] = cat [] .<. f
+cat (f:fs) = cat [f] >> cat fs
+
+tac :: (MonadFinalizer m,MonadScanner m, MonadPrinter m, MonadIO m,Functor m) => [String] -> m ()
+tac [] = mscanL >>= (mprint . unlines . reverse . lines)
+tac fs = cat fs .|. tac []
+
+tee :: (MonadScanner m, MonadPrinter m, MonadIO m, Functor m) => String -> m ()
+tee f = do
+  s <- mscanL
+  mprint s .>. f
+  mprint s
+
+echo :: (MonadPrinter m,MonadExpand m) => String => m ()
+echo = mprintLn <=< expand
+
+data WcMode = CountChars | CountLines | CountWords
+
+wc :: (MonadScanner m, MonadPrinter m, MonadIO m, Functor m) => WcMode -> m ()
+wc CountChars = mscanL >>= (mprint . show . length) >> mprint "\n"
+wc CountLines = mscanL >>= (mprint . show . length . lines) >> mprint "\n"
+wc CountWords = mscanL >>= (mprint . show . length . words) >> mprint "\n"
+
+cd :: MonadIO m => String -> m ()
+cd = liftIO . setCurrentDirectory
+
+pwd :: (MonadIO m,MonadPrinter m) => m ()
+pwd = liftIO getCurrentDirectory >>= mprintLn
+
+ls :: (MonadIO m,MonadPrinter m) => [String] -> m ()
+ls [] = liftIO (getDirectoryContents ".") >>= (mprint . unlines)
+ls [p] = do
+  fs <- liftIO $ getFileStatus p
+  when (isDirectory fs) $
+    liftIO (getDirectoryContents p) >>= (mprint . unlines)
+  when (isRegularFile fs) $
+    mprintLn p
+ls (p:ps) = ls [p] >> ls ps
+  
+head :: (MonadScanner m,MonadPrinter m,MonadIO m,Functor m) => Int -> m ()
+head n = mscanL >>= (mprint . unlines . take n . lines)
+
+tail :: (MonadScanner m,MonadPrinter m,MonadIO m,Functor m) => Int -> m ()
+tail n = mscanL >>= (mprint . unlines . reverse . take n . reverse . lines)
diff --git a/Chatty/Expansion.hs b/Chatty/Expansion.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Expansion.hs
@@ -0,0 +1,88 @@
+{-# LANGUAGE ExistentialQuantification, RankNTypes, Rank2Types #-}
+
+module Chatty.Expansion where
+
+import Data.List
+import Control.Arrow
+import Control.Monad
+import Control.Monad.IO.Class
+import Control.Monad.Trans.Class
+import System.Environment hiding (getEnv)
+import System.Posix.Env (getEnv, setEnv)
+--import System.SetEnv
+
+data EnvVar = NotSet | Literal String | forall a.Show a => Scalar a | Array [EnvVar]
+
+instance Show EnvVar where
+  show (Scalar s) = show s
+  show (Literal s) = s
+  show (Array ps) = unwords $ map show ps
+  show NotSet = ""
+
+newtype ExpanderT m a = Expander {
+    runExpanderT :: [(String,EnvVar)] -> m (a,[(String,EnvVar)])
+  }
+
+instance Monad m => Monad (ExpanderT m) where
+  return a = Expander $ \vs -> return (a,vs)
+  (Expander e) >>= f = Expander $ \vs -> do (a,vs') <- e vs; runExpanderT (f a) vs'
+
+instance MonadTrans ExpanderT where
+  lift m = Expander $ \vs -> do a <- m; return (a,vs)
+
+instance MonadIO m => MonadIO (ExpanderT m) where
+  liftIO = lift . liftIO
+
+instance Monad m => Functor (ExpanderT m) where
+  fmap f a = Expander $ \vs -> do (a',vs') <- runExpanderT a vs; return (f a',vs')
+
+localEnvironment :: Functor m => ExpanderT m a -> m a
+localEnvironment m = fmap fst $ runExpanderT m []
+
+forkEnvironment :: (Functor m,Monad m,MonadIO m) => ExpanderT m a -> m a
+forkEnvironment m = do
+  es <- liftIO getEnvironment
+  fmap fst $ runExpanderT m $ fmap (second Literal) es
+
+exportAll :: (Monad m,MonadIO m) => ExpanderT m ()
+exportAll = Expander $ \vs -> do
+  liftIO $ forM_ vs $ \(k,v) -> setEnv k (show v) True
+  return ((),vs)
+
+class Monad ee => ExpanderEnv ee where
+  mgetv :: String -> ee EnvVar
+  mputv :: String -> EnvVar -> ee ()
+
+instance Monad m => ExpanderEnv (ExpanderT m) where
+  mgetv s = Expander $ \vs -> return $
+    case filter ((==s).fst) vs of
+      [] -> (NotSet,vs)
+      ((_,v):_) -> (v,vs)
+  mputv k v = Expander $ \vs -> return ((),(k,v):filter ((/=k).fst) vs)
+
+instance ExpanderEnv IO where
+  mgetv = fmap (\v -> case v of Nothing -> NotSet; Just v' -> Literal v') . getEnv
+  mputv k v = setEnv k (show v) True
+
+class Monad e => MonadExpand e where
+  expand :: String -> e String
+
+instance MonadExpand IO where
+  expand = expandVars
+
+instance Monad m => MonadExpand (ExpanderT m) where
+  expand = expandVars
+
+expandVars :: (Monad m,Functor m,ExpanderEnv m) => String -> m String
+expandVars [] = return []
+expandVars ('$':ss) =
+  let nm = takeWhile isAnum ss
+      rm = dropWhile isAnum ss
+  in do
+    v <- fmap show $ mgetv nm
+    r <- expandVars rm
+    return (v++r)
+expandVars (s:ss) = do ss' <- expandVars ss; return (s:ss')
+
+isAnum = (`elem` (['a'..'z']++['A'..'Z']++"_"++['0'..'9']))
+
diff --git a/Chatty/Extended/ANSI.hs b/Chatty/Extended/ANSI.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Extended/ANSI.hs
@@ -0,0 +1,45 @@
+module Chatty.Extended.ANSI where
+
+import qualified System.Console.ANSI as A
+import Control.Monad.Trans.Class
+import Control.Monad.IO.Class
+import Chatty.Printer
+import Chatty.Extended.Printer
+
+newtype AnsiPrinterT m a = AnsiPrinter { runAnsiPrinterT :: Colour -> m a }
+
+instance Monad m => Monad (AnsiPrinterT m) where
+  return a = AnsiPrinter $ \s -> return a
+  (AnsiPrinter p) >>= f = AnsiPrinter $ \s -> do a <- p s; runAnsiPrinterT (f a) s
+
+instance MonadTrans AnsiPrinterT where
+  lift m = AnsiPrinter $ return m
+
+instance Monad m => Functor (AnsiPrinterT m) where
+  fmap f a = AnsiPrinter $ \s -> do a' <- runAnsiPrinterT a s; return (f a')
+
+instance MonadIO m => MonadIO (AnsiPrinterT m) where
+  liftIO = lift . liftIO
+
+instance MonadPrinter m => MonadPrinter (AnsiPrinterT m) where
+  mprint = lift . mprint
+  mnoecho = lift . mnoecho
+  mflush = lift mflush
+
+instance MonadPrinter m => ExtendedPrinter (AnsiPrinterT m) where
+  estart c = AnsiPrinter $ \c1 -> mprint $ A.setSGRCode [A.SetColor A.Foreground (mkColourInt c) (mkColourCode c)]
+  efin = AnsiPrinter $ \c1 -> mprint $ A.setSGRCode [A.SetColor A.Foreground (mkColourInt c1) (mkColourCode c1)]
+
+mkColourInt (Dull _) = A.Dull
+mkColourInt (Vivid _) = A.Vivid
+
+mkColourCode (Dull c) = mkColourCode (Vivid c)
+mkColourCode (Vivid c) = case c of
+  Green -> A.Green
+  Red -> A.Red
+  Yellow -> A.Yellow
+  Blue -> A.Blue
+  Black -> A.Black
+  White -> A.White
+  Cyan -> A.Cyan
+  Magenta -> A.Magenta
diff --git a/Chatty/Extended/HTML.hs b/Chatty/Extended/HTML.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Extended/HTML.hs
@@ -0,0 +1,54 @@
+module Chatty.Extended.HTML where
+
+import Chatty.Printer
+import Chatty.Extended.Printer
+import Control.Monad.Trans.Class
+import Control.Monad.IO.Class
+
+newtype HtmlPrinterT m a = HtmlPrinter { runHtmlPrinterT :: m a }
+
+instance Monad m => Monad (HtmlPrinterT m) where
+  return = HtmlPrinter . return
+  (HtmlPrinter p) >>= f = HtmlPrinter $ do p' <- p; runHtmlPrinterT (f p')
+
+instance MonadTrans HtmlPrinterT where
+  lift = HtmlPrinter
+
+instance Functor m => Functor (HtmlPrinterT m) where
+  fmap f (HtmlPrinter p) = HtmlPrinter $ fmap f p
+
+instance MonadIO m => MonadIO (HtmlPrinterT m) where
+  liftIO = lift . liftIO
+
+instance MonadPrinter m => MonadPrinter (HtmlPrinterT m) where
+  mprint = lift . mprint . concatMap maskHtml
+  mnoecho = lift . mnoecho . concatMap maskHtml
+  mflush = lift mflush
+
+instance MonadPrinter m => ExtendedPrinter (HtmlPrinterT m) where
+  estart c =  lift $ mprint $ concat ["<span style=\"color: #", hexColour c, ";\">"]
+  efin = lift $ mprint "</span>"
+
+maskHtml :: Char -> String
+maskHtml '&' = "&amp;"
+maskHtml '<' = "&lt;"
+maskHtml '>' = "&gt;"
+maskHtml ' ' = "&nbsp;"
+maskHtml c = [c]
+
+hexColour (Dull Green) = "004400"
+hexColour (Vivid Green) = "00FF00"
+hexColour (Dull Red) = "440000"
+hexColour (Vivid Red) = "FF0000"
+hexColour (Dull Yellow) = "444400"
+hexColour (Vivid Yellow) = "FFFF00"
+hexColour (Dull Blue) = "000044"
+hexColour (Vivid Blue) = "0000FF"
+hexColour (Dull Black) = "000000"
+hexColour (Vivid Black) = "444444"
+hexColour (Dull White) = "888888"
+hexColour (Vivid White) = "FFFFFF"
+hexColour (Dull Cyan) = "004444"
+hexColour (Vivid Cyan) = "00FFFF"
+hexColour (Dull Magenta) = "440044"
+hexColour (Vivid Magenta) = "FF00FF"
diff --git a/Chatty/Extended/Printer.hs b/Chatty/Extended/Printer.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Extended/Printer.hs
@@ -0,0 +1,17 @@
+module Chatty.Extended.Printer where
+
+import Chatty.Printer
+
+data Tone = Green | Red | Yellow | Blue | Black | White | Cyan | Magenta
+data Colour = Dull Tone | Vivid Tone
+
+class MonadPrinter m => ExtendedPrinter m where
+  ebracket :: Colour -> m a -> m a
+  ebracket c m = do estart c; a <- m; efin; return a
+  eprint :: Colour -> String -> m ()
+  eprint c = ebracket c . mprint
+  eprintLn :: Colour -> String -> m ()
+  eprintLn c s = eprint c s >> mprintLn ""
+  estart :: Colour -> m ()
+  efin :: m ()
+
diff --git a/Chatty/Finalizer.hs b/Chatty/Finalizer.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Finalizer.hs
@@ -0,0 +1,37 @@
+module Chatty.Finalizer where
+
+import Control.Monad
+import Control.Monad.IO.Class
+import Control.Monad.Trans.Class
+import System.IO
+
+class Monad m => MonadFinalizer m where
+  mqfh :: Handle -> m ()
+  mqfhs :: [Handle] -> m ()
+  mqfhs = foldr ((>>) . mqfh) (return ())
+  mfin :: m ()
+
+newtype HandleCloserT m a = HandleCloser { runHandleCloserT :: [Handle] -> m (a,[Handle]) }
+
+instance Monad m => Monad (HandleCloserT m) where
+  return a = HandleCloser $ \hs -> return (a,hs)
+  (HandleCloser m) >>= f = HandleCloser $ \hs -> do (a,hs') <- m hs; runHandleCloserT (f a) hs'
+
+instance MonadTrans HandleCloserT where
+  lift m = HandleCloser $ \hs -> do a <- m; return (a,hs)
+
+instance Monad m => Functor (HandleCloserT m) where
+  fmap f a = HandleCloser $ \hs -> do (a',hs') <- runHandleCloserT a hs; return (f a',hs')
+
+instance MonadIO m => MonadIO (HandleCloserT m) where
+  liftIO = lift . liftIO
+
+instance MonadIO m => MonadFinalizer (HandleCloserT m) where
+  mqfh h = HandleCloser $ \hs -> return ((),h:hs)
+  mfin = HandleCloser $ \hs -> do
+    sequence_ $ fmap (liftIO.hClose) hs
+    return ((),[])
+
+withLazyIO :: (MonadIO m,Functor m) => HandleCloserT m a -> m a
+withLazyIO m = fmap fst $ runHandleCloserT (do a <- m; mfin; return a) []
+
diff --git a/Chatty/Interactor.hs b/Chatty/Interactor.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Interactor.hs
@@ -0,0 +1,57 @@
+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies, TemplateHaskell #-}
+
+module Chatty.Interactor where
+
+import Chatty.Printer
+import Chatty.Scanner
+import Chatty.Finalizer
+import Chatty.Expansion
+import Chatty.Extended.HTML
+import Chatty.Extended.ANSI
+import Chatty.Misc
+import Chatty.Interactor.Templates
+import Chatty.Spawn
+import Chatty.Spawn.Overlay
+import Control.Monad
+import Control.Monad.Trans.Class
+import Control.Monad.Identity
+
+mkInteractor ''RecorderT mkScanner mkFinalizer mkExpander mkSpawn mkRandom mkClock
+mkInteractor ''DeafT mkScanner mkFinalizer mkExpander mkSpawn mkRandom mkClock
+mkInteractor ''OutRedirT mkScanner mkFinalizer mkExpander mkSpawn mkRandom mkClock
+mkInteractor ''HandleCloserT mkScanner mkPrinter mkExpander mkSpawn mkRandom mkClock
+mkInteractor ''ExpanderT mkScanner mkPrinter mkFinalizer mkSpawn mkRandom mkClock
+mkInteractor ''HereStringT mkPrinter mkExpander mkSpawn mkRandom mkClock
+mkInteractor ''QuietT mkPrinter mkExpander mkSpawn mkRandom mkClock
+mkInteractor ''InRedirT mkPrinter mkExpander mkSpawn mkRandom mkClock
+mkInteractor ''SpawnOverlayT mkPrinter mkScanner mkExpander mkFinalizer mkRandom mkClock
+mkInteractor ''HtmlPrinterT mkScanner mkExpander mkFinalizer mkSpawn mkRandom mkClock
+mkInteractor ''AnsiPrinterT mkScanner mkExpander mkFinalizer mkSpawn mkRandom mkClock
+
+type IgnorantT m = QuietT (DeafT m)
+type Ignorant = IgnorantT Identity
+type ChattyT m = HereStringT (RecorderT m)
+type Chatty = ChattyT Identity
+
+runIgnorantT :: Monad m => IgnorantT m a -> m a
+runIgnorantT = runDeafT . runQuietT
+
+runIgnorant :: Ignorant a -> a
+runIgnorant = runIdentity . runIgnorantT
+
+runChattyT :: (Monad m,Functor m) => ChattyT m a -> String -> m (a,String,Replayable)
+runChattyT m input = fmap (\((a,u),r) -> (a,u,r)) $ runRecorderT $ runHereStringT m input
+
+runChatty :: Chatty a -> String -> (a,String,Replayable)
+runChatty m = runIdentity . runChattyT m
+
+-- Shell-like syntax
+(.|.) :: (Monad m,Functor m) => RecorderT m a -> HereStringT m b -> m b
+m1 .|. m2 = do
+  (_,r) <- runRecorderT m1
+  fmap fst $ runHereStringT m2 (replay r)
+
+(.<$.) :: (Functor m,Monad m) => (String -> m b) -> RecorderT m a -> m b
+m1 .<$. m2 = do
+  (_,r) <- runRecorderT m2
+  m1 $ replay r
diff --git a/Chatty/Interactor/Templates.hs b/Chatty/Interactor/Templates.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Interactor/Templates.hs
@@ -0,0 +1,86 @@
+{-# LANGUAGE TemplateHaskell, QuasiQuotes, FlexibleInstances #-}
+
+module Chatty.Interactor.Templates (mkScanner, mkPrinter, mkFinalizer, mkExpander,mkInteractor,mkSpawn,mkRandom,mkClock) where
+
+import Chatty.Scanner
+import Chatty.Printer
+import Chatty.Finalizer
+import Chatty.Expansion
+import Chatty.Spawn
+import Chatty.Extended.Printer
+import Control.Monad
+import Control.Monad.Trans
+import Language.Haskell.TH
+import Chatty.Templates
+import Chatty.Misc
+
+mkScanner s = [d|
+    instance MonadScanner m => MonadScanner ($sx m) where
+      mscan1 = lift mscan1
+      mscanL = lift mscanL
+      mscannable = lift mscannable
+      mscanh = lift mscanh
+      mready = lift mready
+  |]
+  where sx = strToType s
+
+mkPrinter s = [d|
+    instance MonadPrinter m => MonadPrinter ($sx m) where
+      mprint = lift . mprint
+      mnoecho = lift . mnoecho
+      mflush = lift mflush
+    instance ExtendedPrinter m => ExtendedPrinter ($sx m) where
+      estart = lift . estart
+      efin = lift efin
+      eprint c = lift . eprint c
+      eprintLn c = lift . eprintLn c
+  |]             
+  where sx = strToType s
+
+mkFinalizer s = [d|
+    instance MonadFinalizer m => MonadFinalizer ($sx m) where
+      mqfh = lift . mqfh
+      mfin = lift mfin
+  |]               
+  where sx = strToType s
+
+mkExpander s = [d|
+    instance MonadExpand m => MonadExpand ($sx m) where
+      expand = lift . expand
+    instance ExpanderEnv m => ExpanderEnv ($sx m) where
+      mgetv = lift . mgetv
+      mputv k v = lift $ mputv k v
+  |]
+  where sx = strToType s
+
+mkSpawn s = [d|
+    instance MonadSpawn m => MonadSpawn ($sx m) where
+      mspw pn as si = lift $ mspw pn as si
+      mah = lift . mah
+  |]
+  where sx = strToType s
+
+mkRandom s = [d|
+    instance MonadRandom m => MonadRandom ($sx m) where
+      mrandom = lift mrandom
+      mrandomR = lift . mrandomR
+  |]            
+  where sx = strToType s
+
+mkClock s = [d|
+    instance MonadClock m => MonadClock ($sx m) where
+      mutctime = lift mutctime
+      mgetstamp = lift mgetstamp
+  |]           
+  where sx = strToType s
+
+class InteractorMaker i where
+  mkInteractor' :: Name -> Q [Dec] -> i
+  mkInteractor :: Name -> i
+  mkInteractor n = mkInteractor' n [d| |]
+
+instance InteractorMaker (Q [Dec]) where
+  mkInteractor' _ = id
+
+instance InteractorMaker i => InteractorMaker ((Name -> Q [Dec]) -> i) where
+  mkInteractor' n qs qf = mkInteractor' n (do q1 <- qs; q2 <- qf n; return (q1++q2))
diff --git a/Chatty/Misc.hs b/Chatty/Misc.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Misc.hs
@@ -0,0 +1,21 @@
+module Chatty.Misc where
+
+import Data.Time.Clock
+import System.Random
+
+class (Functor m,Monad m) => MonadClock m where
+  mutctime :: m UTCTime
+  mgetstamp :: m DiffTime
+  mgetstamp = fmap utctDayTime mutctime
+
+instance MonadClock IO where
+  mutctime = getCurrentTime
+
+class Monad m => MonadRandom m where
+  mrandom :: Random r => m r
+  mrandomR :: Random r => (r,r) -> m r
+
+instance MonadRandom IO where
+  mrandom = randomIO
+  mrandomR rs = randomRIO rs
+
diff --git a/Chatty/Printer.hs b/Chatty/Printer.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Printer.hs
@@ -0,0 +1,146 @@
+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies #-}
+
+module Chatty.Printer where
+
+import Control.Arrow
+import Control.Monad
+import Control.Monad.State
+import Control.Monad.Identity
+import System.IO
+
+-- Class Definition for MonadPrinter
+class Monad m => MonadPrinter m where
+  mprint :: String -> m ()
+  mnoecho :: String -> m ()
+  mnoecho = mprint
+  mflush :: m ()
+  mflush = return ()
+
+-- MonadPrinter instance for: IO
+instance MonadPrinter IO where
+  mprint = putStr
+  mnoecho _ = return ()
+  mflush = hFlush stdout
+
+-- MonadPrinter instance for: StateT String m
+instance Monad m => MonadPrinter (StateT String m) where
+  mprint s = modify (++s)
+
+-- Definition of DeafT + instances
+-- DeafT discards all output (much like >/dev/null in the shell)
+newtype DeafT m a = Deaf { runDeafT :: m a }
+
+instance Monad m => Monad (DeafT m) where
+  return = Deaf . return
+  (Deaf d) >>= f = Deaf $ do d' <- d; runDeafT (f d')
+
+instance MonadTrans DeafT where
+  lift = Deaf
+
+instance Functor m => Functor (DeafT m) where
+  fmap f (Deaf a) = Deaf $ fmap f a
+
+instance MonadIO m => MonadIO (DeafT m) where
+  liftIO = lift . liftIO
+
+instance Monad m => MonadPrinter (DeafT m) where
+  mprint _ = return ()
+
+-- Definition of OutRedirT + instances
+-- OutRedirT redirects all output to a given handle (much like >filename in the shell)
+newtype OutRedirT m a = OutRedir { runOutRedirT' :: Handle -> m (a,Handle) }
+type OutRedir = OutRedirT IO
+
+instance Monad m => Monad (OutRedirT m) where
+  return a = OutRedir $ \h -> return (a,h)
+  (OutRedir r) >>= f = OutRedir $ \h -> do (a,h') <- r h; runOutRedirT' (f a) h'
+
+instance MonadTrans OutRedirT where
+  lift m = OutRedir $ \h -> do a <- m; return (a,h)
+
+instance MonadIO m => MonadIO (OutRedirT m) where
+  liftIO = lift . liftIO
+
+instance MonadIO m => MonadPrinter (OutRedirT m) where
+  mprint s = OutRedir $ \h -> do liftIO $ hPutStr h s; return ((),h)
+  mflush = OutRedir $ \h -> do liftIO $ hFlush h; return ((),h)
+
+instance Monad m => Functor (OutRedirT m) where
+  fmap f a = OutRedir $ \h -> do (a',h') <- runOutRedirT' a h; return (f a',h')
+
+runOutRedirT :: Functor m => OutRedirT m a -> Handle -> m a
+runOutRedirT m h = fmap fst $ runOutRedirT' m h
+
+runOutRedir :: OutRedir a -> Handle -> IO a
+runOutRedir = runOutRedirT
+
+runOutRedirFT :: (Functor m,MonadIO m) => OutRedirT m a -> FilePath -> IOMode -> m a
+runOutRedirFT m fp md
+  | md `elem` [AppendMode,WriteMode] = do
+    h <- liftIO $ openFile fp md
+    a <- runOutRedirT m h
+    liftIO $ hClose h
+    return a
+  | otherwise = error "runOutRedirFT does only accept AppendMode or WriteMode."
+
+runOutRedirF :: OutRedir a -> FilePath -> IOMode -> IO a
+runOutRedirF = runOutRedirFT
+
+-- Definition of RecorderT + instances
+-- RecorderT catches all output (much like VAR=$(...) in the shell)
+newtype RecorderT m a = Recorder { runRecorderT' :: [String] -> m (a,[String]) }
+type Recorder = RecorderT Identity
+
+instance Monad m => Monad (RecorderT m) where
+  return a = Recorder $ \s -> return (a,s)
+  (Recorder r) >>= f = Recorder $ \s -> do (a,s') <- r s; runRecorderT' (f a) s'
+
+instance MonadTrans RecorderT where
+  lift m = Recorder $ \s -> do a <- m; return (a,s)
+
+instance Monad m => MonadPrinter (RecorderT m) where
+  mprint s = Recorder $ \s' -> return ((),s:s')
+
+instance Monad m => Functor (RecorderT m) where
+  fmap f a = Recorder $ \s -> do (a',s') <- runRecorderT' a s; return (f a',s')
+
+instance MonadIO m => MonadIO (RecorderT m) where
+  liftIO = lift . liftIO
+
+-- Helper methods for RecorderT
+newtype Replayable = Replayable [String]
+instance Show Replayable where show r = show ((\(Replayable x) -> length x) r) ++ ":" ++ show (replay r)
+
+replayM :: Monad m => m Replayable -> m String
+replayM r = do (Replayable r') <- r; return (concat $ reverse r')
+
+replay :: Replayable -> String
+replay (Replayable r) = concat $ reverse r
+
+replay_ :: Monad m => RecorderT m String
+replay_ = Recorder $ \s -> return (concat $ reverse s,s)
+
+runRecorder :: Recorder a -> (a,Replayable)
+runRecorder = second Replayable . runIdentity . flip runRecorderT' []
+
+runRecorderT :: (Functor m,Monad m) => RecorderT m a -> m (a,Replayable)
+runRecorderT = fmap (second Replayable) . flip runRecorderT' []
+
+-- Line-terminating alternative to mprint
+mprintLn :: MonadPrinter m => String -> m ()
+mprintLn = mprint . (++"\n")
+
+-- Shell-like syntax
+data DiscardO = DiscardO
+data RecordO = RecordO
+class RedirectionTarget t mt a r | t -> mt, t a -> r where
+  (.>.) :: (Functor m,MonadIO m,MonadPrinter (mt m)) => mt m a -> t -> m r
+  (.>>.) :: (Functor m,MonadIO m,MonadPrinter (mt m)) => mt m a -> t -> m r
+  (.>>.) = (.>.)
+instance RedirectionTarget DiscardO DeafT a a where
+  m .>. _ = runDeafT m
+instance RedirectionTarget RecordO RecorderT a (a,Replayable) where
+  m .>. _ = runRecorderT m
+instance RedirectionTarget FilePath OutRedirT a a where
+  m .>. fp = runOutRedirFT m fp WriteMode
+  m .>>. fp = runOutRedirFT m fp AppendMode
diff --git a/Chatty/Scanner.hs b/Chatty/Scanner.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Scanner.hs
@@ -0,0 +1,168 @@
+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies #-}
+
+module Chatty.Scanner where
+
+import Chatty.Finalizer
+import Control.Monad
+import Control.Monad.State
+import Control.Monad.Identity
+import Control.Monad.Trans.Class
+import System.IO
+
+-- Class Definition of MonadScanner
+class Monad m => MonadScanner m where
+  mscan1 :: m Char
+  mscanL :: m String
+  mscannable :: m Bool
+  mscanh :: m (Maybe Handle)
+  mscanh = return Nothing
+  mready :: m Bool
+
+-- MonadScanner instance for: IO
+instance MonadScanner IO where
+  mscan1 = getChar
+  mscanL = getContents
+  mscannable = fmap not isEOF
+  mscanh = return $ Just stdin
+  mready = hReady stdin
+
+-- MonadScanner instance for: StateT String
+instance Monad m => MonadScanner (StateT String m) where
+  mscan1 = do
+    c <- gets head
+    modify tail
+    return c
+  mscanL = do
+    s <- get
+    put []
+    return s
+  mscannable = gets (not.null)
+  mready = return True
+
+-- Definition of HereStringT + instances
+-- HereStringT holds a given string and uses it as input for the function
+-- (much like here-strings in the shell)
+newtype HereStringT m a = HereString { runHereStringT :: String -> m (a,String) }
+
+instance Monad m => Monad (HereStringT m) where
+  return a = HereString $ \s -> return (a,s)
+  (HereString h) >>= f = HereString $ \s -> do (a,s') <- h s; runHereStringT (f a) s'
+
+instance MonadTrans HereStringT where
+  lift m = HereString $ \s -> do a <- m; return (a,s)
+
+instance Monad m => Functor (HereStringT m) where
+  fmap f a = HereString $ \s -> do (a',s') <- runHereStringT a s; return (f a',s')
+
+instance Monad m => MonadScanner (HereStringT m) where
+  mscan1 = HereString $ \(s:ss) -> return (s,ss)
+  mscanL = HereString $ \s -> return (s,[])
+  mscannable = HereString $ \s -> return (not $ null s,s)
+  mready = return True
+
+instance MonadIO m => MonadIO (HereStringT m) where
+  liftIO = lift . liftIO
+
+instance MonadFinalizer m => MonadFinalizer (HereStringT m) where
+  mqfh = lift . mqfh
+  mfin = lift mfin
+
+-- Definition of QuietT + instances
+-- QuietT does not convey any input (much like </dev/null in the shell)
+newtype QuietT m a = Quiet { runQuietT :: m a }
+
+instance Monad m => Monad (QuietT m) where
+  return = Quiet . return
+  (Quiet q) >>= f = Quiet $ do q' <- q; runQuietT (f q')
+
+instance MonadTrans QuietT where
+  lift = Quiet
+
+instance Monad m => MonadScanner (QuietT m) where
+  mscan1 = return undefined
+  mscanL = return []
+  mscannable = return False
+  mready = return False
+
+instance Functor m => Functor (QuietT m) where
+  fmap f (Quiet a) = Quiet $ fmap f a
+
+-- Definition of InRedirT + instances
+-- InRedirT redirects all input to a given handle (much like <filename in the shell)
+newtype InRedirT m a = InRedir { runInRedirT' :: Handle -> m (a,Handle) }
+type InRedir = InRedirT (HandleCloserT IO)
+
+instance Monad m => Monad (InRedirT m) where
+  return a = InRedir $ \h -> return (a,h)
+  (InRedir r) >>= f = InRedir $ \h -> do (a,h') <- r h; runInRedirT' (f a) h'
+
+instance MonadTrans InRedirT where
+  lift m = InRedir $ \h -> do a <- m; return (a,h)
+
+instance MonadIO m => MonadIO (InRedirT m) where
+  liftIO = lift . liftIO
+
+instance MonadIO m => MonadScanner (InRedirT m) where
+  mscan1 = InRedir $ \h -> do c <- liftIO $ hGetChar h; return (c,h)
+  mscanL = InRedir $ \h -> do s <- liftIO $ hGetContents h; return (s,h)
+  mscannable = InRedir $ \h -> do b <- liftIO $ hIsEOF h; return (b,h)
+  mscanh = InRedir $ \h -> return (Just h,h)
+  mready = InRedir $ \h -> do r <- liftIO $ hReady h; return (r,h)
+
+instance Monad m => Functor (InRedirT m) where
+  fmap f a = InRedir $ \h -> do (a',h') <- runInRedirT' a h; return (f a',h')
+
+instance MonadFinalizer m => MonadFinalizer (InRedirT m) where
+  mqfh = lift . mqfh
+  mfin = lift mfin
+
+runInRedirT :: Functor m => InRedirT m a -> Handle -> m a
+runInRedirT m h = fmap fst $ runInRedirT' m h
+
+runInRedir :: InRedir a -> Handle -> IO a
+runInRedir m h = withLazyIO $ runInRedirT m h
+
+runInRedirFT :: (Functor m,MonadIO m,MonadFinalizer m) => InRedirT m a -> FilePath -> m a
+runInRedirFT m fp = do
+  h <- liftIO $ openFile fp ReadMode
+  a <- runInRedirT m h
+  mqfh h
+  --liftIO $ hClose h
+  return a
+
+runInRedirF :: InRedir a -> FilePath -> IO a
+runInRedirF m fp = withLazyIO $ runInRedirFT m fp
+
+-- Line-scanning alternative to mscan1/L
+mscanLn :: MonadScanner m => m String
+mscanLn = do
+  h <- mscan1
+  if h == '\n' then return ""
+               else do
+                 hs <- mscanLn
+                 return (h:hs)
+
+-- Scan a fixed number of chars
+mscanN :: MonadScanner m => Int -> m String
+mscanN n
+  | n > 0 = do
+    b <- mscannable
+    if not b then return []
+             else do
+               h <- mscan1
+               hs <- mscanN (n-1)
+               return (h:hs)
+  | otherwise = return []
+
+-- Shell-like syntax
+data EmptyI = EmptyI
+class RedirectionSource t mt a r | t -> mt, t a -> r where
+  (.<.) :: (MonadFinalizer m,Functor m,MonadIO m,MonadScanner (mt m)) => mt m a -> t -> m a
+instance RedirectionSource EmptyI QuietT a a where
+  m .<. _ = runQuietT m
+instance RedirectionSource FilePath InRedirT a a where
+  m .<. fp = runInRedirFT m fp
+class RedirectionHeredoc t mt a r | t -> mt, t a -> r where
+  (.<<.) :: (Functor m,MonadScanner (mt m)) => mt m a -> t -> m a
+instance RedirectionHeredoc String HereStringT a a where
+  m .<<. str = fmap fst $ runHereStringT m str
diff --git a/Chatty/Spawn.hs b/Chatty/Spawn.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Spawn.hs
@@ -0,0 +1,48 @@
+module Chatty.Spawn where
+
+import Chatty.Finalizer
+import Chatty.Printer
+import Chatty.Scanner
+import Control.Monad.IO.Class
+import System.Exit
+import System.IO
+import qualified System.Process as P
+
+class Monad m => MonadSpawn m where
+  mspw :: String -> [String] -> Either Handle String -> m (Int,String,[Handle])
+  mah :: String -> m Bool
+
+instance MonadSpawn IO where
+  mspw pn as (Left h) = do
+    (_, Just hout, _, ph) <- P.createProcess (P.proc pn as){
+      P.std_in = P.UseHandle h,
+      P.std_out = P.CreatePipe }
+    so <- hGetContents hout
+    ec <- P.waitForProcess ph
+    return (case ec of
+               ExitSuccess -> 0
+               ExitFailure i -> i,
+            so, [hout])
+  mspw pn as (Right si) = do
+    (ec,so,_) <- P.readProcessWithExitCode pn as si
+    return (case ec of
+               ExitSuccess -> 0
+               ExitFailure i -> i,
+            so, [])
+  mah = return $ return True
+
+spawn :: (MonadFinalizer m,MonadScanner m,MonadPrinter m, MonadSpawn m,Functor m) => String -> [String] -> m Int
+spawn fn as = do
+  ah <- mah fn
+  mscanh >>= \h' -> case if ah then h' else Nothing of
+    Nothing -> do
+      si <- mscanL
+      (i,so,hs) <- mspw fn as (Right si)
+      mprint so
+      mqfhs hs
+      return i
+    Just h -> do
+      (i,so,hs) <- mspw fn as (Left h)
+      mprint so
+      mqfhs hs
+      return i
diff --git a/Chatty/Spawn/Builtins.hs b/Chatty/Spawn/Builtins.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Spawn/Builtins.hs
@@ -0,0 +1,12 @@
+module Chatty.Spawn.Builtins (withBuiltins) where
+
+import Chatty.Spawn
+import Chatty.Spawn.Overlay
+
+withBuiltins :: (Functor m, MonadSpawn m) => SpawnOverlayT m a -> m a
+withBuiltins m = fmap fst $ runSpawnOverlayT m builtins
+
+builtins :: MonadSpawn m => [(String,[String] -> String -> m (Int,String))]
+builtins =
+  ("cat", \_ si -> return (0,si)):
+  []
diff --git a/Chatty/Spawn/Overlay.hs b/Chatty/Spawn/Overlay.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Spawn/Overlay.hs
@@ -0,0 +1,39 @@
+module Chatty.Spawn.Overlay where
+
+import Chatty.Spawn
+import Control.Monad.Trans.Class
+import Control.Monad.IO.Class
+import System.IO
+
+newtype SpawnOverlayT m a = SpawnOverlay { runSpawnOverlayT :: [(String,[String] -> String -> m (Int,String))] -> m (a,[(String,[String] -> String -> m (Int,String))]) }
+
+instance Monad m => Monad (SpawnOverlayT m) where
+  return a = SpawnOverlay $ \o -> return (a,o)
+  (SpawnOverlay o) >>= f = SpawnOverlay $ \s -> do (a,s') <- o s; runSpawnOverlayT (f a) s'
+
+instance MonadTrans SpawnOverlayT where
+  lift m = SpawnOverlay $ \s -> do a <- m; return (a,s)
+
+instance MonadIO m => MonadIO (SpawnOverlayT m) where
+  liftIO = lift . liftIO
+
+instance Monad m => Functor (SpawnOverlayT m) where
+  fmap f a = SpawnOverlay $ \s -> do (a',s') <- runSpawnOverlayT a s; return (f a',s')
+
+instance MonadSpawn m => MonadSpawn (SpawnOverlayT m) where
+  mspw pn as (Right si) = SpawnOverlay $ \s ->
+    case pn `elem` (map fst s) of
+      True -> let c = snd $ head $ filter ((==pn).fst) s
+              in do
+                (r,so) <- c as si
+                return ((r,so,[]),s)
+      False -> do
+                r <- mspw pn as (Right si)
+                return (r,s)
+  mspw pn as (Left h) = lift $ mspw pn as (Left h)
+  mah pn = SpawnOverlay $ \s ->
+    case pn `elem` (map fst s) of
+      True -> return (False,s)
+      False -> do
+        ah <- mah pn
+        return (ah,s)
diff --git a/Chatty/Templates.hs b/Chatty/Templates.hs
new file mode 100644
--- /dev/null
+++ b/Chatty/Templates.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE FlexibleInstances #-}
+
+module Chatty.Templates where
+
+import Language.Haskell.TH
+
+strToType :: Name -> Q Type
+strToType s = do
+  TyConI d <- reify s
+  case d of
+    DataD _ n _ _ _ -> conT $ simpleName n
+    NewtypeD _ n _ _ _ -> conT $ simpleName n
+    TySynD n _ _ -> conT $ simpleName n
+  where
+    simpleName :: Name -> Name
+    simpleName nm =
+      let s = nameBase nm
+      in case dropWhile (/=':') s of
+        []          -> mkName s
+        _:[]        -> mkName s
+        _:t         -> mkName t
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,661 @@
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU Affero General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
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/chatty.cabal b/chatty.cabal
new file mode 100644
--- /dev/null
+++ b/chatty.cabal
@@ -0,0 +1,67 @@
+-- Initial chatty.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+-- The name of the package.
+name:                chatty
+
+-- The package version.  See the Haskell package versioning policy (PVP) 
+-- for standards guiding when and how versions should be incremented.
+-- http://www.haskell.org/haskellwiki/Package_versioning_policy
+-- PVP summary:      +-+------- breaking API changes
+--                   | | +----- non-breaking API additions
+--                   | | | +--- code changes with no API change
+version:             0.1.4.0
+
+-- A short (one-line) description of the package.
+synopsis:            Some monad transformers and typeclasses to simplify I/O on a transformer stack.
+
+-- A longer description of the package.
+description:         Some monad transformers and typeclasses for text in- and output on a function scope, including features like here-strings, file redirection, pipes and string expansion. Works best on a transformer stack.
+
+-- The license under which the package is released.
+license:             AGPL-3
+
+-- The file containing the license text.
+license-file:        LICENSE
+
+-- The package author(s).
+author:              Marvin Cohrs
+
+-- An email address to which users can send suggestions, bug reports, and 
+-- patches.
+maintainer:          marvin.cohrs@gmx.net
+
+-- A copyright notice.
+-- copyright:           
+
+category:            Text
+
+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.10
+
+
+library
+  -- Modules exported by the library.
+  exposed-modules:     Chatty.Expansion, Chatty.Commands, Chatty.Spawn, Chatty.Printer, Chatty.Finalizer, Chatty.Templates, Chatty.Scanner, Chatty.Interactor, Chatty.Spawn.Overlay, Chatty.Spawn.Builtins, Chatty.Interactor.Templates, Chatty.Misc, Chatty.Extended.Printer, Chatty.Extended.HTML, Chatty.Extended.ANSI
+  
+  -- Modules included in this library but not exported.
+  -- other-modules:       
+  
+  -- LANGUAGE extensions used by modules in this package.
+  other-extensions:    ExistentialQuantification, RankNTypes, Rank2Types, FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies, TemplateHaskell, QuasiQuotes
+  
+  -- Other library packages from which modules are imported.
+  build-depends:       base >=4.6 && <4.7, transformers >=0.3 && <0.4, directory >=1.2 && <1.3, process >=1.1 && <1.2, mtl >=2.1 && <2.2, template-haskell >=2.8 && <2.9, setenv >= 0.1 && <0.2, unix >= 2.6 && < 2.7, random >= 1.0 && < 1.1, time >= 1.4 && < 1.5, ansi-terminal >= 0.6 && <0.7
+  
+  -- Directories containing source files.
+  -- hs-source-dirs:      
+  
+  -- Base language which the package is written in.
+  default-language:    Haskell2010
+  
