diff --git a/Control/Monad/Supervisor.hs b/Control/Monad/Supervisor.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Supervisor.hs
@@ -0,0 +1,107 @@
+-----------------------------------------------------------------------------
+--
+-- Module      :  Control.Monad.Supervisor
+-- Copyright   :
+-- License     :  BSD3
+--
+-- Maintainer  :  agocorona@gmail.com
+-- Stability   :
+-- Portability :
+--
+-- | A supervisor monad that explore the execution tree of an internal monad and define extra behaviours thanks to flexible instance definitions for each particular purpose.
+-- It can inject new behaviours for backtracking, trace generation, testing, transaction rollbacks etc
+-- The supervisor monad is used in the package MFlow to control the routing, tracing, state management, back button management and navigation in general
+
+--
+-----------------------------------------------------------------------------
+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
+             UndecidableInstances, DeriveDataTypeable,
+             FunctionalDependencies #-}
+
+module Control.Monad.Supervisor where
+
+import Control.Monad.Trans
+import Control.Monad.State
+import Data.Typeable
+
+import Debug.Trace
+(!>)= flip trace
+
+--class  Monad m => MonadState1 s m where
+--   get :: m s
+--   put :: s -> m ()
+
+-- | The internal computation can be reexecuted, proceed forward or backward
+data Control a = Control a | Forward a | Backward deriving (Typeable, Read, Show)
+
+-- | The supervisor add a Control wrapper that is interpreted by the monad instance
+newtype Sup s m a = Sup { runSup :: m (Control a ) }
+
+-- | The supervise class add two general modifiers that can be applied:
+class  MonadState s m => Supervise s m  where
+   supBack :: s -> m ()          -- ^ Called before initiating backtracking in a control point
+                                -- When the computation goes back, by default
+                                -- the  state is kepth. This procedure can change
+                                -- that behaviour. The state passed is the one before the
+                                -- computation was executed.
+   supBack = const $ return ()
+   
+   supervise :: s ->  m (Control a) -> m (Control a)  -- ^ When the conputation has been executed
+                                                    -- this method is an opportunity for modifying the result
+                                                    -- By default: supervise _= id
+   supervise= const $ id
+
+
+-- | Flag the computation that executes @breturn@ as a control point.
+--
+-- When the computation is going back, it will be re-executed (see the monad definition)
+breturn :: Monad m => a -> Sup s m a
+breturn = Sup . return . Control 
+
+--instance MonadState () IO where
+--  get= return()
+--  put= const $ return ()
+  
+--instance MonadState s m => Supervise s m
+
+
+
+-- | The Supervisor Monad is in essence an Identity monad transformer when executing Forward.
+instance  Supervise s m => Monad (Sup s m) where
+    fail   _ = Sup . return $ Backward
+    return x = Sup . return $ Forward x
+    x >>= f    = Sup $ loop 
+     where
+     loop = do
+        s <- get
+        -- execution as usual if supervise== id
+        v <-  supervise s $ runSup x                        
+        case v of
+            --  a normal execution if supervise== id
+            Forward y  -> supervise s $ runSup (f y)
+
+            --   Backward was returned, stop the branch of execution and propagate it back
+            Backward  ->  return  Backward
+
+            -- the computaton x was a control point. if the branch of execution goes Backward
+            -- then x will be reexecuted. supBack will control the state backtracking, how much of
+            -- the current state we want to keep and how much we want to backtrack  
+            Control y  -> do
+                 z <- supervise s $ runSup (f y)            
+                 case z of
+                  Backward  -> supBack s >> loop           -- re-execute x   
+                  other   -> return other
+
+
+instance MonadTrans (Sup s) where
+  lift f = Sup $  f >>= return . Forward
+
+instance (MonadIO m,Supervise s m)=> MonadIO (Sup s m) where
+  liftIO iof= Sup $ liftIO iof  >>= return . Forward
+
+instance Supervise s m => MonadState s (Sup s m) where
+   get= lift get
+   put = lift . put
+
+
+
diff --git a/Control/Monad/Supervisor/Session.hs b/Control/Monad/Supervisor/Session.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Supervisor/Session.hs
@@ -0,0 +1,73 @@
+-----------------------------------------------------------------------------
+--
+-- Module      :  Control.Monad.Supervisor.Session
+-- Copyright   :
+-- License     :  BSD3
+--
+-- Maintainer  :  agocorona@gmail.com
+-- Stability   :
+-- Portability :
+--
+-- |
+--
+-----------------------------------------------------------------------------
+{-# LANGUAGE TypeSynonymInstances,
+             FlexibleInstances,
+             MultiParamTypeClasses,
+             FlexibleContexts,
+             UndecidableInstances #-}
+module Control.Monad.Supervisor.Session where
+import Control.Monad.State
+--import Control.Monad.Supervisor
+import Data.Map as M
+import Data.Typeable
+import Data.Dynamic
+
+
+onNothing m exc= do
+   r <- m
+   case r of
+     Nothing -> exc
+     Just r  -> return r
+
+
+-- | Set user-defined data in the context of the session.
+--
+-- The data is indexed by  type in a map. So the user can insert-retrieve different kinds of data
+-- in the session context to add different behaviours to the supervisor monad.
+--
+
+
+
+
+type SessionData= M.Map TypeRep Dynamic
+
+emptySessionData= M.empty
+
+setSessionData :: ( MonadState SessionData m, Typeable a) => a -> m ()  
+setSessionData  x=
+  modify $ \session ->  M.insert  (typeOf x ) (toDyn x)  session
+
+delSessionData :: ( MonadState SessionData m, Typeable a) => a -> m ()
+delSessionData x=
+ modify $ \session ->  M.delete  (typeOf x )  (session :: M.Map TypeRep Dynamic)
+  
+-- | Get the session data of the desired type if there is any.
+getSessionData ::  (Typeable a, MonadState SessionData m) =>  m (Maybe a)
+getSessionData =  resp where
+ resp= get  >>= \list  ->
+    case M.lookup ( typeOf $ typeResp resp) list :: Maybe Dynamic of
+      Just x  -> return $ cast x
+      Nothing -> return Nothing
+ typeResp :: m (Maybe x) -> x
+ typeResp= undefined
+
+
+
+runs= flip evalStateT
+
+main= do
+   r <- runs emptySessionData  $ do
+            setSessionData  True
+            getSessionData
+   print (r :: Maybe Bool)
diff --git a/Control/Monad/Supervisor/Trace.hs b/Control/Monad/Supervisor/Trace.hs
--- a/Control/Monad/Supervisor/Trace.hs
+++ b/Control/Monad/Supervisor/Trace.hs
@@ -1,4 +1,6 @@
-{-# LANGUAGE ScopedTypeVariables, UndecidableInstances #-}
+{-# LANGUAGE ScopedTypeVariables, TypeSynonymInstances,
+    MultiParamTypeClasses, FlexibleInstances
+    ,FlexibleContexts, UndecidableInstances #-}
 
 -- | This module add a 'MonadLoc' instance to the 'Supervisor' monad. This instance generates a trace when a
 -- uncaugh exception is raised.
@@ -56,18 +58,19 @@
 -- TO DO:  extend it for forward traces and test coverages
 
 module Control.Monad.Supervisor.Trace(runTrace) where
-
+import Control.Monad.State
 import Control.Monad.Supervisor
 import Control.Monad.Loc
-import Control.Monad.State
-import Control.Monad.CatchIO as CMC
+import Control.Monad.Catch as CMC
 import Control.Exception (SomeException)
 import Data.List(intersperse)
 
 
 type Trace= [String]
 
-instance (MonadLoc m, Supervise Trace m, MonadCatchIO m)=> MonadLoc (Sup m) where
+
+
+instance (MonadLoc m, Supervise Trace m, MonadCatch m)=> MonadLoc (Sup Trace m) where
     withLoc loc (Sup f) =  Sup $ do
        withLoc loc $ do
              r <- f `CMC.catch` handler1
@@ -81,14 +84,14 @@
        -- detected failure, add the first line of trace with the error, init execution back
        handler1 (e :: SomeException)=    put ["exception: " ++show e]  >> return Backward
 
-type WState  m = StateT [String] m
 
+
 -- | Execute an Supervisor computation and raise an error with a trace when an uncaugh exception
 -- is raised. It is necessary to preprocess the file with the monadloc-pp preprocessor.
 --
 -- Otherwise, it produces the same error with no trace.
-runTrace :: Sup (WState IO) () -> IO (Control ())
-runTrace  f=  evalStateT (runSup f1) []
+runTrace :: Supervise [String] m => Sup [String] m a -> m (Control a)
+runTrace  f=  runSup f1
   where
   f1= printBackTrace >> f
   printBackTrace= do
@@ -99,5 +102,8 @@
      where
      disp tr= "TRACE (error in the last line):\n\n" ++(concat $ intersperse "\n" tr)
 
-
+---- A less polimorphic version of runTrace. It assumes a state monad for the sole purpose
+---- of capturing traces
+--runTraceState  :: Monad m => Sup (StateT [String] m) a -> m (Control a)
+--runTraceState f= evalStateT (runTrace f) []
 
diff --git a/Control/Monad/Supervisor/Transactions.hs b/Control/Monad/Supervisor/Transactions.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Supervisor/Transactions.hs
@@ -0,0 +1,108 @@
+-----------------------------------------------------------------------------
+--
+-- Module      :  Control.Monad.Supervisor.Transactions
+-- Copyright   :
+-- License     :  BSD3
+--
+-- Maintainer  :  agocorona@gmail.com
+-- Stability   :
+-- Portability :
+--
+-- |
+--
+-----------------------------------------------------------------------------
+{-#LANGUAGE FlexibleInstances, MultiParamTypeClasses,
+            GeneralizedNewtypeDeriving, FlexibleContexts
+            ,UndecidableInstances, DeriveDataTypeable #-}
+module Control.Monad.Supervisor.Transactions (
+
+) where
+import Control.Monad.State
+import Control.Monad.Supervisor hiding (breturn)
+import qualified Control.Monad.Supervisor as Sup(breturn)
+import Data.Monoid
+import Control.Monad.Trans
+import Control.Monad.Supervisor.Session hiding (runs)
+import Data.Typeable
+
+
+
+
+breturn x= setSessionData (BackTracking False) >> Sup.breturn x
+
+instance MonadState SessionData m => Supervise  SessionData m where
+     supBack s= setSessionData (BackTracking True) !> "supBack"
+
+--     supervise _ mx= setSessionData (BackTracking False) >> mx !> "supervise"
+
+--instance (MonadState a m ,MonadState b m)=> MonadState (a,b) m where
+--  get= do
+--    x <- get
+--    y <- get
+--    return (x,y)
+--
+--  put (x,y)= put x >> put y
+
+class  Monad m => BackTrackingStatus m where
+   isGoingBack :: m Bool
+
+
+class Monoid t => HasInverse t where
+  cancel :: t -> t
+  -- property: forall w, w => v <> t <> w <> cancel t === v <> w
+
+newtype BackTracking= BackTracking Bool deriving Typeable
+
+processReversibleEvent :: (Supervise SessionData m, HasInverse a)=> a -> a -> (a -> Sup SessionData m()) -> Sup SessionData m ()
+processReversibleEvent resource event update =  do
+   now <- isGoingBack
+   if  now  !> ("back="++ show now) then  update (resource <> cancel event) >> fail ""
+           else  update (resource <> event) >> breturn ()
+
+--processIrreversibleEvent :: (BackTrackingStatus m, Monoid a)=> a -> a -> Sup m a -> Sup m a
+--processIrreversibleEvent resource event failAction= do
+--   now <- lift $ isGoingBack
+--   if not now
+--    then breturn $ resource <> event
+--    else do
+--         breturn()  -- will not go back beyond this
+--         failAction
+
+instance Monoid Int where mempty=0; mappend =(+)
+newtype Potatoes= Potatoes Int deriving (Num, Monoid, Typeable)
+
+instance HasInverse Potatoes where cancel = negate
+
+
+
+instance Supervise SessionData m => BackTrackingStatus  m where
+   isGoingBack= do
+     BackTracking b <- getSessionData `onNothing` (return (BackTracking False) !> "backtracking not set" ) !> "isgoingback"
+     return b
+
+runs= flip evalStateT
+
+
+main= do
+  print "hi"
+  runs emptySessionData $ runSup $ do
+      setSessionData (BackTracking True)
+      getSessionData `onNothing` error "not set" >>= \(BackTracking b) -> liftIO (print b)
+
+      Potatoes potatoes <- getSessionData `onNothing` return (Potatoes 0)
+      liftIO . print $ " Now you have"++ show potatoes ++ " in your shopping cart"
+      liftIO . print $ "press enter for more potatoes"
+      liftIO $ getLine
+      liftIO . print $ " you want to add potatoes to the shopping cart"
+      processReversibleEvent (Potatoes potatoes) (Potatoes 5) setSessionData
+
+
+      liftIO . print $  "but wait!. you do not need potatoes, you need oranges!. "
+      liftIO . print $  "No problem. press enter to drop the potatoes from the cart"
+      liftIO $ getLine
+      fail ""
+
+
+
+
+
diff --git a/supervisor.cabal b/supervisor.cabal
--- a/supervisor.cabal
+++ b/supervisor.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             0.1.0.0
+version:             0.1.1.0
 
 -- A short (one-line) description of the package.
 synopsis:   Control an internal monad execution for trace generation, backtrakcking, testing and other purposes
@@ -53,11 +53,16 @@
 
 library
   -- Modules exported by the library.
-  exposed-modules:     Control.Monad.Supervisor.Trace
-  
+  exposed-modules:     Control.Monad.Supervisor
+                       Control.Monad.Supervisor.Trace
+                       Control.Monad.Supervisor.Session
+                       Control.Monad.Supervisor.Transactions
+                       
   -- Modules included in this library but not exported.
   -- other-modules:       
   
   -- Other library packages from which modules are imported.
-  build-depends:       base ==4.5.*, mtl -any, monadloc -any, MonadCatchIO-transformers -any
+  build-depends:       base >=4 && <5, mtl -any, monadloc -any
+                       , exceptions -any
+                       , containers -any
 
