doKick ::
  UserInfo   {- ^ kicker      -} ->
  Identifier {- ^ channel     -} ->
  Identifier {- ^ kicked      -} ->
  ByteString {- ^ kick reason -} ->
  IrcConnection -> Logic IrcConnection
doKick who chan tgt reason conn =
  do stamp <- getStamp
     let modes = view (connChannels . ix chan . chanUsers . ix (userNick who)) conn
         mesg = defaultIrcMessage
                { _mesgType = KickMsgType tgt (asUtf8 reason)
                , _mesgSender = who
                , _mesgStamp = stamp
                , _mesgModes = modes
                }

     let conn1 = set (connChannels . ix chan . chanUsers . at tgt)
                     Nothing
                     conn

         stillKnown = has (connChannels . folded . chanUsers . ix (userNick who))
                          conn1

         conn2 | stillKnown = conn1
               | otherwise  = set (connUsers . at (userNick who)) Nothing conn1

         conn3
           | isMyNick tgt conn2 =
                set (connChannels . at chan) Nothing conn2
           | otherwise = conn2

     recordMessage mesg chan conn3
doKick ::
  UserInfo   {- ^ kicker      -} ->
  Identifier {- ^ channel     -} ->
  Identifier {- ^ kicked      -} ->
  ByteString {- ^ kick reason -} ->
  IrcConnection -> Logic IrcConnection
doKick who chan tgt reason conn =
  do stamp <- getStamp
     let modes = view (connChannels . ix chan . chanUsers . ix (userNick who)) conn
         mesg = defaultIrcMessage
                { _mesgType = KickMsgType tgt (asUtf8 reason)
                , _mesgSender = who
                , _mesgStamp = stamp
                , _mesgModes = modes
                }

     let conn1 = set (connChannels . ix chan . chanUsers . at tgt)
                     Nothing
                     conn

         stillKnown = has (connChannels . folded . chanUsers . ix (userNick who))
                          conn1

         conn2 | stillKnown = conn1
               | otherwise  = set (connUsers . at (userNick who)) Nothing conn1

         conn3
           | isMyNick tgt conn2 =
                set (connChannels . at chan) Nothing conn2
           | otherwise = conn2

     recordMessage mesg chan conn3
doKick who chan tgt reason conn =
  do stamp <- getStamp
     let modes = view (connChannels . ix chan . chanUsers . ix (userNick who)) conn
         mesg = defaultIrcMessage
                { _mesgType = KickMsgType tgt (asUtf8 reason)
                , _mesgSender = who
                , _mesgStamp = stamp
                , _mesgModes = modes
                }

     let conn1 = set (connChannels . ix chan . chanUsers . at tgt)
                     Nothing
                     conn

         stillKnown = has (connChannels . folded . chanUsers . ix (userNick who))
                          conn1

         conn2 | stillKnown = conn1
               | otherwise  = set (connUsers . at (userNick who)) Nothing conn1

         conn3
           | isMyNick tgt conn2 =
                set (connChannels . at chan) Nothing conn2
           | otherwise = conn2

     recordMessage mesg chan conn3