Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision 6a1128d1333cf79f1ef9fb1f55b1b8fec67caf2a)
+++ protocols/jabber/jabber.c	(revision a21a8ac4fbd5a234bc8d31d9d487c74a81383c8a)
@@ -44,4 +44,6 @@
 	s = set_add( &acc->set, "resource", "BitlBee", NULL, acc );
 	s->flags |= ACC_SET_OFFLINE_ONLY;
+	
+	s = set_add( &acc->set, "resource_select", "priority", NULL, acc );
 	
 	s = set_add( &acc->set, "server", NULL, set_eval_account, acc );
@@ -137,17 +139,31 @@
 static int jabber_send_im( struct gaim_connection *gc, char *who, char *message, int len, int away )
 {
+	struct jabber_data *jd = gc->proto_data;
+	struct jabber_buddy *bud;
 	struct xt_node *node;
 	int st;
 	
-	/*
-	event = xt_new_node( "active", NULL, NULL );
-	xt_add_attr( event, "xlmns", "http://jabber.org/protocol/chatstates" );
-	
-	event = xt_new_node( "x", NULL, xt_new_node( "composing", NULL, NULL ) );
-	xt_add_attr( event, "xmlns", "jabber:x:event" );
-	*/
+	bud = jabber_buddy_by_jid( gc, who );
 	
 	node = xt_new_node( "body", message, NULL );
-	node = jabber_make_packet( "message", "chat", who, node );
+	node = jabber_make_packet( "message", "chat", bud->full_jid, node );
+	
+	if( ( jd->flags & JFLAG_WANT_TYPING ) &&
+	    ( ( bud->flags & JBFLAG_DOES_JEP85 ) ||
+	     !( bud->flags & JBFLAG_PROBED_JEP85 ) ) )
+	{
+		struct xt_node *act;
+		
+		/* If the user likes typing notification and if we don't know
+		   (and didn't probe before) if this resource supports JEP85,
+		   include a probe in this packet now. */
+		act = xt_new_node( "active", NULL, NULL );
+		xt_add_attr( act, "xmlns", "http://jabber.org/protocol/chatstates" );
+		xt_add_child( node, act );
+		
+		/* Just make sure we do this only once. */
+		bud->flags |= JBFLAG_PROBED_JEP85;
+	}
+	
 	st = jabber_write_packet( gc, node );
 	xt_free_node( node );
@@ -227,4 +243,42 @@
 	   is in the cache for about a minute (which should be enough AFAIK). */
 	jabber_cache_clean( gc );
+}
+
+static int jabber_send_typing( struct gaim_connection *gc, char *who, int typing )
+{
+	struct jabber_data *jd = gc->proto_data;
+	struct jabber_buddy *bud;
+	
+	/* Enable typing notification related code from now. */
+	jd->flags |= JFLAG_WANT_TYPING;
+	
+	bud = jabber_buddy_by_jid( gc, who );
+	if( bud->flags & JBFLAG_DOES_JEP85 )
+	{
+		/* We're only allowed to send this stuff if we know the other
+		   side supports it. */
+		
+		struct xt_node *node;
+		char *type;
+		int st;
+		
+		if( typing == 0 )
+			type = "active";
+		else if( typing == 2 )
+			type = "paused";
+		else /* if( typing == 1 ) */
+			type = "composing";
+		
+		node = xt_new_node( type, NULL, NULL );
+		xt_add_attr( node, "xmlns", "http://jabber.org/protocol/chatstates" );
+		node = jabber_make_packet( "message", "chat", bud->full_jid, node );
+		
+		st = jabber_write_packet( gc, node );
+		xt_free_node( node );
+		
+		return st;
+	}
+	
+	return 1;
 }
 
@@ -250,5 +304,5 @@
 //	ret->chat_open = jabber_chat_open;
 	ret->keepalive = jabber_keepalive;
-//	ret->send_typing = jabber_send_typing;
+	ret->send_typing = jabber_send_typing;
 	ret->handle_cmp = g_strcasecmp;
 
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision 6a1128d1333cf79f1ef9fb1f55b1b8fec67caf2a)
+++ protocols/jabber/jabber.h	(revision a21a8ac4fbd5a234bc8d31d9d487c74a81383c8a)
@@ -32,10 +32,23 @@
 typedef enum
 {
-	JFLAG_STREAM_STARTED = 1,	/* Set when we detected the beginning of the stream and want to do auth. */
+	JFLAG_STREAM_STARTED = 1,	/* Set when we detected the beginning of the stream
+	                                   and want to do auth. */
 	JFLAG_AUTHENTICATED = 2,	/* Set when we're successfully authenticatd. */
-	JFLAG_STREAM_RESTART = 4,	/* Set when we want to restart the stream (after SASL or TLS). */
-	JFLAG_WAIT_SESSION = 8,		/* Set if we sent a <session> tag and need a reply before we continue. */
+	JFLAG_STREAM_RESTART = 4,	/* Set when we want to restart the stream (after
+	                                   SASL or TLS). */
+	JFLAG_WAIT_SESSION = 8,		/* Set if we sent a <session> tag and need a reply
+	                                   before we continue. */
 	JFLAG_WAIT_BIND = 16,		/* ... for <bind> tag. */
+	JFLAG_WANT_TYPING = 32,		/* Set if we ever sent a typing notification, this
+	                                   activates all JEP-85 related code. */
 } jabber_flags_t;
+
+typedef enum
+{
+	JBFLAG_PROBED_JEP85 = 1,	/* Set this when we sent our probe packet to make
+	                                   sure it gets sent only once. */
+	JBFLAG_DOES_JEP85 = 2,		/* Set this when the resource seems to support
+	                                   JEP85 (typing notification shite). */
+} jabber_buddy_flag_t;
 
 struct jabber_data
@@ -81,4 +94,5 @@
 {
 	char *handle;
+	char *full_jid;
 	char *resource;
 	
Index: protocols/jabber/jabber_util.c
===================================================================
--- protocols/jabber/jabber_util.c	(revision 6a1128d1333cf79f1ef9fb1f55b1b8fec67caf2a)
+++ protocols/jabber/jabber_util.c	(revision a21a8ac4fbd5a234bc8d31d9d487c74a81383c8a)
@@ -247,5 +247,6 @@
 	
 	*s = '/';
-	new->resource = g_strdup( s + 1 );
+	new->full_jid = g_strdup( full_jid );
+	new->resource = strchr( new->full_jid, '/' ) + 1;
 	
 	return new;
@@ -268,6 +269,22 @@
 	else
 	{
-		/* TODO: Add selection. */
-		return g_hash_table_lookup( jd->buddies, jid );
+		struct jabber_buddy *best_prio, *best_time;
+		char *set;
+		
+		best_prio = best_time = bud = g_hash_table_lookup( jd->buddies, jid );
+		for( ; bud; bud = bud->next )
+		{
+			if( bud->priority > best_prio->priority )
+				best_prio = bud;
+			if( bud->last_act > best_time->last_act )
+				best_time = bud;
+		}
+		
+		if( ( set = set_getstr( &gc->acc->set, "resource_select" ) ) == NULL )
+			return NULL;
+		else if( strcmp( set, "activity" ) == 0 )
+			return best_time;
+		else /* if( strcmp( set, "priority" ) == 0 ) */
+			return best_prio;
 	}
 	
@@ -295,5 +312,5 @@
 			g_hash_table_remove( jd->buddies, bud->handle );
 			g_free( bud->handle );
-			g_free( bud->resource );
+			g_free( bud->full_jid );
 			g_free( bud->away_message );
 			g_free( bud );
@@ -314,5 +331,5 @@
 					g_hash_table_replace( jd->buddies, bi->handle, bi->next );
 				
-				g_free( bi->resource );
+				g_free( bi->full_jid );
 				g_free( bi->away_message );
 				g_free( bi );
Index: protocols/jabber/message.c
===================================================================
--- protocols/jabber/message.c	(revision 6a1128d1333cf79f1ef9fb1f55b1b8fec67caf2a)
+++ protocols/jabber/message.c	(revision a21a8ac4fbd5a234bc8d31d9d487c74a81383c8a)
@@ -29,25 +29,40 @@
 	char *from = xt_find_attr( node, "from" );
 	char *type = xt_find_attr( node, "type" );
-	struct xt_node *msg = xt_find_node( node->children, "body" );
+	struct xt_node *body = xt_find_node( node->children, "body" );
 	
-	if( !type || !msg )
+	if( !type )
 		return XT_HANDLED;	/* Grmbl... FIXME */
 	
 	if( strcmp( type, "chat" ) == 0 )
 	{
-		char *s;
+		struct jabber_buddy *bud = NULL;
 		
-		s = strchr( from, '/' );
-		if( s )
-			*s = 0;
+		if( strchr( from, '/' ) == NULL )
+		{
+			/* It just shouldn't happen. */
+			hide_login_progress( gc, "Received message packet from bare JID" );
+			signoff( gc );
+			return XT_ABORT;
+		}
 		
-		serv_got_im( gc, from, msg->text, 0, 0, 0 );
+		bud = jabber_buddy_by_jid( gc, from );
+		bud->last_act = time( NULL );
 		
-		if( s )
-			*s = '/';
+		if( body ) /* Could be just a typing notification. */
+			serv_got_im( gc, bud->handle, body->text, 0, 0, 0 );
+		
+		if( xt_find_node( node->children, "composing" ) )
+		{
+			bud->flags |= JBFLAG_DOES_JEP85;
+			serv_got_typing( gc, bud->handle, 0, 1 );
+		}
+		else if( xt_find_node( node->children, "active" ) )
+		{
+			bud->flags |= JBFLAG_DOES_JEP85;
+		}
 	}
 	else
 	{
-		printf( "Received MSG from %s: %s\n", from, msg ? msg->text : "<null>" );
+		printf( "Received MSG from %s:\n", from );
 		xt_print( node );
 	}
Index: protocols/jabber/presence.c
===================================================================
--- protocols/jabber/presence.c	(revision 6a1128d1333cf79f1ef9fb1f55b1b8fec67caf2a)
+++ protocols/jabber/presence.c	(revision a21a8ac4fbd5a234bc8d31d9d487c74a81383c8a)
@@ -30,4 +30,5 @@
 	char *type = xt_find_attr( node, "type" );	/* NULL should mean the person is online. */
 	struct xt_node *c;
+	struct jabber_buddy *bud;
 	
 	if( !from )
@@ -36,5 +37,10 @@
 	if( type == NULL )
 	{
-		struct jabber_buddy *bud;
+		if( strchr( from, '/' ) == NULL )
+		{
+			char *s = xt_to_string( node );
+			serv_got_crap( gc, "WARNING: Ignoring presence tag with bare JID: %s\n", s );
+			g_free( s );
+		}
 		
 		if( !( bud = jabber_buddy_by_jid( gc, from ) ) )
@@ -52,5 +58,10 @@
 			bud->away_state = (void*) jabber_away_state_by_code( c->text );
 		else
+		{
 			bud->away_state = NULL;
+			/* Let's only set last_act if there's *no* away state,
+			   since it could be some auto-away thingy. */
+			bud->last_act = time( NULL );
+		}
 		
 		if( ( c = xt_find_node( node->children, "priority" ) ) && c->text_len > 0 )
@@ -59,5 +70,6 @@
 			bud->priority = 0;
 		
-		serv_got_update( gc, bud->handle, 1, 0, 0, 0, 0, 0 );
+		serv_got_update( gc, bud->handle, 1, 0, 0, 0,
+		                 bud->away_state ? UC_UNAVAILABLE : 0, 0 );
 	}
 	else if( strcmp( type, "unavailable" ) == 0 )
@@ -65,8 +77,13 @@
 		char *s;
 		
+		if( ( s = strchr( from, '/' ) ) == NULL )
+		{
+			char *s = xt_to_string( node );
+			serv_got_crap( gc, "WARNING: Ignoring presence tag with bare JID: %s\n", s );
+			g_free( s );
+		}
+		
 		jabber_buddy_remove( gc, from );
-		
-		if( ( s = strchr( from, '/' ) ) )
-			*s = 0;
+		*s = 0;
 		
 		/* Only count this as offline if there's no other resource
