diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # Revision history for irc-core
 
+## 2.5.0
+
+* Add support for extended JOIN and ACCOUNT messages
+* Added CAP NEW and CAP DEL
+
 ## 2.4.0
 
 * Change TOPIC and INVITING replies to channel target
diff --git a/irc-core.cabal b/irc-core.cabal
--- a/irc-core.cabal
+++ b/irc-core.cabal
@@ -1,5 +1,5 @@
 name:                irc-core
-version:             2.4.0
+version:             2.5.0
 synopsis:            IRC core library for glirc
 description:         IRC core library for glirc
                      .
@@ -32,7 +32,7 @@
                        Irc.UserInfo
   other-modules:       View
 
-  build-depends:       base       >=4.9  && <4.12,
+  build-depends:       base       >=4.11 && <4.12,
                        base64-bytestring >= 1.0.0.1 && <1.1,
                        attoparsec >=0.13 && <0.14,
                        bytestring >=0.10 && <0.11,
diff --git a/src/Irc/Message.hs b/src/Irc/Message.hs
--- a/src/Irc/Message.hs
+++ b/src/Irc/Message.hs
@@ -47,7 +47,7 @@
   = UnknownMsg !RawIrcMsg -- ^ pass-through for unhandled messages
   | Reply !ReplyCode [Text] -- ^ code arguments
   | Nick !UserInfo !Identifier -- ^ old new
-  | Join !UserInfo !Identifier -- ^ user channel
+  | Join !UserInfo !Identifier !Text -- ^ user channel account(extended-join)
   | Part !UserInfo !Identifier (Maybe Text) -- ^ user channel reason
   | Quit !UserInfo (Maybe Text) -- ^ user reason
   | Kick !UserInfo !Identifier !Identifier !Text -- ^ kicker channel kickee comment
@@ -63,7 +63,8 @@
   | Pong [Text] -- ^ parameters
   | Error !Text -- ^ message
   | BatchStart Text Text [Text] -- ^ reference-id type parameters
-  | BatchEnd   Text             -- ^ reference-id
+  | BatchEnd Text -- ^ reference-id
+  | Account !UserInfo Text -- ^ user account name changed (account-notify extension)
   deriving Show
 
 -- | Sub-commands of the CAP command
@@ -74,6 +75,8 @@
   | CapAck -- ^ request accepted
   | CapNak -- ^ request denied
   | CapEnd -- ^ end negotiation
+  | CapNew -- ^ new capability available (cap-notify extension)
+  | CapDel -- ^ capability removed (cap-notify extension)
   deriving (Show, Eq, Ord)
 
 -- | Match command text to structured cap sub-command
@@ -84,6 +87,8 @@
 cookCapCmd "NAK"  = Just CapNak
 cookCapCmd "END"  = Just CapEnd
 cookCapCmd "REQ"  = Just CapReq
+cookCapCmd "NEW"  = Just CapNew
+cookCapCmd "DEL"  = Just CapDel
 cookCapCmd _      = Nothing
 
 -- | Interpret a low-level 'RawIrcMsg' as a high-level 'IrcMsg'.
@@ -118,9 +123,13 @@
              Nothing         -> Notice user (mkId chan) txt
 
     "JOIN" | Just user <- view msgPrefix msg
-           , chan:_    <- view msgParams msg ->
+           , chan:rest <- view msgParams msg ->
 
-           Join user (mkId chan)
+           let acct = case rest of
+                 ["*" , _real] -> ""
+                 [acct, _real] -> acct
+                 _             -> ""
+           in Join user (mkId chan) acct
 
     "QUIT" | Just user <- view msgPrefix msg
            , reasons   <- view msgParams msg ->
@@ -157,6 +166,10 @@
             , Just ('-',refid') <- Text.uncons refid ->
             BatchEnd refid'
 
+    "ACCOUNT" | Just user <- view msgPrefix msg
+              , [acct] <- view msgParams msg ->
+      Account user (if acct == "*" then "" else acct)
+
     _      -> UnknownMsg msg
 
 -- | Parse a CTCP encoded message:
@@ -186,7 +199,7 @@
     Nick user _              -> TargetUser (userNick user)
     Mode _ tgt _ | tgt == me -> TargetNetwork
                  | otherwise -> TargetWindow tgt
-    Join _ chan              -> TargetWindow chan
+    Join _ chan _            -> TargetWindow chan
     Part _ chan _            -> TargetWindow chan
     Quit user _              -> TargetUser (userNick user)
     Kick _ chan _ _          -> TargetWindow chan
@@ -203,6 +216,7 @@
     Reply code args          -> replyTarget code args
     BatchStart{}             -> TargetHidden
     BatchEnd{}               -> TargetHidden
+    Account{}                -> TargetHidden
   where
     directed src tgt
       | Text.null (userHost src) = TargetNetwork -- server message
@@ -222,7 +236,7 @@
     UnknownMsg{}  -> Nothing
     Reply{}       -> Nothing
     Nick x _      -> Just x
-    Join x _      -> Just x
+    Join x _ _    -> Just x
     Part x _ _    -> Just x
     Quit x _      -> Just x
     Kick x _ _ _  -> Just x
@@ -232,6 +246,7 @@
     CtcpNotice x _ _ _ -> Just x
     Notice x _ _  -> Just x
     Mode x _ _    -> Just x
+    Account x _   -> Just x
     Authenticate{}-> Nothing
     Ping{}        -> Nothing
     Pong{}        -> Nothing
@@ -248,7 +263,7 @@
     UnknownMsg raw -> Text.unwords (view msgCommand raw : view msgParams raw)
     Reply (ReplyCode n) xs -> Text.unwords (Text.pack (show n) : xs)
     Nick x y       -> Text.unwords [renderUserInfo x, idText y]
-    Join x _       -> renderUserInfo x
+    Join x _ _     -> renderUserInfo x
     Part x _ mb    -> Text.unwords (renderUserInfo x : maybeToList mb)
     Quit x mb      -> Text.unwords (renderUserInfo x : maybeToList mb)
     Kick x _ z r   -> Text.unwords [renderUserInfo x, idText z, r]
@@ -262,6 +277,7 @@
     Pong xs        -> Text.unwords xs
     Cap _ xs       -> Text.unwords xs
     Error t        -> t
+    Account x a    -> Text.unwords [renderUserInfo x, a]
     Authenticate{} -> ""
     BatchStart{}   -> ""
     BatchEnd{}     -> ""
diff --git a/src/Irc/RawIrcMsg.hs b/src/Irc/RawIrcMsg.hs
--- a/src/Irc/RawIrcMsg.hs
+++ b/src/Irc/RawIrcMsg.hs
@@ -68,8 +68,8 @@
 data RawIrcMsg = RawIrcMsg
   { _msgTags       :: [TagEntry]     -- ^ IRCv3.2 message tags
   , _msgPrefix     :: Maybe UserInfo -- ^ Optional sender of message
-  , _msgCommand    :: !Text          -- ^ command
-  , _msgParams     :: [Text]         -- ^ command parameters
+  , _msgCommand    :: !Text          -- ^ Command
+  , _msgParams     :: [Text]         -- ^ Command parameters
   }
   deriving (Eq, Read, Show)
 
diff --git a/src/Irc/UserInfo.hs b/src/Irc/UserInfo.hs
--- a/src/Irc/UserInfo.hs
+++ b/src/Irc/UserInfo.hs
@@ -13,16 +13,24 @@
 -}
 
 module Irc.UserInfo
-  ( UserInfo(..)
+  (
+  -- * Type
+    UserInfo(..)
+
+  -- * Parser and printer
   , renderUserInfo
   , parseUserInfo
+
+  -- * Lenses
   , uiNick
+  , uiName
+  , uiHost
   ) where
 
-import           Data.Text      (Text)
-import qualified Data.Text      as Text
+import           Data.Text (Text)
+import qualified Data.Text as Text
+
 import           Irc.Identifier
-import           Data.Monoid ((<>))
 
 -- | 'UserInfo' packages a nickname along with the username and hsotname
 -- if they are known in the current context.
@@ -33,9 +41,17 @@
   }
   deriving (Eq, Read, Show)
 
--- | 'Lens' into 'userNick' field.
+-- | Lens into 'userNick' field.
 uiNick :: Functor f => (Identifier -> f Identifier) -> UserInfo -> f UserInfo
 uiNick f ui@UserInfo{userNick = n} = (\n' -> ui{userNick = n'}) <$> f n
+
+-- | Lens into 'userName' field.
+uiName :: Functor f => (Text -> f Text) -> UserInfo -> f UserInfo
+uiName f ui@UserInfo{userName = n} = (\n' -> ui{userName = n'}) <$> f n
+
+-- | Lens into 'userHost' field.
+uiHost :: Functor f => (Text -> f Text) -> UserInfo -> f UserInfo
+uiHost f ui@UserInfo{userHost = n} = (\n' -> ui{userHost = n'}) <$> f n
 
 -- | Render 'UserInfo' as @nick!username\@hostname@
 renderUserInfo :: UserInfo -> Text
