diff --git a/Control/Concurrent/Actors.lhs b/Control/Concurrent/Actors.lhs
--- a/Control/Concurrent/Actors.lhs
+++ b/Control/Concurrent/Actors.lhs
@@ -1,215 +1,399 @@
-> {-# LANGUAGE GeneralizedNewtypeDeriving, ViewPatterns #-}
+> {-# LANGUAGE CPP, GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}
 
 This module exports a simple, idiomatic implementation of the Actor Model.
 
 > module Control.Concurrent.Actors (
->     -- * Actor computations
->       Actor
->     , Loop
->     , NextActor(..)
->     , ActorM()
->     -- ** Building Actors
->     , continue
->     , continue_
->     , done
->     , aseq
->     -- * Message passing and IO
+>
+>     {- | 
+>     Here we demonstrate a binary tree of actors that supports insert and query
+>     operations:
+>      
+>     > import Control.Concurrent.Actors
+>     > import Control.Applicative
+>     > import Control.Concurrent.MVar
+>     > 
+>     > -- the actor equivalent of a Nil leaf node:
+>     > nil :: Behavior Operation
+>     > nil = Receive $ do
+>     >     (Query _ var) <- received 
+>     >     send var False -- signal Int is not present in tree
+>     >     return nil     -- await next message
+>     > 
+>     >    <|> do          -- else, Insert received
+>     >     l <- spawn nil -- spawn child nodes
+>     >     r <- spawn nil
+>     >     branch l r . val <$> received  -- create branch from inserted val
+>     >     
+>     > -- a branch node with a value 'v' and two children
+>     > branch :: Node -> Node -> Int -> Behavior Operation    
+>     > branch l r v = loop where
+>     >     loop = Receive $ do
+>     >         m <- received 
+>     >         case compare (val m) v of
+>     >              LT -> send l m
+>     >              GT -> send r m
+>     >              EQ -> case m of -- signal Int present in tree:
+>     >                         (Query _ var) -> send var True
+>     >                         _             -> return ()
+>     >         return loop
+>     > 
+>     > type Node = Mailbox Operation
+>     > 
+>     > -- operations supported by the network:
+>     > data Operation = Insert { val :: Int }
+>     >                | Query { val :: Int
+>     >                        , sigVar :: MVar Bool }
+>     > 
+>     > insert :: Node -> Int -> IO ()
+>     > insert t = send t . Insert
+>     > 
+>     > -- MVar is in the 'SplitChan' class so actors can 'send' to it:
+>     > query :: Node -> Int -> IO Bool
+>     > query t a = do
+>     >     v <- newEmptyMVar
+>     >     send t (Query a v)
+>     >     takeMVar v
+>     
+>     You can use the tree defined above in GHCi:
+>     
+>     >>> :l TreeExample.hs 
+>     Ok
+>     >>> t <- spawn nil
+>     >>> query t 7
+>     False
+>     >>> insert t 7
+>     >>> query t 7
+>     True
+>
+>     -}
+>
+>     -- * Actor Behaviors
+>       Action()
+>     , Behavior(..)
+>     -- ** Composing Behaviors
+>     , (<.|>)
+>
+>     -- * Available actions
+>     -- ** Message passing
+>     , Mailbox()
 >     , send
->     -- ** Actor system output:
+>     , received
+>     , guardReceived
+>     -- ** Spawning actors
+>     {- | 
+>     The 'spawn' function will be sufficient for forking actors in most cases,
+>     but launching mutually-communicating actors presents a problem.
+>     .
+>     In cases where a 'Behavior' needs access to its own 'Mailbox' or that of 
+>     an actor that must be forked later, the 'MonadFix' instance should be
+>     used. GHC\'s \"Recursive Do\" make this especially easy:
+>     .
+>     > {-# LANGUAGE DoRec #-}
+>     > beh = Receive $ do
+>     >     i <- received
+>     >     -- similar to the scoping in a "let" block:
+>     >     rec b1 <- spawn (senderTo b2)
+>     >         b2 <- spawn (senderTo b1)
+>     >         b3 <- spawn (senderTo b3)
+>     >     -- send initial messages to actors spawned above:
+>     >     send b3 i
+>     >     send "first" b2
+>     >     yield
+>     -}
+>     , spawn
+>     , spawn_
+>     , spawnReading
+>     -- ** Building an actor computation
+>     {- | 
+>     An actor computation can be halted immediately by calling 'yield',
+>     a synonym for 'mzero'. When an 'Action' calling @yield@ is composed with
+>     another using @<|>@ the second takes over processing the /same/ input
+>     which the former @yield@-ed on.
+>
+>     Here is an example of a computation using 'guard' which returns @mzero@ if
+>     the test is false:
+>
+>     > foo c n = Receive $ 
+>     >       do i <- received
+>     >          guard (n<10)
+>     >          send c i
+>     >          return (foo c $ n+1)
+>     >
+>     >   <|> do i <- received -- same as the 'i' above
+>     >          send c $ "TENTH INPUT: "++i
+>     >          return (foo c 0)
+>
+>     The @Monoid@ instance for 'Behavior' works on the same principle.
+>     -}
+>     , yield
 >     , receive
->     , receiveList
->     -- ** Mailbox
->     , Mailbox()
->     , newMailbox
->     -- * Running Actors
->     , Action()
->     , forkActor
->     , forkActorUsing
->     , forkLoop
->     , runActorUsing
->     , runLoop
+>
+>     -- * Utility functions
+>     , runBehavior_
+>     , runBehavior 
+>
+>     -- * Useful predefined @Behavior@s
+>     , printB
+>     , putStrB
+>     , signalB
+>     , constB
+>
 >     ) where
 >
 > import Control.Monad
+> import Control.Monad.Reader(ask)
+> import qualified Data.Foldable as F
 > import Control.Monad.IO.Class
-> import Control.Monad.Trans.Maybe
-> import Control.Concurrent
-> import Control.Applicative
+> import Control.Concurrent(forkIO)
+> import Data.Monoid
+>
+> -- from the contravariant package 
+> import Data.Functor.Contravariant
+> -- from the chan-split package
+> import Control.Concurrent.Chan.Split
+>
+> -- internal:
+> import Control.Concurrent.Actors.Behavior
 
-TODO?:
-    - Function for combining mailboxes (make a monoid? Only allow doing this in IO?)
 
-    Alternately: what if we delegated a single 'mainActor' that is in IO, and which
-    any Actor can send a message to? This would be an IO event loop and we would run
-    this IO loop from 'main' which would block until... so tired.
 
-    RE: Mailbox Class:
-        - Having such a class is a decent idea anyway since we may want to have
-          a synchronous Mailbox type, in which case we should 
+------ CPP MACROS ------
 
-Here we define the Actor environment, similar to IO, in which we can launch new
-Actors and send messages to Actors in scope. The implementation is hidden from
-the user to enforce these restrictions.
+These macros are only provided by cabal unfortunately.... makes it difficult to
+work with GHCi:
 
-> -- | The Actor encironment in which Actors can be spawned and sent messages
-> newtype ActorM a = ActorM { actorM :: MaybeT IO a }
->                  deriving (Monad, Functor, Applicative, 
->                            Alternative, MonadPlus, MonadIO)
->
-> runActorM = runMaybeT . actorM
+#if !MIN_VERSION_base(4,3,0)
+> void :: (Monad m)=> m a -> m ()
+> void = (>> return ())
+#endif
 
-First we define an Actor: a function that takes an input, maybe returning a new
-actor:
+------------------------
 
-    TODO: Consider making Actor the newtype and eliminating NextActor
-      newtype Actor i = Actor { actor :: i -> ActorM (Actor i) }
-      continue :: (i -> ActorM (Actor i)) -> ActorM (Actor i)
+TODO
+-----
 
+ 0.2.0:
+    - performance testing:
+        - take a look at threadscope for random tree test
+        - get complete code coverage into simple test module
+    - interesting: http://en.wikipedia.org/wiki/Huang%27s_algorithm
+    - better method for waiting for threads to complete. should probbly use
+       actor message passing
+    - look into whether we should use Text lib instead of strings?
+      OverloadedStrings?
+        -import Data.String, make polymorphic over IsString
+        -test if this lets us use it in importing module w/ OverloadedStrings
+        extension
+    - structured declarative and unit tests
+    - Performance testing:
+        - test performance vs. straight Chans, etc.
+        - test out overhead of our various locks, especially difference if we
+          scrap the snederLockMutex
+    - some sort of exception handling technique via Actors
+        (look at enumerator package)
+    - investigate ways of positively influencing thread scheduling based on
+       actor work agenda 
+    - strict send' function
+    -Behavior -> enumeratee package translator (and vice versa)
+        (maybe letting us use useful enumerators)
+    - export some more useful Actors and global thingies
+        - 'loop' which keeps consuming (is this provided by a class?)
+        - function returning an actor to "load balance" inputs over multiple
+          actors
+        - an actor that sends a random stream?
+        - a pre-declared Mailbox for IO?
+    - provide an "adapter" for amazon SQS, allowing truly distributed message
+      passing
 
-> type Actor i = i -> ActorM (NextActor i)
-> newtype NextActor i = NextActor { nextActor :: Actor i } 
 
-Now some functions for building Actor computations:
 
-> -- | Continue with a new Actor computation step
-> continue :: Actor i -> ActorM (NextActor i)
-> continue = return . NextActor
 
-    IMPLEMENTATION NOTE: 
-        when an actor terminates, its mailbox persists and we                        
-        currently provide no functions to query an actor's status.                    
-        Signaling an actor's termination should be done with                          
-        message passing.
+CHAN TYPES
+==========
 
-> -- | Actor terminating:
-> done :: ActorM (NextActor i)
-> done = mzero
+> -- | One can 'send' a messages to a @Mailbox@ where it will be processed
+> -- according to an actor\'s defined 'Behavior'
+> newtype Mailbox a = Mailbox { inChan :: InChan a }
+>       deriving (Contravariant)
+>
 
-    IMPLEMENTATION NOTE: 
-        We might find that we can use the monoid abstraction, or 
-        that we should make Actor a newtype for other reasons. For
-        now we have this for composing
+We don't need to expose this thanks to the miracle of MonadFix and recursive do,
+but this can be generated via the NewSplitChan class below if the user imports
+the library:
 
-> -- | compose two actors. The second will take over when the first exits
-> aseq :: Actor i -> Actor i -> Actor i
-> aseq f g i = NextActor <$> (nextf <|> return g)
->     where nextf = (`aseq` g) . nextActor <$> f i
+> newtype Messages a = Messages { outChan :: OutChan a }
+>       deriving (Functor) 
+>
+> -- Not sure how to derive this or if possible:
+> instance SplitChan Mailbox Messages where
+>     readChan = readChan . outChan
+>     writeChan = writeChan . inChan
+>     writeList2Chan = writeList2Chan . inChan
+>
+> instance NewSplitChan Mailbox Messages where
+>     newSplitChan = fmap (\(i,o)-> (Mailbox i, Messages o)) newSplitChan
+>
 
 
-A Loop is just an Actor that ignores its input. We provide some useful
-functions for building and running such computations:
 
-> -- | An Actor that discards its input, i.e. a simple loop.
-> type Loop = ActorM (NextActor ())
->
-> -- | Continue with a Loop computation
-> continue_ :: Loop -> ActorM (NextActor i)
-> continue_ = fmap (NextActor . fixConst . nextActor)
->     where fixConst c = const $ continue_ $ c ()
 
+ACTIONS
+=======
 
+Functionality is based on our underlying type classes, but users shouldn't need
+to import a bunch of libraries to get basic Behavior building functionality.
 
-Here we define the "mailbox" that an Actor collects messages from, and other
-actors send messages to. It is simply a Chan with hidden implementation.
+> infixl 3 <.|>
 
-    IMPLEMENTATION NOTE: 
-        we make no attempt to ensure that only one actor is reading                    
-        from a given Chan. This means two Actors can share the work                    
-        reading from the same mailbox.
-        
-        If we want to change this in the future, Mailbox will contain
-        a type :: TVar ThreadID
+> -- | Sequence two @Behavior@s. After the first 'yield's the second takes over,
+> -- discarding the message the former was processing. See also the 'Monoid'
+> -- instance for @Behavior@.
+> -- 
+> -- > b <.|> b' = b `mappend` constB b'
+> (<.|>) :: Behavior i -> Behavior i -> Behavior i
+> b <.|> b' = b `mappend` constB b'
 
-        To implement synchronous chans (or singly-buffered chans), 
-        we can use a SyncMailbox type containing an MVar and
-        possibly another Var for ensuring syncronicity. An MVar
-        writer will never block indefinitely. Use a class for writing
-        and reading these mailbox types.
+The 'yield' function is so named because it is "relinquishing control", i.e. I
+think the name reminds of the functionality of <|> and mappend (the last input
+is passed along) and also has the meaning "quit".
 
-     
-> -- | the buffered message passing medium used between actors
-> newtype Mailbox i = Mailbox { mailbox :: Chan i }
+Its similarity (or not) to the 'enumerator' function of the same same may be a
+source of confusion (or the opposite)... I'm not sure.
+
+> -- | Immediately give up processing an input, perhaps relinquishing the input
+> -- to an 'Alternative' computation or exiting the actor.
+> -- 
+> -- > yield = mzero
+> yield :: Action i a
+> yield = mzero
 >
+> -- | Useful to make defining a continuing Behavior more readable as a
+> -- \"receive block\", e.g.
+> --
+> -- > pairUp out = Receive $ do
+> -- >     a <- received
+> -- >     receive $ do
+> -- >         b <- received
+> -- >         send out (b,a)
+> -- >         return (pairUp out)
+> --
+> -- Defined: @receive = return . Receive@
+> receive :: Action i (Behavior i) -> Action i (Behavior i)
+> receive = return . Receive
 
-    IMPLEMENTATION NOTE: 
-        We allow sending of messages to Actors in IO, treating the 
-        main thread as something of an Actor with special privileges;
-        It can launch actors and message them, but also read as it 
-        pleases from Mailboxes
+> -- | Return the message received to start this 'Action' block. /N.B/ the value
+> -- returned here does not change between calls in the same 'Action'.
+> --
+> -- > received = ask
+> received :: Action i i
+> received = ask
 
+> -- | Return 'received' message matching predicate, otherwise 'yield'.
+> --
+> -- > guardReceived p = ask >>= \i-> guard (p i) >> return i
+> guardReceived :: (i -> Bool) -> Action i i
+> guardReceived p = ask >>= \i-> guard (p i) >> return i
 
-> -- | Send a message to an Actor. Actors can only be passed messages from other
-> -- actors.
-> send :: (Action m)=> Mailbox a -> a -> m ()
-> send b = liftIOtoA . writeChan (mailbox b)
+> -- | Send a message asynchronously. This can be used to send messages to other
+> -- Actors via a 'Mailbox', or used as a means of output from the Actor system
+> -- to IO since the function is polymorphic.
+> -- .
+> -- > send b = liftIO . writeChan b
+> send :: (MonadIO m, SplitChan c x)=> c a -> a -> m ()
+> send b = liftIO . writeChan b
 
-> -- | Read a message from a mailbox in the IO monad. This can be used as the
-> -- mechanism for output from an Actor system. Blocks if the actor is empty
-> receive :: Mailbox o -> IO o
-> receive = readChan . mailbox
 
-> -- | Return a lazy list of mailbox contents
-> receiveList :: Mailbox o -> IO [o]
-> receiveList = getChanContents . mailbox
 
-> -- | create a new mailbox that Actors can be launched to read from or
-> -- send messages to in order to communicate with other actors
-> newMailbox :: (Action m)=> m (Mailbox a)
-> newMailbox = liftIOtoA newChan >>= return . Mailbox
+FORKING AND RUNNING ACTORS:
+===========================
 
 
-The Action class represents environments in which we can operate on actors. That
-is we would like to be able to send a message in IO
+> -- | Like 'spawn' but allows one to specify explicitly the channel from which
+> -- an actor should take its input. Useful for extending the library to work
+> -- over other channels.
+> spawnReading :: (MonadIO m, SplitChan x c)=> c i -> Behavior i -> m ()
+> spawnReading str = liftIO . void . forkIO . actorRunner 
+>     where actorRunner b =
+>               readChan str >>= runBehaviorStep b >>= F.mapM_ actorRunner
 
-> -- | monads in the Action class can participate in message passing and other
-> -- Actor operations
-> class Monad m => Action m where
->     liftIOtoA :: IO a -> m a
->
->     forkA :: IO () -> m ()
->     forkA io = liftIOtoA $ forkIO io >> return ()
->
-> instance Action IO where
->     liftIOtoA = id
+
+RUNNING ACTORS
+--------------
+
+These work in IO, returning () when the actor finishes with done/mzero:
+
+> -- | Run a @Behavior ()@ in the main thread, returning when the computation
+> -- exits.
+> runBehavior_ :: Behavior () -> IO ()
+> runBehavior_ b = runBehavior b [(),()..]
 >
-> instance Action ActorM where
->     liftIOtoA = ActorM . liftIO
+> -- | run a 'Behavior' in the IO monad, taking its \"messages\" from the list.
+> -- Useful for debugging @Behaviors@.
+> runBehavior :: Behavior a -> [a] -> IO ()
+> runBehavior b (a:as) = runBehaviorStep b a >>= F.mapM_ (`runBehavior` as)
+> runBehavior _ _      = return ()
 
 
 
+FORKING ACTORS
+--------------
 
-> -- | fork an actor, returning its mailbox
-> forkActor :: (Action m)=> Actor i -> m (Mailbox i)
-> forkActor a = do
->     b <- newMailbox
->     forkActorUsing b a
->     return b
->     
-> -- | fork an actor that reads from the supplied Mailbox
-> forkActorUsing :: (Action m)=> Mailbox i -> Actor i -> m ()
-> forkActorUsing b = forkA . actorHandler b
->
-> -- | fork a looping computation which starts immediately
-> forkLoop :: (Action m)=> Loop -> m ()
-> forkLoop = forkA . runLoop  
+> -- | Fork an actor performing the specified 'Behavior'. /N.B./ an actor 
+> -- begins execution of its 'headBehavior' only after a mesage has been 
+> -- received. See also 'spawn_'.
+> spawn :: (MonadIO m)=> Behavior i -> m (Mailbox i)
+> spawn b = do
+>     (m,s) <- liftIO newSplitChan
+>     spawnReading s b
+>     return m
 >
-> -- | run a Loop actor in the main thread, returning when the computation exits
-> runLoop :: Loop -> IO ()
-> runLoop l = runActorM l >>= 
->              maybe (return ()) (runLoop . ($ ()) .  nextActor)
+> -- | Fork a looping computation which starts immediately. Equivalent to
+> -- launching a @Behavior ()@ and another 'Behavior' that sends an infinite stream of
+> -- ()s to the former\'s 'Mailbox'.
+> spawn_ :: (MonadIO m)=> Behavior () -> m ()
+> spawn_ = liftIO . void . forkIO . runBehavior_  
 
->
-> -- | run an Actor in the main thread, returning when the Actor exits
-> runActorUsing :: Mailbox i -> Actor i -> IO ()
-> runActorUsing = actorHandler
 
 
-Internal function that feeds the actor computation its values. This may be
-extended to support additional functionality in the future.
+USEFUL GENERAL BEHAVIORS
+========================
 
-> actorHandler :: Mailbox i -> Actor i -> IO ()
-> actorHandler (mailbox->c) = loop
->     where loop a = readChan c >>= 
->                     runActorM . a >>= 
->                      maybe (return ()) (loop . nextActor)
+> -- | Prints all messages to STDOUT in the order they are received,
+> -- 'yield'-ing /immediately/ after @n@ inputs are printed.
+> printB :: (Show s, Num n)=> n -> Behavior s
+> printB = contramap (unlines . return . show) . putStrB
 
+We want to yield right after printing the last input to print. This lets us
+compose with signalB for instance:
+
+    write5ThenExit = putStrB 5 `mappend` signalB c
+
+and the above will signal as soon as it has printed the last message. If we try
+to define this in a more traditional recursive way the signal above would only
+happen as soon as the sixth message was received.
+
+For now we allow negative
+
+> -- | Like 'printB' but using @putStr@.
+> putStrB :: (Num n)=> n -> Behavior String
+> putStrB 0 = mempty --special case when called directly w/ 0
+> putStrB n = Receive $ do
+>     s <- received
+>     liftIO $ putStr s
+>     guard (n /= 1)
+>     return $ putStrB (n-1)
+
+> -- | Sends a @()@ to the passed chan. This is useful with 'mappend' for
+> -- signalling the end of some other 'Behavior'.
+> --
+> -- > signalB c = Receive (send c () >> yield)
+> signalB :: (SplitChan c x)=> c () -> Behavior i
+> signalB c = Receive (send c () >> yield)
+
+> -- | A @Behavior@ that discard its first input, returning the passed Behavior
+> -- for processing subsequent inputs. Useful with 'Alternative' or 'Monoid'
+> -- compositions when one wants to ignore the leftover input.
+> --
+> -- > constB = Receive . return
+> constB :: Behavior i -> Behavior i
+> constB = Receive . return
diff --git a/Control/Concurrent/Actors/Behavior.lhs b/Control/Concurrent/Actors/Behavior.lhs
new file mode 100644
--- /dev/null
+++ b/Control/Concurrent/Actors/Behavior.lhs
@@ -0,0 +1,139 @@
+> {-# LANGUAGE CPP, GeneralizedNewtypeDeriving #-}
+> -- Since we don't get a MonadFix instance for MaybeT from transformers:
+> {-# OPTIONS_GHC -fno-warn-orphans #-}
+> module Control.Concurrent.Actors.Behavior
+>     where
+> 
+
+Our main data types for actors and behaviors are defined in this private module.
+We may expose this if it is useful to people:
+
+These imports are mostly for all the instances for Action that we define:
+
+> -- using 'mtl':
+> import Control.Monad.Reader(ReaderT(..))
+> import Control.Monad.Reader.Class
+> import Control.Monad.Trans.Maybe
+> import Control.Monad.IO.Class
+> import Control.Monad.Fix
+> import Control.Applicative
+> import Control.Monad
+>
+> import Control.Arrow
+> import qualified Control.Category as C
+> import Data.Monoid
+>
+> import Data.Functor.Contravariant
+
+
+A Behavior wraps an Action i a, into a list-like sequence of actions to perform
+over inputs:
+
+> -- | An actor is created by 'spawn'ing a @Behavior@. Behaviors consist of
+> -- a composed 'Action' that is executed when a message is 'received' and
+> -- returns the @Behavior@ for processing the next input.
+> newtype Behavior i = Receive { headAction :: Action i (Behavior i) }
+> 
+> instance Contravariant Behavior where
+>     contramap f (Receive a) = Receive $ f ^>> (contramap f <$> a)
+>     --contramap f = Receive . withReaderT f . fmap (contramap f) . headAction
+>
+
+This is essentially a marriage of the Monoid [] instance with Action's
+Alternative instance, and I am mostly convinced it is right and has utility:
+
+> -- | @b1 `mplus` b2@ has the 'headAction' of @b2@ begin where the 'abort'
+> -- occured in @b1@, i.e. @b2@\'s first input will be the final input handed to
+> -- @b1@.
+> instance Monoid (Behavior i) where
+>     mempty = Receive mzero
+>     mappend (Receive a1) b2@(Receive a2) = Receive $ 
+>         -- is this the best way of defining this?:
+>         (flip mappend b2 <$> a1) <|> a2
+
+
+Defining Action as a Reader / Maybe stack lets us have a nice EDSL syntax for
+constructing behaviors, and I am able to derive a bunch of the instances that
+will be useful:
+
+
+> -- | In the Actor Model, at each step an actor...
+> --
+> --     - processes a single 'received' message
+> --     
+> --     - may 'spawn' new actors
+> --     
+> --     - may 'send' messages to other actors
+> --     
+> --     - 'return's the 'Behavior' for processing the /next/ message
+> --
+> -- These actions take place within the @Action i@ monad, where @i@ is the type
+> -- of the input message the actor receives.
+> --
+> -- /N.B.:/ the MonadIO instance here is an abstraction leak. An example of a
+> -- good use of 'liftIO' might be to give an @Action@ access to a source of
+> -- randomness.
+> newtype Action i a = Action { readerT :: ReaderT i (MaybeT IO) a }
+>         deriving (Monad, MonadIO, MonadPlus, MonadReader i,
+>                   Functor, Applicative, Alternative, MonadFix)
+> 
+
+
+------ CPP MACROS ------
+
+This should end up in the next version of 'transformers':
+   http://www.haskell.org/pipermail/libraries/2011-April/016201.html
+
+#if !MIN_VERSION_transformers(0,3,0)
+> instance (MonadFix m) => MonadFix (MaybeT m) where
+>    mfix f = MaybeT $ mfix (runMaybeT . f . unJust)
+>      where unJust = maybe (error "mfix MaybeT: Nothing") id
+#endif
+
+------------------------
+
+
+Some helpers for wrapping / unwrapping:
+
+> -- pack and unpack:
+> runAction :: Action r a -> r -> MaybeT IO a
+> runAction = runReaderT . readerT
+> 
+> action :: (i -> MaybeT IO a) -> Action i a
+> action = Action . ReaderT
+> 
+> runBehaviorStep :: Behavior i -> i -> IO (Maybe (Behavior i))
+> runBehaviorStep = fmap runMaybeT . runAction . headAction
+
+
+Kleisli is ReaderT, so these are basically cribbed from its instances. It's a
+shame ReaderT's type arguments are the way they are or we could have derived
+this:
+
+> instance C.Category Action where
+>     id = ask
+>     f . g = action $ \i-> runAction g i >>= runAction f
+> 
+> instance Arrow Action where
+>     arr = action . fmap return
+>     first f = action $ \ ~(b,d)-> runAction f b >>= \c -> return (c,d)
+>  
+> -- additional Arrow sub-classes:
+> instance ArrowApply Action where
+>     app = action (uncurry runAction)
+> 
+> instance ArrowChoice Action where
+>     left f = f +++ C.id
+> 
+> -- and following that MaybeT IO is a MonadPlus...
+> instance ArrowPlus Action where
+>     f <+> g = action $ \i-> runAction f i `mplus` runAction g i
+> 
+> instance ArrowZero Action where
+>     zeroArrow = action $ const mzero
+> 
+> -- inspired by MonadFix instance. 
+> instance ArrowLoop Action where
+>    loop af = action (liftM fst . mfix . f')
+>        where f' x y = f (x, snd y)
+>              f = runAction af
diff --git a/simple-actors.cabal b/simple-actors.cabal
--- a/simple-actors.cabal
+++ b/simple-actors.cabal
@@ -7,13 +7,19 @@
 -- 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.1
+Version:             0.1.0
 
 -- A short (one-line) description of the package.
-Synopsis:            A simple implementation of the actor model of concurrency
+Synopsis:            A library for more structured concurrent programming, based
+                     on the Actor Model
+Homepage:            http://coder.bsimmons.name/blog/2011/05/simple-actors-a-simple-actor-model-concurrency-library/
 
 -- A longer description of the package
-Description:         Simple concurrency primitives based on the Actor Model.
+Description:         simple-actors is an EDSL-style library for writing
+                     more structured concurrent programs, based on the Actor 
+                     Model. Computations are structured as "Behaviors" which take a
+                     single input value, perform some 'Action's, and return the
+                     Behavior to process the next input message it receives.
 
 -- The license under which the package is released.
 License:             BSD3
@@ -43,19 +49,29 @@
 -- Extra-source-files:  
 
 -- Constraint on the version of Cabal needed to build this package.
-Cabal-version:       >=1.2
+Cabal-version:       >=1.6
 
+source-repository head   
+    type:     git
+    location: https://github.com/jberryman/simple-actors.git
 
 Library
   -- Modules exported by the library.
   Exposed-modules:     Control.Concurrent.Actors
   
   -- Packages needed in order to build this package.
-  Build-depends:      transformers
-                    , base >= 4 && < 5    
+  Build-depends:       base >= 4 && < 5    
+                     , chan-split
+                     , mtl >= 2
+                     , transformers
+                     , contravariant
+                    
   
+  ghc-options:        -Wall
+
   -- Modules not exported by this package.
-  -- Other-modules:       
+  Other-modules:     Control.Concurrent.Actors.Behavior
+                     
   
   -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.
   -- Build-tools:         
