diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,8 +15,18 @@
 This functionality is provided via the 'toExport' and 'fromExport' functions.
 * Furthermore, this version also exports the initial reference.
 
-## 0.3.2.1 -- 2021-01-10
+## 0.3.2.1 -- 2021-10-01
 * Add the toExport and fromExport functions to the exported functions in the pure module.
 
-## 0.4.0.0 -- 2021-01-10
+## 0.4.0.0 -- 2021-10-01
 * fromExport function now correctly determines the referece to use for generation of new nodes.
+
+## 1.0.0.0 -- 2021-10-06
+* Change explorer model to the new model where the exploration is always reported
+by a tree and sharing is possible via the optional shadow graph.
+Furthermore, the *jump* action is introduced to allow jumping to any node in the tree without the 
+destructive property. In addition, the *revert* action is now always destructive and can only operate 
+on the current trace.
+* Add the Tools module.
+This module includes an implementation of the exploring interpreter protocol and an implementation
+of an language parametric REPL.
diff --git a/Language/Explorer/Basic.hs b/Language/Explorer/Basic.hs
--- a/Language/Explorer/Basic.hs
+++ b/Language/Explorer/Basic.hs
@@ -1,14 +1,13 @@
+{-# LANGUAGE ConstraintKinds #-}
+
 module Language.Explorer.Basic
     ( Explorer
+    , mkExplorer
+    , mkExplorerNoSharing
     , execute
     , executeAll
     , revert
-    , dynamicRevert
     , ExplorerM.toTree
-    , mkExplorerStack
-    , mkExplorerTree
-    , mkExplorerGraph
-    , mkExplorerGSS
     , config
     , currRef
     , Ref
@@ -19,7 +18,8 @@
     , getPathsFromTo
     , getPathFromTo
     , executionGraph
-    , ExplorerM.initialRef
+    , fromExport
+    , toExport
     ) where
 
 import qualified Language.Explorer.Monadic as ExplorerM
@@ -36,7 +36,14 @@
 -- the same.
 type Ref = ExplorerM.Ref
 type Explorer a b = ExplorerM.Explorer a Identity b ()
+type BasicLanguage p c = Eq p
 
+mkExplorer :: BasicLanguage p c => Bool -> (c -> c -> Bool) -> (p -> c -> Maybe c) -> c -> Explorer p c
+mkExplorer shadow eqfunc definterp initialConf = ExplorerM.mkExplorer shadow eqfunc (wrap definterp) initialConf
+
+mkExplorerNoSharing :: BasicLanguage p c => (p -> c -> Maybe c) -> c -> Explorer p c
+mkExplorerNoSharing = mkExplorer False (const . const $ False)
+
 currRef :: Explorer a b -> Ref
 currRef = ExplorerM.currRef
 
@@ -50,22 +57,12 @@
 wrap :: Monad m => (a -> b -> Maybe b) -> a -> b -> m (Maybe b, ())
 wrap def p e = return $ (def p e, ())
 
--- Constructor for a exploring interpreter.
-mkExplorerStack, mkExplorerTree, mkExplorerGraph, mkExplorerGSS :: (Show a, Eq a, Eq b) => (a -> b -> Maybe b) -> b -> Explorer a b
-mkExplorerStack definterp conf = ExplorerM.mkExplorerStack (wrap definterp) conf
-mkExplorerTree definterp conf = ExplorerM.mkExplorerTree (wrap definterp) conf
-mkExplorerGraph definterp conf = ExplorerM.mkExplorerGraph (wrap definterp) conf
-mkExplorerGSS definterp conf = ExplorerM.mkExplorerGSS (wrap definterp) conf
-
-execute :: (Eq c, Eq p) =>  p -> Explorer p c -> Explorer p c
+execute :: BasicLanguage p c => p -> Explorer p c -> Explorer p c
 execute p e = fst $ runIdentity $ ExplorerM.execute p e
 
-executeAll :: (Eq c, Eq p) => [p] -> Explorer p c -> Explorer p c
+executeAll :: BasicLanguage p c => [p] -> Explorer p c -> Explorer p c
 executeAll p e = fst $ runIdentity $ ExplorerM.executeAll p e
 
-dynamicRevert :: Bool -> Ref -> Explorer p c -> Maybe (Explorer p c)
-dynamicRevert = ExplorerM.dynamicRevert
-
 revert :: ExplorerM.Ref -> Explorer p c -> Maybe (Explorer p c)
 revert = ExplorerM.revert
 
@@ -87,7 +84,7 @@
 getPathFromTo :: Explorer p c -> Ref -> Ref -> [((Ref, c), p, (Ref, c))]
 getPathFromTo e s t = map removeOutput $ ExplorerM.getPathFromTo e s t
 
-executionGraph :: Explorer p c -> (Ref, [Ref], [((Ref, c), p, (Ref, c))])
+executionGraph :: Explorer p c -> ((Ref, c), [(Ref, c)], [((Ref, c), p, (Ref, c))])
 executionGraph e = (curr, nodes, map removeOutput graph)
   where
     (curr, nodes, graph) = ExplorerM.executionGraph e
@@ -96,7 +93,11 @@
 leaves = ExplorerM.leaves
 
 toExport :: Explorer p c -> (Ref, [(Ref, c)], [(Ref, Ref, p)])
-toExport exp = let (curr, nds, edges) = ExplorerM.toExport exp in (curr, nds, map (\(r1, r2, (p, o)) -> (r1, r2, p)) edges)
+toExport = removeOut . ExplorerM.toExport
+  where 
+    removeOut (c, nodes, edges) = (c, nodes, map (\(s, t, (p, _)) -> (s, t, p)) edges)
 
 fromExport :: Explorer p c -> (Ref, [(Ref, c)], [(Ref, Ref, p)]) -> Explorer p c
-fromExport exp (curr, nds, edgs) = ExplorerM.fromExport exp (curr, nds, map (\(r1, r2, p) -> (r1, r2, (p, ()))) edgs)
+fromExport e exported = ExplorerM.fromExport e (addOut exported)
+  where
+    addOut (c, nodes, edges) = (c, nodes, map (\(s, t, p) -> (s, t, (p, ()))) edges)
diff --git a/Language/Explorer/Monadic.hs b/Language/Explorer/Monadic.hs
--- a/Language/Explorer/Monadic.hs
+++ b/Language/Explorer/Monadic.hs
@@ -1,31 +1,34 @@
 {-# LANGUAGE GADTs #-}
+{-# LANGUAGE ConstraintKinds #-}
 
+
 module Language.Explorer.Monadic
     ( Explorer
+    , mkExplorer
+    , mkExplorerNoSharing
     , execute
     , executeAll
     , revert
-    , dynamicRevert
+    , jump
     , toTree
     , incomingEdges
-    , mkExplorerStack
-    , mkExplorerTree
-    , mkExplorerGraph
-    , mkExplorerGSS
     , config
     , execEnv
     , currRef
-    , initialRef
     , leaves
     , Ref
+    , Language
     , deref
     , getTrace
     , getTraces
     , getPathsFromTo
     , getPathFromTo
     , executionGraph
-    , toExport
+    , shadowExecEnv
+    , eqClasses
+    , initialRef
     , fromExport
+    , toExport
     ) where
 
 import Data.Graph.Inductive.Graph
@@ -40,72 +43,93 @@
 import Data.Maybe
 
 type Ref = Int
+type Language p m c o = (Eq p, Eq o, Monad m, Monoid o)
 
 data Explorer programs m configs output where
-    Explorer :: (Show programs, Eq programs, Eq configs, Monad m, Monoid output) =>
-        { sharing :: Bool
-        , backTracking :: Bool
+    Explorer :: Language programs m configs output =>
+        { shadowing :: Bool -- Shadow the exploration tree in a shadow graph.
         , defInterp :: programs -> configs -> m (Maybe configs, output)
         , config :: configs -- Cache the config
         , currRef :: Ref
         , genRef :: Ref
         , cmap :: IntMap.IntMap configs
         , execEnv :: Gr Ref (programs, output)
+        , shadowExecEnv :: Gr [Ref] (programs, output)
+        , configEq :: configs -> configs -> Bool
         } -> Explorer programs m configs output
 
-mkExplorer :: (Show a, Eq a, Eq b, Monad m, Monoid o) =>
-  Bool -> Bool -> (a -> b -> m (Maybe b,o)) -> b -> Explorer a m b o
-mkExplorer share backtrack definterp conf = Explorer
+
+mkExplorer :: Language p m c o => Bool -> (c -> c -> Bool) -> (p -> c -> m (Maybe c, o)) -> c -> Explorer p m c o
+mkExplorer shadow shadowEq definterp conf = Explorer
     { defInterp = definterp
     , config = conf
     , genRef = 1 -- Currently generate references by increasing a counter.
     , currRef = initialRef
     , cmap = IntMap.fromList [(initialRef, conf)]
     , execEnv = mkGraph [(initialRef, initialRef)] []
-    , sharing = share
-    , backTracking = backtrack
+    , shadowExecEnv = mkGraph [(initialRef, [initialRef])] []
+    , shadowing = shadow
+    , configEq = shadowEq
 }
 
 initialRef :: Int
 initialRef = 1
 
-mkExplorerStack, mkExplorerTree, mkExplorerGraph, mkExplorerGSS :: (Show a, Eq a, Eq b, Monad m, Monoid o) => (a -> b -> m (Maybe b,o)) -> b -> Explorer a m b o
-mkExplorerStack = mkExplorer False True
-mkExplorerTree  = mkExplorer False False
-mkExplorerGraph = mkExplorer True False
-mkExplorerGSS   = mkExplorer True True
+mkExplorerNoSharing :: Language p m c o  => (p -> c -> m (Maybe c, o)) -> c -> Explorer p m c o
+mkExplorerNoSharing = mkExplorer False (\_ -> \_ -> False)
 
 deref :: Explorer p m c o -> Ref -> Maybe c
 deref e r = IntMap.lookup r (cmap e)
 
-findRef :: Eq c => Explorer p m c o -> c -> Maybe (Ref, c)
-findRef e c = find (\(r, c') -> c' == c) (IntMap.toList (cmap e))
+findRef :: Explorer p m c o -> c -> (c -> Bool) -> Maybe (Ref, c)
+findRef e c eq = find (\(r, c') -> eq c') (IntMap.toList (cmap e))
 
 addNewPath :: Explorer p m c o -> p -> o -> c -> Explorer p m c o
 addNewPath e p o c = e { config = c, currRef = newref, genRef = newref, cmap = IntMap.insert newref c (cmap e),
      execEnv = insNode (newref, newref) $ insEdge (currRef e, newref, (p,o)) (execEnv e)}
      where newref = genRef e + 1
 
-updateConf :: (Eq c, Eq p, Eq o) => Explorer p m c o -> (p, c, o) -> Explorer p m c o
-updateConf e (p, newconf, output) =
-    if sharing e
-        then case findRef e newconf of
-            Just (r, c) ->
-                if hasLEdge (execEnv e) (currRef e, r, (p,output))
-                    then e  { config = newconf, currRef = r }
-                    else e  { config = newconf, currRef = r
-                            , execEnv = insEdge (currRef e, r, (p,output)) (execEnv e) }
-            Nothing -> addNewPath e p output newconf
-        else addNewPath e p output newconf
 
-execute :: (Eq c, Eq p, Eq o, Monad m, Monoid o) =>  p -> Explorer p m c o -> m (Explorer p m c o, o)
+findNodeRef :: Gr [Ref] (p, o) -> Ref -> Ref
+findNodeRef g r = fst $ fromJust $ find (\(_, rs) -> r `elem` rs) $ labNodes g
+
+
+updateShadowEnv :: Language p m c o => Explorer p m c o -> (p, c, o, Ref, Ref) -> Explorer p m c o
+updateShadowEnv e (p, newconf, output, newref, oldref) =
+  case findRef e newconf (configEq e newconf) of
+    Just (r', _) ->
+      if hasLEdge shadowEnv (nref, findNodeRef shadowEnv r', (p, output))
+        then e
+        else e {
+          shadowExecEnv = updateLabel (findNodeRef shadowEnv r', newref, p, output) $ insEdge (nref, findNodeRef shadowEnv r', (p, output)) shadowEnv
+        }
+    Nothing -> e {
+      shadowExecEnv = insNode (newref, [newref]) $ insEdge (nref, newref, (p, output)) $ shadowExecEnv e
+    }
+    where
+      shadowEnv = shadowExecEnv e
+      nref = findNodeRef shadowEnv oldref
+      updateLabel (target, add_to_label, p, output) gr =
+        case match target gr of
+          (Just (toadj, node, label, fromadj), decomgr) -> (toadj, node, add_to_label : label, fromadj) & decomgr
+          _ -> error "Shadow execution environment is inconsistent."
+
+
+updateExecEnvs :: Language p m c o => Explorer p m c o -> (p, c, o) -> Explorer p m c o
+updateExecEnvs e (p, newconf, output)
+  | shadowing e = addNewPath (updateShadowEnv e (p, newconf, output, (currRef newexplorer), (currRef e))) p output newconf
+  | otherwise = newexplorer
+  where
+    newexplorer = addNewPath e p output newconf
+
+execute :: Language p m c o =>  p -> Explorer p m c o -> m (Explorer p m c o, o)
 execute p e =
   do (mcfg, o) <- defInterp e p (config e)
      case mcfg of
-       Just cfg -> return $ (updateConf e (p, cfg, o), o)
+       Just cfg -> return (updateExecEnvs e (p, cfg, o), o)
        Nothing  -> return (e, o)
 
-executeAll :: (Eq c, Eq p, Eq o, Monad m, Monoid o) => [p] -> Explorer p m c o -> m (Explorer p m c o, o)
+executeAll :: Language p m c o => [p] -> Explorer p m c o -> m (Explorer p m c o, o)
 executeAll ps exp = foldlM executeCollect (exp, mempty) ps
   where executeCollect (exp, out) p = do (res, out') <- execute p exp
                                          return (res, out `mappend` out')
@@ -113,21 +137,57 @@
 deleteMap :: [Ref] -> IntMap.IntMap a -> IntMap.IntMap a
 deleteMap xs m = foldl (flip IntMap.delete) m xs
 
-dynamicRevert :: Bool -> Ref -> Explorer p m c o -> Maybe (Explorer p m c o)
-dynamicRevert backtrack r e =
-  case IntMap.lookup r (cmap e) of
-    Just c | backtrack -> Just e { execEnv = execEnv', currRef = r, config = c, cmap = cmap'}
-           | otherwise -> Just e { currRef = r, config = c }
-    Nothing            -> Nothing
-    where nodesToDel = reachable r (execEnv e) \\ [r]
-          edgesToDel = filter (\(s, t) -> s `elem` nodesToDel || t `elem` nodesToDel) (edges (execEnv e))
-          execEnv'   = (delEdges edgesToDel . delNodes nodesToDel) (execEnv e)
-          cmap'      = deleteMap nodesToDel (cmap e)
 
+deleteFromShadowEnv :: [(Ref, Ref)] -> Gr [Ref] po -> Gr [Ref] po
+deleteFromShadowEnv [(l, r)] gr = case match r gr of
+  (Just (toadj, node, label, fromadj), decomgr) -> (toadj, node, label \\ [l], fromadj) & decomgr
+  _ -> error "Inconsistent shadow env."
+deleteFromShadowEnv (x:xs) gr = deleteFromShadowEnv xs (deleteFromShadowEnv [x] gr)
 
+cleanEdges :: [Ref] -> [(Ref, Ref, (p, o))] -> [(Ref, Ref, (p, o))]
+cleanEdges ref edg = filter (\(s, t, l) -> not $ t `elem` ref) edg
+
+cleanShadowEnv :: Bool -> [Ref] -> Gr [Ref] (p, o) -> Gr [Ref] (p, o)
+cleanShadowEnv False _ g = g
+cleanShadowEnv True nds g = shadowEnv''
+  where
+    shadowEnv' = deleteFromShadowEnv (map (\r -> (r, findNodeRef g r)) nds) g
+    nodesToDel' = map fst (filter (\(r, labels) -> labels == []) $ labNodes (shadowEnv'))
+    edgesToDel' = filter (\(s, t) -> s `elem` nodesToDel' || t `elem` nodesToDel') (edges shadowEnv')
+    shadowEnv'' = (delEdges edgesToDel' . delNodes nodesToDel') shadowEnv'
+
+data RevertableStatus = ContinueRevert | StopRevert deriving Show
+
+findRevertableNodes gr source target = 
+  case findNextNodeInPath gr source target of
+    (Just node) -> fst $ findRevertableNodes' gr node target
+    Nothing     -> []
+  where 
+    findNextNodeInPath gr source target = find (\n -> target `elem` (reachable n gr)) (suc gr source) 
+    findRevertableNodes' gr source target 
+      | source == target = if outdeg gr source > 1 then ([], StopRevert) else ([source], ContinueRevert) 
+      | otherwise = case findNextNodeInPath gr source target of
+        (Just node) -> case findRevertableNodes' gr node target of
+          (res, StopRevert) -> (res, StopRevert)
+          (res, ContinueRevert) -> if outdeg gr source > 1 then (res, StopRevert) else (source : res, ContinueRevert)
+        Nothing -> ([], ContinueRevert)
+
 revert :: Ref -> Explorer p m c o -> Maybe (Explorer p m c o)
-revert r e = dynamicRevert (backTracking e) r e
+revert r e
+  | currRef e `elem` reachNodes =
+      jump r e >>= \e' -> return $ e' { execEnv = mkGraph (zip remainNodes remainNodes) $ cleanEdges reachNodes (labEdges $ execEnv e')
+                                      ,  cmap = deleteMap reachNodes (cmap e')
+                                      , shadowExecEnv = cleanShadowEnv (shadowing e') reachNodes (shadowExecEnv e')}
+  | otherwise = Nothing
+  where
+    reachNodes = findRevertableNodes gr r (currRef e)
+    remainNodes = nodes gr \\ reachNodes
+    gr = execEnv e
 
+jump :: Ref -> Explorer p m c o -> Maybe (Explorer p m c o)
+jump r e = case deref e r of
+             (Just c) -> return $ e { config = c, currRef = r }
+             Nothing -> Nothing
 
 toTree :: Explorer p m c o -> Tree (Ref, c)
 toTree exp = mkTree initialRef
@@ -141,14 +201,6 @@
   where
     unpack ref = fromJust $ deref e ref
 
-
-transformToRealGraph :: Gr Ref p -> Gr Ref Int
-transformToRealGraph g = mkGraph (labNodes g) (map (\(s, t) -> (s, t, 1)) (edges g))
-
-transformToPairs :: [Ref] -> [(Ref, Ref)]
-transformToPairs (s:t:xs) = (s, t) : transformToPairs (t:xs)
-transformToPairs _ = []
-
 getTrace :: Explorer p m c o -> [((Ref, c), (p, o), (Ref, c))]
 getTrace e = getPathFromTo e initialRef (currRef e)
 
@@ -177,12 +229,13 @@
     (x:_) -> x
 
 
-executionGraph :: Explorer p m c o -> (Ref, [Ref], [((Ref, c), (p, o), (Ref, c))])
+
+executionGraph :: Explorer p m c o -> ((Ref, c), [(Ref, c)], [((Ref, c), (p, o), (Ref, c))])
 executionGraph exp =
   (curr, nodes, edges)
   where
-    curr = currRef exp
-    nodes = map fst (labNodes (execEnv exp))
+    curr = (currRef exp, config exp)
+    nodes = IntMap.toList $ cmap exp
     edges = map (\(s, t, p) -> ((s, fromJust $ deref exp s), p, (t, fromJust $ deref exp t)) ) (labEdges (execEnv exp))
 
 {-|
@@ -190,16 +243,26 @@
   This corresponds to leaves in a tree or nodes without an outbound-edge in a graph.
 -}
 leaves :: Explorer p m c o -> [(Ref, c)]
-leaves exp = map refToPair leave_nodes
+leaves exp = map refToPair leaf_nodes
   where
     env = execEnv exp
     refToPair = \r -> (r, fromJust $ deref exp r)
-    leave_nodes = nodes $ nfilter (\n -> (==0) $ outdeg env n) env
+    leaf_nodes = nodes $ nfilter (\n -> (==0) $ outdeg env n) env
 
 
 toExport :: Explorer p m c o -> (Ref, [(Ref, c)], [(Ref, Ref, (p, o))])
 toExport exp = (currRef exp, IntMap.toList $ cmap exp, labEdges $ execEnv exp)
 
 fromExport :: Explorer p m c o -> (Ref, [(Ref, c)], [(Ref, Ref, (p, o))]) -> Explorer p m c o
-fromExport exp (curr, nds, edgs) = exp { genRef = findMax nds, currRef = curr, cmap = IntMap.fromList nds, execEnv = mkGraph (map (\(x, _) -> (x, x)) nds) edgs }
+fromExport exp (curr, nds, edgs) = exp { genRef = findMax nds,
+                                         config = findCurrentConf curr nds,
+                                         currRef = curr, 
+                                         cmap = IntMap.fromList nds, 
+                                         execEnv = mkGraph (map (\(x, _) -> (x, x)) nds) edgs }
   where findMax l = maximum $ map fst l
+        findCurrentConf curr nds = case lookup curr nds of
+                                     Just conf -> conf
+                                     Nothing   -> error "no config found"
+
+eqClasses :: Explorer p m c o -> [[Ref]]
+eqClasses expl = map snd $ labNodes $ shadowExecEnv expl
diff --git a/Language/Explorer/Pure.hs b/Language/Explorer/Pure.hs
--- a/Language/Explorer/Pure.hs
+++ b/Language/Explorer/Pure.hs
@@ -1,19 +1,17 @@
+{-# LANGUAGE ConstraintKinds #-}
+
 module Language.Explorer.Pure
     ( Explorer
+    , mkExplorer
+    , mkExplorerNoSharing
     , execute
     , executeAll
     , revert
-    , dynamicRevert
     , ExplorerM.toTree
     , incomingEdges
-    , mkExplorerStack
-    , mkExplorerTree
-    , mkExplorerGraph
-    , mkExplorerGSS
     , config
     , currRef
     , Ref
-    , ExplorerM.initialRef
     , deref
     , leaves
     , getTrace
@@ -36,7 +34,14 @@
 -- the same.
 type Ref = ExplorerM.Ref
 type Explorer a b o = ExplorerM.Explorer a Identity b o
+type PureLanguage p c o = (Eq p, Eq o, Monoid o)
 
+mkExplorer :: PureLanguage p c o => Bool -> (c -> c -> Bool) -> (p -> c -> (Maybe c, o)) -> c -> Explorer p c o
+mkExplorer shadowing eqfunc definterp initialConf = ExplorerM.mkExplorer shadowing eqfunc (wrap definterp) initialConf
+
+mkExplorerNoSharing :: PureLanguage p c o => (p -> c -> (Maybe c, o)) -> c -> Explorer p c o
+mkExplorerNoSharing = mkExplorer False (const . const $ False)
+
 currRef :: Explorer a b o -> Ref
 currRef = ExplorerM.currRef
 
@@ -46,24 +51,15 @@
 deref :: Explorer p c o -> Ref -> Maybe c
 deref = ExplorerM.deref
 
-wrap :: (Monad m, Monoid o) => (a -> b -> (Maybe b,o)) -> a -> b -> m (Maybe b, o)
+wrap :: (Monad m, Monoid o) => (a -> b -> (Maybe b, o)) -> a -> b -> m (Maybe b, o)
 wrap def p e = return $ def p e
 
-mkExplorerStack, mkExplorerTree, mkExplorerGraph, mkExplorerGSS:: (Show a, Eq a, Eq b, Monoid o) => (a -> b -> (Maybe b,o)) -> b -> Explorer a b o
-mkExplorerStack definterp conf = ExplorerM.mkExplorerStack (wrap definterp) conf
-mkExplorerTree definterp conf = ExplorerM.mkExplorerTree (wrap definterp) conf
-mkExplorerGraph definterp conf = ExplorerM.mkExplorerGraph (wrap definterp) conf
-mkExplorerGSS definterp conf = ExplorerM.mkExplorerGSS (wrap definterp) conf
-
-execute :: (Eq c, Eq p, Eq o, Monoid o) =>  p -> Explorer p c o -> (Explorer p c o, o)
+execute :: PureLanguage p c o =>  p -> Explorer p c o -> (Explorer p c o, o)
 execute p e = runIdentity $ ExplorerM.execute p e
 
-executeAll :: (Eq c, Eq p, Eq o, Monoid o) => [p] -> Explorer p c o -> (Explorer p c o, o)
+executeAll :: PureLanguage p c o => [p] -> Explorer p c o -> (Explorer p c o, o)
 executeAll p e = runIdentity $ ExplorerM.executeAll p e
 
-dynamicRevert :: Bool -> Ref -> Explorer p c o -> Maybe (Explorer p c o)
-dynamicRevert = ExplorerM.dynamicRevert
-
 revert :: ExplorerM.Ref -> Explorer p c o -> Maybe (Explorer p c o)
 revert = ExplorerM.revert
 
@@ -82,7 +78,7 @@
 getPathFromTo :: Explorer p c o -> Ref -> Ref -> [((Ref, c), (p, o), (Ref, c))]
 getPathFromTo = ExplorerM.getPathFromTo
 
-executionGraph :: Explorer p c o -> (Ref, [Ref], [((Ref, c), (p, o), (Ref, c))])
+executionGraph :: Explorer p c o -> ((Ref, c), [(Ref, c)], [((Ref, c), (p, o), (Ref, c))])
 executionGraph = ExplorerM.executionGraph
 
 leaves :: Explorer p c o -> [(Ref, c)]
diff --git a/Language/Explorer/Tools/Protocol.hs b/Language/Explorer/Tools/Protocol.hs
new file mode 100644
--- /dev/null
+++ b/Language/Explorer/Tools/Protocol.hs
@@ -0,0 +1,451 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+
+
+
+module Language.Explorer.Tools.Protocol where
+
+import GHC.Generics
+import Data.Monoid
+import Data.Aeson
+import Network.HTTP.Types.Status
+import Network.HTTP.Types.Header (hContentType)
+import Data.Maybe
+import Control.Concurrent (forkFinally)
+import qualified Control.Exception as E
+import Control.Monad (unless, forever, void)
+import qualified Data.ByteString.Lazy as S
+import qualified Data.Attoparsec.ByteString.Lazy as AB
+import qualified Data.Attoparsec.ByteString.Char8 as ABC
+import Network.Socket hiding (recv)
+import Network.Socket.ByteString.Lazy (recv, sendAll)
+import Data.Scientific
+import qualified Language.Explorer.Monadic as Ex
+import Control.Monad.RWS.Lazy hiding (listen)
+import Control.Monad.Trans.Except
+import Data.List
+
+type ExplorerParser p m c o = (Ex.Explorer p m c o, String -> Maybe p)
+type ProcessResult = Either ErrorMessage Value
+
+type EIP p m c o = RWST (String -> Maybe p) S.ByteString (Ex.Explorer p m c o) m
+
+class ExplorerPostValue p c o where
+    postExecute :: Ex.Explorer p m c o -> Ex.Explorer p m c o -> o -> Value
+    postExecute = \_ _ _ -> Null
+    postJump :: Ex.Explorer p m c o -> Ex.Explorer p m c o -> Value
+    postJump = \_ _ -> Null
+    postRevert :: Ex.Explorer p m c o -> Ex.Explorer p m c o -> [Ex.Ref] -> Value
+    postRevert = \ _ _ _ -> Null
+
+data RequestMessage = RequestMessage {
+    jsonrpc :: String,
+    req_id :: String,
+    method :: String,
+    params :: Maybe Value
+} deriving (Show, Generic)
+
+instance ToJSON RequestMessage where
+    toEncoding = genericToEncoding defaultOptions
+
+instance FromJSON RequestMessage where
+    parseJSON = withObject "RequestMessage" $ \v -> RequestMessage
+        <$> v .: "jsonrpc"
+        <*> v .: "id"
+        <*> v .: "method"
+        <*> v .:? "params"
+
+data ResponseMessage = ResponseMessage {
+    res_id :: String,
+    body :: ProcessResult
+} deriving (Show)
+
+instance ToJSON ResponseMessage where
+    toJSON (ResponseMessage res_id (Left e)) = object ["id" .= res_id, "error" .= e]
+    toJSON (ResponseMessage res_id (Right res)) = object ["id" .= res_id, "result" .= res]
+
+    toEncoding (ResponseMessage res_id (Left e)) = pairs ("id" .= res_id <> "error" .= e)
+    toEncoding (ResponseMessage res_id (Right res)) = pairs ("id" .= res_id <> "result" .= res)
+
+
+data ErrorMessage = ErrorMessage {
+    code :: Int,
+    message :: String,
+    error_data :: Maybe Value
+} deriving (Show, Generic)
+
+instance ToJSON ErrorMessage where
+    toEncoding = genericToEncoding defaultOptions
+
+instance FromJSON ErrorMessage
+    -- No need to provide a parseJSON implementation.
+
+-- instance Except ErrorMessage 
+-- where
+--     noMsg = ErrorMessage { code = 0, message = "", error_data = Nothing}
+--     strMsg msg = ErrorMessage {code = 0, message = msg, error_data = Nothing }
+
+data JumpParams = JumpParams {
+    jump_ref :: Int
+}
+
+instance FromJSON JumpParams where
+    parseJSON = withObject "JumpParams" $ \v -> JumpParams
+        <$> v .: "reference"
+
+data JumpResult = JumpResult {
+    jump_post :: Value
+}
+
+instance ToJSON JumpResult where 
+    toJSON res = object ["post" .= jump_post res]
+
+data ExecuteParams = ExecuteParams {
+    program :: String
+} deriving (Show, Generic)
+
+instance FromJSON ExecuteParams
+
+data ExecuteResult = ExecuteResult {
+    exec_ref :: Int,
+    exec_out :: Value,
+    exec_post :: Value
+}
+
+instance ToJSON ExecuteResult where
+    toJSON (ExecuteResult ref out post) = object ["reference" .= ref, "output" .= out, "post" .= post]
+
+    toEncoding (ExecuteResult ref out post) = pairs ("reference" .= ref <> "output" .= out <> "post" .= post)
+
+data RevertParams = RevertParams {
+    revert_ref :: Int
+}
+
+instance FromJSON RevertParams where
+    parseJSON = withObject "RevertParams" $ \v -> RevertParams
+        <$> v .: "reference"
+
+data RevertResult = RevertResult {
+    revert_deleted :: [Ex.Ref],
+    post_revert :: Value
+}
+
+instance ToJSON RevertResult where 
+    toJSON res = object ["deleted" .= revert_deleted res, "post" .= post_revert res]
+
+data DerefParams = DerefParams {
+    deref_ref :: Int
+}
+
+instance FromJSON DerefParams where
+    parseJSON = withObject "DerefParams" $ \v -> DerefParams
+        <$> v .: "reference"
+
+
+data TraceParams = TraceParams {
+    reference :: Int
+} deriving (Generic)
+
+instance FromJSON TraceParams
+
+
+data Edge = Edge {
+    source :: Int,
+    target :: Int,
+    label  :: EdgeLabel
+} deriving (Generic)
+
+instance ToJSON Edge where
+    toEncoding = genericToEncoding defaultOptions
+
+
+data EdgeLabel = EdgeLabel {
+    program :: Value,
+    mval :: Value
+} deriving (Generic)
+
+instance ToJSON EdgeLabel where
+    toEncoding = genericToEncoding defaultOptions
+
+
+data ExecutionTree = ExecutionTree {
+    current :: Int,
+    references :: [Int],
+    edges :: [Edge]
+} deriving (Generic)
+
+instance ToJSON ExecutionTree where
+    toEncoding = genericToEncoding defaultOptions
+
+data PathParams = PathParams {
+    source :: Int,
+    target :: Int
+} deriving (Generic)
+
+instance FromJSON PathParams
+
+parseErrorCode = -32700
+invalidRequestCode = -32600
+methodNotFoundCode = -32601
+invalidParamsCode = -32602
+internalErrorCode = -32603
+
+referenceNotInTreeCode = 1
+referenceRevertInvalidCode = 2
+programParseErrorCode = 3
+pathNonExistingCode = 4
+
+
+
+parseError :: ErrorMessage
+parseError = ErrorMessage {
+    code = parseErrorCode,
+    message = "Parse error",
+    error_data = Nothing
+}
+
+methodNotFound :: ErrorMessage
+methodNotFound = ErrorMessage {
+    code = methodNotFoundCode,
+    message = "Method not found",
+    error_data = Nothing
+}
+
+invalidParams :: ErrorMessage
+invalidParams = ErrorMessage {
+    code = invalidParamsCode,
+    message = "Invalid method parameter(s)",
+    error_data = Nothing
+}
+
+ensureParameter :: Monad m => Maybe Value -> ExceptT ErrorMessage (EIP p m c o) Value
+ensureParameter Nothing = throwE invalidParams
+ensureParameter (Just v) = return v
+
+fromResult :: Monad m => Result a -> Value -> ExceptT ErrorMessage (EIP p m c o) Value
+fromResult res onSuccess = case res of
+    (Error e) -> throwE invalidParams
+    (Success v) -> return onSuccess
+
+jump :: (Monad m, ExplorerPostValue p c o) => Value -> ExceptT ErrorMessage (EIP p m c o) Value
+jump v = case (fromJSON v) :: Result JumpParams of
+    (Error e) -> throwE invalidParams
+    (Success v') -> do
+        ex <- lift $ get
+        case Ex.jump (jump_ref v') ex of
+            Just ex' -> do
+                lift $ put $ ex'
+                return . toJSON . JumpResult $ postJump ex ex'
+            Nothing -> throwE ErrorMessage { code = referenceNotInTreeCode, message = "", error_data = Nothing }
+
+execute :: (Eq o, Monoid o, ToJSON o, Eq p, ExplorerPostValue p c o) => Value -> ExceptT ErrorMessage (EIP p IO c o) Value
+execute v = case (fromJSON v) :: Result ExecuteParams of
+    (Error e) -> throwE invalidParams
+    (Success v') -> do
+        parser <- lift $ ask
+        let pl = parser $ program (v' :: ExecuteParams)
+        case pl of
+            Just prog -> do
+                ex <- lift $ get
+                (ex', output) <- liftIO $ Ex.execute prog ex
+                lift $ put ex'
+                return $ toJSON $ ExecuteResult { exec_ref = Ex.currRef ex', exec_out = toJSON output, exec_post = postExecute ex ex' output }
+            Nothing -> throwE ErrorMessage { code = programParseErrorCode, message = "", error_data = Nothing }
+
+allRefs :: Ex.Explorer p IO c o -> [(Ex.Ref, c)]
+allRefs ex = refs
+    where
+        (_, refs, _) = Ex.executionGraph ex
+
+
+revert :: (Eq o, Monoid o, Eq p, ExplorerPostValue p c o) => Value -> ExceptT ErrorMessage (EIP p IO c o) Value
+revert v = case (fromJSON v) :: Result RevertParams of
+    (Error e) -> throwE invalidParams
+    (Success v) -> do
+        ex <- lift $ get
+        case Ex.revert (revert_ref v) ex of
+            Just ex' -> do
+                lift $ put ex'
+                return $ toJSON $ RevertResult { revert_deleted = deleted, post_revert = postRevert ex ex' deleted}
+                where 
+                    refs = map fst (allRefs ex)
+                    refs' = map fst (allRefs ex')
+                    deleted = (refs \\ refs')
+            Nothing -> throwE ErrorMessage { code = referenceRevertInvalidCode, message = "", error_data = Nothing }
+
+deref :: (Eq o, Monoid o, Eq p, ToJSON c) => Value -> ExceptT ErrorMessage (EIP p IO c o) Value
+deref v = case (fromJSON v) :: Result DerefParams of
+    (Error e) -> throwE invalidParams
+    (Success v) -> do
+        ex <- lift $ get
+        case Ex.deref ex (deref_ref v) of
+            (Just conf) -> return $ toJSON conf
+            Nothing -> throwE ErrorMessage { code = referenceNotInTreeCode, message = "", error_data = Nothing}
+
+executionTree :: (ToJSON o, ToJSON p) => ExceptT ErrorMessage (EIP p IO c o) Value
+executionTree = do
+    ex <- lift $ get
+    let (curr, nodes, edges) = Ex.executionGraph ex
+    return $ toJSON $ ExecutionTree 
+        { current = fst curr
+        , references = map fst nodes
+        , edges = map (\(s, (p, o), t) -> Edge { source = fst s
+        , label = EdgeLabel { program = toJSON p, mval = toJSON o}
+        , target = fst t} ) edges}
+
+getCurrentReference :: ExceptT ErrorMessage (EIP p IO c o) Value
+getCurrentReference = do
+    ex <- lift $ get
+    return $ toJSON $ Ex.currRef ex
+
+getAllReferences :: ExceptT ErrorMessage (EIP p IO c o) Value
+getAllReferences = do
+    ex <- lift $ get
+    return $ toJSON $ map fst (allRefs ex)
+
+getTrace :: (ToJSON p, ToJSON o) => Maybe Value -> ExceptT ErrorMessage (EIP p IO c o) Value
+getTrace (Just r) = case (fromJSON r) :: Result TraceParams of
+    (Error e) -> throwE invalidParams
+    (Success v) -> do
+        ex <- lift $ get
+        let path = Ex.getPathFromTo ex 1 (reference (v :: TraceParams)) -- Fix hardcode 1(it's initialRef).
+        return $ toJSON $ map (\(s, (p, o), t) -> Edge { source = fst s, target = fst t, label = EdgeLabel { program = toJSON p, mval = toJSON o} }) path
+getTrace Nothing = do
+    ex <- lift $ get
+    let trace = Ex.getTrace ex
+    return $ toJSON $ map (\(s, (p, o), t) -> Edge { source = fst s, target = fst t, label = EdgeLabel { program = toJSON p, mval = toJSON o} }) trace
+
+getPath :: (ToJSON o, ToJSON p) => Value -> ExceptT ErrorMessage (EIP p IO c o) Value
+getPath val = case (fromJSON val) :: Result PathParams of
+    (Error e) -> throwE ErrorMessage { code = pathNonExistingCode, message = "", error_data = Nothing}
+    (Success v) -> do
+        ex <- lift $ get
+        let path = Ex.getPathFromTo ex (source (v :: PathParams)) (target (v :: PathParams))
+        return $ toJSON $ map (\(s, (p, o), t) -> Edge { source = fst s, target = fst t, label = EdgeLabel { program = toJSON p, mval = toJSON o} }) path
+
+getLeaves :: ExceptT ErrorMessage (EIP p IO c o) Value
+getLeaves = do
+    ex <- lift $ get
+    return $ toJSON $ map fst (Ex.leaves ex)
+
+methodDispatch :: (Eq o, Monoid o, ToJSON o, ToJSON p, Eq p, ToJSON c, ExplorerPostValue p c o) => String -> Maybe Value -> ExceptT ErrorMessage (EIP p IO c o) Value
+methodDispatch "jump" mval = ensureParameter mval >>= jump
+methodDispatch "execute" mval = ensureParameter mval >>= execute
+methodDispatch "revert" mval = ensureParameter mval >>= revert
+methodDispatch "deref" mval = ensureParameter mval >>= deref
+methodDispatch "getTrace" mval = getTrace mval
+methodDispatch "getPath" mval = ensureParameter mval >>= getPath
+methodDispatch "getExecutionTree" _ = executionTree
+methodDispatch "getCurrentReference" _ = getCurrentReference
+methodDispatch "getAllReferences" _ = getAllReferences
+methodDispatch "getLeaves" _ = getLeaves
+methodDispatch _ _ = throwE methodNotFound
+
+handleRequest :: (Eq o, Monoid o, ToJSON o, ToJSON o, ToJSON p, Eq p, ToJSON c, ExplorerPostValue p c o) => Maybe RequestMessage -> EIP p IO c o ResponseMessage
+handleRequest (Just msg) = do
+    res <- runExceptT $ methodDispatch (method msg) (params msg)
+    return $ ResponseMessage { res_id = req_id msg, body = res }
+handleRequest Nothing = return $ ResponseMessage { res_id = "0", body = Left parseError { message = "NOthing" }}
+
+
+handleRequest' :: (Eq o, Monoid o, ToJSON o, Eq p, ToJSON p, ToJSON c, ExplorerPostValue p c o) => S.ByteString -> EIP p IO c o ResponseMessage
+handleRequest' body =
+    case decode body of
+        (Just m) -> handleRequest m
+        Nothing -> return invalidHeader
+
+invalidHeader :: ResponseMessage
+invalidHeader = ResponseMessage { res_id = "0", body = Left parseError {message = "Headeer"} }
+
+parseHeader :: AB.Parser (Int, String)
+parseHeader = do
+    AB.string "Content-Length:"
+    AB.skipMany (ABC.char ' ')
+    res <- ABC.scientific
+    AB.skipMany (ABC.char ' ')
+    ABC.char '\r'
+    ABC.char '\n'
+    ABC.string "Content-Type:"
+    AB.skipMany (ABC.char ' ')
+    typ <- AB.manyTill ABC.letter_ascii (ABC.char '\r')
+    AB.skipMany (ABC.char ' ')
+    ABC.char '\n'
+    ABC.char '\r'
+    ABC.char '\n'
+    return $ (fromJust $ ((toBoundedInteger res) :: Maybe Int), typ)
+
+
+intProg :: Int -> Int -> IO (Maybe Int, ())
+intProg x y = do
+    putStrLn . show $ y
+    return (Just x, ())
+
+intParse :: String -> Maybe Int
+intParse _ = Just 1
+
+-- TODO: Handle incorrect request.
+-- TODO: Send correct error messages.
+serve :: (Eq o, Monoid o, ToJSON o, Eq p, ToJSON p, ToJSON c, ExplorerPostValue p c o) => String -> Ex.Explorer p IO c o -> (String -> Maybe p) -> IO ()
+serve port ex parser = withSocketsDo $ do
+    addr <- resolve port
+    E.bracket (open addr) close loop
+  where
+    resolve port = do
+        let hints = defaultHints {
+                addrFlags = [AI_PASSIVE]
+              , addrSocketType = Stream
+              }
+        addr:_ <- getAddrInfo (Just hints) Nothing (Just port)
+        return addr
+    open addr = do
+        sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
+        setSocketOption sock ReuseAddr 1
+        bind sock (addrAddress addr)
+        -- If the prefork technique is not used,
+        -- set CloseOnExec for the security reasons.
+        fd <- fdSocket sock
+        setCloseOnExecIfNeeded fd
+        listen sock 10
+        return sock
+    loop sock = forever $ do
+        (conn, peer) <- accept sock
+        putStrLn $ "Connection from " ++ show peer
+        forkFinally (talk ex parser conn) (\_ -> close conn)
+    talk ex parser conn = do
+        putStrLn "Hello receiving"
+        msg <- recv conn 1024
+        unless (S.null msg) $ do
+            ex' <- acceptCommand ex parser conn msg
+            talk ex' parser conn
+
+acceptCommand ex parser conn command = do
+    let res = AB.parse parseHeader command
+    putStrLn $ show res
+    (result, toParse) <- case res of
+        (AB.Done rem (val, _)) -> do
+            case S.length rem < (fromIntegral val) of
+                True -> do
+                    msg <- recv conn 1024
+                    return (Nothing, S.append command msg)
+                False -> do
+                    let command = S.take (fromIntegral val) rem
+                    putStrLn "-------------------------"
+                    putStrLn $ show command
+                    putStrLn "-------------------------"
+                    out <- runRWST (handleRequest' command) parser ex
+                    return (Just out, S.drop (fromIntegral val) rem)
+        (AB.Fail _ _ "not enough input") -> do
+            msg <- recv conn 1024
+            return (Nothing, S.append command msg)
+        _ ->  return (Just (invalidHeader, ex, ""), "")
+    case result of
+        Nothing -> if toParse == "" then return ex else acceptCommand ex parser conn toParse
+        Just (resp, ex', log) -> do
+            let encoded_resp = encode resp
+            let full_resp = S.concat ["Content-Length:", encode $ S.length encoded_resp, "\r\nContent-Type: jrpcei\r\n\r\n", encoded_resp]
+            sendAll conn full_resp
+            putStrLn $ show full_resp
+            putStrLn $ show toParse
+            if toParse == "" then return ex' else acceptCommand ex' parser conn toParse
diff --git a/Language/Explorer/Tools/REPL.hs b/Language/Explorer/Tools/REPL.hs
new file mode 100644
--- /dev/null
+++ b/Language/Explorer/Tools/REPL.hs
@@ -0,0 +1,72 @@
+module Language.Explorer.Tools.REPL where 
+
+import Control.Monad.IO.Class (MonadIO(..))
+import Language.Explorer.Monadic
+    (Explorer(config), execute, revert, jump, toTree)
+import qualified System.Console.Readline as Rl
+import Data.Tree (drawTree)
+import Data.Maybe (fromJust, isNothing)
+import Data.Char (isSpace)
+import Data.List (find, isPrefixOf) 
+import Text.Read (readMaybe)
+import Control.Arrow (Arrow(first))
+
+
+
+type MetaTable p m c o = [(String, String -> Explorer p m c o -> m (Explorer p m c o))]
+type RParser p c = String -> c -> Maybe p
+type Prompt p m c o = Explorer p m c o -> String
+type MetaHandler p m c o = String -> Explorer p m c o -> m (Explorer p m c o)
+type OutputHandler m o = o -> m ()
+type Repl p m c o = Prompt p m c o -> RParser p c -> String -> MetaTable p m c o -> MetaHandler p m c o -> OutputHandler m o -> Explorer p m c o -> m ()
+
+
+handleJump :: MonadIO m => String -> Explorer p m c o -> m (Explorer p m c o)
+handleJump input ex = case readMaybe (dropWhile isSpace input) of
+  (Just ref_id) -> case jump ref_id ex of
+    (Just ex') -> return ex'
+    Nothing -> liftIO $ putStrLn "Given reference is not in the exploration tree." >> return ex
+  Nothing -> liftIO $ putStrLn "the jump command requires an integer argument." >> return ex
+
+handleRevert :: MonadIO m => MetaHandler p m c o
+handleRevert input ex = case readMaybe (dropWhile isSpace input) of
+  (Just ref_id) -> case revert ref_id ex of
+    (Just ex') -> do
+      liftIO $ putStrLn "reverting"
+      return ex'
+    Nothing -> liftIO $ putStrLn "Given reference is not valid for reverting." >> return ex
+  Nothing -> liftIO $ putStrLn "the jump command requires an integer argument." >> return ex
+
+handleTree :: MonadIO m => MetaHandler p m c o
+handleTree input ex = do
+  liftIO $ putStrLn . drawTree $ fmap (show . fst) (toTree ex)
+  return ex
+
+metaTable :: MonadIO m => [(String, String -> Explorer p m c o -> m (Explorer p m c o))]
+metaTable = [
+  ("jump", handleJump),
+  ("revert", handleRevert),
+  ("tree", handleTree)]
+
+constructMetaTable :: MonadIO m => String -> [(String, String -> Explorer p m c o -> m (Explorer p m c o))]
+constructMetaTable prefix = map (first (prefix ++ )) metaTable
+
+repl :: (Eq p, Eq o, Monoid o, MonadIO m) => Repl p m c o
+repl prompt parser metaPrefix metaTable metaHandler outputHandler ex = do
+  minput <- liftIO . Rl.readline . prompt $ ex
+  case minput of
+    (Just input) -> do
+      liftIO $ Rl.addHistory input
+      if metaPrefix `isPrefixOf` input then runMeta input else runExec input
+    Nothing -> return ()
+  where
+    repl' = repl prompt parser metaPrefix metaTable metaHandler outputHandler
+    runMeta input =
+      let (pcmd, args) = break isSpace input in
+        case find (\(cmd, _) -> (metaPrefix ++ cmd) == pcmd) metaTable of
+          Just (_, f) -> f args ex >>= repl'
+          Nothing -> metaHandler input ex >>= repl'
+    runExec input =
+      case parser input (config ex) of
+        (Just program) -> execute program ex >>= \(newEx, out) -> (outputHandler out >> repl' newEx)
+        Nothing -> repl' ex
diff --git a/examples/Whilelang.hs b/examples/Whilelang.hs
--- a/examples/Whilelang.hs
+++ b/examples/Whilelang.hs
@@ -2,6 +2,7 @@
 
 import qualified Data.Map as Map
 import Data.List
+import Data.Maybe
 import Data.Graph.Inductive (emap)
 import Control.Monad.Trans.Writer.Lazy
 import Control.Monad.Trans.State.Lazy
@@ -135,49 +136,63 @@
 do_ :: Command -> WhileExplorer -> IO WhileExplorer
 do_ (Seq c1 c2) e = do_ c1 e >>= do_ c2
 do_ p e = do
-    let e' = E.execute p e 
+    let e' = E.execute p e
     putStr $ unlines $ cfgOutput (E.config e') \\ cfgOutput (E.config e)
     return e'
 
 do_2 :: Command -> WhileExplorerM -> IO WhileExplorerM
-do_2 (Seq c1 c2) e = do_2 c1 e >>= do_2 c2 
+do_2 (Seq c1 c2) e = do_2 c1 e >>= do_2 c2
 do_2 p e = fst <$> EM.execute p e
 
 do_3 :: Command -> (WhileExplorerO, [String]) -> (WhileExplorerO, [String])
-do_3 (Seq c1 c2) e = do_3 c2 $ do_3 c1 e 
+do_3 (Seq c1 c2) e = do_3 c2 $ do_3 c1 e
 do_3 p (e, o) = (e', o ++ o')
   where (e', o') = EP.execute p e
 
 start :: IO WhileExplorer
-start = return whileGraph
+start = return whileExplorer
 
-startM :: IO WhileExplorerM
-startM = return whileGraphM
+-- startM :: IO WhileExplorerM
+-- startM = return whileTree
 
-startO :: WhileExplorerO
-startO = whileGraphO
+-- startO :: WhileExplorerO
+-- startO = whileGraphO
 
 session1 :: IO WhileExplorer
 session1 = start >>=
-  do_ (assign "x" (intToExpr 1)) >>= 
-  do_ (assign "y" (Id "x")) >>= 
-  do_ (Print (Id "y"))
+  do_ (assign "x" (intToExpr 1)) >>=
+  do_ (assign "y" (Id "x")) >>=
+  do_ (assign "x" (intToExpr 1)) >>=
+  do_ (Print (Id "y")) >>=
+  do_ (Print (Id "x")) . fromJust . EM.jump 2 >>=
+  do_ (assign "z" (intToExpr 100)) >>=
+  do_ (Print (Id "z"))
 
 
--- When using sharing, this results in 3 configurations and not 4,
--- since the IO effect is hidden in the monad and not part of the
--- configurations anymore.
-session2 :: IO WhileExplorerM
-session2 = startM >>=
-  do_2 (assign "x" (intToExpr 1)) >>= 
-  do_2 (assign "y" (Id "x")) >>= 
-  do_2 (Print (Id "y"))
+sessionS :: IO WhileExplorer
+sessionS = start >>=
+  do_ (assign "x" (intToExpr 1)) >>=
+  do_ (assign "y" (Id "x")) >>=
+  do_ (assign "x" (intToExpr 1)) >>=
+  do_ (assign "z" (intToExpr 20)) >>=
+  do_ (assign "y" (Id "x"))
 
 
-session3 :: (WhileExplorerO, [String])
-session3 =
-  do_3 (Print (Id "y")) $ do_3 (assign "y" (Id "x")) $ do_3 (assign "x" (intToExpr 1)) (startO, [])
 
+-- -- When using sharing, this results in 3 configurations and not 4,
+-- -- since the IO effect is hidden in the monad and not part of the
+-- -- configurations anymore.
+-- session2 :: IO WhileExplorerM
+-- session2 = startM >>=
+--   do_2 (assign "x" (intToExpr 1)) >>=
+--   do_2 (assign "y" (Id "x")) >>=
+--   do_2 (Print (Id "y"))
+
+
+-- session3 :: (WhileExplorerO, [String])
+-- session3 =
+--   do_3 (Print (Id "y")) $ do_3 (assign "y" (Id "x")) $ do_3 (assign "x" (intToExpr 1)) (startO, [])
+
 -- Below are some helpers to create a Command and fully evaluate it.
 -- Example:
 -- ghci> let x = wprint (intToExpr 10) `wseq` (wprint (intToExpr 100) `wseq` wprint (intToExpr 200))
@@ -214,20 +229,8 @@
 wseq :: Command -> Command -> Command
 wseq = Seq
 
-whileGraph :: WhileExplorer
-whileGraph = E.mkExplorerGraph definterp initialConfig
-
-whileGraphM :: WhileExplorerM
-whileGraphM = EM.mkExplorerGraph (\p c -> (\c -> (Just c,())) <$> definterpM p c) initialConfig
-
-whileGraphO :: WhileExplorerO
-whileGraphO = EP.mkExplorerGraph definterpO initialConfig
-
-whileTree :: WhileExplorer
-whileTree = E.mkExplorerTree definterp initialConfig
-
-whileStack :: WhileExplorer 
-whileStack = E.mkExplorerStack definterp initialConfig
+whileExplorer :: WhileExplorer
+whileExplorer = E.mkExplorer True (==) definterp initialConfig
 
 whileExample = Seq (Assign "x" (intToExpr 0)) (while (Leq (Id "x") (intToExpr 10)) (Seq (Assign "x" (Plus (Id "x") (intToExpr 1))) (Print (Id "x"))))
 
diff --git a/exploring-interpreters.cabal b/exploring-interpreters.cabal
--- a/exploring-interpreters.cabal
+++ b/exploring-interpreters.cabal
@@ -1,7 +1,7 @@
 cabal-version:       >=1.10
 
 name:                exploring-interpreters
-version:             0.4.0.0
+version:             1.0.0.0
 synopsis:            A generic exploring interpreter for exploratory programming
 -- synopsis:
 -- description:
@@ -22,7 +22,9 @@
 library
   exposed-modules:
       Language.Explorer.Monadic,
-      Language.Explorer.Pure
+      Language.Explorer.Pure,
+      Language.Explorer.Tools.REPL,
+      Language.Explorer.Tools.Protocol
   other-modules:
       Language.Explorer.Basic
   -- other-extensions:
@@ -31,7 +33,15 @@
       containers >=0.5 && <0.7,
       fgl >= 5.7.0 && < 5.8,
       transformers >= 0.5.2 && < 0.6,
-      mtl          >= 2.2.1 && < 2.3
+      mtl          >= 2.2.1 && < 2.3,
+      aeson                 >= 1.5.6 && < 1.6,
+      attoparsec            >= 0.14.1 && < 0.15,
+      bytestring            >= 0.10.10 && < 0.11,
+      scientific            >= 0.3.7 && < 0.4,
+      text                  >= 1.2.4 && < 1.3,
+      http-types            >= 0.12.3 && < 0.13,
+      network               >= 3.1.2 && < 3.2,
+      readline              >= 1.0.3 && < 1.1
 
   -- hs-source-dirs:
   default-language:    Haskell2010
