diff --git a/slixmpp/plugins/xep_0045/muc.py b/slixmpp/plugins/xep_0045/muc.py
index 8e021750..e5971bee 100644
--- a/slixmpp/plugins/xep_0045/muc.py
+++ b/slixmpp/plugins/xep_0045/muc.py
@@ -56,6 +56,7 @@ from slixmpp.types import (
     PresenceArgs,
 )
 
+JoinResult = Tuple[Presence, Message, List[Presence], List[Message]]
 
 log = logging.getLogger(__name__)
 
@@ -71,7 +72,7 @@ class XEP_0045(BasePlugin):
 
     name = 'xep_0045'
     description = 'XEP-0045: Multi-User Chat'
-    dependencies = {'xep_0030', 'xep_0004'}
+    dependencies = {'xep_0030', 'xep_0004', 'xep_0203'}
     stanza = stanza
 
     rooms: Dict[JID, Dict[str, MucRoomItem]]
@@ -254,7 +255,7 @@ class XEP_0045(BasePlugin):
         if msg['body'] or msg['thread']:
             return
         self.xmpp.event('groupchat_subject', msg)
-        self.xmpp.event('muc::%s::groupchat_subject' % msg['from'].bare)
+        self.xmpp.event('muc::%s::groupchat_subject' % msg['from'].bare, msg)
 
     async def join_muc_wait(self, room: JID, nick: str, *,
                             password: Optional[str] = None,
@@ -263,7 +264,7 @@ class XEP_0045(BasePlugin):
                             seconds: Optional[int] = None,
                             since: Optional[datetime] = None,
                             presence_options: Optional[PresenceArgs] = None,
-                            timeout: Optional[int] = None) -> Tuple[Presence, Message]:
+                            timeout: Optional[int] = None) -> JoinResult:
         """
         Try to join a MUC and block until we are joined or get an error.
 
@@ -283,7 +284,8 @@ class XEP_0045(BasePlugin):
                  presence error.
         :raises: An asyncio.TimeoutError if there is neither success nor
                 presence error when the timeout is reached.
-        :return: Our own presence and the subject
+        :return: A tuple containing our own presence, the subject, a list
+                 of occupants and a list of history messages.
         """
         if presence_options is None:
             presence_options = {}
@@ -306,14 +308,36 @@ class XEP_0045(BasePlugin):
         self.rooms[room] = {}
         self.our_nicks[room] = nick
         stanza.send()
+        return await self._await_join(room, timeout)
 
+    async def _await_join(self, room: JID, timeout: Optional[int] = None) -> JoinResult:
+        """Do the heavy lifting for awaiting a MUC join
+
+        A muc join, once the join stanza is sent, is:
+            occupant presences → self-presence → room history → room subject
+        """
         presence_done: asyncio.Future = asyncio.Future()
         topic_received: asyncio.Future = asyncio.Future()
-        context0 = self.xmpp.event_handler("muc::%s::groupchat_subject" % room, topic_received.set_result)
-        context1 = self.xmpp.event_handler("muc::%s::self-presence" % room, presence_done.set_result)
-        context2 = self.xmpp.event_handler("muc::%s::presence-error" % room, presence_done.set_result)
-        with context0:
-            with context1, context2:
+        history_buffer: List[Message] = []
+        occupant_buffer: List[Presence] = []
+
+        def add_message(msg: Message):
+            delay = msg.get_plugin('delay', check=True)
+            print(delay)
+            if delay is not None and delay['from'] == room:
+                history_buffer.append(msg)
+
+        def add_occupant(pres: Presence):
+            occupant_buffer.append(pres)
+
+        catch_occupants = self.xmpp.event_handler("muc::%s::got_online" % room, add_occupant)
+        catch_history = self.xmpp.event_handler("muc::%s::message" % room, add_message)
+        subject_handler = self.xmpp.event_handler("muc::%s::groupchat_subject" % room, topic_received.set_result)
+        self_presence = self.xmpp.event_handler("muc::%s::self-presence" % room, presence_done.set_result)
+        presence_error = self.xmpp.event_handler("muc::%s::presence-error" % room, presence_done.set_result)
+
+        with subject_handler, catch_history, catch_occupants:
+            with self_presence, presence_error:
                 done, pending = await asyncio.wait(
                     [presence_done],
                     timeout=timeout,
@@ -332,7 +356,7 @@ class XEP_0045(BasePlugin):
         subject: Message = topic_received.result()
         # update known nick in case it has changed
         self.our_nicks[room] = pres['from'].resource
-        return (pres, subject)
+        return (pres, subject, occupant_buffer, history_buffer)
 
     def join_muc(self, room: JID, nick: str, maxhistory="0", password='',
                  pstatus='', pshow='', pfrom='') -> asyncio.Future: