Index: protocols/jabber/conference.c
===================================================================
--- protocols/jabber/conference.c	(revision 2758cfed0abcb529975af34fdb4d2603febbf1a3)
+++ protocols/jabber/conference.c	(revision b9f8b870f7b884747b747be91ce0ac797a7c6e82)
@@ -128,5 +128,7 @@
 		   Slightly hackish way of finding out eh? ;-) */
 		
-		/* This is pretty messy... */
+		/* This is pretty messy... Here it sets ext_jid to the real
+		   JID of the participant. Works for non-anonymized channels.
+		   Might break if someone joins a chat twice, though. */
 		for( c = node->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
 			if( ( s = xt_find_attr( c, "xmlns" ) ) &&
@@ -137,5 +139,5 @@
 				{
 					/* Yay, found what we need. :-) */
-					bud->ext_jid = g_strdup( s );
+					bud->ext_jid = jabber_normalize( s );
 					break;
 				}
@@ -146,5 +148,5 @@
 		{
 			if( bud == jc->me )
-				bud->ext_jid = g_strdup( ic->acc->user );
+				bud->ext_jid = jabber_normalize( ic->acc->user );
 			else
 				/* Don't want the nick to be at the end, so let's
Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision 2758cfed0abcb529975af34fdb4d2603febbf1a3)
+++ protocols/jabber/jabber.c	(revision b9f8b870f7b884747b747be91ce0ac797a7c6e82)
@@ -224,4 +224,5 @@
 	struct jabber_buddy *bud;
 	struct xt_node *node;
+	char *s;
 	int st;
 	
@@ -229,5 +230,8 @@
 		return jabber_write( ic, message, strlen( message ) );
 	
-	bud = jabber_buddy_by_jid( ic, who, 0 );
+	if( ( s = strchr( who, '=' ) ) && jabber_chat_by_name( ic, s + 1 ) )
+		bud = jabber_buddy_by_ext_jid( ic, who, 0 );
+	else
+		bud = jabber_buddy_by_jid( ic, who, 0 );
 	
 	node = xt_new_node( "body", message, NULL );
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision 2758cfed0abcb529975af34fdb4d2603febbf1a3)
+++ protocols/jabber/jabber.h	(revision b9f8b870f7b884747b747be91ce0ac797a7c6e82)
@@ -195,4 +195,5 @@
 struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid );
 struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
+struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
 int jabber_buddy_remove( struct im_connection *ic, char *full_jid );
 int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid );
Index: protocols/jabber/jabber_util.c
===================================================================
--- protocols/jabber/jabber_util.c	(revision 2758cfed0abcb529975af34fdb4d2603febbf1a3)
+++ protocols/jabber/jabber_util.c	(revision b9f8b870f7b884747b747be91ce0ac797a7c6e82)
@@ -320,4 +320,6 @@
 	else
 	{
+		/* Keep in mind that full_jid currently isn't really
+		   a full JID... */
 		new->bare_jid = g_strdup( full_jid );
 		g_hash_table_insert( jd->buddies, new->bare_jid, new );
@@ -333,5 +335,6 @@
 	{
 		/* Let's waste some more bytes of RAM instead of to make
-		   memory management a total disaster here.. */
+		   memory management a total disaster here. And it saves
+		   me one g_free() call in this function. :-P */
 		new->full_jid = full_jid;
 	}
@@ -426,4 +429,36 @@
 			return best_prio;
 	}
+}
+
+/* I'm keeping a separate ext_jid attribute to save a JID that makes sense
+   to export to BitlBee. This is mainly for groupchats right now. It's
+   a bit of a hack, but I just think having the user nickname in the hostname
+   part of the hostmask doesn't look nice on IRC. Normally you can convert
+   a normal JID to ext_jid by swapping the part before and after the / and
+   replacing the / with a =. But there should be some stripping (@s are
+   allowed in Jabber nicks...). */
+struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid_, get_buddy_flags_t flags )
+{
+	struct jabber_buddy *bud;
+	char *s, *jid;
+	
+	jid = jabber_normalize( jid_ );
+	
+	if( ( s = strchr( jid, '=' ) ) == NULL )
+		return NULL;
+	
+	for( bud = jabber_buddy_by_jid( ic, s + 1, GET_BUDDY_FIRST ); bud; bud = bud->next )
+	{
+		/* Hmmm, could happen if not all people in the chat are anonymized? */
+		if( bud->ext_jid == NULL )
+			continue;
+		
+		if( strcmp( bud->ext_jid, jid ) == 0 )
+			break;
+	}
+	
+	g_free( jid );
+	
+	return bud;
 }
 
Index: protocols/jabber/message.c
===================================================================
--- protocols/jabber/message.c	(revision 2758cfed0abcb529975af34fdb4d2603febbf1a3)
+++ protocols/jabber/message.c	(revision b9f8b870f7b884747b747be91ce0ac797a7c6e82)
@@ -53,5 +53,8 @@
 		{
 			if( bud )
+			{
 				bud->last_act = time( NULL );
+				from = bud->ext_jid ? : bud->bare_jid;
+			}
 			else
 				*s = 0; /* We need to generate a bare JID now. */
@@ -81,5 +84,5 @@
 		
 		if( fullmsg->len > 0 )
-			imcb_buddy_msg( ic, bud ? bud->bare_jid : from, fullmsg->str,
+			imcb_buddy_msg( ic, from, fullmsg->str,
 			                0, jabber_get_timestamp( node ) );
 		
@@ -90,5 +93,5 @@
 		{
 			bud->flags |= JBFLAG_DOES_XEP85;
-			imcb_buddy_typing( ic, bud ? bud->bare_jid : from, OPT_TYPING );
+			imcb_buddy_typing( ic, from, OPT_TYPING );
 		}
 		/* No need to send a "stopped typing" signal when there's a message. */
@@ -96,10 +99,10 @@
 		{
 			bud->flags |= JBFLAG_DOES_XEP85;
-			imcb_buddy_typing( ic, bud ? bud->bare_jid : from, 0 );
+			imcb_buddy_typing( ic, from, 0 );
 		}
 		else if( xt_find_node( node->children, "paused" ) )
 		{
 			bud->flags |= JBFLAG_DOES_XEP85;
-			imcb_buddy_typing( ic, bud ? bud->bare_jid : from, OPT_THINKING );
+			imcb_buddy_typing( ic, from, OPT_THINKING );
 		}
 		
