diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,13 @@
 # Revision history for glirc2
 
+## 2.1
+
+* Add red highlighting for own nick
+* Synchronize reply codes with Freenode
+* Add textual interpretation of reply codes
+* Add SASL support
+* Add `/channelinfo` command
+
 ## 2.0
 
 * First version of glirc rewrite
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -21,6 +21,7 @@
 * Run commands upon connection
 * Ban lists don't obstruct chat messages
 * Ban list and user list are searchable
+* CERTFP and SASL authentication
 
 TLS
 ===
@@ -100,6 +101,8 @@
 * `username` - text - username
 * `realname` - text - realname / GECOS
 * `password` - text - server password
+* `sasl-username` - text - SASL username
+* `sasl-password` - text - SASL password
 * `tls` - yes/no - use TLS to connect
 * `tls-insecure` - yes/no - disable certificate validation
 * `tls-client-cert` - text - path to TLS client certificate
@@ -109,6 +112,8 @@
 * `socks-port` - number - port number of SOCKS proxy to connect through
 * `server-certificates` - list of text - list of CA certificates to use when validating certificates
 * `chanserv-channels` - list of text - list of channels with chanserv op permission
+* `flood-penalty` - number - cost in seconds per message
+* `flood-threshold` - number - threshold of seconds for burst
 
 
 Commands
@@ -140,6 +145,7 @@
 * `/part` - Part from current channel
 * `/users` - Show channel user list
 * `/masks <mode>` - Show channel bans(b), quiets(q), exempts(e), or invex(I)
+* `/channelinfo` - Show channel topic, creation, url
 
 Filters
 
diff --git a/glirc.cabal b/glirc.cabal
--- a/glirc.cabal
+++ b/glirc.cabal
@@ -1,5 +1,5 @@
 name:                glirc
-version:             2.0
+version:             2.1
 synopsis:            Console IRC client
 description:         Console IRC client
 license:             ISC
@@ -30,6 +30,7 @@
                        Client.EventLoop
                        Client.IdentifierColors
                        Client.Image
+                       Client.Image.ChannelInfo
                        Client.Image.MaskList
                        Client.Image.Message
                        Client.Image.UserList
@@ -69,6 +70,7 @@
                        unordered-containers >=0.2.7  && <0.3,
                        hashable             >=1.2.4  && <1.3,
                        network              >=2.6.2  && <2.7,
+                       vector               >=0.11   && <0.12,
                        tls                  >=1.3.8  && <1.4,
                        split                >=0.2    && <0.3,
                        profunctors          >=5.2    && <5.3,
@@ -79,6 +81,7 @@
                        data-default-class   >=0.1.2  && <0.2,
                        stm                  >=2.4    && <2.5,
                        directory            >=1.2.6  && <1.3,
+                       memory               >=0.13   && <0.14,
                        filepath             >=1.4.1  && <1.5
 
   ghc-options:         -threaded -rtsopts
diff --git a/src/Client/ChannelState.hs b/src/Client/ChannelState.hs
--- a/src/Client/ChannelState.hs
+++ b/src/Client/ChannelState.hs
@@ -16,9 +16,10 @@
 module Client.ChannelState
   (
   -- * Channel state type
-    ChannelState
+    ChannelState(..)
   , chanTopic
   , chanTopicProvenance
+  , chanUrl
   , chanUsers
   , chanModes
   , chanLists
@@ -56,6 +57,8 @@
         -- ^ topic text
   , _chanTopicProvenance :: !(Maybe TopicProvenance)
         -- ^ author and timestamp for topic
+  , _chanUrl :: !(Maybe Text)
+        -- ^ channel URL
   , _chanUsers :: !(HashMap Identifier String)
         -- ^ user list and sigils
   , _chanModes :: !(Map Char Text)
@@ -80,6 +83,7 @@
 newChannel :: ChannelState
 newChannel = ChannelState
   { _chanTopic = Text.empty
+  , _chanUrl = Nothing
   , _chanTopicProvenance = Nothing
   , _chanUsers = HashMap.empty
   , _chanModes = Map.empty
diff --git a/src/Client/Commands.hs b/src/Client/Commands.hs
--- a/src/Client/Commands.hs
+++ b/src/Client/Commands.hs
@@ -141,6 +141,7 @@
   , ("part"      , ChannelCommand cmdPart   simpleChannelTab)
 
   , ("users"     , ChannelCommand cmdUsers  noChannelTab)
+  , ("channelinfo", ChannelCommand cmdChannelInfo noChannelTab)
   , ("masks"     , ChannelCommand cmdMasks  noChannelTab)
   ]
 
@@ -359,6 +360,12 @@
 cmdUsers _ _ _ st _ = commandContinue
                     $ changeSubfocus FocusUsers
                     $ consumeInput st
+
+cmdChannelInfo :: NetworkName -> ConnectionState -> Identifier -> ClientState -> String -> IO CommandResult
+cmdChannelInfo _ _ _ st _
+  = commandContinue
+  $ changeSubfocus FocusInfo
+  $ consumeInput st
 
 cmdMasks :: NetworkName -> ConnectionState -> Identifier -> ClientState -> String -> IO CommandResult
 cmdMasks _ cs _ st rest =
diff --git a/src/Client/Configuration.hs b/src/Client/Configuration.hs
--- a/src/Client/Configuration.hs
+++ b/src/Client/Configuration.hs
@@ -133,6 +133,8 @@
        _ssSocksPort      <- fieldReq' ssSocksPort     (sectionOptNum "socks-port")
        _ssServerCerts    <- fieldReq' ssServerCerts   (sectionOptStrings "server-certificates")
        _ssChanservChannels <- fieldReq' ssChanservChannels (sectionOptIdentifiers "chanserv-channels")
+       _ssFloodPenalty   <- fieldReq' ssFloodPenalty   (sectionOptNum "flood-penalty")
+       _ssFloodThreshold <- fieldReq' ssFloodThreshold (sectionOptNum "flood-threshold")
        return ServerSettings{..}
   where
     field    l key = field'    l (sectionOpt key)
diff --git a/src/Client/ConnectionState.hs b/src/Client/ConnectionState.hs
--- a/src/Client/ConnectionState.hs
+++ b/src/Client/ConnectionState.hs
@@ -19,7 +19,7 @@
 module Client.ConnectionState
   (
   -- * Connection state type
-    ConnectionState
+    ConnectionState(..)
   , csNick
   , csChannels
   , csSocket
@@ -85,7 +85,7 @@
 import           LensUtils
 
 data ConnectionState = ConnectionState
-  { _csNetworkId    :: NetworkId
+  { _csNetworkId    :: !NetworkId
   , _csChannels     :: !(HashMap Identifier ChannelState)
   , _csSocket       :: !NetworkConnection
   , _csModeTypes    :: !ModeTypes
@@ -233,8 +233,11 @@
          $ forgetUser' nick
          $ overChannel chan (partChannel nick) cs
     Reply RPL_WELCOME (me:_) -> doWelcome msgWhen (mkId me) cs
+    Reply RPL_SASLSUCCESS _ -> ([ircCapEnd], cs)
+    Reply RPL_SASLFAIL _ -> ([ircCapEnd], cs)
     Reply code args        -> noReply (doRpl code msgWhen args cs)
     Cap cmd params         -> doCap cmd params cs
+    Authenticate param     -> doAuthenticate param cs
     Mode who target (modes:params)  -> doMode msgWhen who target modes params cs
     Topic user chan topic  -> noReply (doTopic msgWhen user chan topic cs)
     _                      -> noReply cs
@@ -271,7 +274,7 @@
       Just $! posixSecondsToUTCTime (fromInteger i)
     _ -> Nothing
 
-doRpl :: Int -> ZonedTime -> [Text] -> ConnectionState -> ConnectionState
+doRpl :: ReplyCode -> ZonedTime -> [Text] -> ConnectionState -> ConnectionState
 doRpl cmd msgWhen args =
   case cmd of
 
@@ -301,6 +304,12 @@
           overChannel (mkId chan) (set chanCreation (Just when))
         _ -> id
 
+    RPL_CHANNEL_URL ->
+      case args of
+        _me:chan:urlTxt:_ ->
+          overChannel (mkId chan) (set chanUrl (Just urlTxt))
+        _ -> id
+
     RPL_ISUPPORT -> isupport args
 
     RPL_NAMREPLY ->
@@ -350,7 +359,7 @@
                      cs
         _ -> id
 
-    RPL_INVITELIST ->
+    RPL_INVEXLIST ->
       case args of
         _me:_tgt:mask:who:whenTxt:_ | Just when <- parseTimeParam whenTxt ->
           over csTransaction $ \t ->
@@ -358,7 +367,7 @@
             in BanTransaction ((mask,(who,when)):xs)
         _ -> id
 
-    RPL_ENDOFINVITELIST ->
+    RPL_ENDOFINVEXLIST ->
       case args of
         _me:tgt:_ -> \cs ->
            set csTransaction NoTransaction
@@ -408,15 +417,15 @@
 -- | These replies are interpreted by the client and should only be shown
 -- in the detailed view. Any reply interpreted by 'doRpl' should be
 -- listed here.
-squelchReply :: Int -> Bool
+squelchReply :: ReplyCode -> Bool
 squelchReply rpl =
   case rpl of
     RPL_NAMREPLY        -> True
     RPL_ENDOFNAMES      -> True
     RPL_BANLIST         -> True
     RPL_ENDOFBANLIST    -> True
-    RPL_INVITELIST      -> True
-    RPL_ENDOFINVITELIST -> True
+    RPL_INVEXLIST       -> True
+    RPL_ENDOFINVEXLIST  -> True
     RPL_EXCEPTLIST      -> True
     RPL_ENDOFEXCEPTLIST -> True
     RPL_QUIETLIST       -> True
@@ -425,6 +434,7 @@
     RPL_TOPIC           -> True
     RPL_TOPICWHOTIME    -> True
     RPL_CREATIONTIME    -> True
+    RPL_CHANNEL_URL     -> True
     RPL_NOTOPIC         -> True
     RPL_WHOREPLY        -> True
     RPL_ENDOFWHO        -> True
@@ -512,9 +522,23 @@
       | otherwise         = mode:modes
     applyOne modes (False, mode, _) = delete mode modes
 
-supportedCaps :: [Text]
-supportedCaps = ["multi-prefix", "znc.in/server-time-iso"]
+supportedCaps :: ConnectionState -> [Text]
+supportedCaps cs = sasl ++ ["multi-prefix", "znc.in/server-time-iso"]
+  where
+    ss = view csSettings cs
+    sasl = ["sasl" | has ssSaslUsername ss
+                   , has ssSaslPassword ss ]
 
+doAuthenticate :: Text -> ConnectionState -> ([RawIrcMsg], ConnectionState)
+doAuthenticate "+" cs
+  | Just user <- view ssSaslUsername ss
+  , Just pass <- view ssSaslPassword ss
+  = ([ircAuthenticate (encodePlainAuthentication user pass)], cs)
+  where
+    ss = view csSettings cs
+
+doAuthenticate _ cs = ([ircCapEnd], cs)
+
 doCap :: CapCmd -> [Text] -> ConnectionState -> ([RawIrcMsg], ConnectionState)
 doCap cmd args cs =
   case (cmd,args) of
@@ -523,12 +547,15 @@
       | otherwise -> ([ircCapReq reqCaps], cs)
       where
         caps = Text.words capsTxt
-        reqCaps = intersect supportedCaps caps
+        reqCaps = intersect (supportedCaps cs) caps
 
-    (CapAck,_) -> ([ircCapEnd], cs)
-    (CapNak,_) -> ([ircCapEnd], cs)
+    (CapAck,[capsTxt])
+      | "sasl" `elem` caps ->
+          ([ircAuthenticate plainAuthenticationMode], cs)
+      where
+        caps = Text.words capsTxt
 
-    _ -> noReply cs
+    _ -> ([ircCapEnd], cs)
 
 
 initialMessages :: ConnectionState -> [RawIrcMsg]
diff --git a/src/Client/Image.hs b/src/Client/Image.hs
--- a/src/Client/Image.hs
+++ b/src/Client/Image.hs
@@ -14,6 +14,7 @@
 import           Client.ChannelState
 import           Client.ConnectionState
 import qualified Client.EditBox as Edit
+import           Client.Image.ChannelInfo
 import           Client.Image.MaskList
 import           Client.Image.Message
 import           Client.Image.UserList
@@ -56,6 +57,8 @@
 messagePaneImages :: ClientState -> [Image]
 messagePaneImages !st =
   case (view clientFocus st, view clientSubfocus st) of
+    (ChannelFocus network channel, FocusInfo) ->
+      channelInfoImages network channel st
     (ChannelFocus network channel, FocusUsers)
       | view clientDetailView st -> userInfoImages network channel st
       | otherwise                -> userListImages network channel st
@@ -223,6 +226,7 @@
     subfocusName =
       case view clientSubfocus st of
         FocusMessages -> Nothing
+        FocusInfo     -> Just $ string (withForeColor defAttr green) "info"
         FocusUsers    -> Just $ string (withForeColor defAttr green) "users"
         FocusMasks m  -> Just $ horizCat
           [ string (withForeColor defAttr green) "masks"
diff --git a/src/Client/Image/ChannelInfo.hs b/src/Client/Image/ChannelInfo.hs
new file mode 100644
--- /dev/null
+++ b/src/Client/Image/ChannelInfo.hs
@@ -0,0 +1,75 @@
+{-# Language OverloadedStrings #-}
+{-# Language BangPatterns #-}
+
+{-|
+Module      : Client.Image.ChannelInfo
+Description : Channel information renderer
+Copyright   : (c) Eric Mertens, 2016
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module implements a renderer for the window that shows
+channel metadata.
+
+-}
+module Client.Image.ChannelInfo
+  ( channelInfoImages
+  ) where
+
+import           Client.ChannelState
+import           Client.ConnectionState
+import           Client.Image.Message
+import           Client.MircFormatting
+import           Client.State
+import           Control.Lens
+import qualified Data.HashMap.Strict as HashMap
+import           Data.List
+import           Data.Ord
+import           Data.Time
+import           Graphics.Vty.Image
+import           Irc.Identifier
+
+-- | Render the lines used in a channel mask list
+channelInfoImages :: NetworkName -> Identifier -> ClientState -> [Image]
+channelInfoImages network channelId st
+
+  | Just cs      <- preview (clientConnection network) st
+  , Just channel <- preview (csChannels . ix channelId) cs
+  = channelInfoImages' channel cs
+
+  | otherwise = [text' (withForeColor defAttr red) "No channel information"]
+
+channelInfoImages' :: ChannelState -> ConnectionState -> [Image]
+channelInfoImages' !channel !cs
+    = topicLine
+    : provenanceLines
+   ++ creationLines
+   ++ urlLines
+
+  where
+    label = text' (withForeColor defAttr green)
+
+    topicLine = label "Topic: " <|> parseIrcText (view chanTopic channel)
+
+    myNick = view csNick cs
+
+    utcTimeImage = string defAttr . formatTime defaultTimeLocale "%F %T"
+
+    provenanceLines =
+        case view chanTopicProvenance channel of
+          Nothing -> []
+          Just !prov ->
+            [ label "Topic set by: " <|> coloredUserInfo DetailedRender [myNick] (view topicAuthor prov)
+            , label "Topic set on: " <|> utcTimeImage (view topicTime prov)
+            ]
+
+    creationLines =
+        case view chanCreation channel of
+          Nothing   -> []
+          Just time -> [label "Created on: " <|> utcTimeImage time]
+
+    urlLines =
+        case view chanUrl channel of
+          Nothing -> []
+          Just url -> [ label "Channel URL: " <|> parseIrcText url ]
+
diff --git a/src/Client/Image/Message.hs b/src/Client/Image/Message.hs
--- a/src/Client/Image/Message.hs
+++ b/src/Client/Image/Message.hs
@@ -27,6 +27,7 @@
 import           Control.Lens
 import           Data.Time
 import           Graphics.Vty.Image
+import           Irc.Codes
 import           Irc.Identifier
 import           Irc.Message
 import           Irc.RawIrcMsg
@@ -42,6 +43,7 @@
   { rendStatusMsg  :: [Char] -- ^ restricted message sigils
   , rendUserSigils :: [Char] -- ^ sender sigils
   , rendNicks      :: [Identifier] -- ^ nicknames to highlight
+  , rendMyNicks    :: [Identifier] -- ^ nicknames to highlight in red
   }
 
 -- | Default 'MessageRenderParams' with no sigils or nicknames specified
@@ -50,6 +52,7 @@
   { rendStatusMsg = ""
   , rendUserSigils = ""
   , rendNicks = []
+  , rendMyNicks = []
   }
 
 -- | Construct a message given the time the message was received and its
@@ -60,7 +63,7 @@
 msgImage when params body = horizCat
   [ timeImage when
   , statusMsgImage (rendStatusMsg params)
-  , bodyImage NormalRender (rendUserSigils params) (rendNicks params) body
+  , bodyImage NormalRender (rendUserSigils params) (rendMyNicks params) (rendNicks params) body
   ]
 
 -- | Construct a message given the time the message was received and its
@@ -69,7 +72,7 @@
 detailedMsgImage when params body = horizCat
   [ datetimeImage when
   , statusMsgImage (rendStatusMsg params)
-  , bodyImage DetailedRender (rendUserSigils params) (rendNicks params) body
+  , bodyImage DetailedRender (rendUserSigils params) (rendMyNicks params) (rendNicks params) body
   ]
 
 -- | Render the sigils for a restricted message.
@@ -87,11 +90,12 @@
 bodyImage ::
   RenderMode ->
   [Char] {- ^ sigils -} ->
+  [Identifier] {- ^ my nicknames -} ->
   [Identifier] {- ^ nicknames to highlight -} ->
   MessageBody -> Image
-bodyImage rm modes nicks body =
+bodyImage rm modes myNicks nicks body =
   case body of
-    IrcBody irc  -> ircLineImage rm modes nicks irc
+    IrcBody irc  -> ircLineImage rm modes myNicks nicks irc
     ErrorBody ex -> string defAttr ("Exception: " ++ show ex)
     ExitBody     -> string defAttr "Thread finished"
 
@@ -129,9 +133,10 @@
 ircLineImage ::
   RenderMode ->
   [Char]       {- ^ sigils (e.g. \@+) -} ->
+  [Identifier] {- ^ my nicknames to highlight -} ->
   [Identifier] {- ^ nicknames to highlight -} ->
   IrcMsg -> Image
-ircLineImage rm sigils nicks body =
+ircLineImage rm sigils myNicks nicks body =
   let detail img =
         case rm of
           NormalRender -> emptyImage
@@ -141,24 +146,24 @@
     Nick old new ->
       detail (string quietAttr "nick ") <|>
       string (withForeColor defAttr cyan) sigils <|>
-      coloredUserInfo rm old <|>
+      coloredUserInfo rm myNicks old <|>
       string defAttr " became " <|>
-      coloredIdentifier new
+      coloredIdentifier myNicks new
 
     Join nick _chan ->
       string quietAttr "join " <|>
-      coloredUserInfo rm nick
+      coloredUserInfo rm myNicks nick
 
     Part nick _chan mbreason ->
       string quietAttr "part " <|>
-      coloredUserInfo rm nick <|>
+      coloredUserInfo rm myNicks nick <|>
       foldMap (\reason -> string quietAttr " (" <|>
                           parseIrcText reason <|>
                           string quietAttr ")") mbreason
 
     Quit nick mbreason ->
       string quietAttr "quit "   <|>
-      coloredUserInfo rm nick   <|>
+      coloredUserInfo rm myNicks nick   <|>
       foldMap (\reason -> string quietAttr " (" <|>
                           parseIrcText reason <|>
                           string quietAttr ")") mbreason
@@ -166,90 +171,119 @@
     Kick kicker _channel kickee reason ->
       detail (string quietAttr "kick ") <|>
       string (withForeColor defAttr cyan) sigils <|>
-      coloredUserInfo rm kicker <|>
+      coloredUserInfo rm myNicks kicker <|>
       string defAttr " kicked " <|>
-      coloredIdentifier kickee <|>
+      coloredIdentifier myNicks kickee <|>
       string defAttr ": " <|>
       parseIrcText reason
 
     Topic src _dst txt ->
-      coloredUserInfo rm src <|>
+      coloredUserInfo rm myNicks src <|>
       string defAttr " changed topic to " <|>
       parseIrcText txt
 
     Notice src _dst txt ->
       detail (string quietAttr "note ") <|>
       string (withForeColor defAttr cyan) sigils <|>
-      coloredUserInfo rm src <|>
+      coloredUserInfo rm myNicks src <|>
       string (withForeColor defAttr red) ": " <|>
-      parseIrcTextWithNicks nicks txt
+      parseIrcTextWithNicks myNicks nicks txt
 
     Privmsg src _dst txt ->
       detail (string quietAttr "chat ") <|>
       string (withForeColor defAttr cyan) sigils <|>
-      coloredUserInfo rm src <|>
+      coloredUserInfo rm myNicks src <|>
       string defAttr ": " <|>
-      parseIrcTextWithNicks nicks txt
+      parseIrcTextWithNicks myNicks nicks txt
 
     Action src _dst txt ->
       detail (string quietAttr "chat ") <|>
       string (withForeColor defAttr blue) "* " <|>
       string (withForeColor defAttr cyan) sigils <|>
-      coloredUserInfo rm src <|>
+      coloredUserInfo rm myNicks src <|>
       string defAttr " " <|>
-      parseIrcTextWithNicks nicks txt
+      parseIrcTextWithNicks myNicks nicks txt
 
     Ping params ->
-      string defAttr "PING" <|>
-      horizCat [char (withForeColor defAttr blue) '·' <|>
-                 parseIrcText p | p <- params]
+      string defAttr "PING " <|> separatedParams params
 
     Pong params ->
-      string defAttr "PONG" <|>
-      horizCat [char (withForeColor defAttr blue) '·' <|>
-                 parseIrcText p | p <- params]
+      string defAttr "PONG " <|> separatedParams params
 
     Error reason ->
       string (withForeColor defAttr red) "ERROR " <|>
       parseIrcText reason
 
     Reply code params ->
-      string defAttr (show code) <|>
-      horizCat [char (withForeColor defAttr blue) '·' <|>
-                parseIrcText p | p <- params]
+      renderReplyCode rm code <|>
+      char defAttr ' ' <|>
+      separatedParams (dropFst params)
+      where
+        dropFst = case rm of
+                    DetailedRender -> id
+                    NormalRender   -> drop 1
 
     UnknownMsg irc ->
-      maybe emptyImage (\ui -> coloredUserInfo rm ui <|> char defAttr ' ')
+      maybe emptyImage (\ui -> coloredUserInfo rm myNicks ui <|> char defAttr ' ')
         (view msgPrefix irc) <|>
       text' defAttr (view msgCommand irc) <|>
-      horizCat [char (withForeColor defAttr blue) '·' <|>
-                parseIrcText p | p <- view msgParams irc]
+      char defAttr ' ' <|>
+      separatedParams (view msgParams irc)
 
     Cap cmd args ->
       string defAttr (show cmd) <|>
-      horizCat [char (withForeColor defAttr blue) '·' <|>
-                text' defAttr a | a <- args]
+      char defAttr ' ' <|>
+      separatedParams args
 
+    Authenticate{} -> string defAttr "AUTHENTICATE ***"
+
     Mode nick _chan params ->
       detail (string quietAttr "mode ") <|>
       string (withForeColor defAttr cyan) sigils <|>
-      coloredUserInfo rm nick <|>
+      coloredUserInfo rm myNicks nick <|>
       string defAttr " set mode: " <|>
-      horizCat (intersperse (char (withForeColor defAttr blue) '·')
-                            (text' defAttr <$> params))
+      separatedParams params
 
+separatorImage :: Image
+separatorImage = char (withForeColor defAttr blue) '·'
+
+separatedParams :: [Text] -> Image
+separatedParams = horizCat . intersperse separatorImage . map parseIrcText
+
+renderReplyCode :: RenderMode -> ReplyCode -> Image
+renderReplyCode rm code@(ReplyCode w) =
+  case rm of
+    DetailedRender -> string attr (show w)
+    NormalRender   -> text' attr (Text.toLower (replyCodeText info)) <|>
+                      char defAttr ':'
+  where
+    info = replyCodeInfo code
+
+    color = case replyCodeType info of
+              ClientServerReply -> magenta
+              CommandReply      -> green
+              ErrorReply        -> red
+              UnknownReply      -> yellow
+
+    attr = withForeColor defAttr color
+
+
 -- | Render a nickname in its hash-based color.
-coloredIdentifier :: Identifier -> Image
-coloredIdentifier ident =
-  text' (withForeColor defAttr (identifierColor ident)) (idText ident)
+coloredIdentifier :: [Identifier] {- ^ my nicknames -} -> Identifier -> Image
+coloredIdentifier myNicks ident =
+  text' (withForeColor defAttr color) (idText ident)
+  where
+    color
+      | ident `elem` myNicks = red
+      | otherwise            = identifierColor ident
 
 -- | Render an a full user. In normal mode only the nickname will be rendered.
 -- If detailed mode the full user info including the username and hostname parts
 -- will be rendered. The nickname will be colored.
-coloredUserInfo :: RenderMode -> UserInfo -> Image
-coloredUserInfo NormalRender ui = coloredIdentifier (userNick ui)
-coloredUserInfo DetailedRender ui = horizCat
-  [ coloredIdentifier (userNick ui)
+coloredUserInfo :: RenderMode -> [Identifier] -> UserInfo -> Image
+coloredUserInfo NormalRender myNicks ui = coloredIdentifier myNicks (userNick ui)
+coloredUserInfo DetailedRender myNicks ui = horizCat
+  [ coloredIdentifier myNicks (userNick ui)
   , foldMap (\user -> char defAttr '!' <|> text' quietAttr user) (userName ui)
   , foldMap (\host -> char defAttr '@' <|> text' quietAttr host) (userHost ui)
   ]
@@ -263,20 +297,26 @@
 -- control characters in it then the text will be rendered according to
 -- the formatting codes. Otherwise the nicknames in the message are
 -- highlighted.
-parseIrcTextWithNicks :: [Identifier] -> Text -> Image
-parseIrcTextWithNicks nicks txt
+parseIrcTextWithNicks ::
+  [Identifier] {- ^ my nicks -} ->
+  [Identifier] {- ^ other nicks -} ->
+  Text -> Image
+parseIrcTextWithNicks myNicks nicks txt
   | Text.any isControl txt = parseIrcText txt
-  | otherwise              = highlightNicks nicks txt
+  | otherwise              = highlightNicks myNicks nicks txt
 
 -- | Given a list of nicknames and a chat message, this will generate
 -- an image where all of the occurrences of those nicknames are colored.
-highlightNicks :: [Identifier] -> Text -> Image
-highlightNicks nicks txt = horizCat (highlight1 <$> txtParts)
+highlightNicks ::
+  [Identifier] {- ^ my nicks -} ->
+  [Identifier] {- ^ other nicks -} ->
+  Text -> Image
+highlightNicks myNicks nicks txt = horizCat (highlight1 <$> txtParts)
   where
     nickSet = HashSet.fromList nicks
     txtParts = nickSplit txt
     highlight1 part
-      | HashSet.member partId nickSet = coloredIdentifier partId
+      | HashSet.member partId nickSet = coloredIdentifier myNicks partId
       | otherwise                     = text' defAttr part
       where
         partId = mkId part
diff --git a/src/Client/Image/UserList.hs b/src/Client/Image/UserList.hs
--- a/src/Client/Image/UserList.hs
+++ b/src/Client/Image/UserList.hs
@@ -1,3 +1,4 @@
+{-# Language OverloadedStrings #-}
 {-|
 Module      : Client.Image.UserList
 Description : Line renderers for channel user list view
@@ -28,13 +29,18 @@
   Identifier  {- ^ Focused channel name -} ->
   ClientState -> [Image]
 userListImages network channel st =
-    [horizCat (intersperse gap (map renderUser usersList))]
+    [countImage, horizCat (intersperse gap (map renderUser usersList))]
   where
+    countImage = text' (withForeColor defAttr green) "Users: " <|>
+                 string defAttr (show (HashMap.size usersHashMap))
+
     matcher = clientMatcher st
 
+    myNicks = toListOf (clientConnection network . csNick) st
+
     renderUser (ident, sigils) =
       string (withForeColor defAttr cyan) sigils <|>
-      coloredIdentifier ident
+      coloredIdentifier myNicks ident
 
     gap = char defAttr ' '
 
@@ -58,9 +64,11 @@
   where
     matcher = clientMatcher st
 
+    myNicks = toListOf (clientConnection network . csNick) st
+
     renderEntry (info, sigils) =
       string (withForeColor defAttr cyan) sigils <|>
-      coloredUserInfo DetailedRender info
+      coloredUserInfo DetailedRender myNicks info
 
     matcher' (info,sigils) =
       matcher (Text.pack sigils `Text.append` renderUserInfo info)
diff --git a/src/Client/NetworkConnection.hs b/src/Client/NetworkConnection.hs
--- a/src/Client/NetworkConnection.hs
+++ b/src/Client/NetworkConnection.hs
@@ -35,6 +35,7 @@
 import           Control.Concurrent.STM
 import           Control.Concurrent.Async
 import           Control.Exception
+import           Control.Lens
 import           Control.Monad
 import           Data.ByteString (ByteString)
 import qualified Data.ByteString as B
@@ -126,7 +127,9 @@
   TQueue ByteString ->
   IO ()
 startConnection network cxt settings onInput outQueue =
-  do rate <- newRateLimitDefault
+  do rate <- newRateLimit
+               (view ssFloodPenalty settings)
+               (view ssFloodThreshold settings)
      withConnection cxt settings $ \h ->
        withAsync (sendLoop h outQueue rate)      $ \sender ->
        withAsync (receiveLoop network h onInput) $ \receiver ->
diff --git a/src/Client/ServerSettings.hs b/src/Client/ServerSettings.hs
--- a/src/Client/ServerSettings.hs
+++ b/src/Client/ServerSettings.hs
@@ -34,6 +34,8 @@
   , ssSocksPort
   , ssServerCerts
   , ssChanservChannels
+  , ssFloodPenalty
+  , ssFloodThreshold
 
   -- * Load function
   , loadDefaultServerSettings
@@ -50,24 +52,26 @@
 import Network.Socket (HostName, PortNumber)
 
 data ServerSettings = ServerSettings
-  { _ssNick          :: !Text -- ^ connection nickname
-  , _ssUser          :: !Text -- ^ connection username
-  , _ssReal          :: !Text -- ^ connection realname / GECOS
-  , _ssUserInfo      :: !Text -- ^ CTCP userinfo
-  , _ssPassword      :: !(Maybe Text) -- ^ server password
-  , _ssSaslUsername  :: !(Maybe Text) -- ^ SASL username
-  , _ssSaslPassword  :: !(Maybe Text) -- ^ SASL password
-  , _ssHostName      :: !HostName -- ^ server hostname
-  , _ssPort          :: !(Maybe PortNumber) -- ^ server port
-  , _ssTls           :: !Bool -- ^ use TLS to connect
-  , _ssTlsInsecure   :: !Bool -- ^ disable certificate checking
-  , _ssTlsClientCert :: !(Maybe FilePath) -- ^ path to client TLS certificate
-  , _ssTlsClientKey  :: !(Maybe FilePath) -- ^ path to client TLS key
-  , _ssConnectCmds   :: ![Text] -- ^ raw IRC messages to transmit upon successful connection
-  , _ssSocksHost     :: !(Maybe HostName) -- ^ hostname of SOCKS proxy
-  , _ssSocksPort     :: !PortNumber -- ^ port of SOCKS proxy
-  , _ssServerCerts   :: ![FilePath] -- ^ additional CA certificates for validating server
+  { _ssNick             :: !Text -- ^ connection nickname
+  , _ssUser             :: !Text -- ^ connection username
+  , _ssReal             :: !Text -- ^ connection realname / GECOS
+  , _ssUserInfo         :: !Text -- ^ CTCP userinfo
+  , _ssPassword         :: !(Maybe Text) -- ^ server password
+  , _ssSaslUsername     :: !(Maybe Text) -- ^ SASL username
+  , _ssSaslPassword     :: !(Maybe Text) -- ^ SASL password
+  , _ssHostName         :: !HostName -- ^ server hostname
+  , _ssPort             :: !(Maybe PortNumber) -- ^ server port
+  , _ssTls              :: !Bool -- ^ use TLS to connect
+  , _ssTlsInsecure      :: !Bool -- ^ disable certificate checking
+  , _ssTlsClientCert    :: !(Maybe FilePath) -- ^ path to client TLS certificate
+  , _ssTlsClientKey     :: !(Maybe FilePath) -- ^ path to client TLS key
+  , _ssConnectCmds      :: ![Text] -- ^ raw IRC messages to transmit upon successful connection
+  , _ssSocksHost        :: !(Maybe HostName) -- ^ hostname of SOCKS proxy
+  , _ssSocksPort        :: !PortNumber -- ^ port of SOCKS proxy
+  , _ssServerCerts      :: ![FilePath] -- ^ additional CA certificates for validating server
   , _ssChanservChannels :: ![Identifier] -- ^ Channels with chanserv permissions
+  , _ssFloodPenalty     :: !Int -- ^ Flood limiter penalty (seconds)
+  , _ssFloodThreshold   :: !Int -- ^ Flood limited threshold (seconds)
   }
   deriving Show
 
@@ -100,4 +104,6 @@
        , _ssSocksPort     = 1080
        , _ssServerCerts   = []
        , _ssChanservChannels = []
+       , _ssFloodPenalty     = 2 -- RFC 1459 defaults
+       , _ssFloodThreshold   = 10
        }
diff --git a/src/Client/State.hs b/src/Client/State.hs
--- a/src/Client/State.hs
+++ b/src/Client/State.hs
@@ -83,7 +83,6 @@
 import           Data.Text (Text)
 import qualified Data.Text as Text
 import qualified Data.Text.ICU as ICU
-import           Data.Time
 import           Graphics.Vty
 import           Irc.Identifier
 import           Irc.Message
@@ -106,6 +105,7 @@
 
 data ClientSubfocus
   = FocusMessages
+  | FocusInfo
   | FocusUsers
   | FocusMasks !Char
   deriving Eq
@@ -201,10 +201,12 @@
   where
     focus = ChannelFocus network channel'
     wl = toWindowLine rendParams msg
+    myNicks = toListOf (clientConnection network . csNick) st
     rendParams = MessageRendererParams
       { rendStatusMsg  = statusModes
       , rendUserSigils = computeMsgLineModes network channel' msg st
       , rendNicks      = channelUserList network channel' st
+      , rendMyNicks    = myNicks
       }
 
     -- on failure returns mempty/""
@@ -242,7 +244,7 @@
                           | otherwise   -> WLNormal
         Error{}         -> WLImportant
         Reply cmd _ ->
-          case replyType cmd of
+          case replyCodeType (replyCodeInfo cmd) of
             ErrorReply -> WLImportant
             _          -> WLNormal
         _               -> WLBoring
diff --git a/src/Irc/Codes.hs b/src/Irc/Codes.hs
--- a/src/Irc/Codes.hs
+++ b/src/Irc/Codes.hs
@@ -1,1337 +1,854 @@
-{-# Language PatternSynonyms #-}
-
-{-|
-Module      : Irc.Codes
-Description : Helpers for interpreting IRC reply codes
-Copyright   : (c) Eric Mertens, 2016
-License     : ISC
-Maintainer  : emertens@gmail.com
-
-This module defines support for working with IRC's numeric reply
-codes. Pattern synonyms are provided for each of the possible IRC reply codes.
-
-Reply code information was extracted from https://www.alien.net.au/irc/irc2numerics.html
-
--}
-
-module Irc.Codes where
-
--- | Categories for reply codes
-data ReplyType
-  = ClientServerReply -- ^ 0-99 Messages between client and server
-  | CommandReply      -- ^ 200-399 Responses to commands
-  | ErrorReply        -- ^ 200-399 Errors
-  | CustomReply       -- ^ Uncategorized
-
--- | Categorize replies according to the ranges provided in RFC 2812
-replyType :: Int {- reply code -} -> ReplyType
-replyType x
-  | 000 <= x, x < 100 = ClientServerReply
-  | 200 <= x, x < 400 = CommandReply
-  | 400 <= x, x < 600 = ErrorReply
-  | otherwise         = CustomReply
-
-pattern RPL_WELCOME                 :: Int
-pattern RPL_WELCOME                 = 001
-
-pattern RPL_YOURHOST                :: Int
-pattern RPL_YOURHOST                = 002
-
-pattern RPL_CREATED                 :: Int
-pattern RPL_CREATED                 = 003
-
-pattern RPL_MYINFO                  :: Int
-pattern RPL_MYINFO                  = 004
-
-pattern RPL_ISUPPORT                :: Int
-pattern RPL_ISUPPORT                = 005
-
-pattern RPL_SNOMASK                 :: Int
-pattern RPL_SNOMASK                 = 008
-
-pattern RPL_STATMEMTOT              :: Int
-pattern RPL_STATMEMTOT              = 009
-
-pattern RPL_BOUNCE                  :: Int
-pattern RPL_BOUNCE                  = 010
-
-pattern RPL_STATMEM                 :: Int
-pattern RPL_STATMEM                 = 010
-
-pattern RPL_YOURCOOKIE              :: Int
-pattern RPL_YOURCOOKIE              = 014
-
-pattern RPL_YOURID                  :: Int
-pattern RPL_YOURID                  = 042
-
-pattern RPL_SAVENICK                :: Int
-pattern RPL_SAVENICK                = 043
-
-pattern RPL_ATTEMPTINGJUNC          :: Int
-pattern RPL_ATTEMPTINGJUNC          = 050
-
-pattern RPL_ATTEMPTINGREROUTE       :: Int
-pattern RPL_ATTEMPTINGREROUTE       = 051
-
-pattern RPL_TRACELINK               :: Int
-pattern RPL_TRACELINK               = 200
-
-pattern RPL_TRACECONNECTING         :: Int
-pattern RPL_TRACECONNECTING         = 201
-
-pattern RPL_TRACEHANDSHAKE          :: Int
-pattern RPL_TRACEHANDSHAKE          = 202
-
-pattern RPL_TRACEUNKNOWN            :: Int
-pattern RPL_TRACEUNKNOWN            = 203
-
-pattern RPL_TRACEOPERATOR           :: Int
-pattern RPL_TRACEOPERATOR           = 204
-
-pattern RPL_TRACEUSER               :: Int
-pattern RPL_TRACEUSER               = 205
-
-pattern RPL_TRACESERVER             :: Int
-pattern RPL_TRACESERVER             = 206
-
-pattern RPL_TRACESERVICE            :: Int
-pattern RPL_TRACESERVICE            = 207
-
-pattern RPL_TRACENEWTYPE            :: Int
-pattern RPL_TRACENEWTYPE            = 208
-
-pattern RPL_TRACECLASS              :: Int
-pattern RPL_TRACECLASS              = 209
-
-pattern RPL_TRACERECONNECT          :: Int
-pattern RPL_TRACERECONNECT          = 210
-
-pattern RPL_STATS                   :: Int
-pattern RPL_STATS                   = 210
-
-pattern RPL_STATSLINKINFO           :: Int
-pattern RPL_STATSLINKINFO           = 211
-
-pattern RPL_STATSCOMMANDS           :: Int
-pattern RPL_STATSCOMMANDS           = 212
-
-pattern RPL_STATSCLINE              :: Int
-pattern RPL_STATSCLINE              = 213
-
-pattern RPL_STATSILINE              :: Int
-pattern RPL_STATSILINE              = 215
-
-pattern RPL_STATSKLINE              :: Int
-pattern RPL_STATSKLINE              = 216
-
-pattern RPL_STATSYLINE              :: Int
-pattern RPL_STATSYLINE              = 218
-
-pattern RPL_ENDOFSTATS              :: Int
-pattern RPL_ENDOFSTATS              = 219
-
-pattern RPL_UMODEIS                 :: Int
-pattern RPL_UMODEIS                 = 221
-
-pattern RPL_SQLINE_NICK             :: Int
-pattern RPL_SQLINE_NICK             = 222
-
-pattern RPL_STATSDLINE              :: Int
-pattern RPL_STATSDLINE              = 225
-
-pattern RPL_STATSZLINE              :: Int
-pattern RPL_STATSZLINE              = 225
-
-pattern RPL_STATSCOUNT              :: Int
-pattern RPL_STATSCOUNT              = 226
-
-pattern RPL_SERVICEINFO             :: Int
-pattern RPL_SERVICEINFO             = 231
-
-pattern RPL_ENDOFSERVICES           :: Int
-pattern RPL_ENDOFSERVICES           = 232
-
-pattern RPL_SERVICE                 :: Int
-pattern RPL_SERVICE                 = 233
-
-pattern RPL_SERVLIST                :: Int
-pattern RPL_SERVLIST                = 234
-
-pattern RPL_SERVLISTEND             :: Int
-pattern RPL_SERVLISTEND             = 235
-
-pattern RPL_STATSVERBOSE            :: Int
-pattern RPL_STATSVERBOSE            = 236
-
-pattern RPL_STATSIAUTH              :: Int
-pattern RPL_STATSIAUTH              = 239
-
-pattern RPL_STATSLLINE              :: Int
-pattern RPL_STATSLLINE              = 241
-
-pattern RPL_STATSUPTIME             :: Int
-pattern RPL_STATSUPTIME             = 242
-
-pattern RPL_STATSOLINE              :: Int
-pattern RPL_STATSOLINE              = 243
-
-pattern RPL_STATSHLINE              :: Int
-pattern RPL_STATSHLINE              = 244
-
-pattern RPL_STATSSLINE              :: Int
-pattern RPL_STATSSLINE              = 245
-
-pattern RPL_STATSPING               :: Int
-pattern RPL_STATSPING               = 246
-
-pattern RPL_STATSDEFINE             :: Int
-pattern RPL_STATSDEFINE             = 248
-
-pattern RPL_STATSDEBUG              :: Int
-pattern RPL_STATSDEBUG              = 249
-
-pattern RPL_STATSCONN               :: Int
-pattern RPL_STATSCONN               = 250
-
-pattern RPL_LUSERCLIENT             :: Int
-pattern RPL_LUSERCLIENT             = 251
-
-pattern RPL_LUSEROP                 :: Int
-pattern RPL_LUSEROP                 = 252
-
-pattern RPL_LUSERUNKNOWN            :: Int
-pattern RPL_LUSERUNKNOWN            = 253
-
-pattern RPL_LUSERCHANNELS           :: Int
-pattern RPL_LUSERCHANNELS           = 254
-
-pattern RPL_LUSERME                 :: Int
-pattern RPL_LUSERME                 = 255
-
-pattern RPL_ADMINME                 :: Int
-pattern RPL_ADMINME                 = 256
-
-pattern RPL_ADMINLOC1               :: Int
-pattern RPL_ADMINLOC1               = 257
-
-pattern RPL_ADMINLOC2               :: Int
-pattern RPL_ADMINLOC2               = 258
-
-pattern RPL_ADMINEMAIL              :: Int
-pattern RPL_ADMINEMAIL              = 259
-
-pattern RPL_TRACELOG                :: Int
-pattern RPL_TRACELOG                = 261
-
-pattern RPL_TRACEPING               :: Int
-pattern RPL_TRACEPING               = 262
-
-pattern RPL_TRACEEND                :: Int
-pattern RPL_TRACEEND                = 262
-
-pattern RPL_TRYAGAIN                :: Int
-pattern RPL_TRYAGAIN                = 263
-
-pattern RPL_LOCALUSERS              :: Int
-pattern RPL_LOCALUSERS              = 265
-
-pattern RPL_GLOBALUSERS             :: Int
-pattern RPL_GLOBALUSERS             = 266
-
-pattern RPL_START_NETSTAT           :: Int
-pattern RPL_START_NETSTAT           = 267
-
-pattern RPL_NETSTAT                 :: Int
-pattern RPL_NETSTAT                 = 268
-
-pattern RPL_END_NETSTAT             :: Int
-pattern RPL_END_NETSTAT             = 269
-
-pattern RPL_PRIVS                   :: Int
-pattern RPL_PRIVS                   = 270
-
-pattern RPL_SILELIST                :: Int
-pattern RPL_SILELIST                = 271
-
-pattern RPL_ENDOFSILELIST           :: Int
-pattern RPL_ENDOFSILELIST           = 272
-
-pattern RPL_NOTIFY                  :: Int
-pattern RPL_NOTIFY                  = 273
-
-pattern RPL_ENDNOTIFY               :: Int
-pattern RPL_ENDNOTIFY               = 274
-
-pattern RPL_STATSDELTA              :: Int
-pattern RPL_STATSDELTA              = 274
-
-pattern RPL_VCHANEXIST              :: Int
-pattern RPL_VCHANEXIST              = 276
-
-pattern RPL_VCHANLIST               :: Int
-pattern RPL_VCHANLIST               = 277
-
-pattern RPL_VCHANHELP               :: Int
-pattern RPL_VCHANHELP               = 278
-
-pattern RPL_GLIST                   :: Int
-pattern RPL_GLIST                   = 280
-
-pattern RPL_ENDOFGLIST              :: Int
-pattern RPL_ENDOFGLIST              = 281
-
-pattern RPL_ACCEPTLIST              :: Int
-pattern RPL_ACCEPTLIST              = 281
-
-pattern RPL_ENDOFACCEPT             :: Int
-pattern RPL_ENDOFACCEPT             = 282
-
-pattern RPL_JUPELIST                :: Int
-pattern RPL_JUPELIST                = 282
-
-pattern RPL_ENDOFJUPELIST           :: Int
-pattern RPL_ENDOFJUPELIST           = 283
-
-pattern RPL_FEATURE                 :: Int
-pattern RPL_FEATURE                 = 284
-
-pattern RPL_GLIST_HASH              :: Int
-pattern RPL_GLIST_HASH              = 285
-
-pattern RPL_CHANINFO_HANDLE         :: Int
-pattern RPL_CHANINFO_HANDLE         = 285
-
-pattern RPL_NEWHOSTIS               :: Int
-pattern RPL_NEWHOSTIS               = 285
-
-pattern RPL_CHANINFO_USERS          :: Int
-pattern RPL_CHANINFO_USERS          = 286
-
-pattern RPL_CHKHEAD                 :: Int
-pattern RPL_CHKHEAD                 = 286
-
-pattern RPL_CHANINFO_CHOPS          :: Int
-pattern RPL_CHANINFO_CHOPS          = 287
-
-pattern RPL_CHANUSER                :: Int
-pattern RPL_CHANUSER                = 287
-
-pattern RPL_CHANINFO_VOICES         :: Int
-pattern RPL_CHANINFO_VOICES         = 288
-
-pattern RPL_PATCHHEAD               :: Int
-pattern RPL_PATCHHEAD               = 288
-
-pattern RPL_CHANINFO_AWAY           :: Int
-pattern RPL_CHANINFO_AWAY           = 289
-
-pattern RPL_PATCHCON                :: Int
-pattern RPL_PATCHCON                = 289
-
-pattern RPL_CHANINFO_OPERS          :: Int
-pattern RPL_CHANINFO_OPERS          = 290
-
-pattern RPL_HELPHDR                 :: Int
-pattern RPL_HELPHDR                 = 290
-
-pattern RPL_DATASTR                 :: Int
-pattern RPL_DATASTR                 = 290
-
-pattern RPL_CHANINFO_BANNED         :: Int
-pattern RPL_CHANINFO_BANNED         = 291
-
-pattern RPL_HELPOP                  :: Int
-pattern RPL_HELPOP                  = 291
-
-pattern RPL_ENDOFCHECK              :: Int
-pattern RPL_ENDOFCHECK              = 291
-
-pattern RPL_CHANINFO_BANS           :: Int
-pattern RPL_CHANINFO_BANS           = 292
-
-pattern RPL_HELPTLR                 :: Int
-pattern RPL_HELPTLR                 = 292
-
-pattern RPL_CHANINFO_INVITE         :: Int
-pattern RPL_CHANINFO_INVITE         = 293
-
-pattern RPL_HELPHLP                 :: Int
-pattern RPL_HELPHLP                 = 293
-
-pattern RPL_CHANINFO_INVITES        :: Int
-pattern RPL_CHANINFO_INVITES        = 294
-
-pattern RPL_HELPFWD                 :: Int
-pattern RPL_HELPFWD                 = 294
-
-pattern RPL_CHANINFO_KICK           :: Int
-pattern RPL_CHANINFO_KICK           = 295
-
-pattern RPL_HELPIGN                 :: Int
-pattern RPL_HELPIGN                 = 295
-
-pattern RPL_CHANINFO_KICKS          :: Int
-pattern RPL_CHANINFO_KICKS          = 296
-
-pattern RPL_END_CHANINFO            :: Int
-pattern RPL_END_CHANINFO            = 299
-
-pattern RPL_NONE                    :: Int
-pattern RPL_NONE                    = 300
-
-pattern RPL_AWAY                    :: Int
-pattern RPL_AWAY                    = 301
-
-pattern RPL_USERHOST                :: Int
-pattern RPL_USERHOST                = 302
-
-pattern RPL_ISON                    :: Int
-pattern RPL_ISON                    = 303
-
-pattern RPL_TEXT                    :: Int
-pattern RPL_TEXT                    = 304
-
-pattern RPL_UNAWAY                  :: Int
-pattern RPL_UNAWAY                  = 305
-
-pattern RPL_NOWAWAY                 :: Int
-pattern RPL_NOWAWAY                 = 306
-
-pattern RPL_WHOISREGNICK            :: Int
-pattern RPL_WHOISREGNICK            = 307
-
-pattern RPL_SUSERHOST               :: Int
-pattern RPL_SUSERHOST               = 307
-
-pattern RPL_NOTIFYACTION            :: Int
-pattern RPL_NOTIFYACTION            = 308
-
-pattern RPL_WHOISADMIN              :: Int
-pattern RPL_WHOISADMIN              = 308
-
-pattern RPL_NICKTRACE               :: Int
-pattern RPL_NICKTRACE               = 309
-
-pattern RPL_WHOISSADMIN             :: Int
-pattern RPL_WHOISSADMIN             = 309
-
-pattern RPL_WHOISHELPER             :: Int
-pattern RPL_WHOISHELPER             = 309
-
-pattern RPL_WHOISSVCMSG             :: Int
-pattern RPL_WHOISSVCMSG             = 310
-
-pattern RPL_WHOISHELPOP             :: Int
-pattern RPL_WHOISHELPOP             = 310
-
-pattern RPL_WHOISSERVICE            :: Int
-pattern RPL_WHOISSERVICE            = 310
-
-pattern RPL_WHOISUSER               :: Int
-pattern RPL_WHOISUSER               = 311
-
-pattern RPL_WHOISSERVER             :: Int
-pattern RPL_WHOISSERVER             = 312
-
-pattern RPL_WHOISOPERATOR           :: Int
-pattern RPL_WHOISOPERATOR           = 313
-
-pattern RPL_WHOWASUSER              :: Int
-pattern RPL_WHOWASUSER              = 314
-
-pattern RPL_ENDOFWHO                :: Int
-pattern RPL_ENDOFWHO                = 315
-
-pattern RPL_WHOISCHANOP             :: Int
-pattern RPL_WHOISCHANOP             = 316
-
-pattern RPL_WHOISIDLE               :: Int
-pattern RPL_WHOISIDLE               = 317
-
-pattern RPL_ENDOFWHOIS              :: Int
-pattern RPL_ENDOFWHOIS              = 318
-
-pattern RPL_WHOISCHANNELS           :: Int
-pattern RPL_WHOISCHANNELS           = 319
-
-pattern RPL_WHOISVIRT               :: Int
-pattern RPL_WHOISVIRT               = 320
-
-pattern RPL_WHOIS_HIDDEN            :: Int
-pattern RPL_WHOIS_HIDDEN            = 320
-
-pattern RPL_WHOISSPECIAL            :: Int
-pattern RPL_WHOISSPECIAL            = 320
-
-pattern RPL_LISTSTART               :: Int
-pattern RPL_LISTSTART               = 321
-
-pattern RPL_LIST                    :: Int
-pattern RPL_LIST                    = 322
-
-pattern RPL_LISTEND                 :: Int
-pattern RPL_LISTEND                 = 323
-
-pattern RPL_CHANNELMODEIS           :: Int
-pattern RPL_CHANNELMODEIS           = 324
-
-pattern RPL_UNIQOPIS                :: Int
-pattern RPL_UNIQOPIS                = 325
-
-pattern RPL_CHANNELPASSIS           :: Int
-pattern RPL_CHANNELPASSIS           = 325
-
-pattern RPL_NOCHANPASS              :: Int
-pattern RPL_NOCHANPASS              = 326
-
-pattern RPL_CHPASSUNKNOWN           :: Int
-pattern RPL_CHPASSUNKNOWN           = 327
-
-pattern RPL_CHANNEL_URL             :: Int
-pattern RPL_CHANNEL_URL             = 328
-
-pattern RPL_CREATIONTIME            :: Int
-pattern RPL_CREATIONTIME            = 329
-
-pattern RPL_WHOWAS_TIME             :: Int
-pattern RPL_WHOWAS_TIME             = 330
-
-pattern RPL_WHOISACCOUNT            :: Int
-pattern RPL_WHOISACCOUNT            = 330
-
-pattern RPL_NOTOPIC                 :: Int
-pattern RPL_NOTOPIC                 = 331
-
-pattern RPL_TOPIC                   :: Int
-pattern RPL_TOPIC                   = 332
-
-pattern RPL_TOPICWHOTIME            :: Int
-pattern RPL_TOPICWHOTIME            = 333
-
-pattern RPL_LISTUSAGE               :: Int
-pattern RPL_LISTUSAGE               = 334
-
-pattern RPL_COMMANDSYNTAX           :: Int
-pattern RPL_COMMANDSYNTAX           = 334
-
-pattern RPL_LISTSYNTAX              :: Int
-pattern RPL_LISTSYNTAX              = 334
-
-pattern RPL_CHANPASSOK              :: Int
-pattern RPL_CHANPASSOK              = 338
-
-pattern RPL_WHOISACTUALLY           :: Int
-pattern RPL_WHOISACTUALLY           = 338
-
-pattern RPL_BADCHANPASS             :: Int
-pattern RPL_BADCHANPASS             = 339
-
-pattern RPL_INVITING                :: Int
-pattern RPL_INVITING                = 341
-
-pattern RPL_SUMMONING               :: Int
-pattern RPL_SUMMONING               = 342
-
-pattern RPL_INVITED                 :: Int
-pattern RPL_INVITED                 = 345
-
-pattern RPL_INVITELIST              :: Int
-pattern RPL_INVITELIST              = 346
-
-pattern RPL_ENDOFINVITELIST         :: Int
-pattern RPL_ENDOFINVITELIST         = 347
-
-pattern RPL_EXCEPTLIST              :: Int
-pattern RPL_EXCEPTLIST              = 348
-
-pattern RPL_ENDOFEXCEPTLIST         :: Int
-pattern RPL_ENDOFEXCEPTLIST         = 349
-
-pattern RPL_VERSION                 :: Int
-pattern RPL_VERSION                 = 351
-
-pattern RPL_WHOREPLY                :: Int
-pattern RPL_WHOREPLY                = 352
-
-pattern RPL_NAMREPLY                :: Int
-pattern RPL_NAMREPLY                = 353
-
-pattern RPL_WHOSPCRPL               :: Int
-pattern RPL_WHOSPCRPL               = 354
-
-pattern RPL_NAMREPLY_               :: Int
-pattern RPL_NAMREPLY_               = 355
-
-pattern RPL_KILLDONE                :: Int
-pattern RPL_KILLDONE                = 361
-
-pattern RPL_CLOSING                 :: Int
-pattern RPL_CLOSING                 = 362
-
-pattern RPL_CLOSEEND                :: Int
-pattern RPL_CLOSEEND                = 363
-
-pattern RPL_LINKS                   :: Int
-pattern RPL_LINKS                   = 364
-
-pattern RPL_ENDOFLINKS              :: Int
-pattern RPL_ENDOFLINKS              = 365
-
-pattern RPL_ENDOFNAMES              :: Int
-pattern RPL_ENDOFNAMES              = 366
-
-pattern RPL_BANLIST                 :: Int
-pattern RPL_BANLIST                 = 367
-
-pattern RPL_ENDOFBANLIST            :: Int
-pattern RPL_ENDOFBANLIST            = 368
-
-pattern RPL_ENDOFWHOWAS             :: Int
-pattern RPL_ENDOFWHOWAS             = 369
-
-pattern RPL_INFO                    :: Int
-pattern RPL_INFO                    = 371
-
-pattern RPL_MOTD                    :: Int
-pattern RPL_MOTD                    = 372
-
-pattern RPL_INFOSTART               :: Int
-pattern RPL_INFOSTART               = 373
-
-pattern RPL_ENDOFINFO               :: Int
-pattern RPL_ENDOFINFO               = 374
-
-pattern RPL_MOTDSTART               :: Int
-pattern RPL_MOTDSTART               = 375
-
-pattern RPL_ENDOFMOTD               :: Int
-pattern RPL_ENDOFMOTD               = 376
-
-pattern RPL_KICKEXPIRED             :: Int
-pattern RPL_KICKEXPIRED             = 377
-
-pattern RPL_SPAM                    :: Int
-pattern RPL_SPAM                    = 377
-
-pattern RPL_BANEXPIRED              :: Int
-pattern RPL_BANEXPIRED              = 378
-
-pattern RPL_WHOISHOST               :: Int
-pattern RPL_WHOISHOST               = 378
-
-pattern RPL_KICKLINKED              :: Int
-pattern RPL_KICKLINKED              = 379
-
-pattern RPL_BANLINKED               :: Int
-pattern RPL_BANLINKED               = 380
-
-pattern RPL_YOURHELPER              :: Int
-pattern RPL_YOURHELPER              = 380
-
-pattern RPL_YOUREOPER               :: Int
-pattern RPL_YOUREOPER               = 381
-
-pattern RPL_REHASHING               :: Int
-pattern RPL_REHASHING               = 382
-
-pattern RPL_YOURESERVICE            :: Int
-pattern RPL_YOURESERVICE            = 383
-
-pattern RPL_MYPORTIS                :: Int
-pattern RPL_MYPORTIS                = 384
-
-pattern RPL_NOTOPERANYMORE          :: Int
-pattern RPL_NOTOPERANYMORE          = 385
-
-pattern RPL_QLIST                   :: Int
-pattern RPL_QLIST                   = 386
-
-pattern RPL_IRCOPS                  :: Int
-pattern RPL_IRCOPS                  = 386
-
-pattern RPL_ENDOFQLIST              :: Int
-pattern RPL_ENDOFQLIST              = 387
-
-pattern RPL_ENDOFIRCOPS             :: Int
-pattern RPL_ENDOFIRCOPS             = 387
-
-pattern RPL_TIME                    :: Int
-pattern RPL_TIME                    = 391
-
-pattern RPL_USERSSTART              :: Int
-pattern RPL_USERSSTART              = 392
-
-pattern RPL_USERS                   :: Int
-pattern RPL_USERS                   = 393
-
-pattern RPL_ENDOFUSERS              :: Int
-pattern RPL_ENDOFUSERS              = 394
-
-pattern RPL_NOUSERS                 :: Int
-pattern RPL_NOUSERS                 = 395
-
-pattern RPL_HOSTHIDDEN              :: Int
-pattern RPL_HOSTHIDDEN              = 396
-
-pattern ERR_UNKNOWNERROR            :: Int
-pattern ERR_UNKNOWNERROR            = 400
-
-pattern ERR_NOSUCHNICK              :: Int
-pattern ERR_NOSUCHNICK              = 401
-
-pattern ERR_NOSUCHSERVER            :: Int
-pattern ERR_NOSUCHSERVER            = 402
-
-pattern ERR_NOSUCHCHANNEL           :: Int
-pattern ERR_NOSUCHCHANNEL           = 403
-
-pattern ERR_CANNOTSENDTOCHAN        :: Int
-pattern ERR_CANNOTSENDTOCHAN        = 404
-
-pattern ERR_TOOMANYCHANNELS         :: Int
-pattern ERR_TOOMANYCHANNELS         = 405
-
-pattern ERR_WASNOSUCHNICK           :: Int
-pattern ERR_WASNOSUCHNICK           = 406
-
-pattern ERR_TOOMANYTARGETS          :: Int
-pattern ERR_TOOMANYTARGETS          = 407
-
-pattern ERR_NOSUCHSERVICE           :: Int
-pattern ERR_NOSUCHSERVICE           = 408
-
-pattern ERR_NOCOLORSONCHAN          :: Int
-pattern ERR_NOCOLORSONCHAN          = 408
-
-pattern ERR_NOORIGIN                :: Int
-pattern ERR_NOORIGIN                = 409
-
-pattern ERR_NORECIPIENT             :: Int
-pattern ERR_NORECIPIENT             = 411
-
-pattern ERR_NOTEXTTOSEND            :: Int
-pattern ERR_NOTEXTTOSEND            = 412
-
-pattern ERR_NOTOPLEVEL              :: Int
-pattern ERR_NOTOPLEVEL              = 413
-
-pattern ERR_WILDTOPLEVEL            :: Int
-pattern ERR_WILDTOPLEVEL            = 414
-
-pattern ERR_BADMASK                 :: Int
-pattern ERR_BADMASK                 = 415
-
-pattern ERR_TOOMANYMATCHES          :: Int
-pattern ERR_TOOMANYMATCHES          = 416
-
-pattern ERR_QUERYTOOLONG            :: Int
-pattern ERR_QUERYTOOLONG            = 416
-
-pattern ERR_LENGTHTRUNCATED         :: Int
-pattern ERR_LENGTHTRUNCATED         = 419
-
-pattern ERR_UNKNOWNCOMMAND          :: Int
-pattern ERR_UNKNOWNCOMMAND          = 421
-
-pattern ERR_NOMOTD                  :: Int
-pattern ERR_NOMOTD                  = 422
-
-pattern ERR_NOADMININFO             :: Int
-pattern ERR_NOADMININFO             = 423
-
-pattern ERR_FILEERROR               :: Int
-pattern ERR_FILEERROR               = 424
-
-pattern ERR_NOOPERMOTD              :: Int
-pattern ERR_NOOPERMOTD              = 425
-
-pattern ERR_TOOMANYAWAY             :: Int
-pattern ERR_TOOMANYAWAY             = 429
-
-pattern ERR_EVENTNICKCHANGE         :: Int
-pattern ERR_EVENTNICKCHANGE         = 430
-
-pattern ERR_NONICKNAMEGIVEN         :: Int
-pattern ERR_NONICKNAMEGIVEN         = 431
-
-pattern ERR_ERRONEUSNICKNAME        :: Int
-pattern ERR_ERRONEUSNICKNAME        = 432
-
-pattern ERR_NICKNAMEINUSE           :: Int
-pattern ERR_NICKNAMEINUSE           = 433
-
-pattern ERR_SERVICENAMEINUSE        :: Int
-pattern ERR_SERVICENAMEINUSE        = 434
-
-pattern ERR_NORULES                 :: Int
-pattern ERR_NORULES                 = 434
-
-pattern ERR_SERVICECONFUSED         :: Int
-pattern ERR_SERVICECONFUSED         = 435
-
-pattern ERR_BANONCHAN               :: Int
-pattern ERR_BANONCHAN               = 435
-
-pattern ERR_NICKCOLLISION           :: Int
-pattern ERR_NICKCOLLISION           = 436
-
-pattern ERR_UNAVAILRESOURCE         :: Int
-pattern ERR_UNAVAILRESOURCE         = 437
-
-pattern ERR_BANNICKCHANGE           :: Int
-pattern ERR_BANNICKCHANGE           = 437
-
-pattern ERR_NICKTOOFAST             :: Int
-pattern ERR_NICKTOOFAST             = 438
-
-pattern ERR_DEAD                    :: Int
-pattern ERR_DEAD                    = 438
-
-pattern ERR_TARGETTOOFAST           :: Int
-pattern ERR_TARGETTOOFAST           = 439
-
-pattern ERR_SERVICESDOWN            :: Int
-pattern ERR_SERVICESDOWN            = 440
-
-pattern ERR_USERNOTINCHANNEL        :: Int
-pattern ERR_USERNOTINCHANNEL        = 441
-
-pattern ERR_NOTONCHANNEL            :: Int
-pattern ERR_NOTONCHANNEL            = 442
-
-pattern ERR_USERONCHANNEL           :: Int
-pattern ERR_USERONCHANNEL           = 443
-
-pattern ERR_NOLOGIN                 :: Int
-pattern ERR_NOLOGIN                 = 444
-
-pattern ERR_SUMMONDISABLED          :: Int
-pattern ERR_SUMMONDISABLED          = 445
-
-pattern ERR_USERSDISABLED           :: Int
-pattern ERR_USERSDISABLED           = 446
-
-pattern ERR_NONICKCHANGE            :: Int
-pattern ERR_NONICKCHANGE            = 447
-
-pattern ERR_NOTIMPLEMENTED          :: Int
-pattern ERR_NOTIMPLEMENTED          = 449
-
-pattern ERR_NOTREGISTERED           :: Int
-pattern ERR_NOTREGISTERED           = 451
-
-pattern ERR_IDCOLLISION             :: Int
-pattern ERR_IDCOLLISION             = 452
-
-pattern ERR_NICKLOST                :: Int
-pattern ERR_NICKLOST                = 453
-
-pattern ERR_HOSTILENAME             :: Int
-pattern ERR_HOSTILENAME             = 455
-
-pattern ERR_ACCEPTFULL              :: Int
-pattern ERR_ACCEPTFULL              = 456
-
-pattern ERR_ACCEPTEXIST             :: Int
-pattern ERR_ACCEPTEXIST             = 457
-
-pattern ERR_ACCEPTNOT               :: Int
-pattern ERR_ACCEPTNOT               = 458
-
-pattern ERR_NOHIDING                :: Int
-pattern ERR_NOHIDING                = 459
-
-pattern ERR_NOTFORHALFOPS           :: Int
-pattern ERR_NOTFORHALFOPS           = 460
-
-pattern ERR_NEEDMOREPARAMS          :: Int
-pattern ERR_NEEDMOREPARAMS          = 461
-
-pattern ERR_ALREADYREGISTERED       :: Int
-pattern ERR_ALREADYREGISTERED       = 462
-
-pattern ERR_NOPERMFORHOST           :: Int
-pattern ERR_NOPERMFORHOST           = 463
-
-pattern ERR_PASSWDMISMATCH          :: Int
-pattern ERR_PASSWDMISMATCH          = 464
-
-pattern ERR_YOUREBANNEDCREEP        :: Int
-pattern ERR_YOUREBANNEDCREEP        = 465
-
-pattern ERR_YOUWILLBEBANNED         :: Int
-pattern ERR_YOUWILLBEBANNED         = 466
-
-pattern ERR_KEYSET                  :: Int
-pattern ERR_KEYSET                  = 467
-
-pattern ERR_INVALIDUSERNAME         :: Int
-pattern ERR_INVALIDUSERNAME         = 468
-
-pattern ERR_ONLYSERVERSCANCHANGE    :: Int
-pattern ERR_ONLYSERVERSCANCHANGE    = 468
-
-pattern ERR_LINKSET                 :: Int
-pattern ERR_LINKSET                 = 469
-
-pattern ERR_LINKCHANNEL             :: Int
-pattern ERR_LINKCHANNEL             = 470
-
-pattern ERR_KICKEDFROMCHAN          :: Int
-pattern ERR_KICKEDFROMCHAN          = 470
-
-pattern ERR_CHANNELISFULL           :: Int
-pattern ERR_CHANNELISFULL           = 471
-
-pattern ERR_UNKNOWNMODE             :: Int
-pattern ERR_UNKNOWNMODE             = 472
-
-pattern ERR_INVITEONLYCHAN          :: Int
-pattern ERR_INVITEONLYCHAN          = 473
-
-pattern ERR_BANNEDFROMCHAN          :: Int
-pattern ERR_BANNEDFROMCHAN          = 474
-
-pattern ERR_BADCHANNELKEY           :: Int
-pattern ERR_BADCHANNELKEY           = 475
-
-pattern ERR_BADCHANMASK             :: Int
-pattern ERR_BADCHANMASK             = 476
-
-pattern ERR_NOCHANMODES             :: Int
-pattern ERR_NOCHANMODES             = 477
-
-pattern ERR_NEEDREGGEDNICK          :: Int
-pattern ERR_NEEDREGGEDNICK          = 477
-
-pattern ERR_BANLISTFULL             :: Int
-pattern ERR_BANLISTFULL             = 478
-
-pattern ERR_BADCHANNAME             :: Int
-pattern ERR_BADCHANNAME             = 479
-
-pattern ERR_LINKFAIL                :: Int
-pattern ERR_LINKFAIL                = 479
-
-pattern ERR_NOULINE                 :: Int
-pattern ERR_NOULINE                 = 480
-
-pattern ERR_CANNOTKNOCK             :: Int
-pattern ERR_CANNOTKNOCK             = 480
-
-pattern ERR_NOPRIVILEGES            :: Int
-pattern ERR_NOPRIVILEGES            = 481
-
-pattern ERR_CHANOPRIVSNEEDED        :: Int
-pattern ERR_CHANOPRIVSNEEDED        = 482
-
-pattern ERR_CANTKILLSERVER          :: Int
-pattern ERR_CANTKILLSERVER          = 483
-
-pattern ERR_RESTRICTED              :: Int
-pattern ERR_RESTRICTED              = 484
-
-pattern ERR_ISCHANSERVICE           :: Int
-pattern ERR_ISCHANSERVICE           = 484
-
-pattern ERR_DESYNC                  :: Int
-pattern ERR_DESYNC                  = 484
-
-pattern ERR_ATTACKDENY              :: Int
-pattern ERR_ATTACKDENY              = 484
-
-pattern ERR_UNIQOPRIVSNEEDED        :: Int
-pattern ERR_UNIQOPRIVSNEEDED        = 485
-
-pattern ERR_KILLDENY                :: Int
-pattern ERR_KILLDENY                = 485
-
-pattern ERR_CANTKICKADMIN           :: Int
-pattern ERR_CANTKICKADMIN           = 485
-
-pattern ERR_ISREALSERVICE           :: Int
-pattern ERR_ISREALSERVICE           = 485
-
-pattern ERR_NONONREG                :: Int
-pattern ERR_NONONREG                = 486
-
-pattern ERR_HTMDISABLED             :: Int
-pattern ERR_HTMDISABLED             = 486
-
-pattern ERR_ACCOUNTONLY             :: Int
-pattern ERR_ACCOUNTONLY             = 486
-
-pattern ERR_CHANTOORECENT           :: Int
-pattern ERR_CHANTOORECENT           = 487
-
-pattern ERR_MSGSERVICES             :: Int
-pattern ERR_MSGSERVICES             = 487
-
-pattern ERR_TSLESSCHAN              :: Int
-pattern ERR_TSLESSCHAN              = 488
-
-pattern ERR_VOICENEEDED             :: Int
-pattern ERR_VOICENEEDED             = 489
-
-pattern ERR_SECUREONLYCHAN          :: Int
-pattern ERR_SECUREONLYCHAN          = 489
-
-pattern ERR_NOOPERHOST              :: Int
-pattern ERR_NOOPERHOST              = 491
-
-pattern ERR_NOSERVICEHOST           :: Int
-pattern ERR_NOSERVICEHOST           = 492
-
-pattern ERR_NOFEATURE               :: Int
-pattern ERR_NOFEATURE               = 493
-
-pattern ERR_BADFEATURE              :: Int
-pattern ERR_BADFEATURE              = 494
-
-pattern ERR_BADLOGTYPE              :: Int
-pattern ERR_BADLOGTYPE              = 495
-
-pattern ERR_BADLOGSYS               :: Int
-pattern ERR_BADLOGSYS               = 496
-
-pattern ERR_BADLOGVALUE             :: Int
-pattern ERR_BADLOGVALUE             = 497
-
-pattern ERR_ISOPERLCHAN             :: Int
-pattern ERR_ISOPERLCHAN             = 498
-
-pattern ERR_CHANOWNPRIVNEEDED       :: Int
-pattern ERR_CHANOWNPRIVNEEDED       = 499
-
-pattern ERR_UMODEUNKNOWNFLAG        :: Int
-pattern ERR_UMODEUNKNOWNFLAG        = 501
-
-pattern ERR_USERSDONTMATCH          :: Int
-pattern ERR_USERSDONTMATCH          = 502
-
-pattern ERR_GHOSTEDCLIENT           :: Int
-pattern ERR_GHOSTEDCLIENT           = 503
-
-pattern ERR_VWORLDWARN              :: Int
-pattern ERR_VWORLDWARN              = 503
-
-pattern ERR_USERNOTONSERV           :: Int
-pattern ERR_USERNOTONSERV           = 504
-
-pattern ERR_SILELISTFULL            :: Int
-pattern ERR_SILELISTFULL            = 511
-
-pattern ERR_TOOMANYWATCH            :: Int
-pattern ERR_TOOMANYWATCH            = 512
-
-pattern ERR_BADPING                 :: Int
-pattern ERR_BADPING                 = 513
-
-pattern ERR_INVALID_ERROR           :: Int
-pattern ERR_INVALID_ERROR           = 514
-
-pattern ERR_TOOMANYDCC              :: Int
-pattern ERR_TOOMANYDCC              = 514
-
-pattern ERR_BADEXPIRE               :: Int
-pattern ERR_BADEXPIRE               = 515
-
-pattern ERR_DONTCHEAT               :: Int
-pattern ERR_DONTCHEAT               = 516
-
-pattern ERR_DISABLED                :: Int
-pattern ERR_DISABLED                = 517
-
-pattern ERR_NOINVITE                :: Int
-pattern ERR_NOINVITE                = 518
-
-pattern ERR_LONGMASK                :: Int
-pattern ERR_LONGMASK                = 518
-
-pattern ERR_ADMONLY                 :: Int
-pattern ERR_ADMONLY                 = 519
-
-pattern ERR_TOOMANYUSERS            :: Int
-pattern ERR_TOOMANYUSERS            = 519
-
-pattern ERR_OPERONLY                :: Int
-pattern ERR_OPERONLY                = 520
-
-pattern ERR_MASKTOOWIDE             :: Int
-pattern ERR_MASKTOOWIDE             = 520
-
-pattern ERR_WHOTRUNC                :: Int
-pattern ERR_WHOTRUNC                = 520
-
-pattern ERR_LISTSYNTAX              :: Int
-pattern ERR_LISTSYNTAX              = 521
-
-pattern ERR_WHOSYNTAX               :: Int
-pattern ERR_WHOSYNTAX               = 522
-
-pattern ERR_WHOLIMEXCEED            :: Int
-pattern ERR_WHOLIMEXCEED            = 523
-
-pattern ERR_QUARANTINED             :: Int
-pattern ERR_QUARANTINED             = 524
-
-pattern ERR_OPERSPVERIFY            :: Int
-pattern ERR_OPERSPVERIFY            = 524
-
-pattern ERR_REMOTEPFX               :: Int
-pattern ERR_REMOTEPFX               = 525
-
-pattern ERR_PFXUNROUTABLE           :: Int
-pattern ERR_PFXUNROUTABLE           = 526
-
-pattern ERR_BADHOSTMASK             :: Int
-pattern ERR_BADHOSTMASK             = 550
-
-pattern ERR_HOSTUNAVAIL             :: Int
-pattern ERR_HOSTUNAVAIL             = 551
-
-pattern ERR_USINGSLINE              :: Int
-pattern ERR_USINGSLINE              = 552
-
-pattern ERR_STATSSLINE              :: Int
-pattern ERR_STATSSLINE              = 553
-
-pattern RPL_LOGON                   :: Int
-pattern RPL_LOGON                   = 600
-
-pattern RPL_LOGOFF                  :: Int
-pattern RPL_LOGOFF                  = 601
-
-pattern RPL_WATCHOFF                :: Int
-pattern RPL_WATCHOFF                = 602
-
-pattern RPL_WATCHSTAT               :: Int
-pattern RPL_WATCHSTAT               = 603
-
-pattern RPL_NOWON                   :: Int
-pattern RPL_NOWON                   = 604
-
-pattern RPL_NOWOFF                  :: Int
-pattern RPL_NOWOFF                  = 605
-
-pattern RPL_WATCHLIST               :: Int
-pattern RPL_WATCHLIST               = 606
-
-pattern RPL_ENDOFWATCHLIST          :: Int
-pattern RPL_ENDOFWATCHLIST          = 607
-
-pattern RPL_WATCHCLEAR              :: Int
-pattern RPL_WATCHCLEAR              = 608
-
-pattern RPL_ISOPER                  :: Int
-pattern RPL_ISOPER                  = 610
-
-pattern RPL_ISLOCOP                 :: Int
-pattern RPL_ISLOCOP                 = 611
-
-pattern RPL_ISNOTOPER               :: Int
-pattern RPL_ISNOTOPER               = 612
-
-pattern RPL_ENDOFISOPER             :: Int
-pattern RPL_ENDOFISOPER             = 613
-
-pattern RPL_DCCSTATUS               :: Int
-pattern RPL_DCCSTATUS               = 617
-
-pattern RPL_DCCLIST                 :: Int
-pattern RPL_DCCLIST                 = 618
-
-pattern RPL_ENDOFDCCLIST            :: Int
-pattern RPL_ENDOFDCCLIST            = 619
-
-pattern RPL_WHOWASHOST              :: Int
-pattern RPL_WHOWASHOST              = 619
-
-pattern RPL_DCCINFO                 :: Int
-pattern RPL_DCCINFO                 = 620
-
-pattern RPL_RULES                   :: Int
-pattern RPL_RULES                   = 621
-
-pattern RPL_ENDOFO                  :: Int
-pattern RPL_ENDOFO                  = 626
-
-pattern RPL_SETTINGS                :: Int
-pattern RPL_SETTINGS                = 630
-
-pattern RPL_ENDOFSETTINGS           :: Int
-pattern RPL_ENDOFSETTINGS           = 631
-
-pattern RPL_DUMPING                 :: Int
-pattern RPL_DUMPING                 = 640
-
-pattern RPL_DUMPRPL                 :: Int
-pattern RPL_DUMPRPL                 = 641
-
-pattern RPL_EODUMP                  :: Int
-pattern RPL_EODUMP                  = 642
-
-pattern RPL_TRACEROUTE_HOP          :: Int
-pattern RPL_TRACEROUTE_HOP          = 660
-
-pattern RPL_TRACEROUTE_START        :: Int
-pattern RPL_TRACEROUTE_START        = 661
-
-pattern RPL_MODECHANGEWARN          :: Int
-pattern RPL_MODECHANGEWARN          = 662
-
-pattern RPL_CHANREDIR               :: Int
-pattern RPL_CHANREDIR               = 663
-
-pattern RPL_SERVMODEIS              :: Int
-pattern RPL_SERVMODEIS              = 664
-
-pattern RPL_OTHERUMODEIS            :: Int
-pattern RPL_OTHERUMODEIS            = 665
-
-pattern RPL_ENDOF_GENERIC           :: Int
-pattern RPL_ENDOF_GENERIC           = 666
-
-pattern RPL_WHOWASDETAILS           :: Int
-pattern RPL_WHOWASDETAILS           = 670
-
-pattern RPL_WHOISSECURE             :: Int
-pattern RPL_WHOISSECURE             = 671
-
-pattern RPL_UNKNOWNMODES            :: Int
-pattern RPL_UNKNOWNMODES            = 672
-
-pattern RPL_CANNOTSETMODES          :: Int
-pattern RPL_CANNOTSETMODES          = 673
-
-pattern RPL_LUSERSTAFF              :: Int
-pattern RPL_LUSERSTAFF              = 678
-
-pattern RPL_TIMEONSERVERIS          :: Int
-pattern RPL_TIMEONSERVERIS          = 679
-
-pattern RPL_NETWORKS                :: Int
-pattern RPL_NETWORKS                = 682
-
-pattern RPL_YOURLANGUAGEIS          :: Int
-pattern RPL_YOURLANGUAGEIS          = 687
-
-pattern RPL_LANGUAGE                :: Int
-pattern RPL_LANGUAGE                = 688
-
-pattern RPL_WHOISSTAFF              :: Int
-pattern RPL_WHOISSTAFF              = 689
-
-pattern RPL_WHOISLANGUAGE           :: Int
-pattern RPL_WHOISLANGUAGE           = 690
-
-pattern RPL_ENDOFMODLIST            :: Int
-pattern RPL_ENDOFMODLIST            = 703
-
-pattern RPL_HELPSTART               :: Int
-pattern RPL_HELPSTART               = 704
-
-pattern RPL_HELPTXT                 :: Int
-pattern RPL_HELPTXT                 = 705
-
-pattern RPL_ENDOFHELP               :: Int
-pattern RPL_ENDOFHELP               = 706
-
-pattern RPL_ETRACEFULL              :: Int
-pattern RPL_ETRACEFULL              = 708
-
-pattern RPL_ETRACE                  :: Int
-pattern RPL_ETRACE                  = 709
-
-pattern RPL_KNOCK                   :: Int
-pattern RPL_KNOCK                   = 710
-
-pattern RPL_KNOCKDLVR               :: Int
-pattern RPL_KNOCKDLVR               = 711
-
-pattern ERR_TOOMANYKNOCK            :: Int
-pattern ERR_TOOMANYKNOCK            = 712
-
-pattern ERR_CHANOPEN                :: Int
-pattern ERR_CHANOPEN                = 713
-
-pattern ERR_KNOCKONCHAN             :: Int
-pattern ERR_KNOCKONCHAN             = 714
-
-pattern ERR_KNOCKDISABLED           :: Int
-pattern ERR_KNOCKDISABLED           = 715
-
-pattern RPL_TARGUMODEG              :: Int
-pattern RPL_TARGUMODEG              = 716
-
-pattern RPL_TARGNOTIFY              :: Int
-pattern RPL_TARGNOTIFY              = 717
-
-pattern RPL_UMODEGMSG               :: Int
-pattern RPL_UMODEGMSG               = 718
-
-pattern RPL_ENDOFOMOTD              :: Int
-pattern RPL_ENDOFOMOTD              = 722
-
-pattern ERR_NOPRIVS                 :: Int
-pattern ERR_NOPRIVS                 = 723
-
-pattern RPL_TESTMARK                :: Int
-pattern RPL_TESTMARK                = 724
-
-pattern RPL_TESTLINE                :: Int
-pattern RPL_TESTLINE                = 725
-
-pattern RPL_NOTESTLINE              :: Int
-pattern RPL_NOTESTLINE              = 726
-
-pattern RPL_QUIETLIST               :: Int
-pattern RPL_QUIETLIST               = 728
-
-pattern RPL_ENDOFQUIETLIST          :: Int
-pattern RPL_ENDOFQUIETLIST          = 729
-
-pattern RPL_XINFO                   :: Int
-pattern RPL_XINFO                   = 771
-
-pattern RPL_XINFOSTART              :: Int
-pattern RPL_XINFOSTART              = 773
-
-pattern RPL_XINFOEND                :: Int
-pattern RPL_XINFOEND                = 774
-
-pattern ERR_CANNOTDOCOMMAND         :: Int
-pattern ERR_CANNOTDOCOMMAND         = 972
-
-pattern ERR_CANNOTCHANGEUMODE       :: Int
-pattern ERR_CANNOTCHANGEUMODE       = 973
-
-pattern ERR_CANNOTCHANGECHANMODE    :: Int
-pattern ERR_CANNOTCHANGECHANMODE    = 974
-
-pattern ERR_CANNOTCHANGESERVERMODE  :: Int
-pattern ERR_CANNOTCHANGESERVERMODE  = 975
-
-pattern ERR_CANNOTSENDTONICK        :: Int
-pattern ERR_CANNOTSENDTONICK        = 976
-
-pattern ERR_UNKNOWNSERVERMODE       :: Int
-pattern ERR_UNKNOWNSERVERMODE       = 977
-
-pattern ERR_SERVERMODELOCK          :: Int
-pattern ERR_SERVERMODELOCK          = 979
-
-pattern ERR_BADCHARENCODING         :: Int
-pattern ERR_BADCHARENCODING         = 980
-
-pattern ERR_TOOMANYLANGUAGES        :: Int
-pattern ERR_TOOMANYLANGUAGES        = 981
-
-pattern ERR_NOLANGUAGE              :: Int
-pattern ERR_NOLANGUAGE              = 982
-
-pattern ERR_TEXTTOOSHORT            :: Int
-pattern ERR_TEXTTOOSHORT            = 983
-
-pattern ERR_NUMERIC_ERR             :: Int
-pattern ERR_NUMERIC_ERR             = 999
+{-# Language PatternSynonyms, OverloadedStrings #-}
+{-# OPTIONS_GHC -Wno-missing-pattern-synonym-signatures #-}
+
+{-|
+Module      : Irc.Codes
+Description : Helpers for interpreting IRC reply codes
+Copyright   : (c) Eric Mertens, 2016
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module defines support for working with IRC's numeric reply
+codes. Pattern synonyms are provided for each of the possible IRC reply codes.
+
+Reply code information was extracted from https://www.alien.net.au/irc/irc2numerics.html
+
+-}
+
+module Irc.Codes where
+
+import           Data.Vector (Vector)
+import qualified Data.Vector as Vector
+import           Data.Text (Text)
+import qualified Data.Text as Text
+
+-- | Type of numeric reply codes
+newtype ReplyCode = ReplyCode Word
+
+instance Show ReplyCode where
+  showsPrec p (ReplyCode x) = showsPrec p x
+
+-- | Categories for reply codes
+data ReplyType
+  = ClientServerReply -- ^ 0-99 Messages between client and server
+  | CommandReply      -- ^ 200-399 Responses to commands
+  | ErrorReply        -- ^ 200-399 Errors
+  | UnknownReply      -- ^ Uncategorized
+
+pattern RPL_WELCOME                 = ReplyCode 001
+pattern RPL_YOURHOST                = ReplyCode 002
+pattern RPL_CREATED                 = ReplyCode 003
+pattern RPL_MYINFO                  = ReplyCode 004
+pattern RPL_ISUPPORT                = ReplyCode 005
+pattern RPL_SNOMASK                 = ReplyCode 008
+pattern RPL_STATMEMTOT              = ReplyCode 009
+pattern RPL_REDIR                   = ReplyCode 010
+pattern RPL_YOURCOOKIE              = ReplyCode 014
+pattern RPL_MAP                     = ReplyCode 015
+pattern RPL_MAPEND                  = ReplyCode 017
+pattern RPL_YOURID                  = ReplyCode 042
+pattern RPL_SAVENICK                = ReplyCode 043
+pattern RPL_ATTEMPTINGJUNC          = ReplyCode 050
+pattern RPL_ATTEMPTINGREROUTE       = ReplyCode 051
+pattern RPL_TRACELINK               = ReplyCode 200
+pattern RPL_TRACECONNECTING         = ReplyCode 201
+pattern RPL_TRACEHANDSHAKE          = ReplyCode 202
+pattern RPL_TRACEUNKNOWN            = ReplyCode 203
+pattern RPL_TRACEOPERATOR           = ReplyCode 204
+pattern RPL_TRACEUSER               = ReplyCode 205
+pattern RPL_TRACESERVER             = ReplyCode 206
+pattern RPL_TRACESERVICE            = ReplyCode 207
+pattern RPL_TRACENEWTYPE            = ReplyCode 208
+pattern RPL_TRACECLASS              = ReplyCode 209
+pattern RPL_TRACERECONNECT          = ReplyCode 210
+pattern RPL_STATS                   = ReplyCode 210
+pattern RPL_STATSLINKINFO           = ReplyCode 211
+pattern RPL_STATSCOMMANDS           = ReplyCode 212
+pattern RPL_STATSCLINE              = ReplyCode 213
+pattern RPL_STATSNLINE              = ReplyCode 214
+pattern RPL_STATSILINE              = ReplyCode 215
+pattern RPL_STATSKLINE              = ReplyCode 216
+pattern RPL_STATSQLINE              = ReplyCode 217
+pattern RPL_STATSYLINE              = ReplyCode 218
+pattern RPL_ENDOFSTATS              = ReplyCode 219
+pattern RPL_STATSPLINE              = ReplyCode 220
+pattern RPL_UMODEIS                 = ReplyCode 221
+pattern RPL_SQLINE_NICK             = ReplyCode 222
+pattern RPL_STATSDLINE              = ReplyCode 225
+pattern RPL_STATSZLINE              = ReplyCode 225
+pattern RPL_STATSCOUNT              = ReplyCode 226
+pattern RPL_SERVICEINFO             = ReplyCode 231
+pattern RPL_ENDOFSERVICES           = ReplyCode 232
+pattern RPL_SERVICE                 = ReplyCode 233
+pattern RPL_SERVLIST                = ReplyCode 234
+pattern RPL_SERVLISTEND             = ReplyCode 235
+pattern RPL_STATSVERBOSE            = ReplyCode 236
+pattern RPL_STATSIAUTH              = ReplyCode 239
+pattern RPL_STATSLLINE              = ReplyCode 241
+pattern RPL_STATSUPTIME             = ReplyCode 242
+pattern RPL_STATSOLINE              = ReplyCode 243
+pattern RPL_STATSHLINE              = ReplyCode 244
+pattern RPL_STATSSLINE              = ReplyCode 245
+pattern RPL_STATSPING               = ReplyCode 246
+pattern RPL_STATSXLINE              = ReplyCode 247
+pattern RPL_STATSULINE              = ReplyCode 248
+pattern RPL_STATSDEBUG              = ReplyCode 249
+pattern RPL_STATSCONN               = ReplyCode 250
+pattern RPL_LUSERCLIENT             = ReplyCode 251
+pattern RPL_LUSEROP                 = ReplyCode 252
+pattern RPL_LUSERUNKNOWN            = ReplyCode 253
+pattern RPL_LUSERCHANNELS           = ReplyCode 254
+pattern RPL_LUSERME                 = ReplyCode 255
+pattern RPL_ADMINME                 = ReplyCode 256
+pattern RPL_ADMINLOC1               = ReplyCode 257
+pattern RPL_ADMINLOC2               = ReplyCode 258
+pattern RPL_ADMINEMAIL              = ReplyCode 259
+pattern RPL_TRACELOG                = ReplyCode 261
+pattern RPL_ENDOFTRACE              = ReplyCode 262
+pattern RPL_LOAD2HI                 = ReplyCode 263
+pattern RPL_LOCALUSERS              = ReplyCode 265
+pattern RPL_GLOBALUSERS             = ReplyCode 266
+pattern RPL_START_NETSTAT           = ReplyCode 267
+pattern RPL_NETSTAT                 = ReplyCode 268
+pattern RPL_END_NETSTAT             = ReplyCode 269
+pattern RPL_PRIVS                   = ReplyCode 270
+pattern RPL_SILELIST                = ReplyCode 271
+pattern RPL_ENDOFSILELIST           = ReplyCode 272
+pattern RPL_NOTIFY                  = ReplyCode 273
+pattern RPL_ENDNOTIFY               = ReplyCode 274
+pattern RPL_STATSDELTA              = ReplyCode 274
+pattern RPL_WHOISCERTFP             = ReplyCode 276
+pattern RPL_VCHANLIST               = ReplyCode 277
+pattern RPL_VCHANHELP               = ReplyCode 278
+pattern RPL_GLIST                   = ReplyCode 280
+pattern RPL_ACCEPTLIST              = ReplyCode 281
+pattern RPL_ENDOFACCEPT             = ReplyCode 282
+pattern RPL_ENDOFJUPELIST           = ReplyCode 283
+pattern RPL_FEATURE                 = ReplyCode 284
+pattern RPL_DATASTR                 = ReplyCode 290
+pattern RPL_END_CHANINFO            = ReplyCode 299
+pattern RPL_NONE                    = ReplyCode 300
+pattern RPL_AWAY                    = ReplyCode 301
+pattern RPL_USERHOST                = ReplyCode 302
+pattern RPL_ISON                    = ReplyCode 303
+pattern RPL_TEXT                    = ReplyCode 304
+pattern RPL_UNAWAY                  = ReplyCode 305
+pattern RPL_NOWAWAY                 = ReplyCode 306
+pattern RPL_WHOISREGNICK            = ReplyCode 307
+pattern RPL_SUSERHOST               = ReplyCode 307
+pattern RPL_NOTIFYACTION            = ReplyCode 308
+pattern RPL_WHOISADMIN              = ReplyCode 308
+pattern RPL_NICKTRACE               = ReplyCode 309
+pattern RPL_WHOISSADMIN             = ReplyCode 309
+pattern RPL_WHOISHELPER             = ReplyCode 309
+pattern RPL_WHOISUSER               = ReplyCode 311
+pattern RPL_WHOISSERVER             = ReplyCode 312
+pattern RPL_WHOISOPERATOR           = ReplyCode 313
+pattern RPL_WHOWASUSER              = ReplyCode 314
+pattern RPL_ENDOFWHO                = ReplyCode 315
+pattern RPL_WHOISCHANOP             = ReplyCode 316
+pattern RPL_WHOISIDLE               = ReplyCode 317
+pattern RPL_ENDOFWHOIS              = ReplyCode 318
+pattern RPL_WHOISCHANNELS           = ReplyCode 319
+pattern RPL_WHOISSPECIAL            = ReplyCode 320
+pattern RPL_LISTSTART               = ReplyCode 321
+pattern RPL_LIST                    = ReplyCode 322
+pattern RPL_LISTEND                 = ReplyCode 323
+pattern RPL_CHANNELMODEIS           = ReplyCode 324
+pattern RPL_CHANNELMLOCKIS          = ReplyCode 325
+pattern RPL_NOCHANPASS              = ReplyCode 326
+pattern RPL_CHPASSUNKNOWN           = ReplyCode 327
+pattern RPL_CHANNEL_URL             = ReplyCode 328
+pattern RPL_CREATIONTIME            = ReplyCode 329
+pattern RPL_WHOWAS_TIME             = ReplyCode 330
+pattern RPL_WHOISACCOUNT            = ReplyCode 330
+pattern RPL_NOTOPIC                 = ReplyCode 331
+pattern RPL_TOPIC                   = ReplyCode 332
+pattern RPL_TOPICWHOTIME            = ReplyCode 333
+pattern RPL_LISTUSAGE               = ReplyCode 334
+pattern RPL_COMMANDSYNTAX           = ReplyCode 334
+pattern RPL_LISTSYNTAX              = ReplyCode 334
+pattern RPL_WHOISACTUALLY           = ReplyCode 338
+pattern RPL_BADCHANPASS             = ReplyCode 339
+pattern RPL_INVITING                = ReplyCode 341
+pattern RPL_SUMMONING               = ReplyCode 342
+pattern RPL_INVITED                 = ReplyCode 345
+pattern RPL_INVEXLIST               = ReplyCode 346
+pattern RPL_ENDOFINVEXLIST          = ReplyCode 347
+pattern RPL_EXCEPTLIST              = ReplyCode 348
+pattern RPL_ENDOFEXCEPTLIST         = ReplyCode 349
+pattern RPL_VERSION                 = ReplyCode 351
+pattern RPL_WHOREPLY                = ReplyCode 352
+pattern RPL_NAMREPLY                = ReplyCode 353
+pattern RPL_WHOSPCRPL               = ReplyCode 354
+pattern RPL_NAMREPLY_               = ReplyCode 355
+pattern RPL_WHOWASREAL              = ReplyCode 360
+pattern RPL_KILLDONE                = ReplyCode 361
+pattern RPL_CLOSING                 = ReplyCode 362
+pattern RPL_CLOSEEND                = ReplyCode 363
+pattern RPL_LINKS                   = ReplyCode 364
+pattern RPL_ENDOFLINKS              = ReplyCode 365
+pattern RPL_ENDOFNAMES              = ReplyCode 366
+pattern RPL_BANLIST                 = ReplyCode 367
+pattern RPL_ENDOFBANLIST            = ReplyCode 368
+pattern RPL_ENDOFWHOWAS             = ReplyCode 369
+pattern RPL_INFO                    = ReplyCode 371
+pattern RPL_MOTD                    = ReplyCode 372
+pattern RPL_INFOSTART               = ReplyCode 373
+pattern RPL_ENDOFINFO               = ReplyCode 374
+pattern RPL_MOTDSTART               = ReplyCode 375
+pattern RPL_ENDOFMOTD               = ReplyCode 376
+pattern RPL_WHOISHOST               = ReplyCode 378
+pattern RPL_KICKLINKED              = ReplyCode 379
+pattern RPL_YOUREOPER               = ReplyCode 381
+pattern RPL_REHASHING               = ReplyCode 382
+pattern RPL_YOURESERVICE            = ReplyCode 383
+pattern RPL_MYPORTIS                = ReplyCode 384
+pattern RPL_NOTOPERANYMORE          = ReplyCode 385
+pattern RPL_RSACHALLENGE            = ReplyCode 386
+pattern RPL_TIME                    = ReplyCode 391
+pattern RPL_USERSSTART              = ReplyCode 392
+pattern RPL_USERS                   = ReplyCode 393
+pattern RPL_ENDOFUSERS              = ReplyCode 394
+pattern RPL_NOUSERS                 = ReplyCode 395
+pattern RPL_HOSTHIDDEN              = ReplyCode 396
+pattern ERR_UNKNOWNERROR            = ReplyCode 400
+pattern ERR_NOSUCHNICK              = ReplyCode 401
+pattern ERR_NOSUCHSERVER            = ReplyCode 402
+pattern ERR_NOSUCHCHANNEL           = ReplyCode 403
+pattern ERR_CANNOTSENDTOCHAN        = ReplyCode 404
+pattern ERR_TOOMANYCHANNELS         = ReplyCode 405
+pattern ERR_WASNOSUCHNICK           = ReplyCode 406
+pattern ERR_TOOMANYTARGETS          = ReplyCode 407
+pattern ERR_NOORIGIN                = ReplyCode 409
+pattern ERR_NORECIPIENT             = ReplyCode 411
+pattern ERR_NOTEXTTOSEND            = ReplyCode 412
+pattern ERR_NOTOPLEVEL              = ReplyCode 413
+pattern ERR_WILDTOPLEVEL            = ReplyCode 414
+pattern ERR_BADMASK                 = ReplyCode 415
+pattern ERR_TOOMANYMATCHES          = ReplyCode 416
+pattern ERR_LENGTHTRUNCATED         = ReplyCode 419
+pattern ERR_UNKNOWNCOMMAND          = ReplyCode 421
+pattern ERR_NOMOTD                  = ReplyCode 422
+pattern ERR_NOADMININFO             = ReplyCode 423
+pattern ERR_FILEERROR               = ReplyCode 424
+pattern ERR_NOOPERMOTD              = ReplyCode 425
+pattern ERR_TOOMANYAWAY             = ReplyCode 429
+pattern ERR_EVENTNICKCHANGE         = ReplyCode 430
+pattern ERR_NONICKNAMEGIVEN         = ReplyCode 431
+pattern ERR_ERRONEUSNICKNAME        = ReplyCode 432
+pattern ERR_NICKNAMEINUSE           = ReplyCode 433
+pattern ERR_SERVICENAMEINUSE        = ReplyCode 434
+pattern ERR_NORULES                 = ReplyCode 434
+pattern ERR_BANNICKCHANGE           = ReplyCode 435
+pattern ERR_NICKCOLLISION           = ReplyCode 436
+pattern ERR_UNAVAILRESOURCE         = ReplyCode 437
+pattern ERR_NICKTOOFAST             = ReplyCode 438
+pattern ERR_TARGETTOOFAST           = ReplyCode 439
+pattern ERR_SERVICESDOWN            = ReplyCode 440
+pattern ERR_USERNOTINCHANNEL        = ReplyCode 441
+pattern ERR_NOTONCHANNEL            = ReplyCode 442
+pattern ERR_USERONCHANNEL           = ReplyCode 443
+pattern ERR_NOLOGIN                 = ReplyCode 444
+pattern ERR_SUMMONDISABLED          = ReplyCode 445
+pattern ERR_USERSDISABLED           = ReplyCode 446
+pattern ERR_NONICKCHANGE            = ReplyCode 447
+pattern ERR_NOTIMPLEMENTED          = ReplyCode 449
+pattern ERR_NOTREGISTERED           = ReplyCode 451
+pattern ERR_IDCOLLISION             = ReplyCode 452
+pattern ERR_NICKLOST                = ReplyCode 453
+pattern ERR_HOSTILENAME             = ReplyCode 455
+pattern ERR_ACCEPTFULL              = ReplyCode 456
+pattern ERR_ACCEPTEXIST             = ReplyCode 457
+pattern ERR_ACCEPTNOT               = ReplyCode 458
+pattern ERR_NOHIDING                = ReplyCode 459
+pattern ERR_NOTFORHALFOPS           = ReplyCode 460
+pattern ERR_NEEDMOREPARAMS          = ReplyCode 461
+pattern ERR_ALREADYREGISTERED       = ReplyCode 462
+pattern ERR_NOPERMFORHOST           = ReplyCode 463
+pattern ERR_PASSWDMISMATCH          = ReplyCode 464
+pattern ERR_YOUREBANNEDCREEP        = ReplyCode 465
+pattern ERR_YOUWILLBEBANNED         = ReplyCode 466
+pattern ERR_KEYSET                  = ReplyCode 467
+pattern ERR_INVALIDUSERNAME         = ReplyCode 468
+pattern ERR_ONLYSERVERSCANCHANGE    = ReplyCode 468
+pattern ERR_LINKSET                 = ReplyCode 469
+pattern ERR_LINKCHANNEL             = ReplyCode 470
+pattern ERR_CHANNELISFULL           = ReplyCode 471
+pattern ERR_UNKNOWNMODE             = ReplyCode 472
+pattern ERR_INVITEONLYCHAN          = ReplyCode 473
+pattern ERR_BANNEDFROMCHAN          = ReplyCode 474
+pattern ERR_BADCHANNELKEY           = ReplyCode 475
+pattern ERR_BADCHANMASK             = ReplyCode 476
+pattern ERR_NEEDREGGEDNICK          = ReplyCode 477
+pattern ERR_BANLISTFULL             = ReplyCode 478
+pattern ERR_BADCHANNAME             = ReplyCode 479
+pattern ERR_THROTTLE                = ReplyCode 480
+pattern ERR_NOPRIVILEGES            = ReplyCode 481
+pattern ERR_CHANOPRIVSNEEDED        = ReplyCode 482
+pattern ERR_CANTKILLSERVER          = ReplyCode 483
+pattern ERR_ISCHANSERVICE           = ReplyCode 484
+pattern ERR_BANNEDNICK              = ReplyCode 485
+pattern ERR_NONONREG                = ReplyCode 486
+pattern ERR_TSLESSCHAN              = ReplyCode 488
+pattern ERR_VOICENEEDED             = ReplyCode 489
+pattern ERR_NOOPERHOST              = ReplyCode 491
+pattern ERR_NOSERVICEHOST           = ReplyCode 492
+pattern ERR_NOFEATURE               = ReplyCode 493
+pattern ERR_OWNMODE                 = ReplyCode 494
+pattern ERR_BADLOGTYPE              = ReplyCode 495
+pattern ERR_BADLOGSYS               = ReplyCode 496
+pattern ERR_BADLOGVALUE             = ReplyCode 497
+pattern ERR_ISOPERLCHAN             = ReplyCode 498
+pattern ERR_CHANOWNPRIVNEEDED       = ReplyCode 499
+pattern ERR_UMODEUNKNOWNFLAG        = ReplyCode 501
+pattern ERR_USERSDONTMATCH          = ReplyCode 502
+pattern ERR_GHOSTEDCLIENT           = ReplyCode 503
+pattern ERR_USERNOTONSERV           = ReplyCode 504
+pattern ERR_SILELISTFULL            = ReplyCode 511
+pattern ERR_TOOMANYWATCH            = ReplyCode 512
+pattern ERR_WRONGPONG               = ReplyCode 513
+pattern ERR_BADEXPIRE               = ReplyCode 515
+pattern ERR_DONTCHEAT               = ReplyCode 516
+pattern ERR_DISABLED                = ReplyCode 517
+pattern ERR_NOINVITE                = ReplyCode 518
+pattern ERR_LONGMASK                = ReplyCode 518
+pattern ERR_ADMONLY                 = ReplyCode 519
+pattern ERR_TOOMANYUSERS            = ReplyCode 519
+pattern ERR_OPERONLY                = ReplyCode 520
+pattern ERR_MASKTOOWIDE             = ReplyCode 520
+pattern ERR_WHOTRUNC                = ReplyCode 520
+pattern ERR_LISTSYNTAX              = ReplyCode 521
+pattern ERR_WHOSYNTAX               = ReplyCode 522
+pattern ERR_WHOLIMEXCEED            = ReplyCode 523
+pattern ERR_HELPNOTFOUND            = ReplyCode 524
+pattern ERR_REMOTEPFX               = ReplyCode 525
+pattern ERR_PFXUNROUTABLE           = ReplyCode 526
+pattern ERR_BADHOSTMASK             = ReplyCode 550
+pattern ERR_HOSTUNAVAIL             = ReplyCode 551
+pattern ERR_USINGSLINE              = ReplyCode 552
+pattern ERR_STATSSLINE              = ReplyCode 553
+pattern RPL_LOGON                   = ReplyCode 600
+pattern RPL_LOGOFF                  = ReplyCode 601
+pattern RPL_WATCHOFF                = ReplyCode 602
+pattern RPL_WATCHSTAT               = ReplyCode 603
+pattern RPL_NOWON                   = ReplyCode 604
+pattern RPL_NOWOFF                  = ReplyCode 605
+pattern RPL_WATCHLIST               = ReplyCode 606
+pattern RPL_ENDOFWATCHLIST          = ReplyCode 607
+pattern RPL_WATCHCLEAR              = ReplyCode 608
+pattern RPL_ISOPER                  = ReplyCode 610
+pattern RPL_ISLOCOP                 = ReplyCode 611
+pattern RPL_ISNOTOPER               = ReplyCode 612
+pattern RPL_ENDOFISOPER             = ReplyCode 613
+pattern RPL_DCCSTATUS               = ReplyCode 617
+pattern RPL_DCCLIST                 = ReplyCode 618
+pattern RPL_ENDOFDCCLIST            = ReplyCode 619
+pattern RPL_WHOWASHOST              = ReplyCode 619
+pattern RPL_DCCINFO                 = ReplyCode 620
+pattern RPL_RULES                   = ReplyCode 621
+pattern RPL_ENDOFO                  = ReplyCode 626
+pattern RPL_SETTINGS                = ReplyCode 630
+pattern RPL_ENDOFSETTINGS           = ReplyCode 631
+pattern RPL_DUMPING                 = ReplyCode 640
+pattern RPL_DUMPRPL                 = ReplyCode 641
+pattern RPL_EODUMP                  = ReplyCode 642
+pattern RPL_TRACEROUTE_HOP          = ReplyCode 660
+pattern RPL_TRACEROUTE_START        = ReplyCode 661
+pattern RPL_MODECHANGEWARN          = ReplyCode 662
+pattern RPL_CHANREDIR               = ReplyCode 663
+pattern RPL_SERVMODEIS              = ReplyCode 664
+pattern RPL_OTHERUMODEIS            = ReplyCode 665
+pattern RPL_ENDOF_GENERIC           = ReplyCode 666
+pattern RPL_WHOWASDETAILS           = ReplyCode 670
+pattern RPL_WHOISSECURE             = ReplyCode 671
+pattern RPL_UNKNOWNMODES            = ReplyCode 672
+pattern RPL_CANNOTSETMODES          = ReplyCode 673
+pattern RPL_LUSERSTAFF              = ReplyCode 678
+pattern RPL_TIMEONSERVERIS          = ReplyCode 679
+pattern RPL_NETWORKS                = ReplyCode 682
+pattern RPL_YOURLANGUAGEIS          = ReplyCode 687
+pattern RPL_LANGUAGE                = ReplyCode 688
+pattern RPL_WHOISSTAFF              = ReplyCode 689
+pattern RPL_WHOISLANGUAGE           = ReplyCode 690
+pattern RPL_MODLIST                 = ReplyCode 702
+pattern RPL_ENDOFMODLIST            = ReplyCode 703
+pattern RPL_HELPSTART               = ReplyCode 704
+pattern RPL_HELPTXT                 = ReplyCode 705
+pattern RPL_ENDOFHELP               = ReplyCode 706
+pattern ERR_TARGCHANGE              = ReplyCode 707
+pattern RPL_ETRACEFULL              = ReplyCode 708
+pattern RPL_ETRACE                  = ReplyCode 709
+pattern RPL_KNOCK                   = ReplyCode 710
+pattern RPL_KNOCKDLVR               = ReplyCode 711
+pattern ERR_TOOMANYKNOCK            = ReplyCode 712
+pattern ERR_CHANOPEN                = ReplyCode 713
+pattern ERR_KNOCKONCHAN             = ReplyCode 714
+pattern ERR_KNOCKDISABLED           = ReplyCode 715
+pattern RPL_TARGUMODEG              = ReplyCode 716
+pattern RPL_TARGNOTIFY              = ReplyCode 717
+pattern RPL_UMODEGMSG               = ReplyCode 718
+pattern RPL_OMOTDSTART              = ReplyCode 720
+pattern RPL_OMOTD                   = ReplyCode 721
+pattern RPL_ENDOFOMOTD              = ReplyCode 722
+pattern ERR_NOPRIVS                 = ReplyCode 723
+pattern RPL_TESTMASK                = ReplyCode 724
+pattern RPL_TESTLINE                = ReplyCode 725
+pattern RPL_NOTESTLINE              = ReplyCode 726
+pattern RPL_QUIETLIST               = ReplyCode 728
+pattern RPL_ENDOFQUIETLIST          = ReplyCode 729
+pattern RPL_MONONLINE               = ReplyCode 730
+pattern RPL_MONOFFLINE              = ReplyCode 731
+pattern RPL_MONLIST                 = ReplyCode 732
+pattern RPL_ENDOFMONLIST            = ReplyCode 733
+pattern ERR_MONLISTFULL             = ReplyCode 734
+pattern RPL_RSACHALLENGE2           = ReplyCode 740
+pattern RPL_ENDOFRSACHALLENGE2      = ReplyCode 741
+pattern ERR_MLOCKRESTRICTED         = ReplyCode 742
+pattern RPL_SCANMATCHED             = ReplyCode 750
+pattern RPL_SCANUMODES              = ReplyCode 751
+pattern RPL_XINFO                   = ReplyCode 771
+pattern RPL_XINFOSTART              = ReplyCode 773
+pattern RPL_XINFOEND                = ReplyCode 774
+pattern RPL_LOGGEDIN                = ReplyCode 900
+pattern RPL_LOGGEDOUT               = ReplyCode 901
+pattern RPL_NICKLOCKED              = ReplyCode 902
+pattern RPL_SASLSUCCESS             = ReplyCode 903
+pattern RPL_SASLFAIL                = ReplyCode 904
+pattern RPL_SASLTOOLONG             = ReplyCode 905
+pattern RPL_SASLABORTED             = ReplyCode 906
+pattern RPL_SASLALREADY             = ReplyCode 907
+pattern RPL_SASLMECHS               = ReplyCode 908
+pattern ERR_CANNOTDOCOMMAND         = ReplyCode 972
+pattern ERR_CANNOTCHANGEUMODE       = ReplyCode 973
+pattern ERR_CANNOTCHANGECHANMODE    = ReplyCode 974
+pattern ERR_CANNOTCHANGESERVERMODE  = ReplyCode 975
+pattern ERR_CANNOTSENDTONICK        = ReplyCode 976
+pattern ERR_UNKNOWNSERVERMODE       = ReplyCode 977
+pattern ERR_SERVERMODELOCK          = ReplyCode 979
+pattern ERR_BADCHARENCODING         = ReplyCode 980
+pattern ERR_TOOMANYLANGUAGES        = ReplyCode 981
+pattern ERR_NOLANGUAGE              = ReplyCode 982
+pattern ERR_TEXTTOOSHORT            = ReplyCode 983
+pattern ERR_NUMERIC_ERR             = ReplyCode 999
+
+data ReplyCodeInfo = ReplyCodeInfo
+  { replyCodeType :: !ReplyType
+  , replyCodeText :: !Text
+  }
+
+replyCodeInfo :: ReplyCode -> ReplyCodeInfo
+replyCodeInfo (ReplyCode w) =
+  case replyCodeInfoTable Vector.!? i of
+    Nothing -> defaultReplyCodeInfo i
+    Just info -> info
+  where
+    i = fromIntegral w
+
+defaultReplyCodeInfo :: Int -> ReplyCodeInfo
+defaultReplyCodeInfo = ReplyCodeInfo UnknownReply . Text.pack . show
+
+replyCodeInfoTable :: Vector ReplyCodeInfo
+replyCodeInfoTable
+  = Vector.accumulate
+      (\_def new -> new)
+      (Vector.generate 1000 defaultReplyCodeInfo)
+  $ fmap (\(ReplyCode code,info) -> (fromIntegral code, info))
+  $ Vector.fromList
+  [ (RPL_WELCOME               , ReplyCodeInfo ClientServerReply "WELCOME")
+  , (RPL_YOURHOST              , ReplyCodeInfo ClientServerReply "YOURHOST")
+  , (RPL_CREATED               , ReplyCodeInfo ClientServerReply "CREATED")
+  , (RPL_MYINFO                , ReplyCodeInfo ClientServerReply "MYINFO")
+  , (RPL_ISUPPORT              , ReplyCodeInfo ClientServerReply "ISUPPORT")
+  , (RPL_SNOMASK               , ReplyCodeInfo ClientServerReply "SNOMASK")
+  , (RPL_STATMEMTOT            , ReplyCodeInfo ClientServerReply "STATMEMTOT")
+  , (RPL_REDIR                 , ReplyCodeInfo ClientServerReply "REDIR")
+  , (RPL_YOURCOOKIE            , ReplyCodeInfo ClientServerReply "YOURCOOKIE")
+  , (RPL_MAP                   , ReplyCodeInfo ClientServerReply "MAP")
+  , (RPL_MAPEND                , ReplyCodeInfo ClientServerReply "MAPEND")
+  , (RPL_YOURID                , ReplyCodeInfo ClientServerReply "YOURID")
+  , (RPL_SAVENICK              , ReplyCodeInfo ClientServerReply "SAVENICK")
+  , (RPL_ATTEMPTINGJUNC        , ReplyCodeInfo ClientServerReply "ATTEMPTINGJUNC")
+  , (RPL_ATTEMPTINGREROUTE     , ReplyCodeInfo ClientServerReply "ATTEMPTINGREROUTE")
+  , (RPL_TRACELINK             , ReplyCodeInfo CommandReply "TRACELINK")
+  , (RPL_TRACECONNECTING       , ReplyCodeInfo CommandReply "TRACECONNECTING")
+  , (RPL_TRACEHANDSHAKE        , ReplyCodeInfo CommandReply "TRACEHANDSHAKE")
+  , (RPL_TRACEUNKNOWN          , ReplyCodeInfo CommandReply "TRACEUNKNOWN")
+  , (RPL_TRACEOPERATOR         , ReplyCodeInfo CommandReply "TRACEOPERATOR")
+  , (RPL_TRACEUSER             , ReplyCodeInfo CommandReply "TRACEUSER")
+  , (RPL_TRACESERVER           , ReplyCodeInfo CommandReply "TRACESERVER")
+  , (RPL_TRACESERVICE          , ReplyCodeInfo CommandReply "TRACESERVICE")
+  , (RPL_TRACENEWTYPE          , ReplyCodeInfo CommandReply "TRACENEWTYPE")
+  , (RPL_TRACECLASS            , ReplyCodeInfo CommandReply "TRACECLASS")
+  , (RPL_TRACERECONNECT        , ReplyCodeInfo CommandReply "TRACERECONNECT")
+  , (RPL_STATS                 , ReplyCodeInfo CommandReply "STATS")
+  , (RPL_STATSLINKINFO         , ReplyCodeInfo CommandReply "STATSLINKINFO")
+  , (RPL_STATSCOMMANDS         , ReplyCodeInfo CommandReply "STATSCOMMANDS")
+  , (RPL_STATSCLINE            , ReplyCodeInfo CommandReply "STATSCLINE")
+  , (RPL_STATSNLINE            , ReplyCodeInfo CommandReply "STATSNLINE")
+  , (RPL_STATSILINE            , ReplyCodeInfo CommandReply "STATSILINE")
+  , (RPL_STATSKLINE            , ReplyCodeInfo CommandReply "STATSKLINE")
+  , (RPL_STATSQLINE            , ReplyCodeInfo CommandReply "STATSQLINE")
+  , (RPL_STATSYLINE            , ReplyCodeInfo CommandReply "STATSYLINE")
+  , (RPL_ENDOFSTATS            , ReplyCodeInfo CommandReply "ENDOFSTATS")
+  , (RPL_STATSPLINE            , ReplyCodeInfo CommandReply "STATSPLINE")
+  , (RPL_UMODEIS               , ReplyCodeInfo CommandReply "UMODEIS")
+  , (RPL_SQLINE_NICK           , ReplyCodeInfo CommandReply "SQLINE_NICK")
+  , (RPL_STATSDLINE            , ReplyCodeInfo CommandReply "STATSDLINE")
+  , (RPL_STATSZLINE            , ReplyCodeInfo CommandReply "STATSZLINE")
+  , (RPL_STATSCOUNT            , ReplyCodeInfo CommandReply "STATSCOUNT")
+  , (RPL_SERVICEINFO           , ReplyCodeInfo CommandReply "SERVICEINFO")
+  , (RPL_ENDOFSERVICES         , ReplyCodeInfo CommandReply "ENDOFSERVICES")
+  , (RPL_SERVICE               , ReplyCodeInfo CommandReply "SERVICE")
+  , (RPL_SERVLIST              , ReplyCodeInfo CommandReply "SERVLIST")
+  , (RPL_SERVLISTEND           , ReplyCodeInfo CommandReply "SERVLISTEND")
+  , (RPL_STATSVERBOSE          , ReplyCodeInfo CommandReply "STATSVERBOSE")
+  , (RPL_STATSIAUTH            , ReplyCodeInfo CommandReply "STATSIAUTH")
+  , (RPL_STATSLLINE            , ReplyCodeInfo CommandReply "STATSLLINE")
+  , (RPL_STATSUPTIME           , ReplyCodeInfo CommandReply "STATSUPTIME")
+  , (RPL_STATSOLINE            , ReplyCodeInfo CommandReply "STATSOLINE")
+  , (RPL_STATSHLINE            , ReplyCodeInfo CommandReply "STATSHLINE")
+  , (RPL_STATSSLINE            , ReplyCodeInfo CommandReply "STATSSLINE")
+  , (RPL_STATSPING             , ReplyCodeInfo CommandReply "STATSPING")
+  , (RPL_STATSXLINE            , ReplyCodeInfo CommandReply "STATSXLINE")
+  , (RPL_STATSULINE            , ReplyCodeInfo CommandReply "STATSULINE")
+  , (RPL_STATSDEBUG            , ReplyCodeInfo CommandReply "STATSDEBUG")
+  , (RPL_STATSCONN             , ReplyCodeInfo CommandReply "STATSCONN")
+  , (RPL_LUSERCLIENT           , ReplyCodeInfo CommandReply "LUSERCLIENT")
+  , (RPL_LUSEROP               , ReplyCodeInfo CommandReply "LUSEROP")
+  , (RPL_LUSERUNKNOWN          , ReplyCodeInfo CommandReply "LUSERUNKNOWN")
+  , (RPL_LUSERCHANNELS         , ReplyCodeInfo CommandReply "LUSERCHANNELS")
+  , (RPL_LUSERME               , ReplyCodeInfo CommandReply "LUSERME")
+  , (RPL_ADMINME               , ReplyCodeInfo CommandReply "ADMINME")
+  , (RPL_ADMINLOC1             , ReplyCodeInfo CommandReply "ADMINLOC1")
+  , (RPL_ADMINLOC2             , ReplyCodeInfo CommandReply "ADMINLOC2")
+  , (RPL_ADMINEMAIL            , ReplyCodeInfo CommandReply "ADMINEMAIL")
+  , (RPL_TRACELOG              , ReplyCodeInfo CommandReply "TRACELOG")
+  , (RPL_ENDOFTRACE            , ReplyCodeInfo CommandReply "ENDOFTRACE")
+  , (RPL_LOAD2HI               , ReplyCodeInfo CommandReply "LOAD2HI")
+  , (RPL_LOCALUSERS            , ReplyCodeInfo CommandReply "LOCALUSERS")
+  , (RPL_GLOBALUSERS           , ReplyCodeInfo CommandReply "GLOBALUSERS")
+  , (RPL_START_NETSTAT         , ReplyCodeInfo CommandReply "START_NETSTAT")
+  , (RPL_NETSTAT               , ReplyCodeInfo CommandReply "NETSTAT")
+  , (RPL_END_NETSTAT           , ReplyCodeInfo CommandReply "END_NETSTAT")
+  , (RPL_PRIVS                 , ReplyCodeInfo CommandReply "PRIVS")
+  , (RPL_SILELIST              , ReplyCodeInfo CommandReply "SILELIST")
+  , (RPL_ENDOFSILELIST         , ReplyCodeInfo CommandReply "ENDOFSILELIST")
+  , (RPL_NOTIFY                , ReplyCodeInfo CommandReply "NOTIFY")
+  , (RPL_ENDNOTIFY             , ReplyCodeInfo CommandReply "ENDNOTIFY")
+  , (RPL_STATSDELTA            , ReplyCodeInfo CommandReply "STATSDELTA")
+  , (RPL_WHOISCERTFP           , ReplyCodeInfo CommandReply "WHOISCERTFP")
+  , (RPL_VCHANLIST             , ReplyCodeInfo CommandReply "VCHANLIST")
+  , (RPL_VCHANHELP             , ReplyCodeInfo CommandReply "VCHANHELP")
+  , (RPL_GLIST                 , ReplyCodeInfo CommandReply "GLIST")
+  , (RPL_ACCEPTLIST            , ReplyCodeInfo CommandReply "ACCEPTLIST")
+  , (RPL_ENDOFACCEPT           , ReplyCodeInfo CommandReply "ENDOFACCEPT")
+  , (RPL_ENDOFJUPELIST         , ReplyCodeInfo CommandReply "ENDOFJUPELIST")
+  , (RPL_FEATURE               , ReplyCodeInfo CommandReply "FEATURE")
+  , (RPL_DATASTR               , ReplyCodeInfo CommandReply "DATASTR")
+  , (RPL_END_CHANINFO          , ReplyCodeInfo CommandReply "END_CHANINFO")
+  , (RPL_NONE                  , ReplyCodeInfo CommandReply "NONE")
+  , (RPL_AWAY                  , ReplyCodeInfo CommandReply "AWAY")
+  , (RPL_USERHOST              , ReplyCodeInfo CommandReply "USERHOST")
+  , (RPL_ISON                  , ReplyCodeInfo CommandReply "ISON")
+  , (RPL_TEXT                  , ReplyCodeInfo CommandReply "TEXT")
+  , (RPL_UNAWAY                , ReplyCodeInfo CommandReply "UNAWAY")
+  , (RPL_NOWAWAY               , ReplyCodeInfo CommandReply "NOWAWAY")
+  , (RPL_WHOISREGNICK          , ReplyCodeInfo CommandReply "WHOISREGNICK")
+  , (RPL_SUSERHOST             , ReplyCodeInfo CommandReply "SUSERHOST")
+  , (RPL_NOTIFYACTION          , ReplyCodeInfo CommandReply "NOTIFYACTION")
+  , (RPL_WHOISADMIN            , ReplyCodeInfo CommandReply "WHOISADMIN")
+  , (RPL_NICKTRACE             , ReplyCodeInfo CommandReply "NICKTRACE")
+  , (RPL_WHOISSADMIN           , ReplyCodeInfo CommandReply "WHOISSADMIN")
+  , (RPL_WHOISHELPER           , ReplyCodeInfo CommandReply "WHOISHELPER")
+  , (RPL_WHOISUSER             , ReplyCodeInfo CommandReply "WHOISUSER")
+  , (RPL_WHOISSERVER           , ReplyCodeInfo CommandReply "WHOISSERVER")
+  , (RPL_WHOISOPERATOR         , ReplyCodeInfo CommandReply "WHOISOPERATOR")
+  , (RPL_WHOWASUSER            , ReplyCodeInfo CommandReply "WHOWASUSER")
+  , (RPL_ENDOFWHO              , ReplyCodeInfo CommandReply "ENDOFWHO")
+  , (RPL_WHOISCHANOP           , ReplyCodeInfo CommandReply "WHOISCHANOP")
+  , (RPL_WHOISIDLE             , ReplyCodeInfo CommandReply "WHOISIDLE")
+  , (RPL_ENDOFWHOIS            , ReplyCodeInfo CommandReply "ENDOFWHOIS")
+  , (RPL_WHOISCHANNELS         , ReplyCodeInfo CommandReply "WHOISCHANNELS")
+  , (RPL_WHOISSPECIAL          , ReplyCodeInfo CommandReply "WHOISSPECIAL")
+  , (RPL_LISTSTART             , ReplyCodeInfo CommandReply "LISTSTART")
+  , (RPL_LIST                  , ReplyCodeInfo CommandReply "LIST")
+  , (RPL_LISTEND               , ReplyCodeInfo CommandReply "LISTEND")
+  , (RPL_CHANNELMODEIS         , ReplyCodeInfo CommandReply "CHANNELMODEIS")
+  , (RPL_CHANNELMLOCKIS        , ReplyCodeInfo CommandReply "CHANNELMLOCKIS")
+  , (RPL_NOCHANPASS            , ReplyCodeInfo CommandReply "NOCHANPASS")
+  , (RPL_CHPASSUNKNOWN         , ReplyCodeInfo CommandReply "CHPASSUNKNOWN")
+  , (RPL_CHANNEL_URL           , ReplyCodeInfo CommandReply "CHANNEL_URL")
+  , (RPL_CREATIONTIME          , ReplyCodeInfo CommandReply "CREATIONTIME")
+  , (RPL_WHOWAS_TIME           , ReplyCodeInfo CommandReply "WHOWAS_TIME")
+  , (RPL_WHOISACCOUNT          , ReplyCodeInfo CommandReply "WHOISACCOUNT")
+  , (RPL_NOTOPIC               , ReplyCodeInfo CommandReply "NOTOPIC")
+  , (RPL_TOPIC                 , ReplyCodeInfo CommandReply "TOPIC")
+  , (RPL_TOPICWHOTIME          , ReplyCodeInfo CommandReply "TOPICWHOTIME")
+  , (RPL_LISTUSAGE             , ReplyCodeInfo CommandReply "LISTUSAGE")
+  , (RPL_COMMANDSYNTAX         , ReplyCodeInfo CommandReply "COMMANDSYNTAX")
+  , (RPL_LISTSYNTAX            , ReplyCodeInfo CommandReply "LISTSYNTAX")
+  , (RPL_WHOISACTUALLY         , ReplyCodeInfo CommandReply "WHOISACTUALLY")
+  , (RPL_BADCHANPASS           , ReplyCodeInfo CommandReply "BADCHANPASS")
+  , (RPL_INVITING              , ReplyCodeInfo CommandReply "INVITING")
+  , (RPL_SUMMONING             , ReplyCodeInfo CommandReply "SUMMONING")
+  , (RPL_INVITED               , ReplyCodeInfo CommandReply "INVITED")
+  , (RPL_INVEXLIST             , ReplyCodeInfo CommandReply "INVEXLIST")
+  , (RPL_ENDOFINVEXLIST        , ReplyCodeInfo CommandReply "ENDOFINVEXLIST")
+  , (RPL_EXCEPTLIST            , ReplyCodeInfo CommandReply "EXCEPTLIST")
+  , (RPL_ENDOFEXCEPTLIST       , ReplyCodeInfo CommandReply "ENDOFEXCEPTLIST")
+  , (RPL_VERSION               , ReplyCodeInfo CommandReply "VERSION")
+  , (RPL_WHOREPLY              , ReplyCodeInfo CommandReply "WHOREPLY")
+  , (RPL_NAMREPLY              , ReplyCodeInfo CommandReply "NAMREPLY")
+  , (RPL_WHOSPCRPL             , ReplyCodeInfo CommandReply "WHOSPCRPL")
+  , (RPL_NAMREPLY_             , ReplyCodeInfo CommandReply "NAMREPLY_")
+  , (RPL_WHOWASREAL            , ReplyCodeInfo CommandReply "WHOWASREAL")
+  , (RPL_KILLDONE              , ReplyCodeInfo CommandReply "KILLDONE")
+  , (RPL_CLOSING               , ReplyCodeInfo CommandReply "CLOSING")
+  , (RPL_CLOSEEND              , ReplyCodeInfo CommandReply "CLOSEEND")
+  , (RPL_LINKS                 , ReplyCodeInfo CommandReply "LINKS")
+  , (RPL_ENDOFLINKS            , ReplyCodeInfo CommandReply "ENDOFLINKS")
+  , (RPL_ENDOFNAMES            , ReplyCodeInfo CommandReply "ENDOFNAMES")
+  , (RPL_BANLIST               , ReplyCodeInfo CommandReply "BANLIST")
+  , (RPL_ENDOFBANLIST          , ReplyCodeInfo CommandReply "ENDOFBANLIST")
+  , (RPL_ENDOFWHOWAS           , ReplyCodeInfo CommandReply "ENDOFWHOWAS")
+  , (RPL_INFO                  , ReplyCodeInfo CommandReply "INFO")
+  , (RPL_MOTD                  , ReplyCodeInfo CommandReply "MOTD")
+  , (RPL_INFOSTART             , ReplyCodeInfo CommandReply "INFOSTART")
+  , (RPL_ENDOFINFO             , ReplyCodeInfo CommandReply "ENDOFINFO")
+  , (RPL_MOTDSTART             , ReplyCodeInfo CommandReply "MOTDSTART")
+  , (RPL_ENDOFMOTD             , ReplyCodeInfo CommandReply "ENDOFMOTD")
+  , (RPL_WHOISHOST             , ReplyCodeInfo CommandReply "WHOISHOST")
+  , (RPL_KICKLINKED            , ReplyCodeInfo CommandReply "KICKLINKED")
+  , (RPL_YOUREOPER             , ReplyCodeInfo CommandReply "YOUREOPER")
+  , (RPL_REHASHING             , ReplyCodeInfo CommandReply "REHASHING")
+  , (RPL_YOURESERVICE          , ReplyCodeInfo CommandReply "YOURESERVICE")
+  , (RPL_MYPORTIS              , ReplyCodeInfo CommandReply "MYPORTIS")
+  , (RPL_NOTOPERANYMORE        , ReplyCodeInfo CommandReply "NOTOPERANYMORE")
+  , (RPL_RSACHALLENGE          , ReplyCodeInfo CommandReply "RSACHALLENGE")
+  , (RPL_TIME                  , ReplyCodeInfo CommandReply "TIME")
+  , (RPL_USERSSTART            , ReplyCodeInfo CommandReply "USERSSTART")
+  , (RPL_USERS                 , ReplyCodeInfo CommandReply "USERS")
+  , (RPL_ENDOFUSERS            , ReplyCodeInfo CommandReply "ENDOFUSERS")
+  , (RPL_NOUSERS               , ReplyCodeInfo CommandReply "NOUSERS")
+  , (RPL_HOSTHIDDEN            , ReplyCodeInfo CommandReply "HOSTHIDDEN")
+  , (ERR_UNKNOWNERROR          , ReplyCodeInfo ErrorReply "UNKNOWNERROR")
+  , (ERR_NOSUCHNICK            , ReplyCodeInfo ErrorReply "NOSUCHNICK")
+  , (ERR_NOSUCHSERVER          , ReplyCodeInfo ErrorReply "NOSUCHSERVER")
+  , (ERR_NOSUCHCHANNEL         , ReplyCodeInfo ErrorReply "NOSUCHCHANNEL")
+  , (ERR_CANNOTSENDTOCHAN      , ReplyCodeInfo ErrorReply "CANNOTSENDTOCHAN")
+  , (ERR_TOOMANYCHANNELS       , ReplyCodeInfo ErrorReply "TOOMANYCHANNELS")
+  , (ERR_WASNOSUCHNICK         , ReplyCodeInfo ErrorReply "WASNOSUCHNICK")
+  , (ERR_TOOMANYTARGETS        , ReplyCodeInfo ErrorReply "TOOMANYTARGETS")
+  , (ERR_NOORIGIN              , ReplyCodeInfo ErrorReply "NOORIGIN")
+  , (ERR_NORECIPIENT           , ReplyCodeInfo ErrorReply "NORECIPIENT")
+  , (ERR_NOTEXTTOSEND          , ReplyCodeInfo ErrorReply "NOTEXTTOSEND")
+  , (ERR_NOTOPLEVEL            , ReplyCodeInfo ErrorReply "NOTOPLEVEL")
+  , (ERR_WILDTOPLEVEL          , ReplyCodeInfo ErrorReply "WILDTOPLEVEL")
+  , (ERR_BADMASK               , ReplyCodeInfo ErrorReply "BADMASK")
+  , (ERR_TOOMANYMATCHES        , ReplyCodeInfo ErrorReply "TOOMANYMATCHES")
+  , (ERR_LENGTHTRUNCATED       , ReplyCodeInfo ErrorReply "LENGTHTRUNCATED")
+  , (ERR_UNKNOWNCOMMAND        , ReplyCodeInfo ErrorReply "UNKNOWNCOMMAND")
+  , (ERR_NOMOTD                , ReplyCodeInfo ErrorReply "NOMOTD")
+  , (ERR_NOADMININFO           , ReplyCodeInfo ErrorReply "NOADMININFO")
+  , (ERR_FILEERROR             , ReplyCodeInfo ErrorReply "FILEERROR")
+  , (ERR_NOOPERMOTD            , ReplyCodeInfo ErrorReply "NOOPERMOTD")
+  , (ERR_TOOMANYAWAY           , ReplyCodeInfo ErrorReply "TOOMANYAWAY")
+  , (ERR_EVENTNICKCHANGE       , ReplyCodeInfo ErrorReply "EVENTNICKCHANGE")
+  , (ERR_NONICKNAMEGIVEN       , ReplyCodeInfo ErrorReply "NONICKNAMEGIVEN")
+  , (ERR_ERRONEUSNICKNAME      , ReplyCodeInfo ErrorReply "ERRONEUSNICKNAME")
+  , (ERR_NICKNAMEINUSE         , ReplyCodeInfo ErrorReply "NICKNAMEINUSE")
+  , (ERR_SERVICENAMEINUSE      , ReplyCodeInfo ErrorReply "SERVICENAMEINUSE")
+  , (ERR_NORULES               , ReplyCodeInfo ErrorReply "NORULES")
+  , (ERR_BANNICKCHANGE         , ReplyCodeInfo ErrorReply "BANNICKCHANGE")
+  , (ERR_NICKCOLLISION         , ReplyCodeInfo ErrorReply "NICKCOLLISION")
+  , (ERR_UNAVAILRESOURCE       , ReplyCodeInfo ErrorReply "UNAVAILRESOURCE")
+  , (ERR_NICKTOOFAST           , ReplyCodeInfo ErrorReply "NICKTOOFAST")
+  , (ERR_TARGETTOOFAST         , ReplyCodeInfo ErrorReply "TARGETTOOFAST")
+  , (ERR_SERVICESDOWN          , ReplyCodeInfo ErrorReply "SERVICESDOWN")
+  , (ERR_USERNOTINCHANNEL      , ReplyCodeInfo ErrorReply "USERNOTINCHANNEL")
+  , (ERR_NOTONCHANNEL          , ReplyCodeInfo ErrorReply "NOTONCHANNEL")
+  , (ERR_USERONCHANNEL         , ReplyCodeInfo ErrorReply "USERONCHANNEL")
+  , (ERR_NOLOGIN               , ReplyCodeInfo ErrorReply "NOLOGIN")
+  , (ERR_SUMMONDISABLED        , ReplyCodeInfo ErrorReply "SUMMONDISABLED")
+  , (ERR_USERSDISABLED         , ReplyCodeInfo ErrorReply "USERSDISABLED")
+  , (ERR_NONICKCHANGE          , ReplyCodeInfo ErrorReply "NONICKCHANGE")
+  , (ERR_NOTIMPLEMENTED        , ReplyCodeInfo ErrorReply "NOTIMPLEMENTED")
+  , (ERR_NOTREGISTERED         , ReplyCodeInfo ErrorReply "NOTREGISTERED")
+  , (ERR_IDCOLLISION           , ReplyCodeInfo ErrorReply "IDCOLLISION")
+  , (ERR_NICKLOST              , ReplyCodeInfo ErrorReply "NICKLOST")
+  , (ERR_HOSTILENAME           , ReplyCodeInfo ErrorReply "HOSTILENAME")
+  , (ERR_ACCEPTFULL            , ReplyCodeInfo ErrorReply "ACCEPTFULL")
+  , (ERR_ACCEPTEXIST           , ReplyCodeInfo ErrorReply "ACCEPTEXIST")
+  , (ERR_ACCEPTNOT             , ReplyCodeInfo ErrorReply "ACCEPTNOT")
+  , (ERR_NOHIDING              , ReplyCodeInfo ErrorReply "NOHIDING")
+  , (ERR_NOTFORHALFOPS         , ReplyCodeInfo ErrorReply "NOTFORHALFOPS")
+  , (ERR_NEEDMOREPARAMS        , ReplyCodeInfo ErrorReply "NEEDMOREPARAMS")
+  , (ERR_ALREADYREGISTERED     , ReplyCodeInfo ErrorReply "ALREADYREGISTERED")
+  , (ERR_NOPERMFORHOST         , ReplyCodeInfo ErrorReply "NOPERMFORHOST")
+  , (ERR_PASSWDMISMATCH        , ReplyCodeInfo ErrorReply "PASSWDMISMATCH")
+  , (ERR_YOUREBANNEDCREEP      , ReplyCodeInfo ErrorReply "YOUREBANNEDCREEP")
+  , (ERR_YOUWILLBEBANNED       , ReplyCodeInfo ErrorReply "YOUWILLBEBANNED")
+  , (ERR_KEYSET                , ReplyCodeInfo ErrorReply "KEYSET")
+  , (ERR_INVALIDUSERNAME       , ReplyCodeInfo ErrorReply "INVALIDUSERNAME")
+  , (ERR_ONLYSERVERSCANCHANGE  , ReplyCodeInfo ErrorReply "ONLYSERVERSCANCHANGE")
+  , (ERR_LINKSET               , ReplyCodeInfo ErrorReply "LINKSET")
+  , (ERR_LINKCHANNEL           , ReplyCodeInfo ErrorReply "LINKCHANNEL")
+  , (ERR_CHANNELISFULL         , ReplyCodeInfo ErrorReply "CHANNELISFULL")
+  , (ERR_UNKNOWNMODE           , ReplyCodeInfo ErrorReply "UNKNOWNMODE")
+  , (ERR_INVITEONLYCHAN        , ReplyCodeInfo ErrorReply "INVITEONLYCHAN")
+  , (ERR_BANNEDFROMCHAN        , ReplyCodeInfo ErrorReply "BANNEDFROMCHAN")
+  , (ERR_BADCHANNELKEY         , ReplyCodeInfo ErrorReply "BADCHANNELKEY")
+  , (ERR_BADCHANMASK           , ReplyCodeInfo ErrorReply "BADCHANMASK")
+  , (ERR_NEEDREGGEDNICK        , ReplyCodeInfo ErrorReply "NEEDREGGEDNICK")
+  , (ERR_BANLISTFULL           , ReplyCodeInfo ErrorReply "BANLISTFULL")
+  , (ERR_BADCHANNAME           , ReplyCodeInfo ErrorReply "BADCHANNAME")
+  , (ERR_THROTTLE              , ReplyCodeInfo ErrorReply "THROTTLE")
+  , (ERR_NOPRIVILEGES          , ReplyCodeInfo ErrorReply "NOPRIVILEGES")
+  , (ERR_CHANOPRIVSNEEDED      , ReplyCodeInfo ErrorReply "CHANOPRIVSNEEDED")
+  , (ERR_CANTKILLSERVER        , ReplyCodeInfo ErrorReply "CANTKILLSERVER")
+  , (ERR_ISCHANSERVICE         , ReplyCodeInfo ErrorReply "ISCHANSERVICE")
+  , (ERR_BANNEDNICK            , ReplyCodeInfo ErrorReply "BANNEDNICK")
+  , (ERR_NONONREG              , ReplyCodeInfo ErrorReply "NONONREG")
+  , (ERR_TSLESSCHAN            , ReplyCodeInfo ErrorReply "TSLESSCHAN")
+  , (ERR_VOICENEEDED           , ReplyCodeInfo ErrorReply "VOICENEEDED")
+  , (ERR_NOOPERHOST            , ReplyCodeInfo ErrorReply "NOOPERHOST")
+  , (ERR_NOSERVICEHOST         , ReplyCodeInfo ErrorReply "NOSERVICEHOST")
+  , (ERR_NOFEATURE             , ReplyCodeInfo ErrorReply "NOFEATURE")
+  , (ERR_OWNMODE               , ReplyCodeInfo ErrorReply "OWNMODE")
+  , (ERR_BADLOGTYPE            , ReplyCodeInfo ErrorReply "BADLOGTYPE")
+  , (ERR_BADLOGSYS             , ReplyCodeInfo ErrorReply "BADLOGSYS")
+  , (ERR_BADLOGVALUE           , ReplyCodeInfo ErrorReply "BADLOGVALUE")
+  , (ERR_ISOPERLCHAN           , ReplyCodeInfo ErrorReply "ISOPERLCHAN")
+  , (ERR_CHANOWNPRIVNEEDED     , ReplyCodeInfo ErrorReply "CHANOWNPRIVNEEDED")
+  , (ERR_UMODEUNKNOWNFLAG      , ReplyCodeInfo ErrorReply "UMODEUNKNOWNFLAG")
+  , (ERR_USERSDONTMATCH        , ReplyCodeInfo ErrorReply "USERSDONTMATCH")
+  , (ERR_GHOSTEDCLIENT         , ReplyCodeInfo ErrorReply "GHOSTEDCLIENT")
+  , (ERR_USERNOTONSERV         , ReplyCodeInfo ErrorReply "USERNOTONSERV")
+  , (ERR_SILELISTFULL          , ReplyCodeInfo ErrorReply "SILELISTFULL")
+  , (ERR_TOOMANYWATCH          , ReplyCodeInfo ErrorReply "TOOMANYWATCH")
+  , (ERR_WRONGPONG             , ReplyCodeInfo ErrorReply "WRONGPONG")
+  , (ERR_BADEXPIRE             , ReplyCodeInfo ErrorReply "BADEXPIRE")
+  , (ERR_DONTCHEAT             , ReplyCodeInfo ErrorReply "DONTCHEAT")
+  , (ERR_DISABLED              , ReplyCodeInfo ErrorReply "DISABLED")
+  , (ERR_NOINVITE              , ReplyCodeInfo ErrorReply "NOINVITE")
+  , (ERR_LONGMASK              , ReplyCodeInfo ErrorReply "LONGMASK")
+  , (ERR_ADMONLY               , ReplyCodeInfo ErrorReply "ADMONLY")
+  , (ERR_TOOMANYUSERS          , ReplyCodeInfo ErrorReply "TOOMANYUSERS")
+  , (ERR_OPERONLY              , ReplyCodeInfo ErrorReply "OPERONLY")
+  , (ERR_MASKTOOWIDE           , ReplyCodeInfo ErrorReply "MASKTOOWIDE")
+  , (ERR_WHOTRUNC              , ReplyCodeInfo ErrorReply "WHOTRUNC")
+  , (ERR_LISTSYNTAX            , ReplyCodeInfo ErrorReply "LISTSYNTAX")
+  , (ERR_WHOSYNTAX             , ReplyCodeInfo ErrorReply "WHOSYNTAX")
+  , (ERR_WHOLIMEXCEED          , ReplyCodeInfo ErrorReply "WHOLIMEXCEED")
+  , (ERR_HELPNOTFOUND          , ReplyCodeInfo ErrorReply "HELPNOTFOUND")
+  , (ERR_REMOTEPFX             , ReplyCodeInfo ErrorReply "REMOTEPFX")
+  , (ERR_PFXUNROUTABLE         , ReplyCodeInfo ErrorReply "PFXUNROUTABLE")
+  , (ERR_BADHOSTMASK           , ReplyCodeInfo ErrorReply "BADHOSTMASK")
+  , (ERR_HOSTUNAVAIL           , ReplyCodeInfo ErrorReply "HOSTUNAVAIL")
+  , (ERR_USINGSLINE            , ReplyCodeInfo ErrorReply "USINGSLINE")
+  , (ERR_STATSSLINE            , ReplyCodeInfo ErrorReply "STATSSLINE")
+  , (RPL_LOGON                 , ReplyCodeInfo CommandReply "LOGON")
+  , (RPL_LOGOFF                , ReplyCodeInfo CommandReply "LOGOFF")
+  , (RPL_WATCHOFF              , ReplyCodeInfo CommandReply "WATCHOFF")
+  , (RPL_WATCHSTAT             , ReplyCodeInfo CommandReply "WATCHSTAT")
+  , (RPL_NOWON                 , ReplyCodeInfo CommandReply "NOWON")
+  , (RPL_NOWOFF                , ReplyCodeInfo CommandReply "NOWOFF")
+  , (RPL_WATCHLIST             , ReplyCodeInfo CommandReply "WATCHLIST")
+  , (RPL_ENDOFWATCHLIST        , ReplyCodeInfo CommandReply "ENDOFWATCHLIST")
+  , (RPL_WATCHCLEAR            , ReplyCodeInfo CommandReply "WATCHCLEAR")
+  , (RPL_ISOPER                , ReplyCodeInfo CommandReply "ISOPER")
+  , (RPL_ISLOCOP               , ReplyCodeInfo CommandReply "ISLOCOP")
+  , (RPL_ISNOTOPER             , ReplyCodeInfo CommandReply "ISNOTOPER")
+  , (RPL_ENDOFISOPER           , ReplyCodeInfo CommandReply "ENDOFISOPER")
+  , (RPL_DCCSTATUS             , ReplyCodeInfo CommandReply "DCCSTATUS")
+  , (RPL_DCCLIST               , ReplyCodeInfo CommandReply "DCCLIST")
+  , (RPL_ENDOFDCCLIST          , ReplyCodeInfo CommandReply "ENDOFDCCLIST")
+  , (RPL_WHOWASHOST            , ReplyCodeInfo CommandReply "WHOWASHOST")
+  , (RPL_DCCINFO               , ReplyCodeInfo CommandReply "DCCINFO")
+  , (RPL_RULES                 , ReplyCodeInfo CommandReply "RULES")
+  , (RPL_ENDOFO                , ReplyCodeInfo CommandReply "ENDOFO")
+  , (RPL_SETTINGS              , ReplyCodeInfo CommandReply "SETTINGS")
+  , (RPL_ENDOFSETTINGS         , ReplyCodeInfo CommandReply "ENDOFSETTINGS")
+  , (RPL_DUMPING               , ReplyCodeInfo CommandReply "DUMPING")
+  , (RPL_DUMPRPL               , ReplyCodeInfo CommandReply "DUMPRPL")
+  , (RPL_EODUMP                , ReplyCodeInfo CommandReply "EODUMP")
+  , (RPL_TRACEROUTE_HOP        , ReplyCodeInfo CommandReply "TRACEROUTE_HOP")
+  , (RPL_TRACEROUTE_START      , ReplyCodeInfo CommandReply "TRACEROUTE_START")
+  , (RPL_MODECHANGEWARN        , ReplyCodeInfo CommandReply "MODECHANGEWARN")
+  , (RPL_CHANREDIR             , ReplyCodeInfo CommandReply "CHANREDIR")
+  , (RPL_SERVMODEIS            , ReplyCodeInfo CommandReply "SERVMODEIS")
+  , (RPL_OTHERUMODEIS          , ReplyCodeInfo CommandReply "OTHERUMODEIS")
+  , (RPL_ENDOF_GENERIC         , ReplyCodeInfo CommandReply "ENDOF_GENERIC")
+  , (RPL_WHOWASDETAILS         , ReplyCodeInfo CommandReply "WHOWASDETAILS")
+  , (RPL_WHOISSECURE           , ReplyCodeInfo CommandReply "WHOISSECURE")
+  , (RPL_UNKNOWNMODES          , ReplyCodeInfo CommandReply "UNKNOWNMODES")
+  , (RPL_CANNOTSETMODES        , ReplyCodeInfo CommandReply "CANNOTSETMODES")
+  , (RPL_LUSERSTAFF            , ReplyCodeInfo CommandReply "LUSERSTAFF")
+  , (RPL_TIMEONSERVERIS        , ReplyCodeInfo CommandReply "TIMEONSERVERIS")
+  , (RPL_NETWORKS              , ReplyCodeInfo CommandReply "NETWORKS")
+  , (RPL_YOURLANGUAGEIS        , ReplyCodeInfo CommandReply "YOURLANGUAGEIS")
+  , (RPL_LANGUAGE              , ReplyCodeInfo CommandReply "LANGUAGE")
+  , (RPL_WHOISSTAFF            , ReplyCodeInfo CommandReply "WHOISSTAFF")
+  , (RPL_WHOISLANGUAGE         , ReplyCodeInfo CommandReply "WHOISLANGUAGE")
+  , (RPL_MODLIST               , ReplyCodeInfo CommandReply "MODLIST")
+  , (RPL_ENDOFMODLIST          , ReplyCodeInfo CommandReply "ENDOFMODLIST")
+  , (RPL_HELPSTART             , ReplyCodeInfo CommandReply "HELPSTART")
+  , (RPL_HELPTXT               , ReplyCodeInfo CommandReply "HELPTXT")
+  , (RPL_ENDOFHELP             , ReplyCodeInfo CommandReply "ENDOFHELP")
+  , (ERR_TARGCHANGE            , ReplyCodeInfo ErrorReply "TARGCHANGE")
+  , (RPL_ETRACEFULL            , ReplyCodeInfo CommandReply "ETRACEFULL")
+  , (RPL_ETRACE                , ReplyCodeInfo CommandReply "ETRACE")
+  , (RPL_KNOCK                 , ReplyCodeInfo CommandReply "KNOCK")
+  , (RPL_KNOCKDLVR             , ReplyCodeInfo CommandReply "KNOCKDLVR")
+  , (ERR_TOOMANYKNOCK          , ReplyCodeInfo ErrorReply "TOOMANYKNOCK")
+  , (ERR_CHANOPEN              , ReplyCodeInfo ErrorReply "CHANOPEN")
+  , (ERR_KNOCKONCHAN           , ReplyCodeInfo ErrorReply "KNOCKONCHAN")
+  , (ERR_KNOCKDISABLED         , ReplyCodeInfo ErrorReply "KNOCKDISABLED")
+  , (RPL_TARGUMODEG            , ReplyCodeInfo CommandReply "TARGUMODEG")
+  , (RPL_TARGNOTIFY            , ReplyCodeInfo CommandReply "TARGNOTIFY")
+  , (RPL_UMODEGMSG             , ReplyCodeInfo CommandReply "UMODEGMSG")
+  , (RPL_OMOTDSTART            , ReplyCodeInfo CommandReply "OMOTDSTART")
+  , (RPL_OMOTD                 , ReplyCodeInfo CommandReply "OMOTD")
+  , (RPL_ENDOFOMOTD            , ReplyCodeInfo CommandReply "ENDOFOMOTD")
+  , (ERR_NOPRIVS               , ReplyCodeInfo ErrorReply "NOPRIVS")
+  , (RPL_TESTMASK              , ReplyCodeInfo CommandReply "TESTMASK")
+  , (RPL_TESTLINE              , ReplyCodeInfo CommandReply "TESTLINE")
+  , (RPL_NOTESTLINE            , ReplyCodeInfo CommandReply "NOTESTLINE")
+  , (RPL_QUIETLIST             , ReplyCodeInfo CommandReply "QUIETLIST")
+  , (RPL_ENDOFQUIETLIST        , ReplyCodeInfo CommandReply "ENDOFQUIETLIST")
+  , (RPL_MONONLINE             , ReplyCodeInfo CommandReply "MONONLINE")
+  , (RPL_MONOFFLINE            , ReplyCodeInfo CommandReply "MONOFFLINE")
+  , (RPL_MONLIST               , ReplyCodeInfo CommandReply "MONLIST")
+  , (RPL_ENDOFMONLIST          , ReplyCodeInfo CommandReply "ENDOFMONLIST")
+  , (ERR_MONLISTFULL           , ReplyCodeInfo ErrorReply "MONLISTFULL")
+  , (RPL_RSACHALLENGE2         , ReplyCodeInfo CommandReply "RSACHALLENGE2")
+  , (RPL_ENDOFRSACHALLENGE2    , ReplyCodeInfo CommandReply "ENDOFRSACHALLENGE2")
+  , (ERR_MLOCKRESTRICTED       , ReplyCodeInfo ErrorReply "MLOCKRESTRICTED")
+  , (RPL_SCANMATCHED           , ReplyCodeInfo CommandReply "SCANMATCHED")
+  , (RPL_SCANUMODES            , ReplyCodeInfo CommandReply "SCANUMODES")
+  , (RPL_XINFO                 , ReplyCodeInfo CommandReply "XINFO")
+  , (RPL_XINFOSTART            , ReplyCodeInfo CommandReply "XINFOSTART")
+  , (RPL_XINFOEND              , ReplyCodeInfo CommandReply "XINFOEND")
+  , (RPL_LOGGEDIN              , ReplyCodeInfo CommandReply "LOGGEDIN")
+  , (RPL_LOGGEDOUT             , ReplyCodeInfo CommandReply "LOGGEDOUT")
+  , (RPL_NICKLOCKED            , ReplyCodeInfo CommandReply "NICKLOCKED")
+  , (RPL_SASLSUCCESS           , ReplyCodeInfo CommandReply "SASLSUCCESS")
+  , (RPL_SASLFAIL              , ReplyCodeInfo CommandReply "SASLFAIL")
+  , (RPL_SASLTOOLONG           , ReplyCodeInfo CommandReply "SASLTOOLONG")
+  , (RPL_SASLABORTED           , ReplyCodeInfo CommandReply "SASLABORTED")
+  , (RPL_SASLALREADY           , ReplyCodeInfo CommandReply "SASLALREADY")
+  , (RPL_SASLMECHS             , ReplyCodeInfo CommandReply "SASLMECHS")
+  , (ERR_CANNOTDOCOMMAND       , ReplyCodeInfo ErrorReply "CANNOTDOCOMMAND")
+  , (ERR_CANNOTCHANGEUMODE     , ReplyCodeInfo ErrorReply "CANNOTCHANGEUMODE")
+  , (ERR_CANNOTCHANGECHANMODE  , ReplyCodeInfo ErrorReply "CANNOTCHANGECHANMODE")
+  , (ERR_CANNOTCHANGESERVERMODE, ReplyCodeInfo ErrorReply "CANNOTCHANGESERVERMODE")
+  , (ERR_CANNOTSENDTONICK      , ReplyCodeInfo ErrorReply "CANNOTSENDTONICK")
+  , (ERR_UNKNOWNSERVERMODE     , ReplyCodeInfo ErrorReply "UNKNOWNSERVERMODE")
+  , (ERR_SERVERMODELOCK        , ReplyCodeInfo ErrorReply "SERVERMODELOCK")
+  , (ERR_BADCHARENCODING       , ReplyCodeInfo ErrorReply "BADCHARENCODING")
+  , (ERR_TOOMANYLANGUAGES      , ReplyCodeInfo ErrorReply "TOOMANYLANGUAGES")
+  , (ERR_NOLANGUAGE            , ReplyCodeInfo ErrorReply "NOLANGUAGE")
+  , (ERR_TEXTTOOSHORT          , ReplyCodeInfo ErrorReply "TEXTTOOSHORT")
+  , (ERR_NUMERIC_ERR           , ReplyCodeInfo ErrorReply "NUMERIC_ERR")
+  ]
diff --git a/src/Irc/Commands.hs b/src/Irc/Commands.hs
--- a/src/Irc/Commands.hs
+++ b/src/Irc/Commands.hs
@@ -28,12 +28,19 @@
   , ircWho
   , ircWhois
   , ircWhowas
+
+  -- * SASL support
+  , ircAuthenticate
+  , plainAuthenticationMode
+  , encodePlainAuthentication
   ) where
 
 import           Irc.RawIrcMsg
 import           Irc.Identifier
 import           Data.Text (Text)
 import qualified Data.Text as Text
+import qualified Data.Text.Encoding as Text
+import qualified Data.ByteArray.Encoding as Enc
 
 -- | PRIVMSG command
 ircPrivmsg ::
@@ -167,3 +174,19 @@
 -- | CAP LS command
 ircCapLs :: RawIrcMsg
 ircCapLs = rawIrcMsg "CAP" ["LS"]
+
+ircAuthenticate :: Text -> RawIrcMsg
+ircAuthenticate msg = rawIrcMsg "AUTHENTICATE" [msg]
+
+plainAuthenticationMode :: Text
+plainAuthenticationMode = "PLAIN"
+
+encodePlainAuthentication ::
+  Text {- ^ username -} ->
+  Text {- ^ password -} ->
+  Text
+encodePlainAuthentication user pass
+  = Text.decodeUtf8
+  $ Enc.convertToBase Enc.Base64
+  $ Text.encodeUtf8
+  $ Text.intercalate "\0" [user,user,pass]
diff --git a/src/Irc/Message.hs b/src/Irc/Message.hs
--- a/src/Irc/Message.hs
+++ b/src/Irc/Message.hs
@@ -39,10 +39,11 @@
 import           Irc.Identifier
 import           Irc.RawIrcMsg
 import           Irc.UserInfo
+import           Irc.Codes
 
 data IrcMsg
   = UnknownMsg RawIrcMsg
-  | Reply Int [Text]
+  | Reply ReplyCode [Text]
   | Nick UserInfo Identifier
   | Join UserInfo Identifier
   | Part UserInfo Identifier (Maybe Text)
@@ -53,6 +54,7 @@
   | Action UserInfo Identifier Text -- ^ source target txt
   | Notice UserInfo Identifier Text -- ^ source target txt
   | Mode UserInfo Identifier [Text] -- ^ source target txt
+  | Authenticate Text
   | Cap CapCmd [Text]
   | Ping [Text]
   | Pong [Text]
@@ -81,11 +83,14 @@
 cookIrcMsg msg =
   case view msgCommand msg of
     cmd | Right (n,"") <- decimal cmd ->
-        Reply n (view msgParams msg)
+        Reply (ReplyCode n) (view msgParams msg)
     "CAP" | _target:cmdTxt:rest <- view msgParams msg
           , Just cmd <- cookCapCmd cmdTxt ->
            Cap cmd rest
 
+    "AUTHENTICATE" | x:_ <- view msgParams msg ->
+        Authenticate x
+
     "PING" -> Ping (view msgParams msg)
     "PONG" -> Pong (view msgParams msg)
 
@@ -161,6 +166,7 @@
                       | otherwise -> TargetWindow tgt
     Notice  src tgt _ | tgt == me -> TargetWindow (userNick src)
                       | otherwise -> TargetWindow tgt
+    Authenticate{}                -> TargetHidden
     Ping{}                        -> TargetHidden
     Pong{}                        -> TargetHidden
     Error{}                       -> TargetNetwork
@@ -183,6 +189,7 @@
     Action x _ _  -> Just x
     Notice x _ _  -> Just x
     Mode x _ _    -> Just x
+    Authenticate{}-> Nothing
     Ping{}        -> Nothing
     Pong{}        -> Nothing
     Error{}       -> Nothing
@@ -194,7 +201,7 @@
 ircMsgText msg =
   case msg of
     UnknownMsg raw -> Text.unwords (view msgCommand raw : view msgParams raw)
-    Reply n xs     -> Text.unwords (Text.pack (show n) : xs)
+    Reply (ReplyCode n) xs -> Text.unwords (Text.pack (show n) : xs)
     Nick x y       -> Text.unwords [renderUserInfo x, idText y]
     Join x _       -> renderUserInfo x
     Part x _ mb    -> Text.unwords (renderUserInfo x : maybeToList mb)
@@ -209,6 +216,7 @@
     Pong xs        -> Text.unwords xs
     Cap _ xs       -> Text.unwords xs
     Error t        -> t
+    Authenticate{} -> ""
 
 -- nickname   =  ( letter / special ) *8( letter / digit / special / "-" )
 -- letter     =  %x41-5A / %x61-7A       ; A-Z / a-z
diff --git a/src/Irc/RateLimit.hs b/src/Irc/RateLimit.hs
--- a/src/Irc/RateLimit.hs
+++ b/src/Irc/RateLimit.hs
@@ -18,7 +18,6 @@
 module Irc.RateLimit
   ( RateLimit
   , newRateLimit
-  , newRateLimitDefault
   , tickRateLimit
   ) where
 
@@ -33,11 +32,6 @@
   , rateThreshold :: !Int            -- ^ seconds
   , ratePenalty   :: !Int            -- ^ seconds
   }
-
--- | Construct a new rate limit with the RFC 2813 specified
--- 2 second penalty and 10 second threshold
-newRateLimitDefault :: IO RateLimit
-newRateLimitDefault = newRateLimit 2 12
 
 -- | Construct a new rate limit with the given penalty and threshold.
 newRateLimit ::
