diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Anton Gushcha (c) 2016
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of  nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/gore-and-ash-async.cabal b/gore-and-ash-async.cabal
new file mode 100644
--- /dev/null
+++ b/gore-and-ash-async.cabal
@@ -0,0 +1,73 @@
+name:                gore-and-ash-async
+version:             0.1.0.0
+synopsis:            Core module for Gore&Ash engine that embeds async IO actions into game loop.
+description:         Please see README.md
+homepage:            https://github.com/TeaspotStudio/gore-and-ash-async#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Anton Gushcha
+maintainer:          ncrashed@gmail.com
+copyright:           2016 Anton Gushcha
+category:            Game
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:     src
+  exposed-modules:     
+                      Game.GoreAndAsh.Async
+                      Game.GoreAndAsh.Async.API
+                      Game.GoreAndAsh.Async.Module
+                      Game.GoreAndAsh.Async.State
+  
+  default-language:   Haskell2010
+  build-depends:      base >= 4.7 && < 5
+                    , async >= 2.0.2
+                    , containers >= 0.5.6.2
+                    , deepseq >= 1.4.1.1
+                    , exceptions >= 0.8.2.1
+                    , gore-and-ash >= 1.1.0.1
+                    , hashable >= 1.2.4.0
+                    , mtl >= 2.2.1
+                    , transformers >= 0.4.2.0
+                    , unordered-containers >= 0.2.5.1
+
+  default-extensions: 
+                      BangPatterns
+                      DeriveGeneric
+                      FlexibleInstances
+                      GeneralizedNewtypeDeriving
+                      InstanceSigs
+                      MultiParamTypeClasses
+                      RecordWildCards
+                      ScopedTypeVariables
+                      TupleSections
+                      TypeFamilies
+                      UndecidableInstances
+
+test-suite gore-and-ash-async-test
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  main-is:             Spec.hs
+  build-depends:       base
+                     , gore-and-ash >= 1.1.0.1
+                     , gore-and-ash-async
+                     , test-framework
+                     , test-framework-hunit
+                     , HUnit
+                     , deepseq >= 1.4.1.1
+                     , exceptions >= 0.8.2.1
+                     , transformers >= 0.4.2.0
+                     , mtl >= 2.2.1
+                     , containers >= 0.5.6.2
+
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
+  default-language:    Haskell2010
+  default-extensions:  
+                      Arrows
+                      DataKinds
+                      DeriveGeneric
+                      GeneralizedNewtypeDeriving
+                      MultiParamTypeClasses
+                      OverloadedStrings
+                      TypeFamilies
diff --git a/src/Game/GoreAndAsh/Async.hs b/src/Game/GoreAndAsh/Async.hs
new file mode 100644
--- /dev/null
+++ b/src/Game/GoreAndAsh/Async.hs
@@ -0,0 +1,91 @@
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-|
+Module      : Game.GoreAndAsh.Async
+Description : Core module for embedding concurrent IO actions into main loop.
+Copyright   : (c) Anton Gushcha, 2016
+License     : BSD3
+Maintainer  : ncrashed@gmail.com
+Stability   : experimental
+Portability : POSIX
+
+The core module contains API for embedding concurrent IO actions (async and sync) into main game loop for Gore&Ash.
+
+The module does not depend on any other core modules, so 'AsyncT' could be placed at any place in monad stack.
+
+The module is NOT pure within first phase (see 'ModuleStack' docs), therefore currently only 'IO' end monad can handler the module.
+
+Example of embedding:
+
+@
+-- Language extensions: DataKinds DeriveGeneric GeneralizedNewtypeDeriving MultiParamTypeClasses TypeFamilies
+import Control.DeepSeq
+import Control.Monad.Catch
+import Control.Monad.Fix 
+import Control.Monad.IO.Class
+import Data.Typeable 
+import GHC.Generics (Generic)
+
+import Game.GoreAndAsh.Core
+import Game.GoreAndAsh.Async 
+
+-- | Application monad is monad stack build from given list of modules over base monad (IO or Identity)
+type AppStack = ModuleStack [AsyncT ... other modules ... ] IO
+newtype AppState = AppState (ModuleState AppStack)
+  deriving (Generic)
+
+instance NFData AppState 
+
+-- | Wrapper around type family
+newtype AppMonad a = AppMonad (AppStack a)
+  deriving (Functor, Applicative, Monad, MonadFix, MonadIO, MonadThrow, MonadCatch, MonadAsync ... other modules monads ... )
+
+instance GameModule AppMonad AppState where 
+  type ModuleState AppMonad = AppState
+  runModule (AppMonad m) (AppState s) = do 
+    (a, s') <- runModule m s 
+    return (a, AppState s')
+  newModuleState = AppState <$> newModuleState
+  withModule _ = withModule (Proxy :: Proxy AppStack)
+  cleanupModule (AppState s) = cleanupModule s 
+
+-- | Arrow that is build over the monad stack
+type AppWire a b = GameWire AppMonad a b
+@
+
+-}
+module Game.GoreAndAsh.Async(
+  -- * Low-level
+    AsyncState
+  , AsyncT 
+  , AsyncId
+  , MonadAsync(..)
+  -- * Arrow API
+  -- ** Not bounded async
+  , asyncAction
+  , asyncActionC
+  , asyncActionEx
+  , asyncActionExC
+  , asyncActionFactory
+  , asyncActionFactoryEx
+  -- ** Bounded async
+  , asyncActionBound
+  , asyncActionBoundC
+  , asyncActionBoundEx
+  , asyncActionBoundExC
+  , asyncActionBoundFactory
+  , asyncActionBoundFactoryEx
+  -- ** Sync actions
+  , asyncSyncAction
+  , asyncSyncActionEx
+  , asyncSyncActionC
+  , asyncSyncActionExC
+  , asyncSyncActionFactory 
+  , asyncSyncActionFactoryEx
+  ) where
+
+-- for docs
+import Game.GoreAndAsh
+
+import Game.GoreAndAsh.Async.API as X 
+import Game.GoreAndAsh.Async.Module as X 
+import Game.GoreAndAsh.Async.State as X 
diff --git a/src/Game/GoreAndAsh/Async/API.hs b/src/Game/GoreAndAsh/Async/API.hs
new file mode 100644
--- /dev/null
+++ b/src/Game/GoreAndAsh/Async/API.hs
@@ -0,0 +1,536 @@
+{-|
+Module      : Game.GoreAndAsh.Async.API
+Description : Monadic and arrow API for module
+Copyright   : (c) Anton Gushcha, 2016
+License     : BSD3
+Maintainer  : ncrashed@gmail.com
+Stability   : experimental
+Portability : POSIX
+-}
+module Game.GoreAndAsh.Async.API(
+  -- * Monadic API
+    MonadAsync(..)
+  , MonadAsyncExcepion(..)
+  -- * Arrow API
+  -- ** Not bounded async
+  , asyncAction
+  , asyncActionC
+  , asyncActionEx
+  , asyncActionExC
+  , asyncActionFactory
+  , asyncActionFactoryEx
+  -- ** Bounded async
+  , asyncActionBound
+  , asyncActionBoundC
+  , asyncActionBoundEx
+  , asyncActionBoundExC
+  , asyncActionBoundFactory
+  , asyncActionBoundFactoryEx
+  -- ** Sync actions
+  , asyncSyncAction
+  , asyncSyncActionEx
+  , asyncSyncActionC
+  , asyncSyncActionExC
+  , asyncSyncActionFactory 
+  , asyncSyncActionFactoryEx
+  ) where
+
+import Control.Concurrent.Async 
+import Control.DeepSeq
+import Control.Exception 
+import Control.Monad.Catch 
+import Control.Monad.IO.Class 
+import Control.Monad.State.Strict
+import Control.Wire
+import Control.Wire.Unsafe.Event
+import Data.Dynamic
+import GHC.Generics (Generic)
+import Prelude hiding (id, (.))
+
+import Game.GoreAndAsh.Core
+import Game.GoreAndAsh.Async.Module 
+import Game.GoreAndAsh.Async.State
+
+import Data.Sequence (Seq, (|>), (><))
+import qualified Data.Sequence as S 
+
+import qualified Data.Foldable as F 
+
+-- | Exception of the async monadic API
+data MonadAsyncExcepion =
+    AsyncWrongType TypeRep TypeRep -- ^ Expected type doesn't match stored in async value
+  | AsyncNotFound AsyncId -- ^ There is no async value with the id
+  | SyncWrongType TypeRep TypeRep -- ^ Expected type doesn't match stored in sync value
+  deriving (Generic, Show)
+
+instance Exception MonadAsyncExcepion 
+
+instance NFData MonadAsyncExcepion where 
+  rnf e = case e of 
+    AsyncWrongType tr1 tr2 -> rnfTypeRep tr1 `deepseq` rnfTypeRep tr2
+    AsyncNotFound i -> i `deepseq` ()
+    SyncWrongType tr1 tr2 -> rnfTypeRep tr1 `deepseq` rnfTypeRep tr2
+
+-- | Low level monadic API for module.
+--
+-- Note: does not require 'm' to be 'IO' monad.
+class (MonadIO m, MonadThrow m) => MonadAsync m where 
+  -- | Start execution of 'IO' action concurrently and return its id
+  asyncActionM :: Typeable a => IO a -> m AsyncId
+
+  -- | Start execution of 'IO' action concurrently and return its id
+  --
+  -- Note: forks thread within same OS thread.
+  asyncActionBoundM :: Typeable a => IO a -> m AsyncId
+
+  -- | Check state of concurrent value
+  --
+  -- Could throw 'MonadAsyncExcepion', 'AsyncWrongType' and 'AsyncNotFound' constructors.
+  asyncPollM :: Typeable a => AsyncId -> m (Maybe (Either SomeException a))
+
+  -- | Stops given async execution
+  asyncCancelM :: AsyncId -> m ()
+
+  -- | Schedule action to be executed at the end of frame.
+  --
+  -- Use 'asyncSyncPollM' to get result at next frame.
+  --
+  -- Note: order of IO actions is preserved.
+  asyncSyncActionM :: Typeable a => IO a -> m SyncId
+
+  -- | Fires when given synchronious action is completed (at next frame after scheduling)
+  --
+  -- Could throw 'MonadAsyncExcepion', 'SyncWrongType' constructor.
+  asyncSyncPollM :: Typeable a => SyncId -> m (Maybe (Either SomeException a))
+
+  -- | Unshedule given action from execution
+  --
+  -- Actually you can unshedule it until end of frame when corresponding 'asyncSyncActionM'
+  -- was called.
+  asyncSyncCanceM :: SyncId -> m ()
+
+instance {-# OVERLAPPING #-} (MonadIO m, MonadThrow m) => MonadAsync (AsyncT s m) where
+  asyncActionM !io = do 
+    av <- liftIO . async $! io 
+    state $! registerAsyncValue av
+
+  asyncActionBoundM !io = do 
+    av <- liftIO . asyncBound $! io 
+    state $! registerAsyncValue av
+
+  asyncPollM :: forall a . Typeable a => AsyncId -> AsyncT s m (Maybe (Either SomeException a))
+  asyncPollM i = do 
+    mav <- getFinishedAsyncValue i <$> AsyncT get 
+    case mav of 
+      Nothing -> throwM . AsyncNotFound $! i 
+      Just av -> case av of 
+        Nothing -> return Nothing 
+        Just ev -> case ev of 
+          Left e -> return . Just . Left $! e
+          Right da -> case fromDynamic da of 
+            Nothing -> throwM $! AsyncWrongType (typeRep (Proxy :: Proxy a)) (dynTypeRep da)
+            Just a -> return . Just . Right $! a
+
+  asyncCancelM i = do 
+    mav <- state $! cancelAsyncValue i
+    case mav of 
+      Nothing -> return ()
+      Just av -> liftIO $! cancel av 
+
+  asyncSyncActionM = state . registerSyncValue
+
+  asyncSyncPollM :: forall a . Typeable a => SyncId -> AsyncT s m (Maybe (Either SomeException a))
+  asyncSyncPollM i = do 
+    mav <- getFinishedSyncValue i <$> AsyncT get 
+    case mav of 
+      Nothing -> return Nothing 
+      Just ev -> case ev of 
+        Left e -> return . Just . Left $! e
+        Right da -> case fromDynamic da of 
+          Nothing -> throwM $! SyncWrongType (typeRep (Proxy :: Proxy a)) (dynTypeRep da)
+          Just a -> return . Just . Right $! a
+
+  asyncSyncCanceM i = state $! ((), ) <$> cancelSyncValue i
+
+instance {-# OVERLAPPABLE #-} (MonadIO (mt m), MonadThrow (mt m), MonadAsync m, MonadTrans mt) => MonadAsync (mt m) where 
+  asyncActionM = lift . asyncActionM
+  asyncActionBoundM = lift . asyncActionBoundM
+  asyncPollM = lift . asyncPollM
+  asyncCancelM = lift . asyncCancelM
+  asyncSyncActionM = lift . asyncSyncActionM
+  asyncSyncPollM = lift . asyncSyncPollM
+  asyncSyncCanceM = lift . asyncSyncCanceM
+
+-- | Execute given 'IO' action concurrently. Event fires once when the action 
+-- is finished. Exceptions are rethrown into main thread.
+asyncActionG :: (MonadAsync m, Typeable a) => 
+  (IO a -> GameMonadT m AsyncId) -- ^ Maker of async value
+  -> IO a -> GameWire m b (Event a)
+asyncActionG mkAsync io = mkGen $ \_ _ -> do 
+  i <- mkAsync io 
+  return (Right NoEvent, go i)
+  where
+    go i = mkGen $ \_ _ -> do
+      mr <- asyncPollM i 
+      case mr of 
+        Nothing -> return (Right NoEvent, go i)
+        Just ea -> case ea of 
+          Left e -> throwM e 
+          Right a -> return (Right $ Event a, never)
+
+-- | Execute given 'IO' action concurrently. Event fires once when the action 
+-- is finished. Exceptions are rethrown into main thread.
+--
+-- The concurrent action can be canceled by input event.
+asyncActionCG :: (MonadAsync m, Typeable a) =>
+  (IO a -> GameMonadT m AsyncId) -- ^ Maker of async value
+  -> IO a -> GameWire m (Event b) (Event a)
+asyncActionCG mkAsync io = mkGen $ \_ ce -> case ce of 
+  NoEvent -> do 
+    i <- mkAsync io 
+    return (Right NoEvent, go i)
+  Event _ -> return (Right NoEvent, never)
+  where
+    go i = mkGen $ \_ ce -> case ce of  
+      NoEvent -> do
+        mr <- asyncPollM i 
+        case mr of 
+          Nothing -> return (Right NoEvent, go i)
+          Just ea -> case ea of 
+            Left e -> throwM e 
+            Right a -> return (Right $ Event a, never)
+      Event _ -> do 
+        asyncCancelM i 
+        return (Right NoEvent, never)
+
+-- | Execute given 'IO' action concurrently. 
+-- 
+-- Event fires once when the action is finished. Exceptions in the concurrent
+-- action are returned in event payload.
+asyncActionExG :: (MonadAsync m, Typeable a) =>
+  (IO a -> GameMonadT m AsyncId) -- ^ Maker of async value
+  -> IO a -> GameWire m b (Event (Either SomeException a))
+asyncActionExG mkAsync io = mkGen $ \_ _ -> do 
+  i <- mkAsync io 
+  return (Right NoEvent, go i)
+  where
+    go i = mkGen $ \_ _ -> do
+      mr <- asyncPollM i 
+      case mr of 
+        Nothing -> return (Right NoEvent, go i)
+        Just ea -> return (Right $ Event ea, never)
+
+-- | Execute given 'IO' action concurrently. 
+--
+-- Event fires once when the action is finished. Exceptions in the 
+-- concurrent action are returned in event payload.
+--
+-- The concurrent action can be canceled by input event.
+asyncActionExCG :: (MonadAsync m, Typeable a) =>
+  (IO a -> GameMonadT m AsyncId) -- ^ Maker of async value
+  -> IO a -> GameWire m (Event b) (Event (Either SomeException a))
+asyncActionExCG mkAsync io = mkGen $ \_ ce -> case ce of 
+  NoEvent -> do 
+    i <- mkAsync io 
+    return (Right NoEvent, go i)
+  Event _ -> return (Right NoEvent, never)
+  where
+    go i = mkGen $ \_ ce -> case ce of  
+      NoEvent -> do
+        mr <- asyncPollM i 
+        case mr of 
+          Nothing -> return (Right NoEvent, go i)
+          Just ea -> return (Right $ Event ea, never)
+      Event _ -> do 
+        asyncCancelM i 
+        return (Right NoEvent, never)
+
+-- | Execute given 'IO' action concurrently. Event fires once when the action 
+-- is finished. Exceptions are rethrown into main thread.
+asyncAction :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event a)
+asyncAction = asyncActionG asyncActionM
+
+-- | Execute given 'IO' action concurrently. Event fires once when the action 
+-- is finished. Exceptions are rethrown into main thread.
+--
+-- The concurrent action can be canceled by input event.
+asyncActionC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event a)
+asyncActionC = asyncActionCG asyncActionM
+
+-- | Execute given 'IO' action concurrently. 
+-- 
+-- Event fires once when the action is finished. Exceptions in the concurrent
+-- action are returned in event payload.
+asyncActionEx :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event (Either SomeException a))
+asyncActionEx = asyncActionExG asyncActionM
+
+-- | Execute given 'IO' action concurrently. 
+--
+-- Event fires once when the action is finished. Exceptions in the 
+-- concurrent action are returned in event payload.
+--
+-- The concurrent action can be canceled by input event.
+asyncActionExC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event (Either SomeException a))
+asyncActionExC = asyncActionExCG asyncActionM
+
+-- | Execute given 'IO' action concurrently. Event fires once when the action 
+-- is finished. Exceptions are rethrown into main thread.
+--
+-- Note: forks thread within same OS thread.
+asyncActionBound :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event a)
+asyncActionBound = asyncActionG asyncActionBoundM
+
+-- | Execute given 'IO' action concurrently. Event fires once when the action 
+-- is finished. Exceptions are rethrown into main thread.
+--
+-- The concurrent action can be canceled by input event.
+--
+-- Note: forks thread within same OS thread.
+asyncActionBoundC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event a)
+asyncActionBoundC = asyncActionCG asyncActionBoundM
+
+-- | Execute given 'IO' action concurrently. 
+-- 
+-- Event fires once when the action is finished. Exceptions in the concurrent
+-- action are returned in event payload.
+--
+-- Note: forks thread within same OS thread.
+asyncActionBoundEx :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event (Either SomeException a))
+asyncActionBoundEx = asyncActionExG asyncActionBoundM
+
+-- | Execute given 'IO' action concurrently. 
+--
+-- Event fires once when the action is finished. Exceptions in the 
+-- concurrent action are returned in event payload.
+--
+-- The concurrent action can be canceled by input event.
+--
+-- Note: forks thread within same OS thread.`
+asyncActionBoundExC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event (Either SomeException a))
+asyncActionBoundExC = asyncActionExCG asyncActionBoundM
+
+-- | Execute given 'IO' action at end of current frame. Event fires once at next frame.
+-- 
+-- Exceptions are rethrown into main thread.
+asyncSyncAction :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event a)
+asyncSyncAction io = mkGen $ \_ _ -> do 
+  i <- asyncSyncActionM io 
+  return (Right NoEvent, go i)
+  where
+    go i = mkGen $ \_ _ -> do
+      mr <- asyncSyncPollM i 
+      case mr of 
+        Nothing -> return (Right NoEvent, never) -- One has canceled the action
+        Just ea -> case ea of 
+          Left e -> throwM e 
+          Right a -> return (Right $ Event a, never)
+
+-- | Execute given 'IO' action at end of current frame. Event fires once at next frame.
+-- 
+-- Exceptions are returned in event payload.
+asyncSyncActionEx :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event (Either SomeException a))
+asyncSyncActionEx io = mkGen $ \_ _ -> do 
+  i <- asyncSyncActionM io 
+  return (Right NoEvent, go i)
+  where
+    go i = mkGen $ \_ _ -> do
+      mr <- asyncSyncPollM i 
+      case mr of 
+        Nothing -> return (Right NoEvent, never) -- One has canceled the action
+        Just ea -> return (Right $ Event ea, never)
+
+-- | Execute given 'IO' action at end of current frame. Event fires once at next frame.
+-- 
+-- Exceptions are rethrown into main thread.
+--
+-- Action can be canceled with input event, although you have only the frame to do this.
+asyncSyncActionC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event a)
+asyncSyncActionC io = mkGen $ \_ ce -> case ce of 
+  NoEvent -> do 
+    i <- asyncSyncActionM io 
+    return (Right NoEvent, go i)
+  Event _ -> return (Right NoEvent, never)
+  where
+    go i = mkGen $ \_ ce -> case ce of 
+      NoEvent -> do
+        mr <- asyncSyncPollM i 
+        case mr of 
+          Nothing -> return (Right NoEvent, never) -- One has canceled the action
+          Just ea -> case ea of 
+            Left e -> throwM e 
+            Right a -> return (Right $ Event a, never)
+      Event _ -> return (Right NoEvent, never)
+
+-- | Execute given 'IO' action at end of current frame. Event fires once at next frame.
+-- 
+-- Exceptions are rethrown into main thread.
+--
+-- Action can be canceled with input event, although you have only the frame to do this.
+asyncSyncActionExC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event (Either SomeException a))
+asyncSyncActionExC io = mkGen $ \_ ce -> case ce of 
+  NoEvent -> do 
+    i <- asyncSyncActionM io 
+    return (Right NoEvent, go i)
+  Event _ -> return (Right NoEvent, never)
+  where
+    go i = mkGen $ \_ ce -> case ce of 
+      NoEvent -> do
+        mr <- asyncSyncPollM i 
+        case mr of 
+          Nothing -> return (Right NoEvent, never) -- One has canceled the action
+          Just ea -> return (Right $ Event ea, never)
+      Event _ -> return (Right NoEvent, never)
+
+-- | Wire that executes incoming 'IO' actions concurrently and then produces
+-- events with results once for each action.
+-- 
+-- Exceptions are rethrown into main thread.
+asyncActionFactoryG :: forall m a . (MonadAsync m, Typeable a) => 
+  (IO a -> GameMonadT m AsyncId) -- ^ Maker of async value
+  -> GameWire m (Event (Seq (IO a))) (Event (Seq a))
+asyncActionFactoryG mkAsync = go S.empty
+  where 
+  go :: Seq AsyncId -> GameWire m (Event (Seq (IO a))) (Event (Seq a))
+  go is = mkGen $ \_ eios -> do 
+    -- spawn new values
+    newIs <- case eios of 
+      NoEvent -> return S.empty 
+      Event ios -> mapM mkAsync ios
+
+    -- poll current values
+    rs <- mapM asyncPollM is
+    (as, is') <- F.foldlM procValue (S.empty, S.empty) $ rs `S.zip` is
+
+    -- return values, produce new ids
+    let e = if S.null as then NoEvent else Event as
+    let is'' = is' >< newIs
+    return $ is'' `deepseq` e `seq` (Right e, go is'')
+
+  procValue :: (Seq a, Seq AsyncId) -> (Maybe (Either SomeException a), AsyncId) -> GameMonadT m (Seq a, Seq AsyncId)
+  procValue (as, is) (mr, i) = case mr of
+      Nothing -> return (as, is |> i)
+      Just ea -> case ea of 
+        Left e -> throwM e 
+        Right a -> return (as |> a, is)
+
+-- | Wire that executes incoming 'IO' actions concurrently and then produces
+-- events with results once for each action.
+-- 
+-- Exceptions are returned in event payload.
+asyncActionFactoryExG :: forall m a . (MonadAsync m, Typeable a) => 
+  (IO a -> GameMonadT m AsyncId) -- ^ Maker of async value
+  -> GameWire m (Event (Seq (IO a))) (Event (Seq (Either SomeException a)))
+asyncActionFactoryExG mkAsync = go S.empty
+  where 
+  go :: Seq AsyncId -> GameWire m (Event (Seq (IO a))) (Event (Seq (Either SomeException a)))
+  go is = mkGen $ \_ eios -> do 
+    -- spawn new values
+    newIs <- case eios of 
+      NoEvent -> return S.empty 
+      Event ios -> mapM mkAsync ios
+
+    -- poll current values
+    rs <- mapM asyncPollM is
+    (as, is') <- F.foldlM procValue (S.empty, S.empty) $ rs `S.zip` is
+
+    -- return values, produce new ids
+    let e = if S.null as then NoEvent else Event as
+    let is'' = is' >< newIs
+    return $ is'' `deepseq` e `seq` (Right e, go is'')
+
+  procValue :: (Seq (Either SomeException a), Seq AsyncId) -> (Maybe (Either SomeException a), AsyncId) -> GameMonadT m (Seq (Either SomeException a), Seq AsyncId)
+  procValue (as, is) (mr, i) = case mr of
+      Nothing -> return (as, is |> i)
+      Just ea -> return (as |> ea, is)
+
+-- | Wire that executes incoming 'IO' actions concurrently and then produces
+-- events with results once for each action.
+-- 
+-- Exceptions are rethrown into main thread.
+asyncActionFactory :: (MonadAsync m, Typeable a) => GameWire m (Event (Seq (IO a))) (Event (Seq a))
+asyncActionFactory = asyncActionFactoryG asyncActionM
+
+-- | Wire that executes incoming 'IO' actions concurrently and then produces
+-- events with results once for each action.
+-- 
+-- Exceptions are returned in event payload.
+asyncActionFactoryEx :: (MonadAsync m, Typeable a) => GameWire m (Event (Seq (IO a))) (Event (Seq (Either SomeException a)))
+asyncActionFactoryEx = asyncActionFactoryExG asyncActionM
+
+-- | Wire that executes incoming 'IO' actions concurrently and then produces
+-- events with results once for each action.
+-- 
+-- Exceptions are rethrown into main thread.
+--
+-- Note: forks thread within same OS thread.
+asyncActionBoundFactory :: (MonadAsync m, Typeable a) => GameWire m (Event (Seq (IO a))) (Event (Seq a))
+asyncActionBoundFactory = asyncActionFactoryG asyncActionBoundM
+
+-- | Wire that executes incoming 'IO' actions concurrently and then produces
+-- events with results once for each action.
+-- 
+-- Exceptions are returned in event payload.
+--
+-- Note: forks thread within same OS thread.
+asyncActionBoundFactoryEx :: (MonadAsync m, Typeable a) => GameWire m (Event (Seq (IO a))) (Event (Seq (Either SomeException a)))
+asyncActionBoundFactoryEx = asyncActionFactoryExG asyncActionM
+
+-- | Wire that executes incoming 'IO' actions at end of current frame and then produces
+-- events with results once for each action.
+-- 
+-- Exceptions are rethrown into main thread.
+asyncSyncActionFactory :: forall m a . (MonadAsync m, Typeable a)
+  => GameWire m (Event (Seq (IO a))) (Event (Seq a))
+asyncSyncActionFactory = go S.empty
+  where 
+  go :: Seq SyncId -> GameWire m (Event (Seq (IO a))) (Event (Seq a))
+  go is = mkGen $ \_ eios -> do 
+    -- spawn new values
+    newIs <- case eios of 
+      NoEvent -> return S.empty 
+      Event ios -> mapM asyncSyncActionM ios
+
+    -- poll current values
+    rs <- mapM asyncSyncPollM is
+    (as, is') <- F.foldlM procValue (S.empty, S.empty) $ rs `S.zip` is
+
+    -- return values, produce new ids
+    let e = if S.null as then NoEvent else Event as
+    let is'' = is' >< newIs
+    return $ is'' `deepseq` e `seq` (Right e, go is'')
+
+  procValue :: (Seq a, Seq SyncId) -> (Maybe (Either SomeException a), SyncId) -> GameMonadT m (Seq a, Seq SyncId)
+  procValue (as, is) (mr, i) = case mr of
+      Nothing -> return (as, is |> i)
+      Just ea -> case ea of 
+        Left e -> throwM e 
+        Right a -> return (as |> a, is)
+
+-- | Wire that executes incoming 'IO' actions at end of current frame and then produces
+-- events with results once for each action.
+-- 
+-- Exceptions are rethrown into main thread.
+asyncSyncActionFactoryEx :: forall m a . (MonadAsync m, Typeable a)
+  => GameWire m (Event (Seq (IO a))) (Event (Seq (Either SomeException a)))
+asyncSyncActionFactoryEx = go S.empty
+  where 
+  go :: Seq SyncId -> GameWire m (Event (Seq (IO a))) (Event (Seq (Either SomeException a)))
+  go is = mkGen $ \_ eios -> do 
+    -- spawn new values
+    newIs <- case eios of 
+      NoEvent -> return S.empty 
+      Event ios -> mapM asyncSyncActionM ios
+
+    -- poll current values
+    rs <- mapM asyncSyncPollM is
+    (as, is') <- F.foldlM procValue (S.empty, S.empty) $ rs `S.zip` is
+
+    -- return values, produce new ids
+    let e = if S.null as then NoEvent else Event as
+    let is'' = is' >< newIs
+    return $ is'' `deepseq` e `seq` (Right e, go is'')
+
+  procValue :: (Seq (Either SomeException a), Seq SyncId) -> (Maybe (Either SomeException a), SyncId) -> GameMonadT m (Seq (Either SomeException a), Seq SyncId)
+  procValue (as, is) (mr, i) = case mr of
+      Nothing -> return (as, is |> i)
+      Just ea -> return (as |> ea, is)
diff --git a/src/Game/GoreAndAsh/Async/Module.hs b/src/Game/GoreAndAsh/Async/Module.hs
new file mode 100644
--- /dev/null
+++ b/src/Game/GoreAndAsh/Async/Module.hs
@@ -0,0 +1,87 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-|
+Module      : Game.GoreAndAsh.Async.Module
+Description : Monad transformer and instance for core module
+Copyright   : (c) Anton Gushcha, 2016
+License     : BSD3
+Maintainer  : ncrashed@gmail.com
+Stability   : experimental
+Portability : POSIX
+-}
+module Game.GoreAndAsh.Async.Module(
+    AsyncT(..)
+  ) where
+
+import Control.Concurrent.Async
+import Control.Monad.Catch
+import Control.Monad.Fix 
+import Control.Monad.State.Strict
+
+import Game.GoreAndAsh
+import Game.GoreAndAsh.Async.State
+
+import qualified Data.Foldable as F  
+import qualified Data.HashMap.Strict as H
+import qualified Data.Sequence as S 
+
+-- | Monad transformer of async core module.
+--
+-- [@s@] - State of next core module in modules chain;
+--
+-- [@m@] - Next monad in modules monad stack;
+--
+-- [@a@] - Type of result value;
+--
+-- How to embed module:
+-- 
+-- @
+-- type AppStack = ModuleStack [AsyncT, ... other modules ... ] IO
+--
+-- newtype AppMonad a = AppMonad (AppStack a)
+--   deriving (Functor, Applicative, Monad, MonadFix, MonadIO, MonadThrow, MonadCatch, MonadAsync)
+-- @
+--
+-- The module is NOT pure within first phase (see 'ModuleStack' docs), therefore currently only 'IO' end monad can handler the module.
+newtype AsyncT s m a = AsyncT { runAsyncT :: StateT (AsyncState s) m a }
+  deriving (Functor, Applicative, Monad, MonadState (AsyncState s), MonadFix, MonadTrans, MonadIO, MonadThrow, MonadCatch, MonadMask)
+
+instance GameModule m s => GameModule (AsyncT s m) (AsyncState s) where 
+  type ModuleState (AsyncT s m) = AsyncState s
+  runModule (AsyncT m) s1 = do
+    ((a, s2), nextState) <- runModule (runStateT m s1) (asyncNextState s1)
+    s3 <- pollAsyncs . purgeAsyncs $! s2 
+    s4 <- liftIO . execSyncs . purgeSyncs $! s3
+    return (a, s4 {
+        asyncNextState = nextState 
+      })
+  
+  newModuleState = emptyAsyncState <$> newModuleState
+  withModule _ = id
+  cleanupModule _ = return ()
+
+-- | Polls all async values and update values
+pollAsyncs :: MonadIO m => AsyncState s -> m (AsyncState s)
+pollAsyncs s = do
+  mp <- mapM pollVal . asyncAValues $! s 
+  return $! s {
+      asyncAValues = mp
+    }
+  where
+  pollVal ev = case ev of 
+    Left a -> do 
+      mr <- liftIO . poll $! a
+      case mr of 
+        Nothing -> return ev 
+        Just r -> return . Right $! r
+    _ -> return ev
+
+-- | Execute all sync values
+execSyncs :: AsyncState s -> IO (AsyncState s)
+execSyncs s = do 
+  as <- mapM (uncurry execAction) . asyncScheduled $! s
+  return $! s {
+      asyncScheduled = S.empty 
+    , asyncSValues = F.foldl' (\acc (k, v) -> H.insert k v acc) H.empty as
+    }
+  where 
+    execAction i io = (fmap ((i,) . Right) io) `catchAll` (return . (i,) . Left)
diff --git a/src/Game/GoreAndAsh/Async/State.hs b/src/Game/GoreAndAsh/Async/State.hs
new file mode 100644
--- /dev/null
+++ b/src/Game/GoreAndAsh/Async/State.hs
@@ -0,0 +1,160 @@
+{-|
+Module      : Game.GoreAndAsh.Async.State
+Description : Internal state of core module
+Copyright   : (c) Anton Gushcha, 2016
+License     : BSD3
+Maintainer  : ncrashed@gmail.com
+Stability   : experimental
+Portability : POSIX
+-}
+module Game.GoreAndAsh.Async.State(
+    AsyncState(..)
+  , emptyAsyncState
+  -- * Async helpers
+  , AsyncId(..)
+  , AsyncValueMap
+  , registerAsyncValue
+  , getFinishedAsyncValue
+  , cancelAsyncValue
+  , purgeAsyncs
+  -- * Sync helpers
+  , SyncId(..)
+  , SyncSheduled
+  , SyncFinished
+  , registerSyncValue
+  , getFinishedSyncValue
+  , cancelSyncValue
+  , purgeSyncs
+  ) where
+
+import Control.Concurrent.Async
+import Control.DeepSeq
+import Control.Exception
+import Data.Dynamic 
+import Data.Either
+import Data.Hashable
+import GHC.Generics (Generic)
+
+import Data.HashMap.Strict (HashMap)
+import qualified Data.HashMap.Strict as H 
+
+import Data.Sequence (Seq, (|>))
+import qualified Data.Sequence as S 
+
+-- | Id of async value, it is used to poll info about the value
+newtype AsyncId = AsyncId { unAsyncId :: Int }
+  deriving (Generic, Eq, Show)
+
+instance Hashable AsyncId 
+instance NFData AsyncId 
+
+-- | Container for async values
+type AsyncValueMap = HashMap AsyncId (Either (Async Dynamic) (Either SomeException Dynamic))
+
+-- | Id of sync value, it is used to identify return value
+newtype SyncId = SyncId { unSyncId :: Int }
+  deriving (Generic, Eq, Ord, Show)
+
+instance Hashable SyncId 
+instance NFData SyncId 
+
+-- | Container for scheduled sync values
+type SyncSheduled = Seq (SyncId, IO Dynamic)
+
+-- | Container for finished sync values
+type SyncFinished = HashMap SyncId (Either SomeException Dynamic)
+
+-- | Internal state of asynchronious core module
+--
+-- [@s@] - state of next module, they are chained until bottom, that is usually
+--         an empty data type.
+data AsyncState s = AsyncState {
+  asyncAValues :: !AsyncValueMap
+, asyncScheduled :: !SyncSheduled
+, asyncSValues :: !SyncFinished
+, asyncNextId :: !Int
+, asyncNextState :: !s
+} deriving (Generic)
+
+instance NFData s => NFData (AsyncState s) where 
+  rnf AsyncState{..} = 
+    asyncAValues `seq`
+    asyncSValues `seq`
+    asyncNextState `deepseq`
+    ()
+
+-- | Create inital async state
+--
+-- [@s@] -  state of next module
+emptyAsyncState :: s -> AsyncState s 
+emptyAsyncState s = AsyncState {
+    asyncAValues = H.empty
+  , asyncScheduled = S.empty
+  , asyncSValues = H.empty
+  , asyncNextId = 0
+  , asyncNextState = s
+  }
+
+-- | Put async value into internal state
+registerAsyncValue :: Typeable a => Async a -> AsyncState s -> (AsyncId, AsyncState s)
+registerAsyncValue !av !s = (i, s {
+    asyncNextId = asyncNextId s + 1
+  , asyncAValues = H.insert i (Left $ toDyn <$> av) . asyncAValues $! s
+  })
+  where
+    i = AsyncId . asyncNextId $! s
+
+-- | Try to get value of given async value
+--
+-- Note: first 'Maybe' layer is test for existense of given async value
+-- 
+-- Note: second 'Maybe' layer is test is the value is finished 
+getFinishedAsyncValue :: AsyncId -> AsyncState s -> Maybe (Maybe (Either SomeException Dynamic))
+getFinishedAsyncValue !i AsyncState{..} = check <$> H.lookup i asyncAValues 
+  where 
+  check v = case v of 
+    Left _ -> Nothing
+    Right a -> Just a
+
+-- | Unregister given id and return stored async
+cancelAsyncValue :: AsyncId -> AsyncState s -> (Maybe (Async Dynamic), AsyncState s)
+cancelAsyncValue !i !s = (check =<< H.lookup i (asyncAValues s), s {
+    asyncAValues = H.delete i . asyncAValues $! s
+  })
+  where
+  check v = case v of 
+    Left a -> Just a
+    Right _ -> Nothing
+
+-- | Deletes calculated values
+purgeAsyncs :: AsyncState s -> AsyncState s 
+purgeAsyncs !s = s {
+    asyncAValues = H.filter isLeft . asyncAValues $! s
+  }
+
+-- | Put sync value into internal state
+registerSyncValue :: Typeable a => IO a -> AsyncState s -> (SyncId, AsyncState s)
+registerSyncValue !io !s = (i, s {
+    asyncNextId = asyncNextId s + 1
+  , asyncScheduled = asyncScheduled s |> (i, toDyn <$> io)
+  })
+  where
+    i = SyncId . asyncNextId $! s
+
+-- | Try to get value of given sync value
+--
+-- Note: first 'Maybe' layer is test for existense of given async value
+getFinishedSyncValue :: SyncId -> AsyncState s -> Maybe (Either SomeException Dynamic)
+getFinishedSyncValue !i AsyncState{..} = H.lookup i asyncSValues 
+
+-- | Unregister given sheduled sync action
+cancelSyncValue :: SyncId -> AsyncState s -> AsyncState s
+cancelSyncValue !i !s = s {
+    asyncScheduled = S.filter ((/= i).fst) . asyncScheduled $! s
+  }
+
+-- | Deletes calculated values
+purgeSyncs :: AsyncState s -> AsyncState s 
+purgeSyncs !s = s {
+    asyncSValues = H.empty
+  }
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,429 @@
+module Main where
+
+import Test.Framework
+import Test.Framework.Providers.HUnit
+import Test.HUnit
+
+import Control.DeepSeq
+import Control.Monad.Catch
+import Control.Monad.Fix 
+import Control.Monad.IO.Class
+import Data.Typeable 
+import GHC.Generics (Generic)
+
+import Control.Concurrent.MVar
+import Control.Wire
+import Control.Wire.Unsafe.Event
+import Data.Either
+import Game.GoreAndAsh.Async 
+import Game.GoreAndAsh.Core
+import Prelude hiding (id, (.))
+
+import qualified Data.Sequence as S 
+
+-- | Application monad is monad stack build from given list of modules over base monad (IO or Identity)
+type AppStack = ModuleStack [AsyncT, AsyncT] IO
+newtype AppState = AppState (ModuleState AppStack)
+  deriving (Generic)
+
+instance NFData AppState 
+
+-- | Wrapper around type family
+newtype AppMonad a = AppMonad (AppStack a)
+  deriving (Functor, Applicative, Monad, MonadFix, MonadIO, MonadThrow, MonadCatch, MonadAsync)
+
+instance GameModule AppMonad AppState where 
+  type ModuleState AppMonad = AppState
+  runModule (AppMonad m) (AppState s) = do 
+    (a, s') <- runModule m s 
+    return (a, AppState s')
+  newModuleState = AppState <$> newModuleState
+  withModule _ = withModule (Proxy :: Proxy AppStack)
+  cleanupModule (AppState s) = cleanupModule s 
+
+-- | Arrow that is build over the monad stack
+type AppWire a b = GameWire AppMonad a b
+
+data TestException = TestException deriving Show 
+
+instance Exception TestException
+
+main :: IO ()
+main = withModule (Proxy :: Proxy AppMonad) $ do
+  defaultMainWithOpts [
+      testGroup "async actions" [
+        testCase "simple" asyncSimple
+      , testCase "except" asyncExcept
+      , testCase "except no catch" asyncExcept'
+      , testCase "cancel" asyncCancel
+      , testCase "cancel delayed" asyncCancelDelayed
+      , testCase "factory" asyncFactory
+      , testCase "factory ex normal" asyncFactoryEx
+      , testCase "factory ex except" asyncFactoryEx'
+      ]
+    , testGroup "async bound actions" [
+        testCase "simple" asyncBoundSimple
+      , testCase "except" asyncBoundExcept
+      , testCase "except no catch" asyncBoundExcept'
+      , testCase "cancel" asyncCancelBound
+      , testCase "cancel delayed" asyncCancelBoundDelayed
+      , testCase "factory" asyncFactoryBound
+      , testCase "factory ex normal" asyncFactoryBoundEx
+      , testCase "factory ex except" asyncFactoryBoundEx'
+      ]
+    , testGroup "async sync actions" [
+        testCase "simple" asyncSyncSimple
+      , testCase "except" asyncSyncExcept
+      , testCase "except no catch" asyncSyncExcept'
+      , testCase "cancel" asyncCancelSync
+      , testCase "factory" asyncFactorySync
+      , testCase "factory ex normal" asyncSyncFactoryEx
+      , testCase "factory ex except" asyncSyncFactoryEx'
+      ]
+    ] mempty
+
+-- | Runs wire n times and return it result
+runWire :: Int -> AppWire () a -> IO (Maybe a)
+runWire n w = do 
+  gs <- newGameState w
+  go gs n Nothing
+  where 
+  go gs i ma = if i <= 0 then return ma
+    else do 
+      (ma', gs') <- stepGame gs (return ())
+      go gs' (i-1) ma'
+
+asyncSimple :: Assertion
+asyncSimple = do 
+  ma <- runWire 100 w 
+  assertEqual "wire switch" (Just True) ma
+  where
+    w = proc _ -> do 
+      e <- asyncAction (return True) -< ()
+      rSwitch (pure False) -< ((), pure <$> e)
+
+asyncExcept :: Assertion
+asyncExcept = do 
+  ma <- runWire 100 w 
+  assertBool "returned is exception" (check ma) 
+  where 
+    check ma = case ma of 
+      Nothing -> False 
+      Just ea -> isLeft ea 
+
+    w :: AppWire () (Either SomeException Bool)
+    w = proc _ -> do 
+      e <- asyncActionEx (throwM TestException) -< ()
+      rSwitch (pure $ Right False) -< ((), pure <$> e)
+
+asyncCancel :: Assertion
+asyncCancel = do 
+  ma <- runWire 100 w 
+  assertEqual "wire switch" (Just False) ma
+  where
+    w = proc _ -> do 
+      ce <- now -< ()
+      e <- asyncActionC (return True) -< ce
+      rSwitch (pure False) -< ((), pure <$> e)
+
+asyncCancelDelayed :: Assertion
+asyncCancelDelayed = do 
+  ma <- runWire 100 w0 
+  assertEqual "wire switch" (Just False) ma
+  where
+    w0 = switch $ proc _ -> do 
+      evar <- liftGameMonadEvent1 (const $ liftIO newEmptyMVar) . now -< ()
+      returnA -< (False, w <$> evar)
+
+    w var = proc _ -> do 
+      ce <- delay NoEvent . now -< ()
+      e <- asyncActionC (io var) -< ce
+      liftGameMonadEvent1 (const . liftIO $ putMVar var ()) -< ce
+      rSwitch (pure False) -< ((), pure <$> e)
+
+    io var = do 
+      _ <- readMVar var
+      return True
+
+asyncFactory :: Assertion 
+asyncFactory = do 
+  ma <- runWire 100 w
+  assertEqual "summed values" (Just 20) ma
+  where
+  w = proc _ -> do 
+    eio <- wgen -< ()
+    eas <- asyncActionFactory -< eio
+    hold . accumE (\i as -> i + sum as) 0 -< eas 
+
+  wgen :: AppWire () (Event (S.Seq (IO Int))) 
+  wgen = go 2 10
+    where
+    go k 0 = never
+    go k n = mkSFN $ \_ -> (Event $ S.replicate k (return 1), go k (n-1))
+
+seqRights :: S.Seq (Either a b) -> S.Seq b
+seqRights = fmap fromRight . S.filter isRight
+  where 
+  fromRight (Left _) = error "seqRights"
+  fromRight (Right a) = a 
+
+asyncFactoryEx :: Assertion 
+asyncFactoryEx = do 
+  ma <- runWire 100 w
+  assertEqual "summed values" (Just 20) ma
+  where
+  w = proc _ -> do 
+    eio <- wgen -< ()
+    eas <- asyncActionFactoryEx -< eio
+    hold . accumE foldResult 0 -< eas 
+
+  foldResult :: Int -> S.Seq (Either SomeException Int) -> Int
+  foldResult i eas = i + sum (seqRights eas)
+
+  wgen :: AppWire () (Event (S.Seq (IO Int))) 
+  wgen = go 2 10
+    where
+    go k 0 = never
+    go k n = mkSFN $ \_ -> (Event $ S.replicate k (return 1), go k (n-1))
+
+asyncFactoryEx' :: Assertion 
+asyncFactoryEx' = do 
+  ma <- runWire 100 w
+  assertEqual "summed values" (Just 0) ma
+  where
+  w = proc _ -> do 
+    eio <- wgen -< ()
+    eas <- asyncActionFactoryEx -< eio
+    hold . accumE foldResult 0 -< eas 
+
+  foldResult :: Int -> S.Seq (Either SomeException Int) -> Int
+  foldResult i eas = i + sum (seqRights eas)
+
+  wgen :: AppWire () (Event (S.Seq (IO Int))) 
+  wgen = go 2 10
+    where
+    go k 0 = never
+    go k n = mkSFN $ \_ -> (Event $ S.replicate k (throwM TestException), go k (n-1))
+
+asyncExcept' :: Assertion
+asyncExcept' = do 
+  ma <- (fmap Right $ runWire 100 w) `catchAll` (return . Left)
+  assertBool "returned is exception" (isLeft ma) 
+  where 
+    w :: AppWire () Bool
+    w = proc _ -> do 
+      e <- asyncAction (throwM TestException) -< ()
+      rSwitch (pure False) -< ((), pure <$> e)
+
+asyncBoundSimple :: Assertion
+asyncBoundSimple = do 
+  ma <- runWire 100 w 
+  assertEqual "wire switch" (Just True) ma
+  where
+    w = proc _ -> do 
+      e <- asyncActionBound (return True) -< ()
+      rSwitch (pure False) -< ((), pure <$> e)
+
+asyncBoundExcept :: Assertion
+asyncBoundExcept = do 
+  ma <- runWire 100 w 
+  assertBool "returned is exception" (check ma) 
+  where 
+    check ma = case ma of 
+      Nothing -> False 
+      Just ea -> isLeft ea 
+
+    w :: AppWire () (Either SomeException Bool)
+    w = proc _ -> do 
+      e <- asyncActionBoundEx (throwM TestException) -< ()
+      rSwitch (pure $ Right False) -< ((), pure <$> e)
+
+asyncBoundExcept' :: Assertion
+asyncBoundExcept' = do 
+  ma <- (fmap Right $ runWire 100 w) `catchAll` (return . Left)
+  assertBool "returned is exception" (isLeft ma) 
+  where 
+    w :: AppWire () Bool
+    w = proc _ -> do 
+      e <- asyncActionBound (throwM TestException) -< ()
+      rSwitch (pure False) -< ((), pure <$> e)
+
+asyncCancelBound :: Assertion
+asyncCancelBound = do 
+  ma <- runWire 100 w 
+  assertEqual "wire switch" (Just False) ma
+  where
+    w = proc _ -> do 
+      ce <- now -< ()
+      e <- asyncActionBoundC (return True) -< ce
+      rSwitch (pure False) -< ((), pure <$> e)
+
+asyncCancelBoundDelayed :: Assertion
+asyncCancelBoundDelayed = do 
+  ma <- runWire 100 w0 
+  assertEqual "wire switch" (Just False) ma
+  where
+    w0 = switch $ proc _ -> do 
+      evar <- liftGameMonadEvent1 (const $ liftIO newEmptyMVar) . now -< ()
+      returnA -< (False, w <$> evar)
+
+    w var = proc _ -> do 
+      ce <- delay NoEvent . now -< ()
+      e <- asyncActionBoundC (io var) -< ce
+      liftGameMonadEvent1 (const . liftIO $ putMVar var ()) -< ce
+      rSwitch (pure False) -< ((), pure <$> e)
+
+    io var = do 
+      _ <- readMVar var
+      return True
+
+asyncFactoryBound :: Assertion 
+asyncFactoryBound = do 
+  ma <- runWire 100 w
+  assertEqual "summed values" (Just 20) ma
+  where
+  w = proc _ -> do 
+    eio <- wgen -< ()
+    eas <- asyncActionBoundFactory -< eio
+    hold . accumE (\i as -> i + sum as) 0 -< eas 
+
+  wgen :: AppWire () (Event (S.Seq (IO Int))) 
+  wgen = go 2 10
+    where
+    go k 0 = never
+    go k n = mkSFN $ \_ -> (Event $ S.replicate k (return 1), go k (n-1))
+
+asyncFactoryBoundEx :: Assertion 
+asyncFactoryBoundEx = do 
+  ma <- runWire 100 w
+  assertEqual "summed values" (Just 20) ma
+  where
+  w = proc _ -> do 
+    eio <- wgen -< ()
+    eas <- asyncActionBoundFactoryEx -< eio
+    hold . accumE foldResult 0 -< eas 
+
+  foldResult :: Int -> S.Seq (Either SomeException Int) -> Int
+  foldResult i eas = i + sum (seqRights eas)
+
+  wgen :: AppWire () (Event (S.Seq (IO Int))) 
+  wgen = go 2 10
+    where
+    go k 0 = never
+    go k n = mkSFN $ \_ -> (Event $ S.replicate k (return 1), go k (n-1))
+
+asyncFactoryBoundEx' :: Assertion 
+asyncFactoryBoundEx' = do 
+  ma <- runWire 100 w
+  assertEqual "summed values" (Just 0) ma
+  where
+  w = proc _ -> do 
+    eio <- wgen -< ()
+    eas <- asyncActionBoundFactoryEx -< eio
+    hold . accumE foldResult 0 -< eas 
+
+  foldResult :: Int -> S.Seq (Either SomeException Int) -> Int
+  foldResult i eas = i + sum (seqRights eas)
+
+  wgen :: AppWire () (Event (S.Seq (IO Int))) 
+  wgen = go 2 10
+    where
+    go k 0 = never
+    go k n = mkSFN $ \_ -> (Event $ S.replicate k (throwM TestException), go k (n-1))
+
+asyncSyncSimple :: Assertion
+asyncSyncSimple = do 
+  ma <- runWire 100 w 
+  assertEqual "wire switch" (Just True) ma
+  where
+    w = proc _ -> do 
+      e <- asyncSyncAction (return True) -< ()
+      rSwitch (pure False) -< ((), pure <$> e)
+
+asyncSyncExcept :: Assertion
+asyncSyncExcept = do 
+  ma <- runWire 100 w 
+  assertBool "returned is exception" (check ma) 
+  where 
+    check ma = case ma of 
+      Nothing -> False 
+      Just ea -> isLeft ea 
+
+    w :: AppWire () (Either SomeException Bool)
+    w = proc _ -> do 
+      e <- asyncSyncActionEx (throwM TestException) -< ()
+      rSwitch (pure $ Right False) -< ((), pure <$> e)
+
+asyncSyncExcept' :: Assertion
+asyncSyncExcept' = do 
+  ma <- (fmap Right $ runWire 100 w) `catchAll` (return . Left)
+  assertBool "returned is exception" (isLeft ma) 
+  where 
+    w :: AppWire () Bool
+    w = proc _ -> do 
+      e <- asyncSyncAction (throwM TestException) -< ()
+      rSwitch (pure False) -< ((), pure <$> e)
+
+asyncCancelSync :: Assertion
+asyncCancelSync = do 
+  ma <- runWire 100 w 
+  assertEqual "wire switch" (Just False) ma
+  where
+    w = proc _ -> do 
+      ce <- now -< ()
+      e <- asyncSyncActionC (return True) -< ce
+      rSwitch (pure False) -< ((), pure <$> e)
+
+asyncFactorySync :: Assertion 
+asyncFactorySync = do 
+  ma <- runWire 100 w
+  assertEqual "summed values" (Just 20) ma
+  where
+  w = proc _ -> do 
+    eio <- wgen -< ()
+    eas <- asyncSyncActionFactory -< eio
+    hold . accumE (\i as -> i + sum as) 0 -< eas 
+
+  wgen :: AppWire () (Event (S.Seq (IO Int))) 
+  wgen = go 2 10
+    where
+    go k 0 = never
+    go k n = mkSFN $ \_ -> (Event $ S.replicate k (return 1), go k (n-1))
+
+asyncSyncFactoryEx :: Assertion 
+asyncSyncFactoryEx = do 
+  ma <- runWire 100 w
+  assertEqual "summed values" (Just 20) ma
+  where
+  w = proc _ -> do 
+    eio <- wgen -< ()
+    eas <- asyncSyncActionFactoryEx -< eio
+    hold . accumE foldResult 0 -< eas 
+
+  foldResult :: Int -> S.Seq (Either SomeException Int) -> Int
+  foldResult i eas = i + sum (seqRights eas)
+
+  wgen :: AppWire () (Event (S.Seq (IO Int))) 
+  wgen = go 2 10
+    where
+    go k 0 = never
+    go k n = mkSFN $ \_ -> (Event $ S.replicate k (return 1), go k (n-1))
+
+asyncSyncFactoryEx' :: Assertion 
+asyncSyncFactoryEx' = do 
+  ma <- runWire 100 w
+  assertEqual "summed values" (Just 0) ma
+  where
+  w = proc _ -> do 
+    eio <- wgen -< ()
+    eas <- asyncSyncActionFactoryEx -< eio
+    hold . accumE foldResult 0 -< eas 
+
+  foldResult :: Int -> S.Seq (Either SomeException Int) -> Int
+  foldResult i eas = i + sum (seqRights eas)
+
+  wgen :: AppWire () (Event (S.Seq (IO Int))) 
+  wgen = go 2 10
+    where
+    go k 0 = never
+    go k n = mkSFN $ \_ -> (Event $ S.replicate k (throwM TestException), go k (n-1))
