diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # Revision history for irc-core
 
+## 2.8
+
+* `encodePlainAuthentication` has separate authorization and authentication identity parameters
+* Add `ircMonitor` and `ircTrace`
+* Add realname field to `Join` for use with `extended-join`
+
 ## 2.7.2
 
 * Replace empty, non-optional parameters with asterisk (`*`)
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.7.2
+version:             2.8
 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.11 && <4.14,
+  build-depends:       base       >=4.11 && <4.15,
                        base64-bytestring >= 1.0.0.1 && <1.1,
                        attoparsec >=0.13 && <0.14,
                        bytestring >=0.10 && <0.11,
diff --git a/src/Irc/Commands.hs b/src/Irc/Commands.hs
--- a/src/Irc/Commands.hs
+++ b/src/Irc/Commands.hs
@@ -32,6 +32,7 @@
   , ircMap
   , ircMasktrace
   , ircMode
+  , ircMonitor
   , ircMotd
   , ircNick
   , ircNotice
@@ -49,6 +50,7 @@
   , ircTestmask
   , ircTime
   , ircTopic
+  , ircTrace
   , ircUnkline
   , ircUser
   , ircUserhost
@@ -130,6 +132,11 @@
   RawIrcMsg
 ircMode tgt params = rawIrcMsg "MODE" (idText tgt : params)
 
+ircMonitor ::
+  [Text] {- ^ parameters -} ->
+  RawIrcMsg
+ircMonitor params = rawIrcMsg "MONITOR" params
+
 -- | WHOIS command
 ircWhois ::
   [Text] {- ^ parameters -} ->
@@ -292,7 +299,7 @@
 
 -- | TIME command
 ircTime ::
-  Text {- ^ servername -} ->
+  Text {- ^ optional servername -} ->
   RawIrcMsg
 ircTime = rawIrcMsg "TIME" . nonempty
 
@@ -310,7 +317,7 @@
 
 -- | USERS command
 ircUsers ::
-  Text {- ^ server -} ->
+  Text {- ^ optional servername -} ->
   RawIrcMsg
 ircUsers = rawIrcMsg "USERS" . nonempty
 
@@ -383,6 +390,14 @@
   RawIrcMsg
 ircAdmin = rawIrcMsg "ADMIN" . nonempty
 
+-- | TRACE command
+--
+-- > TRACE [<target>]
+ircTrace ::
+  [Text] {- ^ params -} ->
+  RawIrcMsg
+ircTrace = rawIrcMsg "TRACE"
+
 -- | USER command
 ircUser ::
   Text {- ^ username -} ->
@@ -436,18 +451,17 @@
 
 -- | Encoding of username and password in PLAIN authentication
 encodePlainAuthentication ::
-  Text {- ^ username -} ->
+  Text {- ^ authorization identity -} ->
+  Text {- ^ authentication identity -} ->
   Text {- ^ password -} ->
   AuthenticatePayload
-encodePlainAuthentication user pass
+encodePlainAuthentication authz authc pass
   = AuthenticatePayload
   $ Text.encodeUtf8
-  $ Text.intercalate "\0" [user,user,pass]
+  $ Text.intercalate "\0" [authz,authc,pass]
 
 -- | Encoding of username in EXTERNAL authentication
 encodeExternalAuthentication ::
-  Text {- ^ username -} ->
+  Text {- ^ authorization identity -} ->
   AuthenticatePayload
-encodeExternalAuthentication
-  = AuthenticatePayload
-  . Text.encodeUtf8
+encodeExternalAuthentication authz = AuthenticatePayload (Text.encodeUtf8 authz)
diff --git a/src/Irc/Message.hs b/src/Irc/Message.hs
--- a/src/Irc/Message.hs
+++ b/src/Irc/Message.hs
@@ -49,7 +49,7 @@
   = UnknownMsg !RawIrcMsg -- ^ pass-through for unhandled messages
   | Reply !ReplyCode [Text] -- ^ code arguments
   | Nick !UserInfo !Identifier -- ^ old new
-  | Join !UserInfo !Identifier !Text -- ^ user channel account(extended-join)
+  | Join !UserInfo !Identifier !Text !Text -- ^ user channel account account gecos
   | Part !UserInfo !Identifier (Maybe Text) -- ^ user channel reason
   | Quit !UserInfo (Maybe Text) -- ^ user reason
   | Kick !UserInfo !Identifier !Identifier !Text -- ^ kicker channel kickee comment
@@ -128,13 +128,11 @@
              Nothing         -> Notice user (mkId chan) txt
 
     "JOIN" | Just user <- view msgPrefix msg
-           , chan:rest <- view msgParams msg ->
-
-              Join user (mkId chan)
-            $ case rest of
-                ["*" , _real] -> ""
-                [acct, _real] -> acct
-                _             -> ""
+           , chan:rest <- view msgParams msg
+           , let (a, r) = case rest of
+                            [acct, real] -> (acct, real)
+                            _            -> ("", "") ->
+           Join user (mkId chan) a r
 
     "QUIT" | Just user <- view msgPrefix msg
            , reasons   <- view msgParams msg ->
@@ -213,7 +211,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
@@ -250,7 +248,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
@@ -279,7 +277,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]
