diff --git a/Kevin/Base.hs b/Kevin/Base.hs
--- a/Kevin/Base.hs
+++ b/Kevin/Base.hs
@@ -36,16 +36,15 @@
 import System.IO.Error
 
 runPrinter :: Chan T.Text -> Handle -> IO ()
-runPrinter ch h = void . forkIO . forever $ readChan ch >>=
-    T.hPutStr h . T.encodeUtf8
+runPrinter ch h = void . forkIO . forever $ readChan ch >>= T.hPutStr h . T.encodeUtf8
 
 io :: MonadIO m => IO a -> m a
 io = liftIO
 
 class KevinServer a where
-    readClient, readServer :: a -> IO T.Text
-    writeServer :: a -> T.Text -> IO ()
-    writeClient :: a -> T.Text -> IO ()
+    readClient, readServer   :: a -> IO T.Text
+    writeServer              :: a -> T.Text -> IO ()
+    writeClient              :: a -> T.Text -> IO ()
     closeClient, closeServer :: a -> IO ()
 
 data KevinException = ParseFailure
@@ -59,24 +58,21 @@
 -- actions
 
 hGetCharTimeout :: Handle -> Int -> IO Char
-hGetCharTimeout h t = do
-    hSetBuffering h NoBuffering
-    ready <- hWaitForInput h t
-    if ready
-        then hGetChar h
-        else throwIO $ mkIOError eofErrorType "read timeout" (Just h) Nothing
+hGetCharTimeout h t = do hSetBuffering h NoBuffering
+                         ready <- hWaitForInput h t
+                         if ready
+                            then hGetChar h
+                            else throwIO $ mkIOError eofErrorType "read timeout" (Just h) Nothing
 
 hGetSep :: Char -> Handle -> IO String
-hGetSep sep h = fix (\f -> do
-    ch <- hGetCharTimeout h 180000
-    if ch == sep
-        then return ""
-        else (ch:) <$> f)
+hGetSep sep h = fix (\f -> do ch <- hGetCharTimeout h 180000
+                              if ch == sep
+                                 then return ""
+                                 else (ch:) <$> f)
 
 instance KevinServer Kevin where
-    readClient k = do
-        line <- T.decodeUtf8 <$> T.hGetLine (irc k)
-        return $ T.init line
+    readClient k = do line <- T.decodeUtf8 <$> T.hGetLine (irc k)
+                      return $ T.init line
     readServer k = T.pack <$> hGetSep '\NUL' (damn k)
 
     writeClient k = writeChan (iChan k)
diff --git a/Kevin/Chatrooms.hs b/Kevin/Chatrooms.hs
--- a/Kevin/Chatrooms.hs
+++ b/Kevin/Chatrooms.hs
@@ -25,7 +25,7 @@
 
 deleteBy' :: (a -> Bool) -> [a] -> [a]
 deleteBy' f (x:xs) = if f x then xs else x:deleteBy' f xs
-deleteBy' _ [] = []
+deleteBy' _ []     = []
 
 removeRoom :: Chatroom -> KevinIO ()
 removeRoom c = kevin $ privclasses.at c .= Nothing >> users.at c .= Nothing
@@ -34,12 +34,9 @@
 addUser ch us = kevin $ users.ix ch %= (us:)
 
 numUsers :: Chatroom -> T.Text -> KevinIO Int
-numUsers ch us = do
-    st <- gets_ $ view users
-    case st^.at ch of
-        Just usrs -> return . length
-            $ findIndices (\u -> us == username u) usrs
-        Nothing -> return 0
+numUsers ch us = do st <- gets_ $ view users
+                    case st^.at ch of Just usrs -> return . length $ findIndices (\u -> us == username u) usrs
+                                      Nothing   -> return 0
 
 removeUser :: Chatroom -> T.Text -> KevinIO ()
 removeUser ch us = kevin $ users.ix ch %= deleteBy' ((== us) . username)
@@ -54,23 +51,17 @@
 setPrivclasses room ps = kevin $ privclasses.at room ?= M.fromList ps
 
 getPrivclass :: Chatroom -> T.Text -> KevinIO (Maybe T.Text)
-getPrivclass room user = do
-    st <- gets_ $ view users
-    case st^.at room of
-        Just qs -> return $ privclass
-            <$> listToMaybe (filter ((== user) . username) qs)
-        Nothing -> return Nothing
+getPrivclass room user = do st <- gets_ $ view users
+                            case st^.at room of Just qs -> return $ privclass <$> listToMaybe (filter ((== user) . username) qs)
+                                                Nothing -> return Nothing
         
 getPrivclassLevel :: Chatroom -> T.Text -> KevinIO Int
-getPrivclassLevel room pc = do
-    st <- gets_ $ view privclasses
-    return . fromMaybe 0 $ st^.at room >>= (^.at pc)
+getPrivclassLevel room pc = do st <- gets_ $ view privclasses
+                               return . fromMaybe 0 $ st^.at room >>= (^.at pc)
 
 setUserPrivclass :: Chatroom -> T.Text -> T.Text -> KevinIO ()
-setUserPrivclass room user pc = do
-    pclevel <- getPrivclassLevel room pc
-    kevin $ users.ix room.traverse.filtered ((user ==) . username)
-            %= (\u -> u {privclass = pc, privclassLevel = pclevel})
+setUserPrivclass room user pc = do pclevel <- getPrivclassLevel room pc
+                                   kevin $ users.ix room.traverse.filtered ((user ==) . username) %= (\u -> u {privclass = pc, privclassLevel = pclevel})
 
 setTitle :: Chatroom -> T.Text -> KevinIO ()
 setTitle ch t = kevin $ titles.at ch ?= t
diff --git a/Kevin/Damn/Packet.hs b/Kevin/Damn/Packet.hs
--- a/Kevin/Damn/Packet.hs
+++ b/Kevin/Damn/Packet.hs
@@ -45,41 +45,35 @@
 parseCommand = takeWhile1 (not . isSpace)
 
 parseParam :: Parser (Maybe T.Text)
-parseParam = do
-    char ' '
-    parm <- takeWhile1 (not . isSpace)
-    return $ Just parm
+parseParam = do char ' '
+                parm <- takeWhile1 (not . isSpace)
+                return $ Just parm
 
 parseArgs :: Parser (M.Map T.Text T.Text)
-parseArgs = (M.fromList <$>) . many $ do
-    char '\n'
-    c <- takeTill (=='=')
-    char '='
-    r <- takeTill (=='\n')
-    return (c,r)
+parseArgs = (M.fromList <$>) . many $ do char '\n'
+                                         c <- takeTill (=='=')
+                                         char '='
+                                         r <- takeTill (=='\n')
+                                         return (c,r)
 
 parseHead :: Parser Packet
-parseHead = do
-    c <- parseCommand
-    p <- option Nothing parseParam
-    a <- parseArgs
-    return $ Packet c p a Nothing
+parseHead = do c <- parseCommand
+               p <- option Nothing parseParam
+               a <- parseArgs
+               return $ Packet c p a Nothing
 
 parsePacket :: T.Text -> Packet
-parsePacket pack = case parseOnly parseHead top of
-    Left _ -> throw ParseFailure
-    Right res -> res & body .~ (T.drop 2 <$> toMaybe (not . T.null) b)
-    where
-        (top, b) = T.breakOn "\n\n" pack
+parsePacket pack = case parseOnly parseHead top of Left _    -> throw ParseFailure
+                                                   Right res -> res & body .~ (T.drop 2 <$> toMaybe (not . T.null) b)
+    where (top, b) = T.breakOn "\n\n" pack
 
 getResult :: Either String a -> a
 getResult x = let Right e = x in e
 
 fixLoginPacket :: Packet -> Packet
 fixLoginPacket pkt = if pkt^.command == "login"
-    then pkt & args %~ (<> getResult
-        (parseOnly parseArgs . T.cons '\n' . fromJust $ pkt^.body))
-    else pkt
+                        then pkt & args %~ (<> getResult (parseOnly parseArgs . T.cons '\n' . fromJust $ pkt^.body))
+                        else pkt
 
 subPacket :: Packet -> Maybe Packet
 subPacket = (parsePacket <$>) . view body
@@ -88,18 +82,15 @@
 okay (Packet _ _ a _) = let e = a ^. at "e" in isNothing e || e == Just "ok"
 
 parsePrivclasses :: T.Text -> [Privclass]
-parsePrivclasses = map (liftM2 (,) (!! 1) (read . T.unpack . head)
-                       . T.splitOn ":") 
+parsePrivclasses = map (liftM2 (,) (!! 1) (read . T.unpack . head) . T.splitOn ":") 
                  . filter (not . T.null)
                  . T.splitOn "\n"
 
 readable :: Packet -> T.Text
-readable (Packet cmd param arg bod) = cmd
-                                   <> maybe "" (' ' `T.cons`) param
-                                   <> formattedArgs (M.toList arg)
-                                   <> maybe "" ("\n\n" <>) bod
-                                   <> "\n\0"
+readable (Packet cmd param arg bod) = cmd <> maybe "" (' ' `T.cons`) param
+                                          <> formattedArgs (M.toList arg)
+                                          <> maybe "" ("\n\n" <>) bod
+                                          <> "\n\0"
     where
         formattedArgs [] = ""
-        formattedArgs q = ("\n" <>) . T.intercalate "\n"
-                        . map (uncurry (\x y -> x <> "=" <> y)) $ q
+        formattedArgs q  = ("\n" <>) . T.intercalate "\n" . map (uncurry (\x y -> x <> "=" <> y)) $ q
diff --git a/Kevin/Damn/Protocol.hs b/Kevin/Damn/Protocol.hs
--- a/Kevin/Damn/Protocol.hs
+++ b/Kevin/Damn/Protocol.hs
@@ -28,197 +28,151 @@
 cleanup = klog Blue "cleanup server"
 
 listen :: KevinIO ()
-listen = fix (\f -> flip catches errHandlers $ do
-    k <- get_
-    pkt <- io $ parsePacket <$> readServer k
-    respond pkt (view command pkt)
-    f)
+listen = fix (\f -> flip catches errHandlers $ do k   <- get_
+                                                  pkt <- io $ parsePacket <$> readServer k
+                                                  respond pkt (view command pkt)
+                                                  f)
 
 -- main responder
 respond :: Packet -> T.Text -> KevinIO ()
-respond _ "dAmnServer" = do
-    s <- use_ settings
-    sendLogin (s^.name) (s^.authtoken)
+respond _ "dAmnServer" = do s <- use_ settings
+                            sendLogin (s^.name) (s^.authtoken)
 
 respond pkt "login" = if okay pkt
-    then do
-        j <- kevin $ do
-           loggedIn .= True
-           use joining
-        mapM_ sendJoin j
-    else I.sendNotice $ "Login failed: " <> pkt ^. args.ix "e"
+                         then do j <- kevin $ do loggedIn .= True
+                                                 use joining
+                                 mapM_ sendJoin j
+                         else I.sendNotice $ "Login failed: " <> pkt ^. args.ix "e"
 
-respond pkt "join" = do
-    roomname <- deformatRoom $ pkt^.parameter._Just
-    if okay pkt
-        then do
-            kevin $ joining %= (roomname:)
-            uname <- use_ name
-            I.sendJoin uname roomname
-        else I.sendNotice $ T.concat
-            ["Couldn't join ", roomname, ": ", pkt^.args.ix "e"]
+respond pkt "join" = do roomname <- deformatRoom $ pkt^.parameter._Just
+                        if okay pkt
+                           then do kevin $ joining %= (roomname:)
+                                   uname <- use_ name
+                                   I.sendJoin uname roomname
+                           else I.sendNotice $ T.concat ["Couldn't join ", roomname, ": ", pkt^.args.ix "e"]
 
-respond pkt "part" = do
-    roomname <- deformatRoom $ pkt^.parameter._Just
-    if okay pkt
-        then do
-            uname <- use_ name
-            removeRoom roomname
-            I.sendPart uname roomname Nothing
-        else I.sendNotice $ T.concat
-            ["Couldn't part ", roomname, ": ", pkt^.args.ix "e"]
+respond pkt "part" = do roomname <- deformatRoom $ pkt^.parameter._Just
+                        if okay pkt
+                            then do uname <- use_ name
+                                    removeRoom roomname
+                                    I.sendPart uname roomname Nothing
+                            else I.sendNotice $ T.concat ["Couldn't part ", roomname, ": ", pkt^.args.ix "e"]
 
-respond pkt "property" = do
-    roomname <- deformatRoom (pkt^.parameter._Just)
-    case pkt^.args.ix "p" of
-        "privclasses" -> setPrivclasses roomname . parsePrivclasses
-            $ pkt^.body._Just
+respond pkt "property" = do roomname <- deformatRoom (pkt^.parameter._Just)
+                            case pkt^.args.ix "p" of "privclasses" -> setPrivclasses roomname . parsePrivclasses $ pkt^.body._Just
 
-        "topic" -> do
-            uname <- use_ name
-            I.sendTopic uname roomname
-                        (fromMaybe uname $ pkt^.args.at "by")
-                        (T.replace "\n" " - " . entityDecode
-                            . tablumpDecode $ pkt^.body._Just)
-                        (pkt^.args.ix "ts")
+                                                     "topic" -> do uname <- use_ name
+                                                                   I.sendTopic uname roomname (fromMaybe uname $ pkt^.args.at "by")
+                                                                                              (T.replace "\n" " - " . entityDecode . tablumpDecode $ pkt^.body._Just)
+                                                                                              (pkt^.args.ix "ts")
 
-        "title" -> setTitle roomname (T.replace "\n" " - " . entityDecode
-                                     . tablumpDecode $ pkt^.body._Just)
+                                                     "title" -> setTitle roomname (T.replace "\n" " - " . entityDecode . tablumpDecode $ pkt^.body._Just)
 
-        "members" -> do
-            k <- get_
-            let members = map (mkUser roomname (k^.privclasses) . parsePacket)
-                        . init . T.splitOn "\n\n"
-                        $ pkt^.body._Just
-                pc = privclass . head . filter (\x -> username x == k^.name)
-                   $ members
-                n = nub members
-            setUsers roomname members
-            when (roomname `elem` k^.joining) $ do
-                I.sendUserList (k^.name) n roomname
-                pclevel <- getPrivclassLevel roomname pc
-                I.sendSetUserMode (k^.name) roomname pclevel
-                kevin $ joining %= delete roomname
+                                                     "members" -> do k <- get_
+                                                                     let members = map (mkUser roomname (k^.privclasses) . parsePacket)
+                                                                                 . init . T.splitOn "\n\n"
+                                                                                 $ pkt^.body._Just
+                                                                         pc      = privclass . head . filter (\x -> username x == k^.name) $ members
+                                                                         n       = nub members
+                                                                     setUsers roomname members
+                                                                     when (roomname `elem` k^.joining) $ do I.sendUserList (k^.name) n roomname
+                                                                                                            pclevel <- getPrivclassLevel roomname pc
+                                                                                                            I.sendSetUserMode (k^.name) roomname pclevel
+                                                                                                            kevin $ joining %= delete roomname
 
-        "info" -> do
-            us <- use_ name
-            curtime <- io $ floor <$> getPOSIXTime
-            let fixedPacket = parsePacket . T.init
-                            . T.replace "\n\nusericon" "\nusericon"
-                            . readable $ pkt
-                uname = T.drop 6 $ pkt^.parameter._Just
-                rn = fixedPacket^.args.ix "realname"
-                conns = map (\pk ->
-                    let x = parsePacket $ "conn" <> pk
-                    in ( read (T.unpack $ x^.args.ix "online") :: Int
-                       , read (T.unpack $ x^.args.ix "idle") :: Int
-                       , map (T.drop 8) . filter (not . T.null)
-                       . T.splitOn "\n\n" $ x^.body._Just
-                    )
-                  ) . tail . T.splitOn "conn"
-                    $ fixedPacket^.body._Just
-                allRooms = nub $ conns >>= (\(_,_,c) -> c)
-                (onlinespan,idle,_) = minimumBy (comparing (view _1)) conns
-                signon = curtime - onlinespan
-            I.sendWhoisReply us uname (entityDecode rn) allRooms idle signon
+                                                     "info" -> do us <- use_ name
+                                                                  curtime <- io $ floor <$> getPOSIXTime
+                                                                  let fixedPacket = parsePacket . T.init
+                                                                                  . T.replace "\n\nusericon" "\nusericon"
+                                                                                  . readable $ pkt
+                                                                      uname = T.drop 6 $ pkt^.parameter._Just
+                                                                      rn    = fixedPacket^.args.ix "realname"
+                                                                      conns = map (\pk -> let x = parsePacket $ "conn" <> pk
+                                                                                           in ( read (T.unpack $ x^.args.ix "online") :: Int
+                                                                                              , read (T.unpack $ x^.args.ix "idle"  ) :: Int
+                                                                                              , map (T.drop 8) . filter (not . T.null) . T.splitOn "\n\n" $ x^.body._Just
+                                                                                              )) . tail . T.splitOn "conn" $ fixedPacket^.body._Just
+                                                                      allRooms            = nub $ conns >>= (\(_,_,c) -> c)
+                                                                      (onlinespan,idle,_) = minimumBy (comparing (view _1)) conns
+                                                                      signon              = curtime - onlinespan
+                                                                  I.sendWhoisReply us uname (entityDecode rn) allRooms idle signon
 
-        q -> klogError $ "Unrecognized property " ++ T.unpack q
+                                                     q -> klogError $ "Unrecognized property " ++ T.unpack q
 
-respond spk "recv" = deformatRoom (spk^.parameter._Just) >>= \roomname ->
-    case pkt^.command of
-    "join" -> do
-        let usname = pkt^.parameter._Just
-        pcs <- gets_ $ view privclasses
-        countUser <- numUsers roomname usname
-        let us = mkUser roomname pcs modifiedPkt
-        addUser roomname us
-        if countUser == 0
-            then do
-                I.sendJoin usname roomname
-                pclevel <- getPrivclassLevel roomname
-                    $ modifiedPkt^.args.ix "pc"
-                I.sendSetUserMode usname roomname pclevel
-            else I.sendNoticeClone (username us) (succ countUser) roomname
+respond spk "recv" = deformatRoom (spk^.parameter._Just) >>=
+    \roomname -> case pkt^.command of "join" -> do let usname = pkt^.parameter._Just
+                                                   pcs <- gets_ $ view privclasses
+                                                   countUser <- numUsers roomname usname
+                                                   let us = mkUser roomname pcs modifiedPkt
+                                                   addUser roomname us
+                                                   if countUser == 0
+                                                      then do I.sendJoin usname roomname
+                                                              pclevel <- getPrivclassLevel roomname $ modifiedPkt^.args.ix "pc"
+                                                              I.sendSetUserMode usname roomname pclevel
+                                                      else I.sendNoticeClone (username us) (succ countUser) roomname
 
-    "part" -> do
-        let uname = pkt^.parameter._Just
-        removeUser roomname uname
-        countUser <- numUsers roomname uname
-        if countUser < 1
-            then I.sendPart uname roomname $ pkt^.args.at "r"
-            else I.sendNoticeUnclone uname countUser roomname
+                                      "part" -> do let uname = pkt^.parameter._Just
+                                                   removeUser roomname uname
+                                                   countUser <- numUsers roomname uname
+                                                   if countUser < 1
+                                                      then I.sendPart uname roomname $ pkt^.args.at "r"
+                                                      else I.sendNoticeUnclone uname countUser roomname
 
-    "msg" -> do
-        let uname = arg "from"
-            msg   = pkt^.body._Just
-        un <- use_ name
-        unless (un == uname) $ I.sendChanMsg uname roomname
-            (entityDecode $ tablumpDecode msg)
+                                      "msg" -> do let uname = arg "from"
+                                                      msg   = pkt^.body._Just
+                                                  un <- use_ name
+                                                  unless (un == uname) $ I.sendChanMsg uname roomname (entityDecode $ tablumpDecode msg)
 
-    "action" -> do
-        let uname = arg "from"
-            msg   = pkt^.body._Just
-        un <- use_ name
-        unless (un == uname) $ I.sendChanAction uname roomname
-            (entityDecode $ tablumpDecode msg)
+                                      "action" -> do let uname = arg "from"
+                                                         msg   = pkt^.body._Just
+                                                     un <- use_ name
+                                                     unless (un == uname) $ I.sendChanAction uname roomname (entityDecode $ tablumpDecode msg)
 
-    "privchg" -> do
-        let user = pkt^.parameter._Just
-            by = arg "by"
-            newPc = arg "pc"
-        oldPc <- getPrivclass roomname user
-        oldPcLevel <- getPrivclassLevel roomname (fromMaybe "" oldPc)
-        newPcLevel <- getPrivclassLevel roomname newPc
-        setUserPrivclass roomname user newPc
-        I.sendRoomNotice roomname $ T.concat
-            [user, " has been moved"
-            , maybe "" (" from " <>) oldPc
-            , " to ", newPc, " by ", by
-            ]
-        I.sendChangeUserMode user roomname oldPcLevel newPcLevel
+                                      "privchg" -> do let user  = pkt^.parameter._Just
+                                                          by    = arg "by"
+                                                          newPc = arg "pc"
+                                                      oldPc      <- getPrivclass roomname user
+                                                      oldPcLevel <- getPrivclassLevel roomname (fromMaybe "" oldPc)
+                                                      newPcLevel <- getPrivclassLevel roomname newPc
+                                                      setUserPrivclass roomname user newPc
+                                                      I.sendRoomNotice roomname $ T.concat [ user, " has been moved"
+                                                                                           , maybe "" (" from " <>) oldPc
+                                                                                           , " to ", newPc, " by ", by
+                                                                                           ]
+                                                      I.sendChangeUserMode user roomname oldPcLevel newPcLevel
 
-    "kicked" -> do
-        let uname = pkt^.parameter._Just
-        removeUserAll roomname uname
-        I.sendKick uname (arg "by") roomname $ pkt^.body.traverse ^? notNull_
+                                      "kicked" -> do let uname = pkt^.parameter._Just
+                                                     removeUserAll roomname uname
+                                                     I.sendKick uname (arg "by") roomname $ pkt^.body.traverse ^? notNull_
 
-    "admin" -> case pkt^.parameter._Just of
-        "create" -> I.sendRoomNotice roomname $
-            T.concat ["Privclass ", arg "name"
-                     , " created by ", arg "by"
-                     , " with: ", arg "privs"]
-        "update" -> I.sendRoomNotice roomname $
-            T.concat ["Privclass ", arg "name"
-                     , " updated by ", arg "by"
-                     , " with: ", arg "privs"]
-        "rename" -> I.sendRoomNotice roomname $
-            T.concat ["Privclass ", arg "prev"
-                     , " renamed to ", arg "name"
-                     , " by ", arg "by"]
-        "move"   -> I.sendRoomNotice roomname $
-            T.concat [ arg "n", " users in privclass "
-                     , arg "prev", " moved to "
-                     , arg "name", " by ", arg "by"]
-        "remove" -> I.sendRoomNotice roomname $
-            T.concat ["Privclass", arg "name", " removed by ", arg "by"]
-        "show"   -> mapM_ (I.sendRoomNotice roomname) . T.splitOn "\n"
-                        $ pkt^.body._Just
-        "privclass" -> I.sendRoomNotice roomname $ "Admin error: " <> arg "e"
-        q -> klogError $ "Unknown admin packet type " ++ show q
+                                      "admin" -> case pkt^.parameter._Just of "create"    -> I.sendRoomNotice roomname $ T.concat [ "Privclass ", arg "name"
+                                                                                                                                  , " created by ", arg "by"
+                                                                                                                                  , " with: ", arg "privs" ]
+                                                                              "update"    -> I.sendRoomNotice roomname $ T.concat [ "Privclass ", arg "name"
+                                                                                                                                  , " updated by ", arg "by"
+                                                                                                                                  , " with: ", arg "privs" ]
+                                                                              "rename"    -> I.sendRoomNotice roomname $ T.concat [ "Privclass ", arg "prev"
+                                                                                                                                  , " renamed to ", arg "name"
+                                                                                                                                  , " by ", arg "by" ]
+                                                                              "move"      -> I.sendRoomNotice roomname $ T.concat [ arg "n", " users in privclass "
+                                                                                                                                  , arg "prev", " moved to "
+                                                                                                                                  , arg "name", " by ", arg "by" ]
+                                                                              "remove"    -> I.sendRoomNotice roomname $ T.concat [ "Privclass", arg "name"
+                                                                                                                                  , " removed by ", arg "by" ]
+                                                                              "show"      -> mapM_ (I.sendRoomNotice roomname) . T.splitOn "\n" $ pkt^.body._Just
+                                                                              "privclass" -> I.sendRoomNotice roomname $ "Admin error: " <> arg "e"
+                                                                              q           -> klogError $ "Unknown admin packet type " ++ show q
 
-    x -> klogError $ "Unknown packet type " ++ show x
+                                      x -> klogError $ "Unknown packet type " ++ show x
 
-    where
-        pkt = fromJust $ subPacket spk
-        modifiedPkt = parsePacket (T.replace "\n\npc" "\npc" $ readable pkt)
-        arg s = pkt^.args.ix s
+    where pkt         = fromJust $ subPacket spk
+          modifiedPkt = parsePacket (T.replace "\n\npc" "\npc" $ readable pkt)
+          arg s       = pkt^.args.ix s
 
-respond pkt "kicked" = do
-    roomname <- deformatRoom $ pkt^.parameter._Just
-    uname <- use_ name
-    removeRoom roomname
-    I.sendKick uname (pkt^.args.ix "by") roomname
-        $ pkt^.body.traverse ^? notNull_
+respond pkt "kicked" = do roomname <- deformatRoom $ pkt^.parameter._Just
+                          uname <- use_ name
+                          removeRoom roomname
+                          I.sendKick uname (pkt^.args.ix "by") roomname $ pkt^.body.traverse ^? notNull_
 
 respond pkt "send" = I.sendNotice $ "Send error: " <> pkt^.args.ix "e"
 
@@ -229,16 +183,14 @@
 
 mkUser :: Chatroom -> PrivclassStore -> Packet -> User
 mkUser room st p = User (p^.parameter._Just)
-                       (g "pc")
-                       (fromMaybe 0 $ st^.at room >>= (^.at (g "pc")))
-                       (g "symbol")
-                       (entityDecode $ g "realname")
-                       (g "typename")
-                       (g "gpc")
-    where
-        g s = p^.args.ix s
+                        (g "pc")
+                        (fromMaybe 0 $ st^.at room >>= (^.at (g "pc")))
+                        (g "symbol")
+                        (entityDecode $ g "realname")
+                        (g "typename")
+                        (g "gpc")
+    where g s = p^.args.ix s
 
 errHandlers :: [Handler KevinIO ()]
-errHandlers = [ handler_ _KevinException
-                    $ klogError "Malformed communication from server"
+errHandlers = [ handler_ _KevinException $ klogError "Malformed communication from server"
               , handler _IOException (\e -> klogError $ "server: " ++ show e) ]
diff --git a/Kevin/Damn/Protocol/Send.hs b/Kevin/Damn/Protocol/Send.hs
--- a/Kevin/Damn/Protocol/Send.hs
+++ b/Kevin/Damn/Protocol/Send.hs
@@ -36,99 +36,80 @@
 sendPacket p = get_ >>= \k -> io . writeServer k . T.snoc p $ '\0'
 
 formatRoom :: T.Text -> KevinIO T.Text
-formatRoom b =
-    case T.splitAt 1 b of
-        ("#",s) -> return $ "chat:" <> s
-        ("&",s) -> do
-            uname <- use_ name
-            return . ("pchat:" <>) . T.intercalate ":"
-                   . sort . map (T.map toLower) $ [uname, s]
-        r -> return $ "chat" <> uncurry (<>) r
+formatRoom b = case T.splitAt 1 b of ("#",s) -> return $ "chat:" <> s
+                                     ("&",s) -> do uname <- use_ name
+                                                   return . ("pchat:" <>) . T.intercalate ":" . sort . map (T.map toLower) $ [uname, s]
+                                     r -> return $ "chat" <> uncurry (<>) r
 
 deformatRoom :: T.Text -> KevinIO T.Text
 deformatRoom room = if "chat:" `T.isPrefixOf` room
-    then return $ '#' `T.cons` T.drop 5 room
-    else do
-        uname <- use_ name
-        return $ T.cons '&' (head (filter (/= uname) . T.splitOn ":"
-                                  . T.drop 6 $ room))
+                       then return $ '#' `T.cons` T.drop 5 room
+                       else do uname <- use_ name
+                               return $ T.cons '&' (head (filter (/= uname) . T.splitOn ":" . T.drop 6 $ room))
 
-type Str = T.Text -- just make it shorter
-type Room = Str
+type Str      = T.Text -- just make it shorter
+type Room     = Str
 type Username = Str
-type Pc = Str
+type Pc       = Str
 
 -- * Communication to the server
-sendHandshake :: KevinIO ()
-sendLogin :: Username -> Str -> KevinIO ()
-sendJoin, sendPart :: Room -> KevinIO ()
-sendMsg, sendAction, sendNpMsg :: Room -> Str -> KevinIO ()
-sendPromote, sendDemote :: Room -> Username -> Maybe Pc -> KevinIO ()
-sendBan, sendUnban :: Room -> Username -> KevinIO ()
-sendKick :: Room -> Username -> Maybe Str -> KevinIO ()
-sendGet :: Room -> Str -> KevinIO ()
-sendWhois :: Username -> KevinIO ()
-sendSet :: Room -> Str -> Str -> KevinIO ()
-sendAdmin :: Room -> Str -> KevinIO ()
-sendKill :: Username -> Str -> KevinIO ()
+sendHandshake                  ::                                  KevinIO ()
+sendLogin                      :: Username -> Str               -> KevinIO ()
+sendJoin, sendPart             :: Room                          -> KevinIO ()
+sendMsg, sendAction, sendNpMsg :: Room -> Str                   -> KevinIO ()
+sendPromote, sendDemote        :: Room -> Username -> Maybe Pc  -> KevinIO ()
+sendBan, sendUnban             :: Room -> Username              -> KevinIO ()
+sendKick                       :: Room -> Username -> Maybe Str -> KevinIO ()
+sendGet                        :: Room -> Str                   -> KevinIO ()
+sendWhois                      :: Username                      -> KevinIO ()
+sendSet                        :: Room -> Str -> Str            -> KevinIO ()
+sendAdmin                      :: Room -> Str                   -> KevinIO ()
+sendKill                       :: Username -> Str               -> KevinIO ()
 
-sendHandshake = sendPacket $ printf "dAmnClient 0.3\nagent=kevin%s\n"
-                    [versionStr]
+sendHandshake = sendPacket $ printf "dAmnClient 0.3\nagent=kevin%s\n" [versionStr]
 
 sendLogin u token = sendPacket $ printf "login %s\npk=%s\n" [u, token]
 
-sendJoin room = do
-    roomname <- formatRoom room
-    sendPacket $ printf "join %s\n" [roomname]
+sendJoin room = do roomname <- formatRoom room
+                   sendPacket $ printf "join %s\n" [roomname]
 
-sendPart room = do
-    roomname <- formatRoom room
-    sendPacket $ printf "part %s\n" [roomname]
+sendPart room = do roomname <- formatRoom room
+                   sendPacket $ printf "part %s\n" [roomname]
 
-sendMsg room msg = do
-    roomname <- formatRoom room
-    sendPacket $ printf "send %s\n\nmsg main\n\n%s" [roomname, msg]
+sendMsg = sendNpMsg
 
-sendAction room msg = do
-    roomname <- formatRoom room
-    sendPacket $ printf "send %s\n\naction main\n\n%s" [roomname, msg]
+sendAction room msg = do roomname <- formatRoom room
+                         sendPacket $ printf "send %s\n\naction main\n\n%s" [roomname, msg]
 
-sendNpMsg = undefined
+sendNpMsg room msg = do roomname <- formatRoom room
+                        sendPacket $ printf "send %s\n\nnpmsg main\n\n%s" [roomname, msg]
 
-sendPromote room us pc = do
-    roomname <- formatRoom room
-    sendPacket $ printf "send %s\n\npromote %s%s" [roomname, us, maybeBody pc]
+sendPromote room us pc = do roomname <- formatRoom room
+                            sendPacket $ printf "send %s\n\npromote %s%s" [roomname, us, maybeBody pc]
 
-sendDemote room us pc = do
-    roomname <- formatRoom room
-    sendPacket $ printf "send %s\n\ndemote %s%s" [roomname, us, maybeBody pc]
+sendDemote room us pc = do roomname <- formatRoom room
+                           sendPacket $ printf "send %s\n\ndemote %s%s" [roomname, us, maybeBody pc]
 
-sendBan room us = do
-    roomname <- formatRoom room
-    sendPacket $ printf "send %s\n\nban %s\n\n" [roomname, us]
+sendBan room us = do roomname <- formatRoom room
+                     sendPacket $ printf "send %s\n\nban %s\n\n" [roomname, us]
 
-sendUnban room us = do
-    roomname <- formatRoom room
-    sendPacket $ printf "send %s\n\nunban %s\n\n" [roomname, us]
+sendUnban room us = do roomname <- formatRoom room
+                       sendPacket $ printf "send %s\n\nunban %s\n\n" [roomname, us]
 
-sendKick room us reason = do
-    roomname <- formatRoom room
-    sendPacket $ printf "kick %s\nu=%s%s\n" [roomname, us, maybeBody reason]
+sendKick room us reason = do roomname <- formatRoom room
+                             sendPacket $ printf "kick %s\nu=%s%s\n" [roomname, us, maybeBody reason]
 
-sendGet room prop = do
-    guard $ prop `elem` ["title", "topic", "privclasses", "members"]
-    roomname <- formatRoom room
-    sendPacket $ printf "get %s\np=%s\n" [roomname, prop]
+sendGet room prop = do guard $ prop `elem` ["title", "topic", "privclasses", "members"]
+                       roomname <- formatRoom room
+                       sendPacket $ printf "get %s\np=%s\n" [roomname, prop]
 
 sendWhois us = sendPacket $ printf "get login:%s\np=info\n" [us]
 
-sendSet room prop val = do
-    guard (prop == "topic" || prop == "title")
-    roomname <- formatRoom room
-    sendPacket $ printf "set %s\np=%s\n\n%s\n" [roomname, prop, val]
+sendSet room prop val = do guard (prop == "topic" || prop == "title")
+                           roomname <- formatRoom room
+                           sendPacket $ printf "set %s\np=%s\n\n%s\n" [roomname, prop, val]
 
-sendAdmin room cmd = do
-    roomname <- formatRoom room
-    sendPacket $ printf "send %s\n\nadmin\n\n%s" [roomname, cmd]
+sendAdmin room cmd = do roomname <- formatRoom room
+                        sendPacket $ printf "send %s\n\nadmin\n\n%s" [roomname, cmd]
 
 sendKill = undefined
diff --git a/Kevin/IRC/Packet.hs b/Kevin/IRC/Packet.hs
--- a/Kevin/IRC/Packet.hs
+++ b/Kevin/IRC/Packet.hs
@@ -15,9 +15,9 @@
 import qualified Data.Text as T
 import Prelude hiding (takeWhile)
 
-data Packet = Packet { _prefix :: Maybe T.Text
+data Packet = Packet { _prefix  :: Maybe T.Text
                      , _command :: T.Text
-                     , _params :: [T.Text]
+                     , _params  :: [T.Text]
                      }
             | BadPacket deriving (Show)
 
@@ -33,11 +33,10 @@
 servername = takeWhile1 (inClass "a-z0-9.-")
 
 username :: Parser T.Text
-username = do
-    n <- nick
-    u <- option "" (T.cons <$> char '!' <*> user)
-    h <- option "" (T.cons <$> char '@' <*> servername)
-    return $ T.concat [n, u, h]
+username = do n <- nick
+              u <- option "" (T.cons <$> char '!' <*> user)
+              h <- option "" (T.cons <$> char '@' <*> servername)
+              return $ T.concat [n, u, h]
 
 nick :: Parser T.Text
 nick = T.cons <$> letter <*> takeWhile (inClass "a-zA-Z0-9[]\\`^{}-")
@@ -49,9 +48,7 @@
 parsePrefix = username <|> servername
 
 parseCommand :: Parser T.Text
-parseCommand = takeWhile1 isAlpha
-           <|> liftM3 (\a b c -> T.pack [a,b,c])
-                      digit digit digit
+parseCommand = takeWhile1 isAlpha <|> liftM3 (\a b c -> T.pack [a,b,c]) digit digit digit
 
 parseParams :: Parser [T.Text]
 parseParams = (colonParam <|> nonColonParam) `sepBy` spaces
@@ -69,26 +66,23 @@
 messageBegin = Just <$> (char ':' *> parsePrefix <* spaces)
 
 packetParser :: Parser Packet
-packetParser = do
-    pr <- option Nothing messageBegin
-    cmd <- T.map toUpper <$> parseCommand
-    spaces
-    par <- filter (not . T.null) <$> parseParams
-    option "" crlf
-    return $ Packet pr cmd par
+packetParser = do pr <- option Nothing messageBegin
+                  cmd <- T.map toUpper <$> parseCommand
+                  spaces
+                  par <- filter (not . T.null) <$> parseParams
+                  option "" crlf
+                  return $ Packet pr cmd par
 
 parsePacket :: T.Text -> Packet
-parsePacket str = case parseOnly packetParser str of
-    Left _ -> BadPacket
-    Right p -> p
+parsePacket str = case parseOnly packetParser str of Left _  -> BadPacket
+                                                     Right p -> p
 
 showParams :: [T.Text] -> T.Text
 showParams = T.unwords . map (\str -> if " " `T.isInfixOf` str
-    then T.cons ':' str
-    else str)
+                                         then T.cons ':' str
+                                         else str)
 
 readable :: Packet -> T.Text
-readable (Packet (Just str) cmd pms) = (<> "\r\n")
-    $ T.unwords [T.cons ':' str, cmd, showParams pms]
-readable (Packet Nothing c p) = (<> "\r\n") $ T.unwords [c, showParams p]
-readable _ = ""
+readable (Packet (Just str) cmd pms) = (<> "\r\n") $ T.unwords [T.cons ':' str, cmd, showParams pms]
+readable (Packet Nothing c p)        = (<> "\r\n") $ T.unwords [c, showParams p]
+readable _                           = ""
diff --git a/Kevin/IRC/Protocol.hs b/Kevin/IRC/Protocol.hs
--- a/Kevin/IRC/Protocol.hs
+++ b/Kevin/IRC/Protocol.hs
@@ -30,71 +30,61 @@
 cleanup = klog Green "cleanup client"
 
 listen :: KevinIO ()
-listen = fix (\f -> flip catches errHandlers $ do
-    k <- get_
-    pkt <- io $ parsePacket <$> readClient k
-    respond pkt (view command pkt)
-    f)
+listen = fix (\f -> flip catches errHandlers $ do k <- get_
+                                                  pkt <- io $ parsePacket <$> readClient k
+                                                  respond pkt (view command pkt)
+                                                  f)
 
 respond :: Packet -> T.Text -> KevinIO ()
 respond BadPacket _ = sendNotice "Bad packet, try again."
-respond pkt "JOIN" = do
-    l <- gets_ (view loggedIn)
-    if l
-        then mapM_ D.sendJoin rooms
-        else kevin $ joining %= (rooms ++)
-    where
-        rooms = T.splitOn "," $ pkt^.params._head
+respond pkt "JOIN" = do l <- gets_ (view loggedIn)
+                        if l
+                           then mapM_ D.sendJoin rooms
+                           else kevin $ joining %= (rooms ++)
+    where rooms = T.splitOn "," $ pkt^.params._head
 
 respond pkt "PART" = mapM_ D.sendPart . T.splitOn "," $ pkt^.params._head
 
-respond pkt "PRIVMSG" = do
-    let (room:msg:_) = pkt^.params
-    if "\1ACTION" `T.isPrefixOf` msg
-        then do
-            let newMsg = T.drop 8 $ T.init msg
-            D.sendAction room $ entityEncode newMsg
-        else D.sendMsg room $ entityEncode msg
+respond pkt "PRIVMSG" = do let (room:msg:_) = pkt^.params
+                           if "\1ACTION" `T.isPrefixOf` msg
+                              then do let newMsg = T.drop 8 $ T.init msg
+                                      D.sendAction room $ entityEncode newMsg
+                              else D.sendMsg room $ entityEncode msg
 
 respond pkt "MODE" = if length (pkt^.params) > 1
-    then do
-        let (toggle,mode) = first (=="+") . T.splitAt 1 $ pkt^.params.ix 1
-        case mode of
-            "b" -> if' toggle D.sendBan D.sendUnban
-                       (pkt^.params._head)
-                       (fromMaybe "random unparseable garbage" . unmask
-                       $ pkt^.params._last)
-            "o" -> if' toggle D.sendPromote D.sendDemote
-                       (pkt^.params._head)
-                       (pkt^.params._last)
-                       Nothing
-            _ -> sendRoomNotice (pkt^.params._head)
-                    $ "Unsupported mode " <> mode
-    else do
-        uname <- use_ name
-        sendChanMode uname (pkt^.params._head)
+                        then do let (toggle,mode) = first (=="+") . T.splitAt 1 $ pkt^.params.ix 1
+                                case mode of "b" -> if' toggle
+                                                        D.sendBan
+                                                        D.sendUnban
+                                                        (pkt^.params._head)
+                                                        (fromMaybe "random unparseable garbage" . unmask $ pkt^.params._last)
+                                             "o" -> if' toggle
+                                                        D.sendPromote
+                                                        D.sendDemote
+                                                        (pkt^.params._head)
+                                                        (pkt^.params._last)
+                                                        Nothing
+                                             _ -> sendRoomNotice (pkt^.params._head) $ "Unsupported mode " <> mode
+                        else do uname <- use_ name
+                                sendChanMode uname (pkt^.params._head)
 
-respond pkt "TOPIC" = case pkt^.params of
-    [] -> sendNotice "Malformed packet"
-    [room] -> D.sendGet room "topic"
-    (room:topic:_) -> D.sendSet room "topic" topic
+respond pkt "TOPIC" = case pkt^.params of []             -> sendNotice "Malformed packet"
+                                          [room]         -> D.sendGet room "topic"
+                                          (room:topic:_) -> D.sendSet room "topic" topic
 
-respond pkt "TITLE" = case pkt^.params of
-    [] -> sendNotice "Malformed packet"
-    [room] -> do
-        title <- gets_ . view $ titles.ix room
-        let p = T.concat ["Title for ", room, ": "]
-        mapM_ (sendRoomNotice room . (p <>)) (T.splitOn "\n" title)
-    (room:title) -> D.sendSet room "title" $ T.unwords title
+respond pkt "TITLE" = case pkt^.params of []           -> sendNotice "Malformed packet"
+                                          [room]       -> do title <- gets_ . view $ titles.ix room
+                                                             let p = T.concat ["Title for ", room, ": "]
+                                                             mapM_ (sendRoomNotice room . (p <>)) (T.splitOn "\n" title)
+                                          (room:title) -> D.sendSet room "title" $ T.unwords title
 
 respond pkt "PING" = sendPong $ pkt^.params._head
 
 respond pkt "WHOIS" = D.sendWhois $ pkt^.params._head
 
-respond pkt "NAMES" = do
-    let room = pkt^.params._head
-    k <- get_
-    sendUserList (k^.name) (nubBy ((==) `on` username) (k^.users.ix room)) room
+respond pkt "NAMES" = do let room = pkt^.params._head
+                         k <- get_
+                         sendUserList (k^.name) (nubBy ((==) `on` username) (k^.users.ix room)) room
 
 respond pkt "KICK" = let p = pkt^.params
                       in D.sendKick (head p)
@@ -108,92 +98,67 @@
 respond pkt "ADMIN" = D.sendAdmin p $ T.intercalate " " ps
     where (p:ps) = pkt^.params
 
-respond pkt "PROMOTE" = case pkt^.params of
-    (room:user:group:_) -> D.sendPromote room user $ Just group
-    (room:_) -> sendRoomNotice room "Usage: /promote #room username group"
-    _ -> sendNotice "Usage: /promote #room username group"
+respond pkt "PROMOTE" = case pkt^.params of (room:user:group:_) -> D.sendPromote room user $ Just group
+                                            (room:_)            -> sendRoomNotice room "Usage: /promote #room username group"
+                                            _                   -> sendNotice "Usage: /promote #room username group"
 
 respond _ str = klogError $ T.unpack str
 
 
 unmask :: T.Text -> Maybe T.Text
-unmask y = case T.split (`elem` "@!") y of
-    [s] -> Just s
-    xs -> listToMaybe $ filter (not . T.isInfixOf "*") xs
+unmask y = case T.split (`elem` "@!") y of [s] -> Just s
+                                           xs  -> listToMaybe $ filter (not . T.isInfixOf "*") xs
 
 errHandlers :: [Handler KevinIO ()]
-errHandlers = [ handler_ _KevinException
-                    $ klogError "Bad communication from client"
-              , handler _IOException (\e -> klogError $ "client: " ++ show e)]
+errHandlers = [ handler_ _KevinException $ klogError "Bad communication from client"
+              , handler _IOException (\e -> klogError $ "client: " ++ show e) ]
 
 -- * Authentication-getting function
 notice :: Handle -> T.Text -> IO ()
-notice h str = do
-    klogNow Blue ("client -> " ++ T.unpack asStr)
-    T.hPutStr h (asStr <> "\r\n")
-    where
-        asStr = printf "NOTICE AUTH :%s" [str]
+notice h str = do klogNow Blue ("client -> " ++ T.unpack asStr)
+                  T.hPutStr h (asStr <> "\r\n")
+    where asStr = printf "NOTICE AUTH :%s" [str]
 
 getAuthInfo :: Handle -> Bool -> KevinState ()
-getAuthInfo handle = fix (\f authRetry -> do
-    pkt <- io $ parsePacket <$> T.hGetLine handle
-    io $ klogNow Yellow $ "client <- " ++ T.unpack (readable pkt)
-    case pkt^.command of
-        "PASS" -> do
-           password .= pkt^.params._head
-           passed .= True
-        "NICK" -> do
-           name .= pkt^.params._head
-           nicked .= True
-        "USER" -> usered .= True
-        _ -> io $ klogNow Red $ "invalid packet: " ++ show pkt
-    if authRetry
-        then checkToken handle
-        else do
-            p <- use passed
-            n <- use nicked
-            u <- use usered
-            if p && n && u
-                then welcome handle
-                else f False
-    )
+getAuthInfo handle = fix (\f authRetry -> do pkt <- io $ parsePacket <$> T.hGetLine handle
+                                             io $ klogNow Yellow $ "client <- " ++ T.unpack (readable pkt)
+                                             case pkt^.command of "PASS" -> do password .= pkt^.params._head
+                                                                               passed .= True
+                                                                  "NICK" -> do name .= pkt^.params._head
+                                                                               nicked .= True
+                                                                  "USER" -> usered .= True
+                                                                  _      -> io $ klogNow Red $ "invalid packet: " ++ show pkt
+                                             if authRetry
+                                                then checkToken handle
+                                                else do p <- use passed
+                                                        n <- use nicked
+                                                        u <- use usered
+                                                        if p && n && u
+                                                           then welcome handle
+                                                           else f False)
 
 welcome :: Handle -> KevinState ()
-welcome handle = do
-    nick <- use name
-    mapM_ (\x -> io $ do
-        klogNow Blue ("client -> " ++ T.unpack x)
-        T.hPutStr handle (x <> "\r\n")) [
-        printf ":%s 001 %s :Welcome to dAmnServer %s!%s@chat.deviantart.com"
-            [hostname, nick, nick, nick],
-        printf ":%s 002 %s :Your host is chat.deviantart.com\
-            \, running dAmnServer 0.3" [hostname, nick],
-        printf ":%s 003 %s :This server was created Thu Apr 28 1994\
-            \ at 05:30:00 EDT" [hostname, nick],
-        printf ":%s 004 %s chat.deviantart.com dAmnServer0.3 qov i"
-            [hostname, nick],
-        printf ":%s 005 %s PREFIX=(qov)~@+" [hostname, nick],
-        printf ":%s 375 %s :- chat.deviantart.com Message of the day -" 
-            [hostname, nick],
-        printf ":%s 372 %s :- deviantART chat on IRC brought to you\
-            \ by kevin %s, created" [hostname, nick, versionStr],
-        printf ":%s 372 %s :- and maintained by Joel Taylor <http://otte.rs>"
-            [hostname, nick],
-        printf ":%s 376 %s :End of MOTD command" [hostname, nick]]
-    checkToken handle
-    where
-        hostname = "chat.deviantart.com"
+welcome handle = do nick <- use name
+                    mapM_ (\x -> io $ do
+                        klogNow Blue ("client -> " ++ T.unpack x)
+                        T.hPutStr handle (x <> "\r\n")) [
+                            printf ":%s 001 %s :Welcome to dAmnServer %s!%s@chat.deviantart.com" [hostname, nick, nick, nick],
+                            printf ":%s 002 %s :Your host is chat.deviantart.com, running dAmnServer 0.3" [hostname, nick],
+                            printf ":%s 003 %s :This server was created Thu Apr 28 1994 at 05:30:00 EDT" [hostname, nick],
+                            printf ":%s 004 %s chat.deviantart.com dAmnServer0.3 qov i" [hostname, nick],
+                            printf ":%s 005 %s PREFIX=(qov)~@+" [hostname, nick],
+                            printf ":%s 375 %s :- chat.deviantart.com Message of the day -" [hostname, nick],
+                            printf ":%s 372 %s :- deviantART chat on IRC brought to you by kevin %s, created" [hostname, nick, versionStr],
+                            printf ":%s 372 %s :- and maintained by Joel Taylor <http://otte.rs>" [hostname, nick],
+                            printf ":%s 376 %s :End of MOTD command" [hostname, nick]]
+                    checkToken handle
+    where hostname = "chat.deviantart.com"
 
 checkToken :: Handle -> KevinState ()
-checkToken handle = do
-    s <- get
-    io $ notice handle "Fetching token..."
-    tok <- io $ getToken (s^.name) (s^.password)
-    case tok of
-        Just t -> do
-            authtoken .= t
-            io $ notice handle "Successfully authenticated."
-        Nothing -> do
-            io $ notice handle "Bad password, try again.\
-                 \ (/quote pass yourpassword)"
-            getAuthInfo handle True
+checkToken handle = do s <- get
+                       io $ notice handle "Fetching token..."
+                       tok <- io $ getToken (s^.name) (s^.password)
+                       case tok of Just t  -> do authtoken .= t
+                                                 io $ notice handle "Successfully authenticated."
+                                   Nothing -> do io $ notice handle "Bad password, try again. (/quote pass yourpassword)"
+                                                 getAuthInfo handle True
diff --git a/Kevin/IRC/Protocol/Send.hs b/Kevin/IRC/Protocol/Send.hs
--- a/Kevin/IRC/Protocol/Send.hs
+++ b/Kevin/IRC/Protocol/Send.hs
@@ -37,123 +37,82 @@
 type Room = Str
 type Username = Str
 
-sendJoin :: Username -> Room -> KevinIO ()
-sendPart :: Username -> Room -> Maybe Str -> KevinIO ()
-sendSetUserMode :: Username -> Room -> Int -> KevinIO ()
-sendChangeUserMode :: Username -> Room -> Int -> Int -> KevinIO ()
-sendNotice :: Str -> KevinIO ()
-sendRoomNotice :: Room -> Str -> KevinIO ()
-sendChanMsg, sendChanAction :: Username -> Room -> Str -> KevinIO ()
-sendKick :: Username -> Username -> Room -> Maybe Str -> KevinIO ()
-sendTopic :: Username -> Room -> Username -> Str -> Str -> KevinIO ()
-sendChanMode :: Username -> Room -> KevinIO ()
-sendUserList :: Username -> [User] -> Room -> KevinIO ()
-sendPong :: T.Text -> KevinIO ()
-sendNoticeClone :: Username -> Int -> Room -> KevinIO ()
-sendNoticeUnclone :: Username -> Int -> Room -> KevinIO ()
-sendWhoisReply :: Username
-               -> Username
-               -> Username
-               -> [Room]
-               -> Int
-               -> Int
-               -> KevinIO ()
+sendJoin                    :: Username -> Room                                         -> KevinIO ()
+sendPart                    :: Username -> Room -> Maybe Str                            -> KevinIO ()
+sendSetUserMode             :: Username -> Room -> Int                                  -> KevinIO ()
+sendChangeUserMode          :: Username -> Room -> Int -> Int                           -> KevinIO ()
+sendNotice                  :: Str                                                      -> KevinIO ()
+sendRoomNotice              :: Room -> Str                                              -> KevinIO ()
+sendChanMsg, sendChanAction :: Username -> Room -> Str                                  -> KevinIO ()
+sendKick                    :: Username -> Username -> Room -> Maybe Str                -> KevinIO ()
+sendTopic                   :: Username -> Room -> Username -> Str -> Str               -> KevinIO ()
+sendChanMode                :: Username -> Room                                         -> KevinIO ()
+sendUserList                :: Username -> [User] -> Room                               -> KevinIO ()
+sendPong                    :: T.Text                                                   -> KevinIO ()
+sendNoticeClone             :: Username -> Int -> Room                                  -> KevinIO ()
+sendNoticeUnclone           :: Username -> Int -> Room                                  -> KevinIO ()
+sendWhoisReply              :: Username -> Username -> Username -> [Room] -> Int -> Int -> KevinIO ()
 
-sendJoin us rm =
-    sendPacket $ printf "%s JOIN :%s" [getHost us, rm]
+sendJoin us rm = sendPacket $ printf "%s JOIN :%s" [getHost us, rm]
 
-sendPart us rm msg =
-    sendPacket $ printf "%s PART %s%s" [getHost us, rm, maybeBody msg]
+sendPart us rm msg = sendPacket $ printf "%s PART %s%s" [getHost us, rm, maybeBody msg]
 
-sendSetUserMode us rm m = unless (T.null mode) $
-    sendPacket $ printf "%s MODE %s +%s %s" [hostname, rm, mode, us]
-    where mode = levelToMode m
+sendSetUserMode us rm m = unless (T.null mode) $ sendPacket $ printf "%s MODE %s +%s %s" [hostname, rm, mode, us]
+             where mode = levelToMode m
 
-sendChangeUserMode us rm old new = unless (oldMode == newMode) $
-    sendPacket $ printf "%s MODE %s %s" [hostname, rm, modesAndUser]
-    where
-        oldMode = levelToMode old
-        newMode = levelToMode new
-        modesAndUser = case (oldMode, newMode) of
-            ("", "") -> T.concat ["-v ", us]
-            ("", _) -> T.concat ["+", newMode, " ", us]
-            (_, "") -> T.concat ["-", oldMode, " ", us]
-            (a, b) -> T.concat ["-", a, "+", b, " ", us, " ", us]
+sendChangeUserMode us rm old new = unless (oldMode == newMode) $ sendPacket $ printf "%s MODE %s %s" [hostname, rm, modesAndUser]
+    where oldMode      = levelToMode old
+          newMode      = levelToMode new
+          modesAndUser = case (oldMode, newMode) of ("", "") -> T.concat ["-v ", us]
+                                                    ("", _)  -> T.concat ["+", newMode, " ", us]
+                                                    (_, "")  -> T.concat ["-", oldMode, " ", us]
+                                                    (a, b)   -> T.concat ["-", a, "+", b, " ", us, " ", us]
 
 
-sendNotice =
-    sendPacket . printf "NOTICE AUTH :%s" . return
+sendNotice = sendPacket . printf "NOTICE AUTH :%s" . return
 
-sendRoomNotice room n =
-    sendPacket $ printf "%s NOTICE %s :%s" [hostname, room, n]
+sendRoomNotice room n = sendPacket $ printf "%s NOTICE %s :%s" [hostname, room, n]
 
-sendChanMsg sender room msg = mapM_ (\x ->
-    sendPacket $ printf "%s PRIVMSG %s :%s" [getHost sender, room, x]
-    ) . T.splitOn "\n" $ msg
+sendChanMsg sender room msg = mapM_ (\x -> sendPacket $ printf "%s PRIVMSG %s :%s" [getHost sender, room, x]) . T.splitOn "\n" $ msg
 
-sendChanAction sender room msg = mapM_ (\x ->
-    sendPacket $ printf "%s PRIVMSG %s :\1ACTION %s\1"
-        [getHost sender, room, x]
-    ) . T.splitOn "\n" $ msg
+sendChanAction sender room msg = mapM_ (\x -> sendPacket $ printf "%s PRIVMSG %s :\1ACTION %s\1" [getHost sender, room, x]) . T.splitOn "\n" $ msg
 
-sendKick kickee kicker room msg =
-    sendPacket $ printf "%s KICK %s %s%s"
-        [getHost kicker, room, kickee, maybeBody msg]
+sendKick kickee kicker room msg = sendPacket $ printf "%s KICK %s %s%s" [getHost kicker, room, kickee, maybeBody msg]
 
-sendTopic us rm maker top startdate = do
-    sendPacket $ printf "%s 332 %s %s :%s" [hostname, us, rm, top]
-    sendPacket $ printf "%s 333 %s %s %s %s"
-        [hostname, us, rm, maker, startdate]
+sendTopic us rm maker top startdate = do sendPacket $ printf "%s 332 %s %s :%s" [hostname, us, rm, top]
+                                         sendPacket $ printf "%s 333 %s %s %s %s" [hostname, us, rm, maker, startdate]
 
-sendChanMode us rm = do
-    sendPacket $ printf "%s 324 %s %s +t" [hostname, us, rm]
-    sendPacket $ printf "%s 329 %s %s 767529000" [hostname, us, rm]
+sendChanMode us rm = do sendPacket $ printf "%s 324 %s %s +t" [hostname, us, rm]
+                        sendPacket $ printf "%s 329 %s %s 767529000" [hostname, us, rm]
 
-sendUserList us uss rm = do
-    mapM_ (\nms ->
-        sendPacket $ printf "%s 353 %s = %s :%s"
-            [hostname, us, rm, T.unwords nms]) chunkedNames
-    sendPacket $ printf "%s 366 %s %s :End of /NAMES list." [hostname, us, rm]
-    where
-        names = map (\u ->
-            T.concat [levelToSym $ privclassLevel u, username u]) uss
-        chunkedNames = reverse . map reverse . subchunk' 432 names $ [[]]
-        subchunk' n = fix (\f x y ->
-            let hy = head y
-                hx = head x
-                ty = tail y
-                tx = tail x
-            in if null x
-                then y
-                else f tx $ if sum (map T.length hy) + T.length hx <= n
-                    then (hx:hy):ty
-                    else [hx]:y)
+sendUserList us uss rm = do mapM_ (\nms -> sendPacket $ printf "%s 353 %s = %s :%s" [hostname, us, rm, T.unwords nms]) chunkedNames
+                            sendPacket $ printf "%s 366 %s %s :End of /NAMES list." [hostname, us, rm]
+    where names        = map (\u -> T.concat [levelToSym $ privclassLevel u, username u]) uss
+          chunkedNames = reverse . map reverse . subchunk' 432 names $ [[]]
+          subchunk' n  = fix (\f x y -> let hy = head y
+                                            hx = head x
+                                            ty = tail y
+                                            tx = tail x
+                                         in if null x
+                                               then y
+                                               else f tx $ if sum (map T.length hy) + T.length hx <= n
+                                                              then (hx:hy):ty
+                                                              else [hx]:y)
 
-sendPong p =
-    sendPacket $ printf "%s PONG chat.deviantart.com :%s" [hostname, p]
+sendPong p = sendPacket $ printf "%s PONG chat.deviantart.com :%s" [hostname, p]
 
-sendNoticeClone uname i rm =
-    sendPacket $ printf "%s NOTICE %s :%s has joined again\
-         \ (now joined %s times)" [hostname, rm, uname, T.pack $ show i]
+sendNoticeClone uname i rm = sendPacket $ printf "%s NOTICE %s :%s has joined again (now joined %s times)" [hostname, rm, uname, T.pack $ show i]
 
-sendNoticeUnclone uname i rm =
-    sendPacket $ printf "%s NOTICE %s :%s has parted (now joined %s)"
-        [hostname, rm, uname, times]
-    where
-        times | i == 1    = "once"
-              | otherwise = T.pack (show i) <> " times"
+sendNoticeUnclone uname i rm = sendPacket $ printf "%s NOTICE %s :%s has parted (now joined %s)" [hostname, rm, uname, times]
+    where times | i == 1    = "once"
+                | otherwise = T.pack (show i) <> " times"
 
-sendWhoisReply me us rn rooms idle signon = do
-    sendPacket $ printf "%s 311 %s %s %s chat.deviantart.com * :%s"
-        [hostname, me, us, us, rn]
-    sendPacket $ printf "%s 307 %s %s :is a registered nick" [hostname, me, us]
-    sendPacket $ printf "%s 319 %s %s :%s"
-        [hostname, me, us, T.intercalate " " . map (T.cons '#') $ rooms]
-    sendPacket $ printf "%s 312 %s %s chat.deviantart.com :dAmn"
-        [hostname, me, us]
-    sendPacket $ printf "%s 317 %s %s %s %s :seconds idle, signon time"
-        [hostname, me, us, T.pack $ show idle, T.pack $ show signon]
-    sendPacket $ printf "%s 318 %s %s :End of /WHOIS list." [hostname, me, us]
+sendWhoisReply me us rn rooms idle signon = do sendPacket $ printf "%s 311 %s %s %s chat.deviantart.com * :%s" [hostname, me, us, us, rn]
+                                               sendPacket $ printf "%s 307 %s %s :is a registered nick" [hostname, me, us]
+                                               sendPacket $ printf "%s 319 %s %s :%s" [hostname, me, us, T.intercalate " " . map (T.cons '#') $ rooms]
+                                               sendPacket $ printf "%s 312 %s %s chat.deviantart.com :dAmn" [hostname, me, us]
+                                               sendPacket $ printf "%s 317 %s %s %s %s :seconds idle, signon time" [hostname, me, us, T.pack $ show idle, T.pack $ show signon]
+                                               sendPacket $ printf "%s 318 %s %s :End of /WHOIS list." [hostname, me, us]
 
 levelToSym :: Int -> T.Text
 levelToSym x | x > 0  && x <= 35 = ""
@@ -163,9 +122,8 @@
              | otherwise         = ""
 
 levelToMode :: Int -> T.Text
-levelToMode x = case levelToSym x of
-   "" -> ""
-   "+" -> "v"
-   "@" -> "o"
-   "~" -> "q"
-   _ -> error "levelToSym, what are you doing"
+levelToMode x = case levelToSym x of ""  -> ""
+                                     "+" -> "v"
+                                     "@" -> "o"
+                                     "~" -> "q"
+                                     _   -> error "levelToSym, what are you doing"
diff --git a/Kevin/Protocol.hs b/Kevin/Protocol.hs
--- a/Kevin/Protocol.hs
+++ b/Kevin/Protocol.hs
@@ -15,51 +15,43 @@
                  , handler_ id (return Nothing) ]
 
 mkKevin :: Socket -> IO (Maybe Kevin)
-mkKevin sock = flip catches watchInterrupt . withSocketsDo $ do
-    (client, _, _) <- accept sock
-    hSetBuffering client NoBuffering
-    klogNow Blue "received a client"
-    s <- execStateT (C.getAuthInfo client False) def
-    damnSock <- connectTo "chat.deviantart.com" $ PortNumber 3900
-    hSetBuffering damnSock NoBuffering
-    logChan <- newChan
-    damnChan <- newChan
-    ircChan <- newChan
-    return . Just $ Kevin damnSock
-                          client
-                          damnChan
-                          ircChan
-                          s
-                          mempty
-                          mempty
-                          mempty
-                          mempty
-                          False
-                          logChan
+mkKevin sock = flip catches watchInterrupt . withSocketsDo
+    $ do (client, _, _) <- accept sock
+         hSetBuffering client NoBuffering
+         klogNow Blue "received a client"
+         s <- execStateT (C.getAuthInfo client False) def
+         damnSock <- connectTo "chat.deviantart.com" $ PortNumber 3900
+         hSetBuffering damnSock NoBuffering
+         logChan <- newChan
+         damnChan <- newChan
+         ircChan <- newChan
+         return . Just $ Kevin damnSock
+                               client
+                               damnChan
+                               ircChan
+                               s
+                               mempty
+                               mempty
+                               mempty
+                               mempty
+                               False
+                               logChan
 
 mkListener :: Int -> IO Socket
 mkListener = listenOn . PortNumber . fromIntegral
 
 kevinServer :: Int -> IO ()
-kevinServer n = do
-    sock <- mkListener n
-    putStrLn $ "Listening on port " ++ show n
-    forever $ do
-        kev <- mkKevin sock
-        case kev of
-            Just k -> listen k
-            Nothing -> return ()
+kevinServer n = do sock <- mkListener n
+                   putStrLn $ "Listening on port " ++ show n
+                   forever $ do kev <- mkKevin sock
+                                case kev of Just k -> listen k
+                                            Nothing -> return ()
 
 listen :: Kevin -> IO ()
-listen k = do
-    mvar <- newTVarIO k
-    runLogger (logger k)
-    runPrinter (dChan k) (damn k)
-    runPrinter (iChan k) (irc k)
-    forkIO . void $ runReaderT (bracket_ S.initialize
-                                         (S.cleanup >> io (closeClient k))
-                                         S.listen) mvar
-    forkIO . void $ runReaderT (bracket_ (return ())
-                                         (C.cleanup >> io (closeServer k))
-                                         C.listen) mvar
-    return ()
+listen k = do mvar <- newTVarIO k
+              runLogger (logger k)
+              runPrinter (dChan k) (damn k)
+              runPrinter (iChan k) (irc k)
+              forkIO . void $ runReaderT (bracket_ S.initialize (S.cleanup >> io (closeClient k)) S.listen) mvar
+              forkIO . void $ runReaderT (bracket_ (return ()) (C.cleanup >> io (closeServer k)) C.listen) mvar
+              return ()
diff --git a/Kevin/Settings.hs b/Kevin/Settings.hs
--- a/Kevin/Settings.hs
+++ b/Kevin/Settings.hs
@@ -7,9 +7,9 @@
 data Settings = Settings { _name      :: Text
                          , _password  :: Text
                          , _authtoken :: Text
-                         , _passed :: Bool
-                         , _nicked :: Bool
-                         , _usered :: Bool
+                         , _passed    :: Bool
+                         , _nicked    :: Bool
+                         , _usered    :: Bool
                          } deriving (Show)
 
 makeClassy ''Settings
diff --git a/Kevin/Types.hs b/Kevin/Types.hs
--- a/Kevin/Types.hs
+++ b/Kevin/Types.hs
@@ -39,35 +39,35 @@
 
 type Chatroom = T.Text
 
-data User = User { username :: T.Text
-                 , privclass :: T.Text
+data User = User { username       :: T.Text
+                 , privclass      :: T.Text
                  , privclassLevel :: Int
-                 , symbol :: T.Text
-                 , realname :: T.Text
-                 , typename :: T.Text
-                 , gpc :: T.Text
+                 , symbol         :: T.Text
+                 , realname       :: T.Text
+                 , typename       :: T.Text
+                 , gpc            :: T.Text
                  } deriving (Eq, Show)
 
-type UserStore = M.Map Chatroom [User]
+type UserStore      = M.Map Chatroom [User]
 
-type Privclasses = M.Map T.Text Int
+type Privclasses    = M.Map T.Text Int
 type PrivclassStore = M.Map Chatroom Privclasses
-type Privclass = (T.Text, Int)
+type Privclass      = (T.Text, Int)
 
-type Title = T.Text
-type TitleStore = M.Map Chatroom Title
+type Title          = T.Text
+type TitleStore     = M.Map Chatroom Title
 
-data Kevin = Kevin { damn :: Handle
-                   , irc :: Handle
-                   , dChan :: Chan T.Text
-                   , iChan :: Chan T.Text
+data Kevin = Kevin { damn           :: Handle
+                   , irc            :: Handle
+                   , dChan          :: Chan T.Text
+                   , iChan          :: Chan T.Text
                    , _kevinSettings :: Settings
-                   , _users :: UserStore
-                   , _privclasses :: PrivclassStore
-                   , _titles :: TitleStore
-                   , _joining :: [T.Text]
-                   , _loggedIn :: Bool
-                   , logger :: Chan String
+                   , _users         :: UserStore
+                   , _privclasses   :: PrivclassStore
+                   , _titles        :: TitleStore
+                   , _joining       :: [T.Text]
+                   , _loggedIn      :: Bool
+                   , logger         :: Chan String
                    }
 
 makeLenses ''Kevin
@@ -78,11 +78,10 @@
 type KevinS = StateT Kevin STM
 
 kevin :: KevinS a -> KevinIO a
-kevin m = ask >>= \v -> liftIO $ atomically $ do
-    s <- readTVar v
-    (a, t) <- runStateT m s
-    writeTVar v t
-    return a
+kevin m = ask >>= \v -> liftIO $ atomically $ do s <- readTVar v
+                                                 (a, t) <- runStateT m s
+                                                 writeTVar v t
+                                                 return a
 
 type KevinIO = ReaderT (TVar Kevin) IO
 
diff --git a/Kevin/Util/Entity.hs b/Kevin/Util/Entity.hs
--- a/Kevin/Util/Entity.hs
+++ b/Kevin/Util/Entity.hs
@@ -18,57 +18,48 @@
 decodeCharacter = entityNumeric <|> entityNamed <|> take 1
 
 entityNumeric :: Parser T.Text
-entityNumeric = do
-    string "&#"
-    entity <- (<>) <$> option "" (string "x") <*> takeWhile1 isHexDigit
-    char ';'
-    return . fromMaybe (T.concat ["&#", entity, ";"])
-           $ (if "x" `T.isPrefixOf` entity 
-               then lookupHexEntity
-               else lookupNumericEntity) entity
+entityNumeric = do string "&#"
+                   entity <- (<>) <$> option "" (string "x") <*> takeWhile1 isHexDigit
+                   char ';'
+                   return . fromMaybe (T.concat ["&#", entity, ";"]) $ (if "x" `T.isPrefixOf` entity 
+                                                                           then lookupHexEntity
+                                                                           else lookupNumericEntity) entity
 
 entityNamed :: Parser T.Text
-entityNamed = do
-    char '&'
-    entity <- T.cons <$> letter <*> takeWhile1 isAlphaNum
-    char ';'
-    return . fromMaybe (T.concat ["&", entity, ";"])
-           . lookupNamedEntity $ entity
+entityNamed = do char '&'
+                 entity <- T.cons <$> letter <*> takeWhile1 isAlphaNum
+                 char ';'
+                 return . fromMaybe (T.concat ["&", entity, ";"]) . lookupNamedEntity $ entity
 
 decodeParser :: Parser T.Text
 decodeParser = T.concat <$> many1 decodeCharacter
 
 entityDecode :: T.Text -> T.Text
 entityDecode "" = ""
-entityDecode str = case parseOnly decodeParser str of
-    Left err -> error $ "entityDecode: " ++ err
-    Right s -> s
+entityDecode str = case parseOnly decodeParser str of Left err -> error $ "entityDecode: " ++ err
+                                                      Right s -> s
 
 entityEncode :: T.Text -> T.Text
 entityEncode = T.pack . concat . entityEncodeS . T.unpack
 
 entityEncodeS :: String -> [String]
-entityEncodeS = fix (\f str -> case str of
-    [] -> []
-    (x:xs) -> if x < '\127' then [x]:f xs
-                            else ("&#" ++ show (ord x) ++ ";"):f xs)
+entityEncodeS = fix (\f str -> case str of [] -> []
+                                           (x:xs) -> if x < '\127'
+                                                        then [x]:f xs
+                                                        else ("&#" ++ show (ord x) ++ ";"):f xs)
 
 lookupNamedEntity :: T.Text -> Maybe T.Text
 lookupNamedEntity ent = (T.singleton . chr) <$> lookup ent namedEntities
 
 lookupHexEntity :: T.Text -> Maybe T.Text
-lookupHexEntity e = case R.hexadecimal $ T.cons '0' e of
-    Right (n,_) -> do
-        guard $ n < ord maxBound
-        return . T.singleton . chr $ n
-    Left _ -> Nothing
+lookupHexEntity e = case R.hexadecimal $ T.cons '0' e of Right (n,_) -> do guard $ n < ord maxBound
+                                                                           return . T.singleton . chr $ n
+                                                         Left _ -> Nothing
 
 lookupNumericEntity :: T.Text -> Maybe T.Text
-lookupNumericEntity e = case R.decimal e of
-    Right (n,_) -> do
-        guard $ n < ord maxBound
-        return . T.singleton . chr $ n
-    Left _ -> Nothing
+lookupNumericEntity e = case R.decimal e of Right (n,_) -> do guard $ n < ord maxBound
+                                                              return . T.singleton . chr $ n
+                                            Left _ -> Nothing
 
 namedEntities :: [(T.Text, Int)]
 namedEntities = [ ("quot", 34), ("amp", 38), ("apos", 39), ("lt", 60)
diff --git a/Kevin/Util/Logger.hs b/Kevin/Util/Logger.hs
--- a/Kevin/Util/Logger.hs
+++ b/Kevin/Util/Logger.hs
@@ -42,8 +42,7 @@
                          ++ "m" ++ rtrimmed
                          ++ "\027[0m"
     where
-        rtrimmed = reverse . dropWhile (\x -> isSpace x || x == '\x0')
-                 . reverse $ str
+        rtrimmed = reverse . dropWhile (\x -> isSpace x || x == '\x0') . reverse $ str
 
 klog_ :: Chan String -> Color -> String -> IO ()
 klog_ ch col str = writeChan ch $ render col str
diff --git a/Kevin/Util/Tablump.hs b/Kevin/Util/Tablump.hs
--- a/Kevin/Util/Tablump.hs
+++ b/Kevin/Util/Tablump.hs
@@ -13,15 +13,14 @@
 import Text.Regex.PCRE.String
 
 fromRight :: (Show a) => Either a b -> b
-fromRight (Left x) = error $ "fromRight on Left " ++ show x
+fromRight (Left x)  = error $ "fromRight on Left " ++ show x
 fromRight (Right a) = a
 
 {-# NOINLINE regexReplace #-}
 regexReplace :: Regex -> ([String] -> String) -> String -> String
-regexReplace find replace = fix (\f str -> case fromRight . unsafePerformIO
-        $ regexec find str of
-            Just (bef, _, af, matches) -> concat [bef, replace matches, f af]
-            Nothing -> str)
+regexReplace find replace = fix (\f str ->
+    case fromRight . unsafePerformIO $ regexec find str of Just (bef, _, af, matches) -> concat [bef, replace matches, f af]
+                                                           Nothing                    -> str)
 
 {-# NOINLINE regexen #-}
 regexen :: [(Regex, [String] -> String)]
@@ -29,53 +28,48 @@
     first (fromRight . unsafePerformIO
           . compile defaultCompOpt defaultExecOpt)
      ) . reverse $ [
-        "&b\t"      $$ const "\2",
-        "&/b\t"     $$ const "\15",
-        "&i\t"      $$ const "\22",
-        "&/i\t"     $$ const "\15",
-        "&u\t"      $$ const "\31",
-        "&/u\t"     $$ const "\15",
-        "&s\t"      $$ const "<s>",
-        "&/s\t"     $$ const "</s>",
-        "&sup\t"    $$ const "",
-        "&/sup\t"   $$ const "",
-        "&sub\t"    $$ const "",
-        "&/sub\t"   $$ const "",
-        "&code\t"   $$ const "",
-        "&/code\t"  $$ const "",
-        "&br\t"     $$ const "\n",
-        "&ul\t"     $$ const "",
-        "&/ul\t"    $$ const "",
-        "&ol\t"     $$ const "",
-        "&/ol\t"    $$ const "",
-        "&li\t"     $$ const "- ",
-        "&/li\t"    $$ const "\n",
-        "&bcode\t"  $$ const "",
-        "&/bcode\t" $$ const "",
-        "&/a\t"     $$ const ")",
-        "&/acro\t"  $$ const "</acronym>",
-        "&/abbr\t"  $$ const "</abbr>",
-        "&p\t"      $$ const "",
-        "&/p\t"     $$ const "\n",
-        "&emote\t(.+?)\t.+?\t.+?\t.+?\t.+?\t" $$ head,
-        "&a\t(.+?)\t.*?\t" $$ \(x:_) -> printf "%s (" x,
-        "&link\t(.+?)\t&\t" $$ head,
-        "&link\t(.+?)\t(.+?)\t&\t" $$ \(x:y:_) -> printf "%s (%s)" x y,
-        "&dev\t.+?\t(.+?)\t" $$ head,
-        "&avatar\t(.+?)\t.+?\t" $$ \(x:_) -> printf ":icon%s:" x,
-        "&thumb\t(.+?)\t.+?\t.+?\t.+?\t.+?\t.+?\t.+?\t" $$ \(x:_) ->
-            printf ":thumb%s:" x,
-        "&img\t(.+?)\t(.*?)\t(.*?)\t" $$ \(x:y:z:_) ->
-            printf "<img src='%s' alt='%s' title='%s' />" x y z,
-        "&iframe\t(.+?)\t(.*?)\t(.*?)\t" $$ \(x:y:z:_) ->
-            printf "<iframe src='%s' width='%s' height='%s' />" x y z,
-        "&acro\t(.+?)\t" $$ \(x:_) -> printf "<acronym title='%s'>" x,
-        "&abbr\t(.+?)\t" $$ \(x:_) -> printf "<abbr title='%s'>" x,
-        " ?<abbr title='colors:[0-9A-Fa-f]{6}:[0-9A-Fa-f]{6}'></abbr>"
-            $$ const "",
-        "^<abbr title='(.+?)'>.+?</abbr>:" $$ \(x:_) -> printf "%s:" x,
-        "^[a-zA-Z0-9\\-_]+<abbr title='(.+?)'></abbr>:" $$ \(x:_) ->
-            printf "%s:" x
+        "&b\t"                                                         $$ const "\2",
+        "&/b\t"                                                        $$ const "\15",
+        "&i\t"                                                         $$ const "\22",
+        "&/i\t"                                                        $$ const "\15",
+        "&u\t"                                                         $$ const "\31",
+        "&/u\t"                                                        $$ const "\15",
+        "&s\t"                                                         $$ const "<s>",
+        "&/s\t"                                                        $$ const "</s>",
+        "&sup\t"                                                       $$ const "",
+        "&/sup\t"                                                      $$ const "",
+        "&sub\t"                                                       $$ const "",
+        "&/sub\t"                                                      $$ const "",
+        "&code\t"                                                      $$ const "",
+        "&/code\t"                                                     $$ const "",
+        "&br\t"                                                        $$ const "\n",
+        "&ul\t"                                                        $$ const "",
+        "&/ul\t"                                                       $$ const "",
+        "&ol\t"                                                        $$ const "",
+        "&/ol\t"                                                       $$ const "",
+        "&li\t"                                                        $$ const "- ",
+        "&/li\t"                                                       $$ const "\n",
+        "&bcode\t"                                                     $$ const "",
+        "&/bcode\t"                                                    $$ const "",
+        "&/a\t"                                                        $$ const ")",
+        "&/acro\t"                                                     $$ const "</acronym>",
+        "&/abbr\t"                                                     $$ const "</abbr>",
+        "&p\t"                                                         $$ const "",
+        "&/p\t"                                                        $$ const "\n",
+        "&emote\t(.+?)\t.+?\t.+?\t.+?\t.+?\t"                          $$ head,
+        "&a\t(.+?)\t.*?\t"                                             $$ \(x:_) -> printf "%s (" x,
+        "&link\t(.+?)\t&\t"                                            $$ head,
+        "&link\t(.+?)\t(.+?)\t&\t"                                     $$ \(x:y:_) -> printf "%s (%s)" x y,
+        "&dev\t.+?\t(.+?)\t"                                           $$ head,
+        "&avatar\t(.+?)\t.+?\t"                                        $$ \(x:_) -> printf ":icon%s:" x,
+        "&thumb\t.+?\t(.+?)\t.+?\t.+?\t.+?\t.+?\t"                     $$ \(x:_) -> printf "[thumb: %s]" x,
+        "&img\t(.+?)\t(.*?)\t(.*?)\t"                                  $$ \(x:y:z:_) -> printf "<img src='%s' alt='%s' title='%s' />" x y z,
+        "&iframe\t(.+?)\t(.*?)\t(.*?)\t"                               $$ \(x:y:z:_) -> printf "<iframe src='%s' width='%s' height='%s' />" x y z,
+        "&acro\t(.+?)\t"                                               $$ \(x:_) -> printf "<acronym title='%s'>" x,
+        "&abbr\t(.+?)\t"                                               $$ \(x:_) -> printf "<abbr title='%s'>" x,
+        " ?<abbr title='colors:[0-9A-Fa-f]{6}:[0-9A-Fa-f]{6}'></abbr>" $$ const "",
+        "^<abbr title='(.+?)'>.+?</abbr>:"                             $$ \(x:_) -> printf "%s:" x,
+        "^[a-zA-Z0-9\\-_]+<abbr title='(.+?)'></abbr>:"                $$ \(x:_) -> printf "%s:" x
     ]
 
 tablumpDecode :: T.Text -> T.Text
diff --git a/Kevin/Util/Token.hs b/Kevin/Util/Token.hs
--- a/Kevin/Util/Token.hs
+++ b/Kevin/Util/Token.hs
@@ -16,54 +16,61 @@
 import Text.Printf
 
 recvUntil :: TLSCtx -> B.ByteString -> IO B.ByteString
-recvUntil ctx str = do
-    line <- recvData ctx
-    if str `B.isInfixOf` line
-        then return line
-        else fmap (line <>) $ recvUntil ctx str
+recvUntil ctx str = do line <- recvData ctx
+                       if str `B.isInfixOf` line
+                          then return line
+                          else fmap (line <>) $ recvUntil ctx str
 
 concatHeaders :: [(String,String)] -> String
 concatHeaders = intercalate "\r\n" . map (\(x,y) -> x ++ ": " ++ y)
 
+scrapeFormValue :: String -> B.ByteString -> B.ByteString
+scrapeFormValue key bs = B.takeWhile (/='"') . B.drop 7 . head
+                       . filter (\l -> "value=" `B.isPrefixOf` l) . B.words . head
+                       . filter (\l -> B.pack key `B.isInfixOf` l) . B.lines $ bs
+
+scrapeCookies :: B.ByteString -> B.ByteString
+scrapeCookies bs = B.intercalate ";" . map snd
+                 . filter ((== "Set-Cookie") . fst)
+                 . map (second (B.drop 2 . B.takeWhile (/=';'))
+                       . B.breakSubstring ": ")
+                 . B.lines $ bs
+
 getToken :: T.Text -> T.Text -> IO (Maybe T.Text)
-getToken uname pass = do
-    let params = defaultParams { pCiphers = ciphersuite_all
-                               , onCertificatesRecv =
-                                   certificateChecks [return
-                                     . certificateVerifyDomain
-                                         "chat.deviantart.com"]
-                               }
-        headers :: [(String, String)]
-        headers = [("Connection", "closed"),
-                   ("Content-Type", "application/x-www-form-urlencoded")]
-    gen <- makeSystem
-    ctx <- connectionClient "www.deviantart.com" "443" params gen
-    let payload = urlEncodeVars [ ("username", T.unpack uname)
-                                , ("password", T.unpack pass)
-                                , ("remember_me","1")
-                                ]
-    handshake ctx
-    sendData ctx . LB.pack
-        $ printf "POST /users/login HTTP/1.1\r\n%s\r\n\
-            \Content-Length: %d\r\n\r\n%s"
-            (concatHeaders $ ("Host", "www.deviantart.com"):headers)
-            (length payload)
-            payload
-    bs <- recvData ctx
-    if "wrong-password" `B.isInfixOf` bs
-        then return Nothing
-        else do
-            let cookie = B.intercalate ";" . map snd
-                       . filter ((== "Set-Cookie") . fst)
-                       . map (second (B.drop 2 . B.takeWhile (/=';'))
-                            . B.breakSubstring ": ")
-                       . B.lines $ bs
-                s = printf "GET /chat/Botdom HTTP/1.1\r\n%s\r\n\
-                        \cookie: %s\r\n\r\n"
-                        (concatHeaders [("Host", "chat.deviantart.com")])
-                        (B.unpack cookie)
-            sendData ctx $ LB.pack s
-            bq <- recvUntil ctx "dAmnChat_Init"
-            return . (Just . decodeUtf8 . B.take 32 . B.tail
-                     . B.dropWhile (/='"') . B.dropWhile (/=',') . snd)
-                   . B.breakSubstring "dAmn_Login" $ bq
+getToken uname pass = do let params = defaultParams { pCiphers = ciphersuite_all
+                                                    , onCertificatesRecv = certificateChecks [return . certificateVerifyDomain "chat.deviantart.com"] }
+                             headers :: [(String, String)]
+                             headers = [("Connection", "closed"), ("Content-Type", "application/x-www-form-urlencoded")]
+                         gen <- makeSystem
+                         ctv <- connectionClient "www.deviantart.com" "443" params gen
+                         handshake ctv
+                         sendData ctv . LB.pack $ "GET /users/login HTTP/1.1\r\nHost: www.deviantart.com\r\n\r\n"
+                         bl <- recvUntil ctv "validate_key"
+                         bye ctv
+
+                         let payload = urlEncodeVars [ ("username", T.unpack uname)
+                                                     , ("password", T.unpack pass)
+                                                     , ("validate_token", B.unpack (scrapeFormValue "validate_token" bl))
+                                                     , ("validate_key", B.unpack (scrapeFormValue "validate_key" bl))
+                                                     , ("remember_me","1")
+                                                     ]
+                         ctx <- connectionClient "www.deviantart.com" "443" params gen
+                         handshake ctx
+                         sendData ctx . LB.pack $ printf "POST /users/login HTTP/1.1\r\n%s\r\n\
+                                                         \cookie: %s\r\nContent-Length: %d\r\n\r\n%s"
+                                                         (concatHeaders $ ("Host", "www.deviantart.com"):headers)
+                                                         (B.unpack (scrapeCookies bl))
+                                                         (length payload)
+                                                         payload
+                         bs <- recvData ctx
+                         if "wrong-password" `B.isInfixOf` bs
+                            then return Nothing
+                            else do let s = printf "GET /chat/Botdom HTTP/1.1\r\n%s\r\n\
+                                                \cookie: %s\r\n\r\n"
+                                                (concatHeaders [("Host", "chat.deviantart.com")])
+                                                (B.unpack (scrapeCookies bs))
+                                    sendData ctx $ LB.pack s
+                                    bq <- recvUntil ctx "dAmnChat_Init"
+                                    return . (Just . decodeUtf8 . B.take 32 . B.tail
+                                             . B.dropWhile (/='"') . B.dropWhile (/=',') . snd)
+                                           . B.breakSubstring "dAmn_Login" $ bq
diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -9,30 +9,21 @@
 data Flag = Port Int | Version | Help deriving (Eq)
 
 opts :: [OptDescr Flag]
-opts = [
-        Option "p" ["port"] (ReqArg (Port . read) "number")
-            $ "local port to run the server on (defaults to "
-                ++ show defaultPort
-                ++ ")",
-        Option "h" ["help"] (NoArg Help) "print this message",
-        Option "v" ["version"] (NoArg Version) "show kevin's version number"
-       ]
+opts = [ Option "p" ["port"] (ReqArg (Port . read) "number") $ "local port to run the server on (defaults to " ++ show defaultPort ++ ")"
+       , Option "h" ["help"] (NoArg Help) "print this message"
+       , Option "v" ["version"] (NoArg Version) "show kevin's version number" ]
 
 header :: String
 header = "Usage: kevin [options...]"
 
 getPort :: [Flag] -> Int
 getPort (Port x:_) = x
-getPort (_:xs) = getPort xs
-getPort [] = defaultPort
+getPort (_:xs)     = getPort xs
+getPort []         = defaultPort
 
 main :: IO ()
-main = do
-    args <- getArgs
-    case getOpt Permute opts args of
-        (flags, _, []) -> case flags of
-            f | Help `elem` f -> putStrLn $ usageInfo header opts
-              | Version `elem` f -> putStrLn 
-                  $ "kevin version " ++ showVersion version
-              | otherwise -> kevinServer $ getPort flags
-        (_, _, msgs@(_:_)) -> putStrLn $ concat msgs ++ usageInfo header opts
+main = do args <- getArgs
+          case getOpt Permute opts args of (flags, _, [])     -> case flags of f | Help `elem` f    -> putStrLn $ usageInfo header opts
+                                                                                 | Version `elem` f -> putStrLn $ "kevin version " ++ showVersion version
+                                                                                 | otherwise        -> kevinServer $ getPort flags
+                                           (_, _, msgs@(_:_)) -> putStrLn $ concat msgs ++ usageInfo header opts
diff --git a/kevin.cabal b/kevin.cabal
--- a/kevin.cabal
+++ b/kevin.cabal
@@ -1,5 +1,5 @@
 Name:             kevin
-Version:          0.8.2
+Version:          0.9.0
 Synopsis:         a dAmn ↔ IRC proxy
 Description:      a dAmn ↔ IRC proxy
 License:          GPL
@@ -18,7 +18,7 @@
     Main-is:            Main.hs
 
     Default-language:   Haskell2010
-    
+
     Build-Depends:      attoparsec,
                         base == 4.*,
                         bytestring,
@@ -36,7 +36,7 @@
                         time,
                         tls,
                         tls-extra
-                        
+
     Other-Modules:      Kevin,
                         Kevin.Base,
                         Kevin.Chatrooms,
@@ -54,6 +54,6 @@
                         Kevin.Util.Tablump,
                         Kevin.Util.Token,
                         Kevin.Version
-                
+
     default-extensions: DeriveDataTypeable, ExistentialQuantification, FlexibleContexts, OverloadedStrings, ScopedTypeVariables, TemplateHaskell
     ghc-options:        -Wall -fno-warn-unused-do-bind -threaded
