diff --git a/Kevin/Base.hs b/Kevin/Base.hs
--- a/Kevin/Base.hs
+++ b/Kevin/Base.hs
@@ -37,7 +37,8 @@
 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
diff --git a/Kevin/Chatrooms.hs b/Kevin/Chatrooms.hs
--- a/Kevin/Chatrooms.hs
+++ b/Kevin/Chatrooms.hs
@@ -37,7 +37,8 @@
 numUsers ch us = do
     st <- gets_ $ view users
     case st^.at ch of
-        Just usrs -> return . length $ findIndices (\u -> us == username u) usrs
+        Just usrs -> return . length
+            $ findIndices (\u -> us == username u) usrs
         Nothing -> return 0
 
 removeUser :: Chatroom -> T.Text -> KevinIO ()
@@ -56,7 +57,8 @@
 getPrivclass room user = do
     st <- gets_ $ view users
     case st^.at room of
-        Just qs -> return $ privclass <$> listToMaybe (filter ((== user) . username) qs)
+        Just qs -> return $ privclass
+            <$> listToMaybe (filter ((== user) . username) qs)
         Nothing -> return Nothing
         
 getPrivclassLevel :: Chatroom -> T.Text -> KevinIO Int
diff --git a/Kevin/Damn/Packet.hs b/Kevin/Damn/Packet.hs
--- a/Kevin/Damn/Packet.hs
+++ b/Kevin/Damn/Packet.hs
@@ -88,7 +88,8 @@
 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"
 
@@ -96,9 +97,9 @@
 readable (Packet cmd param arg bod) = cmd
                                    <> maybe "" (' ' `T.cons`) param
                                    <> formattedArgs (M.toList arg)
-                                   <> maybe "" ("\n\n" `T.append`) bod
+                                   <> maybe "" ("\n\n" <>) bod
                                    <> "\n\0"
     where
         formattedArgs [] = ""
-        formattedArgs q = T.append "\n" . T.intercalate "\n"
+        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
@@ -55,7 +55,8 @@
             kevin $ joining %= (roomname:)
             uname <- use_ name
             I.sendJoin uname roomname
-        else I.sendNotice $ T.concat ["Couldn't join ", roomname, ": ", pkt^.args.ix "e"]
+        else I.sendNotice $ T.concat
+            ["Couldn't join ", roomname, ": ", pkt^.args.ix "e"]
 
 respond pkt "part" = do
     roomname <- deformatRoom $ pkt^.parameter._Just
@@ -64,12 +65,14 @@
             uname <- use_ name
             removeRoom roomname
             I.sendPart uname roomname Nothing
-        else I.sendNotice $ T.concat ["Couldn't part ", roomname, ": ", pkt^.args.ix "e"]
+        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
+        "privclasses" -> setPrivclasses roomname . parsePrivclasses
+            $ pkt^.body._Just
 
         "topic" -> do
             uname <- use_ name
@@ -87,7 +90,8 @@
             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
+                pc = privclass . head . filter (\x -> username x == k^.name)
+                   $ members
                 n = nub members
             setUsers roomname members
             when (roomname `elem` k^.joining) $ do
@@ -99,12 +103,13 @@
         "info" -> do
             us <- use_ name
             curtime <- io $ floor <$> getPOSIXTime
-            let fixedPacket = parsePacket . T.init . T.replace "\n\nusericon" "\nusericon"
+            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 . T.append "conn" $ 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)
@@ -130,7 +135,8 @@
         if countUser == 0
             then do
                 I.sendJoin usname roomname
-                pclevel <- getPrivclassLevel roomname (modifiedPkt^.args.ix "pc")
+                pclevel <- getPrivclassLevel roomname
+                    $ modifiedPkt^.args.ix "pc"
                 I.sendSetUserMode usname roomname pclevel
             else I.sendNoticeClone (username us) (succ countUser) roomname
 
@@ -146,13 +152,15 @@
         let uname = arg "from"
             msg   = pkt^.body._Just
         un <- use_ name
-        unless (un == uname) $ I.sendChanMsg uname roomname (entityDecode $ tablumpDecode msg)
+        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)
+        unless (un == uname) $ I.sendChanAction uname roomname
+            (entityDecode $ tablumpDecode msg)
 
     "privchg" -> do
         let user = pkt^.parameter._Just
@@ -164,7 +172,7 @@
         setUserPrivclass roomname user newPc
         I.sendRoomNotice roomname $ T.concat
             [user, " has been moved"
-            , maybe "" (T.append " from ") oldPc
+            , maybe "" (" from " <>) oldPc
             , " to ", newPc, " by ", by
             ]
         I.sendChangeUserMode user roomname oldPcLevel newPcLevel
@@ -193,8 +201,9 @@
                      , 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: " `T.append` arg "e"
+        "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
@@ -208,7 +217,8 @@
     roomname <- deformatRoom $ pkt^.parameter._Just
     uname <- use_ name
     removeRoom roomname
-    I.sendKick uname (pkt^.args.ix "by") roomname $ pkt^.body.traverse ^? notNull_
+    I.sendKick uname (pkt^.args.ix "by") roomname
+        $ pkt^.body.traverse ^? notNull_
 
 respond pkt "send" = I.sendNotice $ "Send error: " <> pkt^.args.ix "e"
 
@@ -229,5 +239,6 @@
         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
@@ -27,9 +27,10 @@
 import Data.Monoid
 import qualified Data.Text as T
 import Kevin.Base
+import Kevin.Version
 
 maybeBody :: Maybe T.Text -> T.Text
-maybeBody = maybe "" (T.append "\n\n")
+maybeBody = maybe "" ("\n\n" <>)
 
 sendPacket :: T.Text -> KevinIO ()
 sendPacket p = get_ >>= \k -> io . writeServer k . T.snoc p $ '\0'
@@ -40,16 +41,17 @@
         ("#",s) -> return $ "chat:" <> s
         ("&",s) -> do
             uname <- use_ name
-            return . T.append "pchat:" . T.intercalate ":"
+            return . ("pchat:" <>) . T.intercalate ":"
                    . sort . map (T.map toLower) $ [uname, s]
-        r -> return $ "chat" <> uncurry T.append r
+        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)
+        return $ T.cons '&' (head (filter (/= uname) . T.splitOn ":"
+                                  . T.drop 6 $ room))
 
 type Str = T.Text -- just make it shorter
 type Room = Str
@@ -70,7 +72,8 @@
 sendAdmin :: Room -> Str -> KevinIO ()
 sendKill :: Username -> Str -> KevinIO ()
 
-sendHandshake = sendPacket $ printf "dAmnClient 0.3\nagent=kevin%s\n" [VERSION]
+sendHandshake = sendPacket $ printf "dAmnClient 0.3\nagent=kevin%s\n"
+                    [versionStr]
 
 sendLogin u token = sendPacket $ printf "login %s\npk=%s\n" [u, token]
 
@@ -113,16 +116,16 @@
     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]
+    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]
+    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
diff --git a/Kevin/IRC/Packet.hs b/Kevin/IRC/Packet.hs
--- a/Kevin/IRC/Packet.hs
+++ b/Kevin/IRC/Packet.hs
@@ -8,8 +8,10 @@
 
 import Control.Applicative ((<|>), (<$>), (<*>), (*>), (<*))
 import Control.Lens
+import Control.Monad
 import Data.Attoparsec.Text
 import Data.Char
+import Data.Monoid
 import qualified Data.Text as T
 import Prelude hiding (takeWhile)
 
@@ -17,7 +19,7 @@
                      , _command :: T.Text
                      , _params :: [T.Text]
                      }
-			| BadPacket deriving (Show)
+            | BadPacket deriving (Show)
 
 makeLenses ''Packet
 
@@ -47,8 +49,9 @@
 parsePrefix = username <|> servername
 
 parseCommand :: Parser T.Text
-parseCommand = takeWhile1 isAlpha <|>
-               (do { a <- digit; b <- digit; c <- digit; return $ T.pack [a,b,c]})
+parseCommand = takeWhile1 isAlpha
+           <|> liftM3 (\a b c -> T.pack [a,b,c])
+                      digit digit digit
 
 parseParams :: Parser [T.Text]
 parseParams = (colonParam <|> nonColonParam) `sepBy` spaces
@@ -85,6 +88,7 @@
     else str)
 
 readable :: Packet -> T.Text
-readable (Packet (Just str) cmd pms) = flip T.append "\r\n" $ T.unwords [T.cons ':' str, cmd, showParams pms]
-readable (Packet Nothing c p) = flip T.append "\r\n" $ T.unwords [c, showParams p]
+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
@@ -11,7 +11,6 @@
 import Control.Monad.State
 import Data.Function (on)
 import Data.List (nubBy)
-import qualified Data.Map as M
 import Data.Maybe
 import Data.Monoid
 import qualified Data.Text as T
@@ -23,6 +22,7 @@
 import Kevin.Util.Entity
 import Kevin.Util.Logger
 import Kevin.Util.Token
+import Kevin.Version
 
 type KevinState = StateT Settings IO
 
@@ -68,22 +68,24 @@
                        (pkt^.params._head)
                        (pkt^.params._last)
                        Nothing
-            _ -> sendRoomNotice (pkt^.params._head) $ "Unsupported mode " <> mode
+            _ -> 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
+    [] -> 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_ $  M.lookup room . (^. titles)
-		let p = T.concat ["Title for ", room, ": "] in mapM_ (sendRoomNotice room . T.append p) (T.splitOn "\n" $ fromMaybe "" title)
-	(room:title) -> D.sendSet room "title" $ T.unwords title
+    [] -> 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
 
@@ -97,11 +99,14 @@
 respond pkt "KICK" = let p = pkt^.params
                       in D.sendKick (head p)
                                     (p !! 1)
-                                    (if length p > 2 then Just $ last p else Nothing)
+                                    (if length p > 2
+                                        then Just $ last p
+                                        else Nothing)
 
 respond _ "QUIT" = klogError "client quit" >> undefined
 
-respond pkt "ADMIN" = let (p:ps) = pkt^.params in D.sendAdmin p $ T.intercalate " " ps
+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
@@ -117,12 +122,15 @@
     xs -> listToMaybe $ filter (not . T.isInfixOf "*") xs
 
 errHandlers :: [Handler KevinIO ()]
-errHandlers = [ handler_ _KevinException $ klogError "Bad communication from client"
+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 = klogNow Blue ("client -> " ++ T.unpack asStr) >> T.hPutStr h (asStr `T.append` "\r\n")
+notice h str = do
+    klogNow Blue ("client -> " ++ T.unpack asStr)
+    T.hPutStr h (asStr <> "\r\n")
     where
         asStr = printf "NOTICE AUTH :%s" [str]
 
@@ -153,15 +161,24 @@
 welcome :: Handle -> KevinState ()
 welcome handle = do
     nick <- use name
-    mapM_ (\x -> io $ klogNow Blue ("client -> " ++ T.unpack x) >> T.hPutStr handle (x `T.append` "\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],
+    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 by kevin %s, created" [hostname, nick, VERSION],
-        printf ":%s 372 %s :- and maintained by Joel Taylor <http://otter.github.com>" [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
@@ -177,5 +194,6 @@
             authtoken .= t
             io $ notice handle "Successfully authenticated."
         Nothing -> do
-            io $ notice handle "Bad password, try again. (/quote pass yourpassword)"
+            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
@@ -4,7 +4,7 @@
     sendSetUserMode,
     sendChangeUserMode,
     sendNotice,
-	sendRoomNotice,
+    sendRoomNotice,
     sendChanMsg,
     sendChanAction,
     sendKick,
@@ -17,6 +17,7 @@
     sendWhoisReply
 ) where
 
+import Data.Monoid
 import qualified Data.Text as T
 import Kevin.Base
 
@@ -27,10 +28,10 @@
 getHost u = T.concat [":", u, "!", u, "@chat.deviantart.com"]
 
 sendPacket :: T.Text -> KevinIO ()
-sendPacket p = get_ >>= \k -> io . writeClient k $ T.append p "\r\n"
+sendPacket p = get_ >>= \k -> io . writeClient k $ p <> "\r\n"
 
 maybeBody :: Maybe T.Text -> T.Text
-maybeBody = maybe "" (T.append " :")
+maybeBody = maybe "" (" :" <>)
 
 type Str = T.Text
 type Room = Str
@@ -50,7 +51,13 @@
 sendPong :: T.Text -> KevinIO ()
 sendNoticeClone :: Username -> Int -> Room -> KevinIO ()
 sendNoticeUnclone :: Username -> Int -> Room -> KevinIO ()
-sendWhoisReply :: Username -> Username -> Username -> [Room] -> Int -> Int -> KevinIO ()
+sendWhoisReply :: Username
+               -> Username
+               -> Username
+               -> [Room]
+               -> Int
+               -> Int
+               -> KevinIO ()
 
 sendJoin us rm =
     sendPacket $ printf "%s JOIN :%s" [getHost us, rm]
@@ -78,22 +85,25 @@
     sendPacket . printf "NOTICE AUTH :%s" . return
 
 sendRoomNotice room n =
-	sendPacket $ printf "%s NOTICE %s :%s" [hostname, 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
 
 sendChanAction sender room msg = mapM_ (\x ->
-    sendPacket $ printf "%s PRIVMSG %s :\1ACTION %s\1" [getHost sender, room, 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]
+    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]
+    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]
@@ -101,35 +111,48 @@
 
 sendUserList us uss rm = do
     mapM_ (\nms ->
-        sendPacket $ printf "%s 353 %s = %s :%s" [hostname, us, rm, T.unwords nms]) chunkedNames
+        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
+        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)
+        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]
 
 sendNoticeClone uname i rm =
-    sendPacket $ printf "%s NOTICE %s :%s has joined again (now joined %s times)" [hostname, rm, uname, T.pack $ show i]
+    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]
+    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) `T.append` " times"
+              | 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 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 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
diff --git a/Kevin/Util/Entity.hs b/Kevin/Util/Entity.hs
--- a/Kevin/Util/Entity.hs
+++ b/Kevin/Util/Entity.hs
@@ -9,6 +9,7 @@
 import Data.Attoparsec.Text
 import Data.Char
 import Data.Maybe
+import Data.Monoid
 import qualified Data.Text as T
 import qualified Data.Text.Read as R
 import Prelude hiding (take)
@@ -19,7 +20,7 @@
 entityNumeric :: Parser T.Text
 entityNumeric = do
     string "&#"
-    entity <- T.append <$> option "" (string "x") <*> takeWhile1 isHexDigit
+    entity <- (<>) <$> option "" (string "x") <*> takeWhile1 isHexDigit
     char ';'
     return . fromMaybe (T.concat ["&#", entity, ";"])
            $ (if "x" `T.isPrefixOf` entity 
@@ -31,7 +32,8 @@
     char '&'
     entity <- T.cons <$> letter <*> takeWhile1 isAlphaNum
     char ';'
-    return . fromMaybe (T.concat ["&", entity, ";"]) . lookupNamedEntity $ entity
+    return . fromMaybe (T.concat ["&", entity, ";"])
+           . lookupNamedEntity $ entity
 
 decodeParser :: Parser T.Text
 decodeParser = T.concat <$> many1 decodeCharacter
@@ -69,4 +71,78 @@
     Left _ -> Nothing
 
 namedEntities :: [(T.Text, Int)]
-namedEntities = [("quot", 34), ("amp", 38), ("apos", 39), ("lt", 60), ("gt", 62), ("nbsp", 160), ("iexcl", 161), ("cent", 162), ("pound", 163), ("curren", 164), ("yen", 165), ("brvbar", 166), ("sect", 167), ("uml", 168), ("copy", 169), ("ordf", 170), ("laquo", 171), ("not", 172), ("shy", 173), ("reg", 174), ("macr", 175), ("deg", 176), ("plusmn", 177), ("sup2", 178), ("sup3", 179), ("acute", 180), ("micro", 181), ("para", 182), ("middot", 183), ("cedil", 184), ("sup1", 185), ("ordm", 186), ("raquo", 187), ("frac14", 188), ("frac12", 189), ("frac34", 190), ("iquest", 191), ("Agrave", 192), ("Aacute", 193), ("Acirc", 194), ("Atilde", 195), ("Auml", 196), ("Aring", 197), ("AElig", 198), ("Ccedil", 199), ("Egrave", 200), ("Eacute", 201), ("Ecirc", 202), ("Euml", 203), ("Igrave", 204), ("Iacute", 205), ("Icirc", 206), ("Iuml", 207), ("ETH", 208), ("Ntilde", 209), ("Ograve", 210), ("Oacute", 211), ("Ocirc", 212), ("Otilde", 213), ("Ouml", 214), ("times", 215), ("Oslash", 216), ("Ugrave", 217), ("Uacute", 218), ("Ucirc", 219), ("Uuml", 220), ("Yacute", 221), ("THORN", 222), ("szlig", 223), ("agrave", 224), ("aacute", 225), ("acirc", 226), ("atilde", 227), ("auml", 228), ("aring", 229), ("aelig", 230), ("ccedil", 231), ("egrave", 232), ("eacute", 233), ("ecirc", 234), ("euml", 235), ("igrave", 236), ("iacute", 237), ("icirc", 238), ("iuml", 239), ("eth", 240), ("ntilde", 241), ("ograve", 242), ("oacute", 243), ("ocirc", 244), ("otilde", 245), ("ouml", 246), ("divide", 247), ("oslash", 248), ("ugrave", 249), ("uacute", 250), ("ucirc", 251), ("uuml", 252), ("yacute", 253), ("thorn", 254), ("yuml", 255), ("OElig", 338), ("oelig", 339), ("Scaron", 352), ("scaron", 353), ("Yuml", 376), ("fnof", 402), ("circ", 710), ("tilde", 732), ("Alpha", 913), ("Beta", 914), ("Gamma", 915), ("Delta", 916), ("Epsilon", 917), ("Zeta", 918), ("Eta", 919), ("Theta", 920), ("Iota", 921), ("Kappa", 922), ("Lambda", 923), ("Mu", 924), ("Nu", 925), ("Xi", 926), ("Omicron", 927), ("Pi", 928), ("Rho", 929), ("Sigma", 931), ("Tau", 932), ("Upsilon", 933), ("Phi", 934), ("Chi", 935), ("Psi", 936), ("Omega", 937), ("alpha", 945), ("beta", 946), ("gamma", 947), ("delta", 948), ("epsilon", 949), ("zeta", 950), ("eta", 951), ("theta", 952), ("iota", 953), ("kappa", 954), ("lambda", 955), ("mu", 956), ("nu", 957), ("xi", 958), ("omicron", 959), ("pi", 960), ("rho", 961), ("sigmaf", 962), ("sigma", 963), ("tau", 964), ("upsilon", 965), ("phi", 966), ("chi", 967), ("psi", 968), ("omega", 969), ("thetasym", 977), ("upsih", 978), ("piv", 982), ("ensp", 8194), ("emsp", 8195), ("thinsp", 8201), ("zwnj", 8204), ("zwj", 8205), ("lrm", 8206), ("rlm", 8207), ("ndash", 8211), ("mdash", 8212), ("lsquo", 8216), ("rsquo", 8217), ("sbquo", 8218), ("ldquo", 8220), ("rdquo", 8221), ("bdquo", 8222), ("dagger", 8224), ("Dagger", 8225), ("bull", 8226), ("hellip", 8230), ("permil", 8240), ("prime", 8242), ("Prime", 8243), ("lsaquo", 8249), ("rsaquo", 8250), ("oline", 8254), ("frasl", 8260), ("euro", 8364), ("image", 8465), ("weierp", 8472), ("real", 8476), ("trade", 8482), ("alefsym", 8501), ("larr", 8592), ("uarr", 8593), ("rarr", 8594), ("darr", 8595), ("harr", 8596), ("crarr", 8629), ("lArr", 8656), ("uArr", 8657), ("rArr", 8658), ("dArr", 8659), ("hArr", 8660), ("forall", 8704), ("part", 8706), ("exist", 8707), ("empty", 8709), ("nabla", 8711), ("isin", 8712), ("notin", 8713), ("ni", 8715), ("prod", 8719), ("sum", 8721), ("minus", 8722), ("lowast", 8727), ("radic", 8730), ("prop", 8733), ("infin", 8734), ("ang", 8736), ("and", 8743), ("or", 8744), ("cap", 8745), ("cup", 8746), ("int", 8747), ("there4", 8756), ("sim", 8764), ("cong", 8773), ("asymp", 8776), ("ne", 8800), ("equiv", 8801), ("le", 8804), ("ge", 8805), ("sub", 8834), ("sup", 8835), ("nsub", 8836), ("sube", 8838), ("supe", 8839), ("oplus", 8853), ("otimes", 8855), ("perp", 8869), ("sdot", 8901), ("lceil", 8968), ("rceil", 8969), ("lfloor", 8970), ("rfloor", 8971), ("lang", 9001), ("rang", 9002), ("loz", 9674), ("spades", 9824), ("clubs", 9827), ("hearts", 9829), ("diams", 9830)]
+namedEntities = [ ("quot", 34), ("amp", 38), ("apos", 39), ("lt", 60)
+                , ("gt", 62), ("nbsp", 160), ("iexcl", 161), ("cent", 162)
+                , ("pound", 163), ("curren", 164), ("yen", 165)
+                , ("brvbar", 166), ("sect", 167), ("uml", 168), ("copy", 169)
+                , ("ordf", 170), ("laquo", 171), ("not", 172), ("shy", 173)
+                , ("reg", 174), ("macr", 175), ("deg", 176), ("plusmn", 177)
+                , ("sup2", 178), ("sup3", 179), ("acute", 180), ("micro", 181)
+                , ("para", 182), ("middot", 183), ("cedil", 184), ("sup1", 185)
+                , ("ordm", 186), ("raquo", 187), ("frac14", 188)
+                , ("frac12", 189), ("frac34", 190), ("iquest", 191)
+                , ("Agrave", 192), ("Aacute", 193), ("Acirc", 194)
+                , ("Atilde", 195), ("Auml", 196), ("Aring", 197)
+                , ("AElig", 198), ("Ccedil", 199), ("Egrave", 200)
+                , ("Eacute", 201), ("Ecirc", 202), ("Euml", 203)
+                , ("Igrave", 204), ("Iacute", 205), ("Icirc", 206)
+                , ("Iuml", 207), ("ETH", 208), ("Ntilde", 209), ("Ograve", 210)
+                , ("Oacute", 211), ("Ocirc", 212), ("Otilde", 213)
+                , ("Ouml", 214), ("times", 215), ("Oslash", 216)
+                , ("Ugrave", 217), ("Uacute", 218), ("Ucirc", 219)
+                , ("Uuml", 220), ("Yacute", 221), ("THORN", 222)
+                , ("szlig", 223), ("agrave", 224), ("aacute", 225)
+                , ("acirc", 226), ("atilde", 227), ("auml", 228)
+                , ("aring", 229), ("aelig", 230), ("ccedil", 231)
+                , ("egrave", 232), ("eacute", 233), ("ecirc", 234)
+                , ("euml", 235), ("igrave", 236), ("iacute", 237)
+                , ("icirc", 238), ("iuml", 239), ("eth", 240), ("ntilde", 241)
+                , ("ograve", 242), ("oacute", 243), ("ocirc", 244)
+                , ("otilde", 245), ("ouml", 246), ("divide", 247)
+                , ("oslash", 248), ("ugrave", 249), ("uacute", 250)
+                , ("ucirc", 251), ("uuml", 252), ("yacute", 253)
+                , ("thorn", 254), ("yuml", 255), ("OElig", 338), ("oelig", 339)
+                , ("Scaron", 352), ("scaron", 353), ("Yuml", 376)
+                , ("fnof", 402), ("circ", 710), ("tilde", 732), ("Alpha", 913)
+                , ("Beta", 914), ("Gamma", 915), ("Delta", 916)
+                , ("Epsilon", 917), ("Zeta", 918), ("Eta", 919), ("Theta", 920)
+                , ("Iota", 921), ("Kappa", 922), ("Lambda", 923), ("Mu", 924)
+                , ("Nu", 925), ("Xi", 926), ("Omicron", 927), ("Pi", 928)
+                , ("Rho", 929), ("Sigma", 931), ("Tau", 932), ("Upsilon", 933)
+                , ("Phi", 934), ("Chi", 935), ("Psi", 936), ("Omega", 937)
+                , ("alpha", 945), ("beta", 946), ("gamma", 947), ("delta", 948)
+                , ("epsilon", 949), ("zeta", 950), ("eta", 951), ("theta", 952)
+                , ("iota", 953), ("kappa", 954), ("lambda", 955), ("mu", 956)
+                , ("nu", 957), ("xi", 958), ("omicron", 959), ("pi", 960)
+                , ("rho", 961), ("sigmaf", 962), ("sigma", 963), ("tau", 964)
+                , ("upsilon", 965), ("phi", 966), ("chi", 967), ("psi", 968)
+                , ("omega", 969), ("thetasym", 977), ("upsih", 978)
+                , ("piv", 982), ("ensp", 8194), ("emsp", 8195)
+                , ("thinsp", 8201), ("zwnj", 8204), ("zwj", 8205)
+                , ("lrm", 8206), ("rlm", 8207), ("ndash", 8211)
+                , ("mdash", 8212), ("lsquo", 8216), ("rsquo", 8217)
+                , ("sbquo", 8218), ("ldquo", 8220), ("rdquo", 8221)
+                , ("bdquo", 8222), ("dagger", 8224), ("Dagger", 8225)
+                , ("bull", 8226), ("hellip", 8230), ("permil", 8240)
+                , ("prime", 8242), ("Prime", 8243), ("lsaquo", 8249)
+                , ("rsaquo", 8250), ("oline", 8254), ("frasl", 8260)
+                , ("euro", 8364), ("image", 8465), ("weierp", 8472)
+                , ("real", 8476), ("trade", 8482), ("alefsym", 8501)
+                , ("larr", 8592), ("uarr", 8593), ("rarr", 8594)
+                , ("darr", 8595), ("harr", 8596), ("crarr", 8629)
+                , ("lArr", 8656), ("uArr", 8657), ("rArr", 8658)
+                , ("dArr", 8659), ("hArr", 8660), ("forall", 8704)
+                , ("part", 8706), ("exist", 8707), ("empty", 8709)
+                , ("nabla", 8711), ("isin", 8712), ("notin", 8713)
+                , ("ni", 8715), ("prod", 8719), ("sum", 8721), ("minus", 8722)
+                , ("lowast", 8727), ("radic", 8730), ("prop", 8733)
+                , ("infin", 8734), ("ang", 8736), ("and", 8743), ("or", 8744)
+                , ("cap", 8745), ("cup", 8746), ("int", 8747), ("there4", 8756)
+                , ("sim", 8764), ("cong", 8773), ("asymp", 8776), ("ne", 8800)
+                , ("equiv", 8801), ("le", 8804), ("ge", 8805), ("sub", 8834)
+                , ("sup", 8835), ("nsub", 8836), ("sube", 8838), ("supe", 8839)
+                , ("oplus", 8853), ("otimes", 8855), ("perp", 8869)
+                , ("sdot", 8901), ("lceil", 8968), ("rceil", 8969)
+                , ("lfloor", 8970), ("rfloor", 8971), ("lang", 9001)
+                , ("rang", 9002), ("loz", 9674), ("spades", 9824)
+                , ("clubs", 9827), ("hearts", 9829), ("diams", 9830)]
diff --git a/Kevin/Util/Logger.hs b/Kevin/Util/Logger.hs
--- a/Kevin/Util/Logger.hs
+++ b/Kevin/Util/Logger.hs
@@ -38,9 +38,12 @@
 printf str reps = T.concat $ interleave (T.splitOn "%s" str) reps
 
 render :: Color -> String -> String
-render col str = "\027[" ++ show (colorAsNum col) ++ "m" ++ rtrimmed ++ "\027[0m"
+render col str = "\027[" ++ show (colorAsNum col)
+                         ++ "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
@@ -18,13 +18,17 @@
 
 {-# 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)]
-regexen = let ($$) = (,) in map (first (fromRight . unsafePerformIO . compile defaultCompOpt defaultExecOpt)) . reverse $ [
+regexen = let ($$) = (,) in map (
+    first (fromRight . unsafePerformIO
+          . compile defaultCompOpt defaultExecOpt)
+     ) . reverse $ [
         "&b\t"      $$ const "\2",
         "&/b\t"     $$ const "\15",
         "&i\t"      $$ const "\22",
@@ -59,14 +63,19 @@
         "&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,
+        "&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='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
+        "^[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
@@ -7,6 +7,7 @@
 import qualified Data.ByteString.Char8 as B
 import qualified Data.ByteString.Lazy.Char8 as LB
 import Data.List
+import Data.Monoid
 import qualified Data.Text as T
 import Data.Text.Encoding (decodeUtf8)
 import Network.HTTP.Base
@@ -19,7 +20,7 @@
     line <- recvData ctx
     if str `B.isInfixOf` line
         then return line
-        else fmap (line `B.append`) $ recvUntil ctx str
+        else fmap (line <>) $ recvUntil ctx str
 
 concatHeaders :: [(String,String)] -> String
 concatHeaders = intercalate "\r\n" . map (\(x,y) -> x ++ ": " ++ y)
@@ -27,11 +28,14 @@
 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"]
+                               , onCertificatesRecv =
+                                   certificateChecks [return
+                                     . certificateVerifyDomain
+                                         "chat.deviantart.com"]
                                }
+        headers :: [(String, String)]
         headers = [("Connection", "closed"),
-                   ("Content-Type", "application/x-www-form-urlencoded")] :: [(String,String)]
+                   ("Content-Type", "application/x-www-form-urlencoded")]
     gen <- makeSystem
     ctx <- connectionClient "www.deviantart.com" "443" params gen
     let payload = urlEncodeVars [ ("username", T.unpack uname)
@@ -40,7 +44,8 @@
                                 ]
     handshake ctx
     sendData ctx . LB.pack
-        $ printf "POST /users/login HTTP/1.1\r\n%s\r\nContent-Length: %d\r\n\r\n%s"
+        $ 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
@@ -48,10 +53,13 @@
     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 ": ")
+            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\ncookie: %s\r\n\r\n"
+                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
diff --git a/Kevin/Version.hs b/Kevin/Version.hs
new file mode 100644
--- /dev/null
+++ b/Kevin/Version.hs
@@ -0,0 +1,10 @@
+module Kevin.Version (showVersion, version, versionStr) where
+
+import Data.Text (Text, pack)
+import Data.Version
+
+version :: Version
+version = Version [0,7,1] []
+
+versionStr :: Text
+versionStr = pack $ showVersion version
diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -1,4 +1,5 @@
 import Kevin
+import Kevin.Version
 import System.Console.GetOpt
 import System.Environment
 
@@ -9,7 +10,10 @@
 
 opts :: [OptDescr Flag]
 opts = [
-        Option "p" ["port"] (ReqArg (Port . read) "number") $ "local port to run the server on (defaults to " ++ show defaultPort ++ ")",
+        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"
        ]
@@ -28,6 +32,7 @@
     case getOpt Permute opts args of
         (flags, _, []) -> case flags of
             f | Help `elem` f -> putStrLn $ usageInfo header opts
-              | Version `elem` f -> putStrLn $ "kevin version " ++ VERSION
+              | 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.7
+Version:          0.7.1
 Synopsis:         a dAmn ↔ IRC proxy
 Description:      a dAmn ↔ IRC proxy
 License:          GPL
@@ -52,8 +52,8 @@
                         Kevin.Util.Entity,
                         Kevin.Util.Logger,
                         Kevin.Util.Tablump,
-                        Kevin.Util.Token
+                        Kevin.Util.Token,
+                        Kevin.Version
                 
-    default-extensions: CPP, DeriveDataTypeable, ExistentialQuantification, FlexibleContexts, OverloadedStrings, ScopedTypeVariables, TemplateHaskell
+    default-extensions: DeriveDataTypeable, ExistentialQuantification, FlexibleContexts, OverloadedStrings, ScopedTypeVariables, TemplateHaskell
     ghc-options:        -Wall -fno-warn-unused-do-bind -threaded
-    cpp-options:        -DVERSION="0.7"
