Index: protocols/jabber/io.c
===================================================================
--- protocols/jabber/io.c	(revision b56b220e4280a75577f79b9dbcaf6eb2d7336873)
+++ protocols/jabber/io.c	(revision 259edd40f5e332791a44f7547346bf799f1f7327)
@@ -465,9 +465,15 @@
 	   infinite loop! */
 	if( strcmp( type, "conflict" ) == 0 )
+	{
+		hide_login_progress( gc, "Account and resource used from a different location" );
 		gc->wants_to_die = TRUE;
-	
-	s = g_strdup_printf( "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" );
-	hide_login_progress_error( gc, s );
-	g_free( s );
+	}
+	else
+	{
+		s = g_strdup_printf( "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" );
+		hide_login_progress_error( gc, s );
+		g_free( s );
+	}
+	
 	signoff( gc );
 	
Index: protocols/jabber/iq.c
===================================================================
--- protocols/jabber/iq.c	(revision b56b220e4280a75577f79b9dbcaf6eb2d7336873)
+++ protocols/jabber/iq.c	(revision 259edd40f5e332791a44f7547346bf799f1f7327)
@@ -30,5 +30,5 @@
 	struct xt_node *c, *reply = NULL;
 	char *type, *s;
-	int st;
+	int st, pack = 1;
 	
 	type = xt_find_attr( node, "type" );
@@ -101,20 +101,32 @@
 		{
 			xt_free_node( reply );
-			reply = NULL;
-		}
-		
-		/* If we recognized the xmlns and managed to generate a reply,
-		   finish and send it. */
-		if( reply )
+			reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" );
+			pack = 0;
+		}
+	}
+	else if( strcmp( type, "set" ) == 0 )
+	{
+		xt_free_node( reply );
+		reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" );
+		pack = 0;
+	}
+	
+	/* If we recognized the xmlns and managed to generate a reply,
+	   finish and send it. */
+	if( reply )
+	{
+		/* Normally we still have to pack it into an iq-result
+		   packet, but for errors, for example, we don't. */
+		if( pack )
 		{
 			reply = jabber_make_packet( "iq", "result", xt_find_attr( node, "from" ), reply );
 			if( ( s = xt_find_attr( node, "id" ) ) )
 				xt_add_attr( reply, "id", s );
-			
-			st = jabber_write_packet( gc, reply );
-			xt_free_node( reply );
-			if( !st )
-				return XT_ABORT;
-		}
+		}
+		
+		st = jabber_write_packet( gc, reply );
+		xt_free_node( reply );
+		if( !st )
+			return XT_ABORT;
 	}
 	
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision b56b220e4280a75577f79b9dbcaf6eb2d7336873)
+++ protocols/jabber/jabber.h	(revision 259edd40f5e332791a44f7547346bf799f1f7327)
@@ -127,4 +127,5 @@
 char *set_eval_tls( set_t *set, char *value );
 struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children );
+struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type );
 void jabber_cache_add( struct gaim_connection *gc, struct xt_node *node, jabber_cache_event func );
 struct xt_node *jabber_cache_get( struct gaim_connection *gc, char *id );
Index: protocols/jabber/jabber_util.c
===================================================================
--- protocols/jabber/jabber_util.c	(revision b56b220e4280a75577f79b9dbcaf6eb2d7336873)
+++ protocols/jabber/jabber_util.c	(revision 259edd40f5e332791a44f7547346bf799f1f7327)
@@ -79,5 +79,35 @@
 }
 
-/* Cache a node/packet for later use. Mainly useful for IQ packets if you need
+struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type )
+{
+	struct xt_node *node, *c;
+	char *to;
+	
+	/* Create the "defined-condition" tag. */
+	c = xt_new_node( err_cond, NULL, NULL );
+	xt_add_attr( c, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas" );
+	
+	/* Put it in an <error> tag. */
+	c = xt_new_node( "error", NULL, c );
+	xt_add_attr( c, "type", err_type );
+	
+	/* To make the actual error packet, we copy the original packet and
+	   add our <error>/type="error" tag. Including the original packet
+	   is recommended, so let's just do it. */
+	node = xt_dup( orig );
+	xt_add_child( node, c );
+	xt_add_attr( node, "type", "error" );
+	
+	/* Return to sender. */
+	if( ( to = xt_find_attr( node, "from" ) ) )
+	{
+		xt_add_attr( node, "to", to );
+		xt_remove_attr( node, "from" );
+	}
+		
+	return node;
+}
+
+/* Cache a node/epacket for later use. Mainly useful for IQ packets if you need
    them when you receive the response. Use this BEFORE sending the packet so
    it'll get an id= tag, and do NOT free() the packet after writing it! */
Index: protocols/jabber/xmltree.c
===================================================================
--- protocols/jabber/xmltree.c	(revision b56b220e4280a75577f79b9dbcaf6eb2d7336873)
+++ protocols/jabber/xmltree.c	(revision 259edd40f5e332791a44f7547346bf799f1f7327)
@@ -550,2 +550,38 @@
 	node->attr[i].value = g_strdup( value );
 }
+
+int xt_remove_attr( struct xt_node *node, char *key )
+{
+	int i, last;
+	
+	for( i = 0; node->attr[i].key; i ++ )
+		if( strcmp( node->attr[i].key, key ) == 0 )
+			break;
+	
+	/* If we didn't find the attribute... */
+	if( node->attr[i].key == NULL )
+		return 0;
+	
+	g_free( node->attr[i].key );
+	g_free( node->attr[i].value );
+	
+	/* If it's the last, this is easy: */
+	if( node->attr[i+1].key == NULL )
+	{
+		node->attr[i].key = node->attr[i].value = NULL;
+	}
+	else /* It's also pretty easy, actually. */
+	{
+		/* Find the last item. */
+		for( last = i + 1; node->attr[last+1].key; last ++ );
+		
+		node->attr[i] = node->attr[last];
+		node->attr[last].key = NULL;
+		node->attr[last].value = NULL;
+	}
+	
+	/* Let's not bother with reallocating memory here. It takes time and
+	   most packets don't stay in memory for long anyway. */
+	
+	return 1;
+}
Index: protocols/jabber/xmltree.h
===================================================================
--- protocols/jabber/xmltree.h	(revision b56b220e4280a75577f79b9dbcaf6eb2d7336873)
+++ protocols/jabber/xmltree.h	(revision 259edd40f5e332791a44f7547346bf799f1f7327)
@@ -93,4 +93,5 @@
 void xt_add_child( struct xt_node *parent, struct xt_node *child );
 void xt_add_attr( struct xt_node *node, char *key, char *value );
+int xt_remove_attr( struct xt_node *node, char *key );
 
 #endif
