Index: protocols/jabber/conference.c
===================================================================
--- protocols/jabber/conference.c	(revision 823de9d44f262ea2364ac8ec6a1e18e0f7dab658)
+++ protocols/jabber/conference.c	(revision fc34fb5d0b717d90edfc7ed78f11166eb23c536e)
@@ -26,5 +26,5 @@
 static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
 
-struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password )
+struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password )
 {
 	struct jabber_chat *jc;
@@ -36,7 +36,7 @@
 	node = xt_new_node( "x", NULL, NULL );
 	xt_add_attr( node, "xmlns", XMLNS_MUC );
-	node = jabber_make_packet( "presence", NULL, roomjid, node );
 	if( password )
 		xt_add_child( node, xt_new_node( "password", password, NULL ) );
+	node = jabber_make_packet( "presence", NULL, roomjid, node );
 	jabber_cache_add( ic, node, jabber_chat_join_failed );
 	
Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision 823de9d44f262ea2364ac8ec6a1e18e0f7dab658)
+++ protocols/jabber/jabber.c	(revision fc34fb5d0b717d90edfc7ed78f11166eb23c536e)
@@ -425,5 +425,5 @@
 }
 
-static struct groupchat *jabber_chat_join_( struct im_connection *ic, char *room, char *nick, char *password )
+static struct groupchat *jabber_chat_join_( struct im_connection *ic, const char *room, const char *nick, const char *password )
 {
 	if( strchr( room, '@' ) == NULL )
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision 823de9d44f262ea2364ac8ec6a1e18e0f7dab658)
+++ protocols/jabber/jabber.h	(revision fc34fb5d0b717d90edfc7ed78f11166eb23c536e)
@@ -240,5 +240,5 @@
 
 /* conference.c */
-struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password );
+struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password );
 struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name );
 void jabber_chat_free( struct groupchat *c );
Index: protocols/jabber/presence.c
===================================================================
--- protocols/jabber/presence.c	(revision 823de9d44f262ea2364ac8ec6a1e18e0f7dab658)
+++ protocols/jabber/presence.c	(revision fc34fb5d0b717d90edfc7ed78f11166eb23c536e)
@@ -49,6 +49,7 @@
 		if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) )
 		{
-			if( set_getbool( &ic->irc->set, "debug" ) )
-				imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from );
+			/*
+			imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from );
+			*/
 			return XT_HANDLED;
 		}
@@ -106,6 +107,7 @@
 		if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL )
 		{
-			if( set_getbool( &ic->irc->set, "debug" ) )
-				imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from );
+			/*
+			imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from );
+			*/
 			return XT_HANDLED;
 		}
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision 823de9d44f262ea2364ac8ec6a1e18e0f7dab658)
+++ protocols/nogaim.c	(revision fc34fb5d0b717d90edfc7ed78f11166eb23c536e)
@@ -249,4 +249,6 @@
 void imcb_connected( struct im_connection *ic )
 {
+	irc_t *irc = ic->irc;
+	struct chat *c;
 	user_t *u;
 	
@@ -271,4 +273,13 @@
 	   exponential backoff timer. */
 	ic->acc->auto_reconnect_delay = 0;
+	
+	for( c = irc->chatrooms; c; c = c->next )
+	{
+		if( c->acc != ic->acc )
+			continue;
+		
+		if( set_getbool( &c->set, "auto_join" ) )
+			chat_join( irc, c, NULL );
+	}
 }
 
@@ -309,4 +320,7 @@
 	ic->acc->prpl->logout( ic );
 	b_event_remove( ic->inpa );
+	
+	g_free( ic->away );
+	ic->away = NULL;
 	
 	u = irc->users;
@@ -716,5 +730,5 @@
 }
 
-struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle )
+struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle )
 {
 	struct groupchat *c;
Index: protocols/nogaim.h
===================================================================
--- protocols/nogaim.h	(revision 823de9d44f262ea2364ac8ec6a1e18e0f7dab658)
+++ protocols/nogaim.h	(revision fc34fb5d0b717d90edfc7ed78f11166eb23c536e)
@@ -213,5 +213,5 @@
 	 * not implement this. */
 	struct groupchat *
-	     (* chat_join)	(struct im_connection *, char *room, char *nick, char *password);
+	     (* chat_join)	(struct im_connection *, const char *room, const char *nick, const char *password);
 	/* Change the topic, if supported. Note that BitlBee expects the IM
 	   server to confirm the topic change with a regular topic change
@@ -243,5 +243,5 @@
  * the account_t parameter. */
 G_MODULE_EXPORT struct im_connection *imcb_new( account_t *acc );
-G_MODULE_EXPORT void imcb_free( struct im_connection *ic );
+G_MODULE_EXPORT void imc_free( struct im_connection *ic );
 /* Once you're connected, you should call this function, so that the user will
  * see the success. */
@@ -294,5 +294,5 @@
  *   the user her/himself. At that point the group chat will be visible to the
  *   user, too. */
-G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle );
+G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle );
 G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, char *handle );
 /* To remove a handle from a group chat. Reason can be NULL. */
Index: protocols/oscar/oscar.c
===================================================================
--- protocols/oscar/oscar.c	(revision 823de9d44f262ea2364ac8ec6a1e18e0f7dab658)
+++ protocols/oscar/oscar.c	(revision fc34fb5d0b717d90edfc7ed78f11166eb23c536e)
@@ -91,5 +91,5 @@
 	GSList *oscar_chats;
 
-	gboolean killme;
+	gboolean killme, no_reconnect;
 	gboolean icq;
 	GSList *evilhack;
@@ -181,4 +181,5 @@
 static int gaim_parse_auth_resp  (aim_session_t *, aim_frame_t *, ...);
 static int gaim_parse_login      (aim_session_t *, aim_frame_t *, ...);
+static int gaim_parse_logout     (aim_session_t *, aim_frame_t *, ...);
 static int gaim_handle_redirect  (aim_session_t *, aim_frame_t *, ...);
 static int gaim_parse_oncoming   (aim_session_t *, aim_frame_t *, ...);
@@ -294,5 +295,5 @@
 			aim_rxdispatch(odata->sess);
                                if (odata->killme)
-                                       imc_logout(ic, TRUE);
+                                       imc_logout(ic, !odata->no_reconnect);
 		} else {
 			if ((conn->type == AIM_CONN_TYPE_BOS) ||
@@ -520,4 +521,5 @@
 		case 0x18:
 			/* connecting too frequently */
+			od->no_reconnect = TRUE;
 			imcb_error(ic, _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer."));
 			break;
@@ -572,4 +574,5 @@
 	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parseaiminfo, 0);
 	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MTN, gaim_parsemtn, 0);
+	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_parse_logout, 0);
 
 	((struct oscar_data *)ic->proto_data)->conn = bosconn;
@@ -747,4 +750,28 @@
 
 	aim_send_login(sess, fr->conn, ic->acc->user, ic->acc->pass, &info, key);
+
+	return 1;
+}
+
+static int gaim_parse_logout(aim_session_t *sess, aim_frame_t *fr, ...) {
+	struct im_connection *ic = sess->aux_data;
+	struct oscar_data *odata = ic->proto_data;
+	int code;
+	va_list ap;
+
+	va_start(ap, fr);
+	code = va_arg(ap, int);
+	va_end(ap);
+	
+	imcb_error( ic, "Connection aborted by server: %s", code == 1 ?
+	                "someone else logged in with your account" :
+	                "unknown reason" );
+	
+	/* Tell BitlBee to disable auto_reconnect if code == 1, since that
+	   means a concurrent login somewhere else. */
+	odata->no_reconnect = code == 1;
+	
+	/* DO NOT log out here! Just tell the callback to do it. */
+	odata->killme = TRUE;
 
 	return 1;
@@ -1939,6 +1966,5 @@
 	aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL);
 
-	if (ic->away)
-		g_free(ic->away);
+	g_free(ic->away);
 	ic->away = NULL;
 
@@ -1960,21 +1986,19 @@
 static void oscar_set_away_icq(struct im_connection *ic, struct oscar_data *od, const char *state, const char *message)
 {
-    const char *msg = NULL;
+	const char *msg = NULL;
 	gboolean no_message = FALSE;
 
 	/* clean old states */
-    if (ic->away) {
-		g_free(ic->away);
-		ic->away = NULL;
-    }
+	g_free(ic->away);
+	ic->away = NULL;
 	od->sess->aim_icq_state = 0;
 
 	/* if no message, then use an empty message */
-    if (message) {
-        msg = message;
-    } else {
-        msg = "";
+	if (message) {
+		msg = message;
+	} else {
+		msg = "";
 		no_message = TRUE;
-    }
+	}
 
 	if (!g_strcasecmp(state, "Online")) {
@@ -1982,25 +2006,25 @@
 	} else if (!g_strcasecmp(state, "Away")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY);
-        ic->away = g_strdup(msg);
+		ic->away = g_strdup(msg);
 		od->sess->aim_icq_state = AIM_MTYPE_AUTOAWAY;
 	} else if (!g_strcasecmp(state, "Do Not Disturb")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY);
-        ic->away = g_strdup(msg);
+		ic->away = g_strdup(msg);
 		od->sess->aim_icq_state = AIM_MTYPE_AUTODND;
 	} else if (!g_strcasecmp(state, "Not Available")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY);
-        ic->away = g_strdup(msg);
+		ic->away = g_strdup(msg);
 		od->sess->aim_icq_state = AIM_MTYPE_AUTONA;
 	} else if (!g_strcasecmp(state, "Occupied")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY);
-        ic->away = g_strdup(msg);
+		ic->away = g_strdup(msg);
 		od->sess->aim_icq_state = AIM_MTYPE_AUTOBUSY;
 	} else if (!g_strcasecmp(state, "Free For Chat")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_CHAT);
-        ic->away = g_strdup(msg);
+		ic->away = g_strdup(msg);
 		od->sess->aim_icq_state = AIM_MTYPE_AUTOFFC;
 	} else if (!g_strcasecmp(state, "Invisible")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_INVISIBLE);
-        ic->away = g_strdup(msg);
+		ic->away = g_strdup(msg);
 	} else if (!g_strcasecmp(state, GAIM_AWAY_CUSTOM)) {
 	 	if (no_message) {
@@ -2008,5 +2032,5 @@
 		} else {
 			aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY);
-            ic->away = g_strdup(msg);
+			ic->away = g_strdup(msg);
 			od->sess->aim_icq_state = AIM_MTYPE_AUTOAWAY;
 		}
@@ -2020,5 +2044,5 @@
 	struct oscar_data *od = (struct oscar_data *)ic->proto_data;
 
-    oscar_set_away_aim(ic, od, state, message);
+	oscar_set_away_aim(ic, od, state, message);
 	if (od->icq)
 		oscar_set_away_icq(ic, od, state, message);
@@ -2581,5 +2605,5 @@
 }
 
-struct groupchat *oscar_chat_join(struct im_connection * ic, char * room, char * nick, char * password )
+struct groupchat *oscar_chat_join(struct im_connection * ic, const char * room, const char * nick, const char * password )
 {
 	struct oscar_data * od = (struct oscar_data *)ic->proto_data;
Index: protocols/yahoo/yahoo.c
===================================================================
--- protocols/yahoo/yahoo.c	(revision 823de9d44f262ea2364ac8ec6a1e18e0f7dab658)
+++ protocols/yahoo/yahoo.c	(revision fc34fb5d0b717d90edfc7ed78f11166eb23c536e)
@@ -197,11 +197,12 @@
 {
 	struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
-	
-	ic->away = NULL;
+	char *away;
+	
+	away = NULL;
 	
 	if( state && msg && g_strcasecmp( state, msg ) != 0 )
 	{
 		yd->current_status = YAHOO_STATUS_CUSTOM;
-		ic->away = "";
+		away = "";
 	}
 	else if( state )
@@ -212,9 +213,9 @@
 		msg = NULL;
 		
-		ic->away = "";
+		away = "";
 		if( g_strcasecmp( state, "Available" ) == 0 )
 		{
 			yd->current_status = YAHOO_STATUS_AVAILABLE;
-			ic->away = NULL;
+			away = NULL;
 		}
 		else if( g_strcasecmp( state, "Be Right Back" ) == 0 )
@@ -242,5 +243,5 @@
 			yd->current_status = YAHOO_STATUS_AVAILABLE;
 			
-			ic->away = NULL;
+			away = NULL;
 		}
 	}
@@ -248,5 +249,5 @@
 		yd->current_status = YAHOO_STATUS_AVAILABLE;
 	
-	yahoo_set_away( yd->y2_id, yd->current_status, msg, ic->away != NULL ? 2 : 0 );
+	yahoo_set_away( yd->y2_id, yd->current_status, msg, away != NULL ? 2 : 0 );
 }
 
@@ -791,7 +792,20 @@
 {
 	struct byahoo_conf_invitation *inv = data;
-	
-	yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
-	imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
+	struct groupchat *b;
+	
+	for( b = inv->ic->groupchats; b; b = b->next )
+		if( b == inv->c )
+			break;
+	
+	if( b != NULL )
+	{
+		yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
+		imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
+	}
+	else
+	{
+		imcb_log( inv->ic, "Duplicate/corrupted invitation to `%s'.", inv->name );
+	}
+	
 	g_free( inv->name );
 	g_free( inv );
