unloadPlugin_ :: String -> HashMap PluginName PluginState
                 -> Bot s (HashMap PluginName PluginState)
unloadPlugin_ pluginName pluginMap = do
  case HashMap.lookup pluginName pluginMap of
    Just PluginState{..} -> do
      forkBot_ $ do
        currentPlugin .= Just pluginData
        s <- copyBotState ()
        liftIO $ do
          void . timeout 10000000 . runBot s . onUnload $ pluginData
          forM_ pluginThreads $ 
            maybe (return ()) killThread <=< deRefWeak
      return $ HashMap.delete pluginName pluginMap
    Nothing -> return pluginMap
unloadPlugin_ :: String -> HashMap PluginName PluginState
                 -> Bot s (HashMap PluginName PluginState)
unloadPlugin_ pluginName pluginMap = do
  case HashMap.lookup pluginName pluginMap of
    Just PluginState{..} -> do
      forkBot_ $ do
        currentPlugin .= Just pluginData
        s <- copyBotState ()
        liftIO $ do
          void . timeout 10000000 . runBot s . onUnload $ pluginData
          forM_ pluginThreads $ 
            maybe (return ()) killThread <=< deRefWeak
      return $ HashMap.delete pluginName pluginMap
    Nothing -> return pluginMap
unloadPlugin_ pluginName pluginMap = do
  case HashMap.lookup pluginName pluginMap of
    Just PluginState{..} -> do
      forkBot_ $ do
        currentPlugin .= Just pluginData
        s <- copyBotState ()
        liftIO $ do
          void . timeout 10000000 . runBot s . onUnload $ pluginData
          forM_ pluginThreads $ 
            maybe (return ()) killThread <=< deRefWeak
      return $ HashMap.delete pluginName pluginMap
    Nothing -> return pluginMap