Index: protocols/jabber/Makefile
===================================================================
--- protocols/jabber/Makefile	(revision 71074ac7e43cfaf9b479e14de70b7d2bb48af806)
+++ protocols/jabber/Makefile	(revision 70ec7ab33202b933a88e04122140a815a7d2081e)
@@ -13,5 +13,5 @@
 
 # [SH] Program variables
-objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o s5bytestream.o sasl.o si.o
+objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o s5bytestream.o sasl.o si.o hipchat.o
 
 LFLAGS += -r
Index: protocols/jabber/hipchat.c
===================================================================
--- protocols/jabber/hipchat.c	(revision 70ec7ab33202b933a88e04122140a815a7d2081e)
+++ protocols/jabber/hipchat.c	(revision 70ec7ab33202b933a88e04122140a815a7d2081e)
@@ -0,0 +1,93 @@
+/***************************************************************************\
+*                                                                           *
+*  BitlBee - An IRC to IM gateway                                           *
+*  Jabber module - HipChat specific functions                               *
+*                                                                           *
+*  Copyright 2015 Xamarin Inc                                               *
+*                                                                           *
+*  This program is free software; you can redistribute it and/or modify     *
+*  it under the terms of the GNU General Public License as published by     *
+*  the Free Software Foundation; either version 2 of the License, or        *
+*  (at your option) any later version.                                      *
+*                                                                           *
+*  This program is distributed in the hope that it will be useful,          *
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
+*  GNU General Public License for more details.                             *
+*                                                                           *
+*  You should have received a copy of the GNU General Public License along  *
+*  with this program; if not, write to the Free Software Foundation, Inc.,  *
+*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.              *
+*                                                                           *
+\***************************************************************************/
+
+#include "jabber.h"
+
+xt_status hipchat_handle_success(struct im_connection *ic, struct xt_node *node)
+{
+	struct jabber_data *jd = ic->proto_data;
+	char *sep, *jid;
+
+	jid = xt_find_attr(node, "jid");
+
+	sep = strchr(jid, '/');
+	if (sep) {
+		*sep = '\0';
+	}
+
+	jabber_set_me(ic, jid);
+	imcb_log(ic, "Setting Hipchat JID to %s", jid);
+
+	if (sep) {
+		*sep = '/';
+	}
+
+	/* Hipchat's auth doesn't expect a restart here */
+	jd->flags &= ~JFLAG_STREAM_RESTART;
+
+	if (!jabber_get_roster(ic) ||
+	    !jabber_iq_disco_server(ic) ||
+	    !jabber_get_hipchat_profile(ic)) {
+		return XT_ABORT;
+	}
+
+	return XT_HANDLED;
+}
+
+int jabber_get_hipchat_profile(struct im_connection *ic)
+{
+	struct jabber_data *jd = ic->proto_data;
+	struct xt_node *node;
+	int st;
+
+	imcb_log(ic, "Fetching hipchat profile for %s", jd->me);
+
+	node = xt_new_node("query", NULL, NULL);
+	xt_add_attr(node, "xmlns", XMLNS_HIPCHAT_PROFILE);
+	node = jabber_make_packet("iq", "get", jd->me, node);
+
+	jabber_cache_add(ic, node, jabber_parse_hipchat_profile);
+	st = jabber_write_packet(ic, node);
+
+	return st;
+}
+
+xt_status jabber_parse_hipchat_profile(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
+{
+	struct xt_node *query, *name_node;
+
+	if (!(query = xt_find_node(node->children, "query"))) {
+		imcb_log(ic, "Warning: Received NULL profile packet");
+		return XT_ABORT;
+	}
+
+	name_node = xt_find_node(query->children, "name");
+	if (!name_node) {
+		imcb_log(ic, "Warning: Can't find real name in profile. Joining groupchats will not be possible.");
+		return XT_ABORT;
+	}
+
+	set_setstr(&ic->acc->set, "display_name", name_node->text);
+	return XT_HANDLED;
+
+}
Index: protocols/jabber/iq.c
===================================================================
--- protocols/jabber/iq.c	(revision 71074ac7e43cfaf9b479e14de70b7d2bb48af806)
+++ protocols/jabber/iq.c	(revision 70ec7ab33202b933a88e04122140a815a7d2081e)
@@ -27,5 +27,4 @@
 static xt_status jabber_parse_roster(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
 static xt_status jabber_iq_display_vcard(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
-static int jabber_iq_disco_server(struct im_connection *ic);
 
 xt_status jabber_pkt_iq(struct xt_node *node, gpointer data)
@@ -374,4 +373,5 @@
 static xt_status jabber_parse_roster(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
 {
+	struct jabber_data *jd = ic->proto_data;
 	struct xt_node *query, *c;
 	int initial = (orig != NULL);
@@ -388,4 +388,5 @@
 		char *name = xt_find_attr(c, "name");
 		char *sub = xt_find_attr(c, "subscription");
+		char *mention_name = xt_find_attr(c, "mention_name");
 
 		if (jid && sub) {
@@ -396,4 +397,10 @@
 				if (name) {
 					imcb_rename_buddy(ic, jid, name);
+				}
+
+				/* This could also be used to set the full name as nick for fb/gtalk,
+				 * but i'm keeping the old (ugly?) default behavior just to be safe */
+				if (mention_name && (jd->flags & JFLAG_HIPCHAT)) {
+					imcb_buddy_nick_hint(ic, jid, mention_name);
 				}
 			} else if (strcmp(sub, "remove") == 0) {
@@ -855,5 +862,5 @@
                                                  struct xt_node *node, struct xt_node *orig);
 
-static int jabber_iq_disco_server(struct im_connection *ic)
+int jabber_iq_disco_server(struct im_connection *ic)
 {
 	struct xt_node *node, *iq;
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision 71074ac7e43cfaf9b479e14de70b7d2bb48af806)
+++ protocols/jabber/jabber.h	(revision 70ec7ab33202b933a88e04122140a815a7d2081e)
@@ -236,4 +236,8 @@
 #define XMLNS_IBB          "http://jabber.org/protocol/ibb"                      /* XEP-0047 */
 
+/* Hipchat protocol extensions*/
+#define XMLNS_HIPCHAT         "http://hipchat.com"
+#define XMLNS_HIPCHAT_PROFILE "http://hipchat.com/protocol/profile"
+
 /* jabber.c */
 void jabber_connect(struct im_connection *ic);
@@ -250,4 +254,5 @@
 xt_status jabber_iq_query_server(struct im_connection *ic, char *jid, char *xmlns);
 void jabber_iq_version_send(struct im_connection *ic, struct jabber_buddy *bud, void *data);
+int jabber_iq_disco_server(struct im_connection *ic);
 
 /* si.c */
@@ -342,3 +347,8 @@
 void jabber_chat_invite(struct groupchat *c, char *who, char *message);
 
+/* hipchat.c */
+int jabber_get_hipchat_profile(struct im_connection *ic);
+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);
+
 #endif
Index: protocols/jabber/sasl.c
===================================================================
--- protocols/jabber/sasl.c	(revision 71074ac7e43cfaf9b479e14de70b7d2bb48af806)
+++ protocols/jabber/sasl.c	(revision 70ec7ab33202b933a88e04122140a815a7d2081e)
@@ -55,5 +55,5 @@
 	char *s;
 	int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_fb = 0;
-	int want_oauth = FALSE;
+	int want_oauth = FALSE, want_hipchat = FALSE;
 	GString *mechs;
 
@@ -75,4 +75,5 @@
 
 	want_oauth = set_getbool(&ic->acc->set, "oauth");
+	want_hipchat = (jd->flags & JFLAG_HIPCHAT);
 
 	mechs = g_string_new("");
@@ -111,5 +112,9 @@
 
 	reply = xt_new_node("auth", NULL, NULL);
-	xt_add_attr(reply, "xmlns", XMLNS_SASL);
+	if (!want_hipchat) {
+		xt_add_attr(reply, "xmlns", XMLNS_SASL);
+	} else {
+		xt_add_attr(reply, "xmlns", XMLNS_HIPCHAT);
+	}
 
 	if (sup_gtalk && want_oauth) {
@@ -143,13 +148,31 @@
 	} else if (sup_plain) {
 		int len;
-
-		xt_add_attr(reply, "mechanism", "PLAIN");
+		GString *gs;
+		char *username;
+
+		if (!want_hipchat) {
+			xt_add_attr(reply, "mechanism", "PLAIN");
+			username = jd->username;
+		} else {
+			username = jd->me;
+		}
+
+		/* set an arbitrary initial size to avoid reallocations */
+		gs = g_string_sized_new(128);
 
 		/* With SASL PLAIN in XMPP, the text should be b64(\0user\0pass) */
-		len = strlen(jd->username) + strlen(ic->acc->pass) + 2;
-		s = g_malloc(len + 1);
-		s[0] = 0;
-		strcpy(s + 1, jd->username);
-		strcpy(s + 2 + strlen(jd->username), ic->acc->pass);
+		g_string_append_c(gs, '\0');
+		g_string_append(gs, username);
+		g_string_append_c(gs, '\0');
+		g_string_append(gs, ic->acc->pass);
+		if (want_hipchat) {
+			/* Hipchat's variation adds \0resource at the end */
+			g_string_append_c(gs, '\0');
+			g_string_append(gs, set_getstr(&ic->acc->set, "resource"));
+		}
+
+		len = gs->len;
+		s = g_string_free(gs, FALSE);
+
 		reply->text = base64_encode((unsigned char *) s, len);
 		reply->text_len = strlen(reply->text);
@@ -397,4 +420,8 @@
 		imcb_log(ic, "Authentication finished");
 		jd->flags |= JFLAG_AUTHENTICATED | JFLAG_STREAM_RESTART;
+
+		if (jd->flags & JFLAG_HIPCHAT) {
+			return hipchat_handle_success(ic, node);
+		}
 	} else if (strcmp(node->name, "failure") == 0) {
 		imcb_error(ic, "Authentication failure");
