Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision e617b35a6771362164aff194cb6e0b757552c0bd)
+++ protocols/jabber/jabber.c	(revision 788a1afa9628aeaf9d69fc53f49131a4330253cf)
@@ -147,14 +147,14 @@
 	
 	node = xt_new_node( "body", message, NULL );
-	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 ) ) )
+	node = jabber_make_packet( "message", "chat", bud ? bud->full_jid : who, node );
+	
+	if( ( jd->flags & JFLAG_WANT_TYPING ) && bud &&
+	    ( ( bud->flags & JBFLAG_DOES_XEP85 ) ||
+	     !( bud->flags & JBFLAG_PROBED_XEP85 ) ) )
 	{
 		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,
+		   (and didn't probe before) if this resource supports XEP85,
 		   include a probe in this packet now. */
 		act = xt_new_node( "active", NULL, NULL );
@@ -163,5 +163,5 @@
 		
 		/* Just make sure we do this only once. */
-		bud->flags |= JBFLAG_PROBED_JEP85;
+		bud->flags |= JBFLAG_PROBED_XEP85;
 	}
 	
@@ -226,4 +226,7 @@
 static void jabber_remove_buddy( struct gaim_connection *gc, char *who, char *group )
 {
+	/* We should always do this part. Clean up our administration a little bit. */
+	jabber_buddy_remove_bare( gc, who );
+	
 	if( jabber_remove_from_roster( gc, who ) )
 		presence_send_request( gc, who, "unsubscribe" );
@@ -248,6 +251,12 @@
 	jd->flags |= JFLAG_WANT_TYPING;
 	
-	bud = jabber_buddy_by_jid( gc, who );
-	if( bud->flags & JBFLAG_DOES_JEP85 )
+	if( ( bud = jabber_buddy_by_jid( gc, who ) ) == NULL )
+	{
+		/* Sending typing notifications to unknown buddies is
+		   unsupported for now. Shouldn't be a problem, I think. */
+		return 0;
+	}
+	
+	if( bud->flags & JBFLAG_DOES_XEP85 )
 	{
 		/* We're only allowed to send this stuff if we know the other
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision e617b35a6771362164aff194cb6e0b757552c0bd)
+++ protocols/jabber/jabber.h	(revision 788a1afa9628aeaf9d69fc53f49131a4330253cf)
@@ -41,13 +41,13 @@
 	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. */
+	                                   activates all XEP-85 related code. */
 } jabber_flags_t;
 
 typedef enum
 {
-	JBFLAG_PROBED_JEP85 = 1,	/* Set this when we sent our probe packet to make
+	JBFLAG_PROBED_XEP85 = 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). */
+	JBFLAG_DOES_XEP85 = 2,		/* Set this when the resource seems to support
+	                                   XEP85 (typing notification shite). */
 } jabber_buddy_flag_t;
 
@@ -138,4 +138,5 @@
 struct jabber_buddy *jabber_buddy_by_jid( struct gaim_connection *gc, char *jid );
 int jabber_buddy_remove( struct gaim_connection *gc, char *full_jid );
+int jabber_buddy_remove_bare( struct gaim_connection *gc, char *bare_jid );
 
 extern const struct jabber_away_state jabber_away_state_list[];
Index: protocols/jabber/jabber_util.c
===================================================================
--- protocols/jabber/jabber_util.c	(revision e617b35a6771362164aff194cb6e0b757552c0bd)
+++ protocols/jabber/jabber_util.c	(revision 788a1afa9628aeaf9d69fc53f49131a4330253cf)
@@ -29,11 +29,18 @@
 {
 	account_t *acc = set->data;
-	char *ret;
-	
-	ret = set_eval_int( set, value );
+	int i;
+	
+	if( sscanf( value, "%d", &i ) == 1 )
+	{
+		/* Priority is a signed 8-bit integer, according to RFC 3921. */
+		if( i < -128 || i > 127 )
+			return NULL;
+	}
+	else
+		return NULL;
 	
 	/* Only run this stuff if the account is online ATM,
 	   and if the setting seems to be acceptable. */
-	if( acc->gc && ret )
+	if( acc->gc )
 	{
 		/* Although set_eval functions usually are very nice and
@@ -47,5 +54,5 @@
 		
 		g_free( set->value );
-		set->value = g_strdup( ret );
+		set->value = g_strdup( value );
 		
 		/* (Yes, sorry, I prefer the hack. :-P) */
@@ -54,5 +61,5 @@
 	}
 	
-	return ret;
+	return value;
 }
 
@@ -283,4 +290,7 @@
 }
 
+/* Finds a buddy from our structures. Can find both full- and bare JIDs. When
+   asked for a bare JID, it uses the "resource_select" setting to see which
+   resource to pick. */
 struct jabber_buddy *jabber_buddy_by_jid( struct gaim_connection *gc, char *jid )
 {
@@ -323,4 +333,6 @@
 }
 
+/* Remove one specific full JID from our list. Use this when a buddy goes
+   off-line (because (s)he can still be online from a different location. */
 int jabber_buddy_remove( struct gaim_connection *gc, char *full_jid )
 {
@@ -381,2 +393,37 @@
 	}
 }
+
+/* Remove a buddy completely; removes all resources that belong to the
+   specified bare JID. Use this when removing someone from the contact
+   list, for example. */
+int jabber_buddy_remove_bare( struct gaim_connection *gc, char *bare_jid )
+{
+	struct jabber_data *jd = gc->proto_data;
+	struct jabber_buddy *bud, *next;
+	
+	if( strchr( bare_jid, '/' ) )
+		return 0;
+	
+	if( ( bud = g_hash_table_lookup( jd->buddies, bare_jid ) ) )
+	{
+		/* Most important: Remove the hash reference. We don't know
+		   this buddy anymore. */
+		g_hash_table_remove( jd->buddies, bud->handle );
+		
+		/* Deallocate the linked list of resources. */
+		while( bud )
+		{
+			next = bud->next;
+			g_free( bud->full_jid );
+			g_free( bud->away_message );
+			g_free( bud );
+			bud = next;
+		}
+		
+		return 1;
+	}
+	else
+	{
+		return 0;
+	}
+}
Index: protocols/jabber/message.c
===================================================================
--- protocols/jabber/message.c	(revision e617b35a6771362164aff194cb6e0b757552c0bd)
+++ protocols/jabber/message.c	(revision 788a1afa9628aeaf9d69fc53f49131a4330253cf)
@@ -30,4 +30,5 @@
 	char *type = xt_find_attr( node, "type" );
 	struct xt_node *body = xt_find_node( node->children, "body" );
+	char *s;
 	
 	if( !type )
@@ -38,5 +39,5 @@
 		struct jabber_buddy *bud = NULL;
 		
-		if( strchr( from, '/' ) == NULL )
+		if( ( s = strchr( from, '/' ) ) == NULL )
 		{
 			/* It just shouldn't happen. */
@@ -46,19 +47,32 @@
 		}
 		
-		bud = jabber_buddy_by_jid( gc, from );
-		bud->last_act = time( NULL );
+		if( ( bud = jabber_buddy_by_jid( gc, from ) ) )
+			bud->last_act = time( NULL );
+		else
+			*s = 0; /* We need to generate a bare JID now. */
 		
 		if( body ) /* Could be just a typing notification. */
-			serv_got_im( gc, bud->handle, body->text, 0, 0, 0 );
+			serv_got_im( gc, bud ? bud->handle : from, body->text, 0, 0, 0 );
 		
+		/* Handling of incoming typing notifications. */
 		if( xt_find_node( node->children, "composing" ) )
 		{
-			bud->flags |= JBFLAG_DOES_JEP85;
-			serv_got_typing( gc, bud->handle, 0, 1 );
+			bud->flags |= JBFLAG_DOES_XEP85;
+			serv_got_typing( gc, bud ? bud->handle : from, 0, 1 );
 		}
-		else if( xt_find_node( node->children, "active" ) )
+		/* No need to send a "stopped typing" signal when there's a message. */
+		else if( xt_find_node( node->children, "active" ) && ( body == NULL ) )
 		{
-			bud->flags |= JBFLAG_DOES_JEP85;
+			bud->flags |= JBFLAG_DOES_XEP85;
+			serv_got_typing( gc, bud ? bud->handle : from, 0, 0 );
 		}
+		else if( xt_find_node( node->children, "paused" ) )
+		{
+			bud->flags |= JBFLAG_DOES_XEP85;
+			serv_got_typing( gc, bud ? bud->handle : from, 0, 2 );
+		}
+		
+		if( s )
+			*s = '/'; /* And convert it back to a full JID. */
 	}
 	else
@@ -70,3 +84,2 @@
 	return XT_HANDLED;
 }
-
Index: protocols/jabber/presence.c
===================================================================
--- protocols/jabber/presence.c	(revision e617b35a6771362164aff194cb6e0b757552c0bd)
+++ protocols/jabber/presence.c	(revision 788a1afa9628aeaf9d69fc53f49131a4330253cf)
@@ -31,4 +31,5 @@
 	struct xt_node *c;
 	struct jabber_buddy *bud;
+	char *s;
 	
 	if( !from )
@@ -37,8 +38,8 @@
 	if( type == NULL )
 	{
-		if( strchr( from, '/' ) == NULL )
+		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 );
+			serv_got_crap( gc, "WARNING: Ignoring presence tag with bare JID: %s", s );
 			g_free( s );
 			return XT_HANDLED;
@@ -47,4 +48,21 @@
 		if( !( bud = jabber_buddy_by_jid( gc, from ) ) )
 		{
+			/* FOR NOW, s still contains the location of the /.
+			   Keep this in mind when changing things here. :-) */
+			
+			/* We check if the buddy is in the contact list,
+			   because Jabber servers seem to like to send
+			   presence information of buddies we removed
+			   from our list sometimes, for example... */
+			
+			*s = 0;
+			if( find_buddy( gc, from ) == NULL )
+			{
+				*s = '/';
+				serv_got_crap( gc, "WARNING: Ignoring presence information from unknown JID: %s", from );
+				return XT_HANDLED;
+			}
+			*s = '/';
+			
 			bud = jabber_buddy_add( gc, from );
 		}
@@ -83,4 +101,10 @@
 			serv_got_crap( gc, "WARNING: Ignoring presence tag with bare JID: %s\n", s );
 			g_free( s );
+			return XT_HANDLED;
+		}
+		
+		if( jabber_buddy_by_jid( gc, from ) == NULL )
+		{
+			serv_got_crap( gc, "WARNING: Received presence information from unknown JID: %s", from );
 			return XT_HANDLED;
 		}
