chatUser :: ChatCoreUser
         -> AcidState ChatCoreState
         -> Event RemoteClient -- ^ New clients for this user.
         -> Reactive ChatUser
chatUser user acid eNewConn = do
    (eNewNetwork, pushNewNetwork) <- newEvent
    let uName = user ^. usrStName
    rec
      -- Networks.
      bNetworks <- behNetworks acid uName eNewNetwork eClientCmd
      let bNetworkList = I.toList <$> bNetworks

      -- Receive core events from networks.
      let eCoreEvent = switchMergeWith (view eNetworkCoreEvt) bNetworkList


      -- Remote clients.
      (bClients, cleanClients) <- behRemoteClients uName eNewConn bNetworks eCoreEvent
      let bClientList = map snd <$> M.toList <$> bClients

      -- Receive client commands from all clients.
      let eClientCmd = switchMergeWith rcCommands bClientList
    
    -- FIXME: Removing this line causes core events to not be received by clients.
    _ <- listen eCoreEvent print

    let bCleanupNetworks = map cleanupChatNetwork <$> bNetworkList
        cleanup = do
            cleanClients
            -- Run cleanup actions for all the networks.
            join (sequence_ <$> sync (sample bCleanupNetworks))

    -- Push an add network event for all the networks.
    mapM_ pushNewNetwork $ I.toList (user ^. usrStNetworks)
    return $ ChatUser uName bNetworks bClientList cleanup
chatUser :: ChatCoreUser
         -> AcidState ChatCoreState
         -> Event RemoteClient -- ^ New clients for this user.
         -> Reactive ChatUser
chatUser user acid eNewConn = do
    (eNewNetwork, pushNewNetwork) <- newEvent
    let uName = user ^. usrStName
    rec
      -- Networks.
      bNetworks <- behNetworks acid uName eNewNetwork eClientCmd
      let bNetworkList = I.toList <$> bNetworks

      -- Receive core events from networks.
      let eCoreEvent = switchMergeWith (view eNetworkCoreEvt) bNetworkList


      -- Remote clients.
      (bClients, cleanClients) <- behRemoteClients uName eNewConn bNetworks eCoreEvent
      let bClientList = map snd <$> M.toList <$> bClients

      -- Receive client commands from all clients.
      let eClientCmd = switchMergeWith rcCommands bClientList
    
    -- FIXME: Removing this line causes core events to not be received by clients.
    _ <- listen eCoreEvent print

    let bCleanupNetworks = map cleanupChatNetwork <$> bNetworkList
        cleanup = do
            cleanClients
            -- Run cleanup actions for all the networks.
            join (sequence_ <$> sync (sample bCleanupNetworks))

    -- Push an add network event for all the networks.
    mapM_ pushNewNetwork $ I.toList (user ^. usrStNetworks)
    return $ ChatUser uName bNetworks bClientList cleanup
chatUser user acid eNewConn = do
    (eNewNetwork, pushNewNetwork) <- newEvent
    let uName = user ^. usrStName
    rec
      -- Networks.
      bNetworks <- behNetworks acid uName eNewNetwork eClientCmd
      let bNetworkList = I.toList <$> bNetworks

      -- Receive core events from networks.
      let eCoreEvent = switchMergeWith (view eNetworkCoreEvt) bNetworkList


      -- Remote clients.
      (bClients, cleanClients) <- behRemoteClients uName eNewConn bNetworks eCoreEvent
      let bClientList = map snd <$> M.toList <$> bClients

      -- Receive client commands from all clients.
      let eClientCmd = switchMergeWith rcCommands bClientList
    
    -- FIXME: Removing this line causes core events to not be received by clients.
    _ <- listen eCoreEvent print

    let bCleanupNetworks = map cleanupChatNetwork <$> bNetworkList
        cleanup = do
            cleanClients
            -- Run cleanup actions for all the networks.
            join (sequence_ <$> sync (sample bCleanupNetworks))

    -- Push an add network event for all the networks.
    mapM_ pushNewNetwork $ I.toList (user ^. usrStNetworks)
    return $ ChatUser uName bNetworks bClientList cleanup