Index: irc.h
===================================================================
--- irc.h	(revision 61e7e02096c7910addba32a9060a5e0cba68284b)
+++ irc.h	(revision e4f08bfadf99f5aadcfa0b3ded8da8f72295e72e)
@@ -147,4 +147,7 @@
 	IRC_CHANNEL_TEMP = 2,   /* Erase the channel when the user leaves,
 	                           and don't save it. */
+
+	/* Show a placeholder of the channel in listings, but don't save it */
+	IRC_CHANNEL_KEEP_PLACEHOLDER = 4,
 
 	/* Hack: Set this flag right before jumping into IM when we expect
Index: irc_channel.c
===================================================================
--- irc_channel.c	(revision 61e7e02096c7910addba32a9060a5e0cba68284b)
+++ irc_channel.c	(revision e4f08bfadf99f5aadcfa0b3ded8da8f72295e72e)
@@ -276,5 +276,5 @@
 		if (ic->irc->status & USTATUS_SHUTDOWN) {
 			/* Don't do anything fancy when we're shutting down anyway. */
-		} else if (ic->flags & IRC_CHANNEL_TEMP) {
+		} else if (ic->flags & IRC_CHANNEL_TEMP && !(ic->flags & IRC_CHANNEL_KEEP_PLACEHOLDER)) {
 			irc_channel_free_soon(ic);
 		} else {
Index: irc_im.c
===================================================================
--- irc_im.c	(revision 61e7e02096c7910addba32a9060a5e0cba68284b)
+++ irc_im.c	(revision e4f08bfadf99f5aadcfa0b3ded8da8f72295e72e)
@@ -576,9 +576,17 @@
 	ic->data = c;
 
-	topic = g_strdup_printf(
-	        "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!",
-	        c->title);
-	irc_channel_set_topic(ic, topic, irc->root);
-	g_free(topic);
+	if (ic->topic == NULL) {
+		/* New channel with no preset topic - make up a generic one */
+		topic = g_strdup_printf(
+		        "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!",
+		        c->title);
+		irc_channel_set_topic(ic, topic, irc->root);
+	} else {
+		/* Preset topic from the channel we picked */
+		topic = g_strdup(ic->topic);
+	}
+
+	g_free(c->topic);
+	c->topic = topic;         /* Let groupchat borrow this pointer */
 
 	return TRUE;
@@ -600,4 +608,25 @@
 	c->ui_data = NULL;
 	irc_channel_del_user(ic, ic->irc->user, IRC_CDU_KICK, "Chatroom closed by server");
+
+	return TRUE;
+}
+
+static gboolean bee_irc_chat_placeholder_new(bee_t *bee, struct im_connection *ic, const char *handle,
+                                             const char *name, const char *topic)
+{
+	irc_t *irc = bee->ui_data;
+	irc_channel_t *ircc;
+	char *full_name = irc_channel_name_gen(irc, name);
+
+	ircc = irc_channel_new(irc, full_name);
+
+	set_setstr(&ircc->set, "type", "chat");
+	set_setstr(&ircc->set, "chat_type", "placeholder");
+	set_setstr(&ircc->set, "account", ic->acc->tag);
+	set_setstr(&ircc->set, "room", (char *) handle);
+
+	irc_channel_set_topic(ircc, topic, NULL);
+
+	g_free(full_name);
 
 	return TRUE;
@@ -826,8 +855,10 @@
 static gboolean bee_irc_channel_chat_join(irc_channel_t *ic)
 {
-	char *acc_s, *room;
+	char *acc_s, *room, *chat_type;
 	account_t *acc;
 
-	if (strcmp(set_getstr(&ic->set, "chat_type"), "room") != 0) {
+	chat_type = set_getstr(&ic->set, "chat_type");
+
+	if (strcmp(chat_type, "room") != 0 && strcmp(chat_type, "placeholder") != 0) {
 		return TRUE;
 	}
@@ -985,8 +1016,12 @@
 	struct irc_channel *ic = set->data;
 
+	ic->flags &= ~(IRC_CHANNEL_TEMP | IRC_CHANNEL_KEEP_PLACEHOLDER);
+
 	if (strcmp(value, "groupchat") == 0) {
 		ic->flags |= IRC_CHANNEL_TEMP;
 	} else if (strcmp(value, "room") == 0) {
-		ic->flags &= ~IRC_CHANNEL_TEMP;
+		// beep boop
+	} else if (strcmp(value, "placeholder") == 0) {
+		ic->flags |= IRC_CHANNEL_TEMP | IRC_CHANNEL_KEEP_PLACEHOLDER;
 	} else {
 		return NULL;
@@ -1072,4 +1107,5 @@
 	bee_irc_chat_new,
 	bee_irc_chat_free,
+	bee_irc_chat_placeholder_new,
 	bee_irc_chat_log,
 	bee_irc_chat_msg,
Index: protocols/bee.h
===================================================================
--- protocols/bee.h	(revision 61e7e02096c7910addba32a9060a5e0cba68284b)
+++ protocols/bee.h	(revision e4f08bfadf99f5aadcfa0b3ded8da8f72295e72e)
@@ -115,4 +115,6 @@
 	gboolean (*chat_new)(bee_t *bee, struct groupchat *c);
 	gboolean (*chat_free)(bee_t *bee, struct groupchat *c);
+	gboolean (*chat_placeholder_new)(bee_t *bee, struct im_connection *ic, const char *handle,
+	                                 const char *name, const char *topic);
 	/* System messages of any kind. */
 	gboolean (*chat_log)(bee_t *bee, struct groupchat *c, const char *text);
@@ -166,4 +168,6 @@
  *   user, too. */
 G_MODULE_EXPORT struct groupchat *imcb_chat_new(struct im_connection *ic, const char *handle);
+G_MODULE_EXPORT void imcb_chat_placeholder_new(struct im_connection *ic, const char *handle, const char *name,
+                                               const char *topic);
 G_MODULE_EXPORT void imcb_chat_name_hint(struct groupchat *c, const char *name);
 G_MODULE_EXPORT void imcb_chat_free(struct groupchat *c);
Index: protocols/bee_chat.c
===================================================================
--- protocols/bee_chat.c	(revision 61e7e02096c7910addba32a9060a5e0cba68284b)
+++ protocols/bee_chat.c	(revision e4f08bfadf99f5aadcfa0b3ded8da8f72295e72e)
@@ -54,4 +54,13 @@
 }
 
+void imcb_chat_placeholder_new(struct im_connection *ic, const char *handle, const char *name, const char *topic)
+{
+	bee_t *bee = ic->bee;
+
+	if (bee->ui->chat_placeholder_new) {
+		bee->ui->chat_placeholder_new(bee, ic, handle, name, topic);
+	}
+}
+
 void imcb_chat_name_hint(struct groupchat *c, const char *name)
 {
Index: protocols/jabber/hipchat.c
===================================================================
--- protocols/jabber/hipchat.c	(revision 61e7e02096c7910addba32a9060a5e0cba68284b)
+++ protocols/jabber/hipchat.c	(revision e4f08bfadf99f5aadcfa0b3ded8da8f72295e72e)
@@ -27,7 +27,8 @@
 {
 	struct jabber_data *jd = ic->proto_data;
-	char *sep, *jid;
+	char *sep, *jid, *muc_host;
 
 	jid = xt_find_attr(node, "jid");
+	muc_host = xt_find_attr(node, "muc_host");
 
 	sep = strchr(jid, '/');
@@ -48,5 +49,6 @@
 	if (!jabber_get_roster(ic) ||
 	    !jabber_iq_disco_server(ic) ||
-	    !jabber_get_hipchat_profile(ic)) {
+	    !jabber_get_hipchat_profile(ic) ||
+            !jabber_iq_disco_muc(ic, muc_host)) {
 		return XT_ABORT;
 	}
@@ -92,2 +94,49 @@
 
 }
+
+int jabber_iq_disco_muc(struct im_connection *ic, char *muc_server)
+{
+	struct xt_node *node;
+	int st;
+
+	imcb_log(ic, "Fetching MUC list");
+
+	node = xt_new_node("query", NULL, NULL);
+	xt_add_attr(node, "xmlns", XMLNS_DISCO_ITEMS);
+	node = jabber_make_packet("iq", "get", muc_server, node);
+
+	jabber_cache_add(ic, node, jabber_parse_muc_list);
+	st = jabber_write_packet(ic, node);
+
+	return st;
+}
+
+xt_status jabber_parse_muc_list(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
+{
+	struct xt_node *query, *c;
+
+	if (!(query = xt_find_node(node->children, "query"))) {
+		imcb_log(ic, "Warning: Received NULL MUC list packet");
+		return XT_HANDLED;
+	}
+
+	c = query->children;
+	while ((c = xt_find_node(c, "item"))) {
+		struct xt_node *c2;
+		char *topic = NULL;
+		char *jid = xt_find_attr(c, "jid");
+		char *name = xt_find_attr(c, "name");
+
+		imcb_log(ic, "Debug: adding MUC to channel list: %s - '%s'", jid, name);
+
+		if ((c2 = xt_find_node_by_attr(c->children, "x", "xmlns", XMLNS_HIPCHAT_MUC)) &&
+		    (c2 = xt_find_node(c2->children, "topic"))) {
+			topic = c2->text;
+		}
+
+		imcb_chat_placeholder_new(ic, jid, name, topic);
+		c = c->next;
+	}
+	return XT_HANDLED;
+
+}
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision 61e7e02096c7910addba32a9060a5e0cba68284b)
+++ protocols/jabber/jabber.h	(revision e4f08bfadf99f5aadcfa0b3ded8da8f72295e72e)
@@ -243,4 +243,5 @@
 #define XMLNS_HIPCHAT         "http://hipchat.com"
 #define XMLNS_HIPCHAT_PROFILE "http://hipchat.com/protocol/profile"
+#define XMLNS_HIPCHAT_MUC     "http://hipchat.com/protocol/muc#room"
 
 /* jabber.c */
@@ -253,4 +254,5 @@
 int jabber_get_roster(struct im_connection *ic);
 int jabber_get_vcard(struct im_connection *ic, char *bare_jid);
+int jabber_iq_disco_muc(struct im_connection *ic, char *muc_server);
 int jabber_add_to_roster(struct im_connection *ic, const char *handle, const char *name, const char *group);
 int jabber_remove_from_roster(struct im_connection *ic, char *handle);
@@ -356,4 +358,5 @@
 xt_status jabber_parse_hipchat_profile(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
 xt_status hipchat_handle_success(struct im_connection *ic, struct xt_node *node);
+xt_status jabber_parse_muc_list(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
 
 #endif
