Index: protocols/jabber/hipchat.c
===================================================================
--- protocols/jabber/hipchat.c	(revision c34247d0b3111f16dae1a52d831df0d61c03ee35)
+++ protocols/jabber/hipchat.c	(revision 9c8dbc75d416c8867be20ccf3732303163e620ce)
@@ -42,4 +42,6 @@
 		*sep = '/';
 	}
+
+	jd->muc_host = g_strdup(xt_find_attr(node, "muc_host"));
 
 	/* Hipchat's auth doesn't expect a restart here */
@@ -92,2 +94,50 @@
 
 }
+
+/* Returns a newly allocated string that tries to match the "slug" part of the JID using an
+ * approximation of the method used by the server. This might fail in some rare conditions
+ * (old JIDs generated a different way, locale settings unicode, etc) */
+char *hipchat_make_channel_slug(const char *name)
+{
+	char *lower;
+	char *new = g_malloc(strlen(name) + 1);
+	int i = 0;
+
+	do {
+		if (*name == ' ') {
+			new[i++] = '_';
+		} else if (*name && !strchr("\"&'/:<>@", *name)) {
+			new[i++] = *name;
+		}
+	} while (*(name++));
+
+	new[i] = '\0';
+
+	lower = g_utf8_strdown(new, -1);
+	g_free(new);
+
+	return lower;
+}
+
+char *hipchat_guess_channel_name(struct im_connection *ic, const char *name)
+{
+	struct jabber_data *jd = ic->proto_data;
+	char *slug, *retval, *underscore;
+	
+	if (!(underscore = strchr(jd->username, '_')) || !jd->muc_host) {
+		return NULL;
+	}
+
+	slug = hipchat_make_channel_slug(name);
+
+	/* Get the organization ID from the username, before the underscore */
+	*underscore = '\0';
+
+	retval = g_strdup_printf("%s_%s@%s", jd->username, slug, jd->muc_host);
+
+	*underscore = '_';
+
+	g_free(slug);
+
+	return retval;
+}
Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision c34247d0b3111f16dae1a52d831df0d61c03ee35)
+++ protocols/jabber/jabber.c	(revision 9c8dbc75d416c8867be20ccf3732303163e620ce)
@@ -371,4 +371,5 @@
 	g_free(jd->internal_jid);
 	g_free(jd->gmail_tid);
+	g_free(jd->muc_host);
 	g_free(jd->username);
 	g_free(jd->me);
@@ -533,4 +534,15 @@
 	}
 
+	if (jd->flags & JFLAG_HIPCHAT && jd->muc_host && !g_str_has_suffix(room, jd->muc_host)) {
+		char *guessed_name = hipchat_guess_channel_name(ic, room);
+		if (guessed_name) {
+			set_setstr(sets, "room", guessed_name);
+			g_free(guessed_name);
+
+			/* call this same function again with the fixed name */
+			return jabber_chat_join_(ic, set_getstr(sets, "room"), nick, password, sets);
+		}
+	}
+
 	if (strchr(room, '@') == NULL) {
 		imcb_error(ic, "%s is not a valid Jabber room name. Maybe you mean %s@conference.%s?",
@@ -539,4 +551,5 @@
 		imcb_error(ic, "Already present in chat `%s'", room);
 	} else {
+		/* jabber_chat_join without the underscore is the conference.c one */
 		return jabber_chat_join(ic, room, final_nick, set_getstr(sets, "password"));
 	}
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision c34247d0b3111f16dae1a52d831df0d61c03ee35)
+++ protocols/jabber/jabber.h	(revision 9c8dbc75d416c8867be20ccf3732303163e620ce)
@@ -113,4 +113,6 @@
 	GSList *streamhosts;
 	int have_streamhosts;
+
+	char *muc_host;
 };
 
@@ -358,4 +360,6 @@
 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);
+char *hipchat_make_channel_slug(const char *name);
+char *hipchat_guess_channel_name(struct im_connection *ic, const char *name);
 
 #endif
Index: tests/check_jabber_util.c
===================================================================
--- tests/check_jabber_util.c	(revision c34247d0b3111f16dae1a52d831df0d61c03ee35)
+++ tests/check_jabber_util.c	(revision 9c8dbc75d416c8867be20ccf3732303163e620ce)
@@ -105,4 +105,23 @@
 }
 
+static void check_hipchat_slug(int l)
+{
+	int i;
+
+	const char *tests[] = {
+		"test !\"#$%&\'()*+,-./0123456789:;<=>?@ABC", "test_!#$%\()*+,-.0123456789;=?abc",
+		"test XYZ[\\]^_`abc", "test_xyz[\\]^_`abc",
+		"test {|}~¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆ", "test_{|}~¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿àáâãäåæ",
+		"test Ĳ ĳ I ı I ı", "test_ĳ_ĳ_i_ı_i_ı",
+		NULL,
+	};
+
+	for (i = 0; tests[i]; i += 2) {
+		char *new = hipchat_make_channel_slug(tests[i]);
+		fail_unless(!strcmp(tests[i + 1], new));
+		g_free(new);
+	}
+}
+
 Suite *jabber_util_suite(void)
 {
@@ -121,4 +140,5 @@
 	tcase_add_test(tc_core, check_buddy_add);
 	tcase_add_test(tc_core, check_compareJID);
+	tcase_add_test(tc_core, check_hipchat_slug);
 	return s;
 }
