Index: irc.c
===================================================================
--- irc.c	(revision 723e611603236aab794ffbbc312705b8309b3f81)
+++ irc.c	(revision fa29d09342c79b886efacee4cfc3078be5f5a722)
@@ -659,5 +659,5 @@
 		}
 	}
-	else if( ( c = conv_findchannel( channel ) ) )
+	else if( ( c = chat_by_channel( channel ) ) )
 	{
 		GList *l;
@@ -812,5 +812,5 @@
 	else
 	{
-		struct conversation *c = conv_findchannel( channel );
+		struct conversation *c = chat_by_channel( channel );
 		
 		if( c )
@@ -950,5 +950,5 @@
 	if( *nick == '#' || *nick == '&' )
 	{
-		if( !( c = conv_findchannel( nick ) ) )
+		if( !( c = chat_by_channel( nick ) ) )
 		{
 			irc_reply( irc, 403, "%s :Channel does not exist", nick );
@@ -1038,5 +1038,5 @@
 	else if( c && c->gc && c->gc->acc && c->gc->acc->prpl )
 	{
-		return( bim_chat_msg( c->gc, c->id, s ) );
+		return( bim_chat_msg( c, s ) );
 	}
 	
Index: irc_commands.c
===================================================================
--- irc_commands.c	(revision 723e611603236aab794ffbbc312705b8309b3f81)
+++ irc_commands.c	(revision fa29d09342c79b886efacee4cfc3078be5f5a722)
@@ -144,5 +144,5 @@
 		irc_join( irc, u, irc->channel );
 	}
-	else if( ( c = conv_findchannel( cmd[1] ) ) )
+	else if( ( c = chat_by_channel( cmd[1] ) ) )
 	{
 		user_t *u = user_find( irc, irc->nick );
@@ -153,5 +153,5 @@
 		{
 			c->joined = 0;
-			c->gc->acc->prpl->chat_leave( c->gc, c->id );
+			c->gc->acc->prpl->chat_leave( c );
 		}
 	}
@@ -201,5 +201,5 @@
 {
 	char *nick = cmd[1], *channel = cmd[2];
-	struct conversation *c = conv_findchannel( channel );
+	struct conversation *c = chat_by_channel( channel );
 	user_t *u = user_find( irc, nick );
 	
@@ -207,5 +207,5 @@
 		if( c->gc && c->gc->acc->prpl->chat_invite )
 		{
-			c->gc->acc->prpl->chat_invite( c->gc, c->id, "", u->handle );
+			c->gc->acc->prpl->chat_invite( c, "", u->handle );
 			irc_reply( irc, 341, "%s %s", nick, channel );
 			return;
@@ -287,5 +287,5 @@
 			u = u->next;
 		}
-	else if( ( c = conv_findchannel( channel ) ) )
+	else if( ( c = chat_by_channel( channel ) ) )
 		for( l = c->in_room; l; l = l->next )
 		{
Index: motd.txt
===================================================================
--- motd.txt	(revision 723e611603236aab794ffbbc312705b8309b3f81)
+++ motd.txt	(revision fa29d09342c79b886efacee4cfc3078be5f5a722)
@@ -14,5 +14,5 @@
 The developers of the Bee hope you have a buzzing time.
 
-* BitlBee development team: wilmer, ctrlsoft, Maurits
+* BitlBee development team: wilmer, jelmer, Maurits
  
 ... Buzzing, haha, get it?
Index: protocols/msn/msn.c
===================================================================
--- protocols/msn/msn.c	(revision 723e611603236aab794ffbbc312705b8309b3f81)
+++ protocols/msn/msn.c	(revision fa29d09342c79b886efacee4cfc3078be5f5a722)
@@ -241,7 +241,7 @@
 }
 
-static int msn_chat_send( struct gaim_connection *gc, int id, char *message )
-{
-	struct msn_switchboard *sb = msn_sb_by_id( gc, id );
+static int msn_chat_send( struct conversation *c, char *message )
+{
+	struct msn_switchboard *sb = msn_sb_by_chat( c );
 	
 	if( sb )
@@ -251,7 +251,7 @@
 }
 
-static void msn_chat_invite( struct gaim_connection *gc, int id, char *msg, char *who )
-{
-	struct msn_switchboard *sb = msn_sb_by_id( gc, id );
+static void msn_chat_invite( struct conversation *c, char *msg, char *who )
+{
+	struct msn_switchboard *sb = msn_sb_by_chat( c );
 	char buf[1024];
 	
@@ -263,7 +263,7 @@
 }
 
-static void msn_chat_leave( struct gaim_connection *gc, int id )
-{
-	struct msn_switchboard *sb = msn_sb_by_id( gc, id );
+static void msn_chat_leave( struct conversation *c )
+{
+	struct msn_switchboard *sb = msn_sb_by_chat( c );
 	
 	if( sb )
@@ -271,5 +271,5 @@
 }
 
-static int msn_chat_open( struct gaim_connection *gc, char *who )
+static struct conversation *msn_chat_open( struct gaim_connection *gc, char *who )
 {
 	struct msn_switchboard *sb;
@@ -280,6 +280,5 @@
 	{
 		debug( "Converting existing switchboard to %s to a groupchat", who );
-		msn_sb_to_chat( sb );
-		return( 1 );
+		return msn_sb_to_chat( sb );
 	}
 	else
@@ -292,8 +291,5 @@
 			g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, who );
 			if( msn_sb_write( sb, buf, strlen( buf ) ) )
-			{
-				msn_sb_to_chat( sb );
-				return( 1 );
-			}
+				return msn_sb_to_chat( sb );
 		}
 		
@@ -314,8 +310,9 @@
 		md->msgq = g_slist_append( md->msgq, m );
 		
-		return( 1 );
-	}
-	
-	return( 0 );
+		/* FIXME: Can I try to return something here already? */
+		return NULL;
+	}
+	
+	return NULL;
 }
 
Index: protocols/msn/msn.h
===================================================================
--- protocols/msn/msn.h	(revision 723e611603236aab794ffbbc312705b8309b3f81)
+++ protocols/msn/msn.h	(revision fa29d09342c79b886efacee4cfc3078be5f5a722)
@@ -169,8 +169,8 @@
 struct msn_switchboard *msn_sb_create( struct gaim_connection *gc, char *host, int port, char *key, int session );
 struct msn_switchboard *msn_sb_by_handle( struct gaim_connection *gc, char *handle );
-struct msn_switchboard *msn_sb_by_id( struct gaim_connection *gc, int id );
+struct msn_switchboard *msn_sb_by_chat( struct conversation *c );
 struct msn_switchboard *msn_sb_spare( struct gaim_connection *gc );
 int msn_sb_sendmessage( struct msn_switchboard *sb, char *text );
-void msn_sb_to_chat( struct msn_switchboard *sb );
+struct conversation *msn_sb_to_chat( struct msn_switchboard *sb );
 void msn_sb_destroy( struct msn_switchboard *sb );
 gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond );
Index: protocols/msn/sb.c
===================================================================
--- protocols/msn/sb.c	(revision 723e611603236aab794ffbbc312705b8309b3f81)
+++ protocols/msn/sb.c	(revision fa29d09342c79b886efacee4cfc3078be5f5a722)
@@ -86,7 +86,7 @@
 }
 
-struct msn_switchboard *msn_sb_by_id( struct gaim_connection *gc, int id )
-{
-	struct msn_data *md = gc->proto_data;
+struct msn_switchboard *msn_sb_by_chat( struct conversation *c )
+{
+	struct msn_data *md = c->gc->proto_data;
 	struct msn_switchboard *sb;
 	GSList *l;
@@ -95,5 +95,5 @@
 	{
 		sb = l->data;
-		if( sb->chat && sb->chat->id == id )
+		if( sb->chat == c )
 			return( sb );
 	}
@@ -177,5 +177,5 @@
 }
 
-void msn_sb_to_chat( struct msn_switchboard *sb )
+struct conversation *msn_sb_to_chat( struct msn_switchboard *sb )
 {
 	struct gaim_connection *gc = sb->gc;
@@ -184,5 +184,5 @@
 	/* Create the groupchat structure. */
 	g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session );
-	sb->chat = serv_got_joined_chat( gc, ++msn_chat_id, buf );
+	sb->chat = serv_got_joined_chat( gc, buf );
 	
 	/* Populate the channel. */
@@ -196,4 +196,6 @@
 		sb->who = NULL;
 	}
+	
+	return sb->chat;
 }
 
@@ -230,5 +232,5 @@
 	if( sb->chat )
 	{
-		serv_got_chat_left( gc, sb->chat->id );
+		serv_got_chat_left( sb->chat );
 	}
 	
@@ -372,5 +374,5 @@
 			{
 				g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session );
-				sb->chat = serv_got_joined_chat( gc, ++msn_chat_id, buf );
+				sb->chat = serv_got_joined_chat( gc, buf );
 				
 				g_free( sb->who );
@@ -610,5 +612,5 @@
 			else if( sb->chat )
 			{
-				serv_got_chat_in( gc, sb->chat->id, cmd[1], 0, body, 0 );
+				serv_got_chat_in( sb->chat, cmd[1], 0, body, 0 );
 			}
 			else
@@ -669,5 +671,5 @@
 			else if( sb->chat )
 			{
-				serv_got_chat_in( gc, sb->chat->id, cmd[1], 0, buf, 0 );
+				serv_got_chat_in( sb->chat, cmd[1], 0, buf, 0 );
 			}
 			else
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision 723e611603236aab794ffbbc312705b8309b3f81)
+++ protocols/nogaim.c	(revision fa29d09342c79b886efacee4cfc3078be5f5a722)
@@ -682,13 +682,12 @@
 }
 
-void serv_got_chat_left( struct gaim_connection *gc, int id )
-{
-	struct conversation *c, *l = NULL;
+void serv_got_chat_left( struct conversation *c )
+{
+	struct gaim_connection *gc = c->gc;
+	struct conversation *l = NULL;
 	GList *ir;
 	
 	if( set_getbool( &gc->irc->set, "debug" ) )
-		serv_got_crap( gc, "You were removed from conversation %d", (int) id );
-	
-	for( c = gc->conversations; c && c->id != id; c = (l=c)->next );
+		serv_got_crap( gc, "You were removed from conversation 0x%x", (int) c );
 	
 	if( c )
@@ -720,7 +719,7 @@
 }
 
-void serv_got_chat_in( struct gaim_connection *gc, int id, char *who, int whisper, char *msg, time_t mtime )
-{
-	struct conversation *c;
+void serv_got_chat_in( struct conversation *c, char *who, int whisper, char *msg, time_t mtime )
+{
+	struct gaim_connection *gc = c->gc;
 	user_t *u;
 	
@@ -730,5 +729,4 @@
 	
 	u = user_findhandle( gc, who );
-	for( c = gc->conversations; c && c->id != id; c = c->next );
 	
 	if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) ||
@@ -739,11 +737,10 @@
 		irc_privmsg( gc->irc, u, "PRIVMSG", c->channel, "", msg );
 	else
-		serv_got_crap( gc, "Message from/to conversation %s@%d (unknown conv/user): %s", who, id, msg );
-}
-
-struct conversation *serv_got_joined_chat( struct gaim_connection *gc, int id, char *handle )
+		serv_got_crap( gc, "Message from/to conversation %s@0x%x (unknown conv/user): %s", who, (int) c, msg );
+}
+
+struct conversation *serv_got_joined_chat( struct gaim_connection *gc, char *handle )
 {
 	struct conversation *c;
-	char *s;
 	
 	/* This one just creates the conversation structure, user won't see anything yet */
@@ -755,19 +752,14 @@
 	}
 	else
-		gc->conversations = c = g_new0( struct conversation, 1);
-	
-	c->id = id;
+		gc->conversations = c = g_new0( struct conversation, 1 );
+	
 	c->gc = gc;
 	c->title = g_strdup( handle );
-	
-	s = g_new( char, 16 );
-	sprintf( s, "&chat_%03d", gc->irc->c_id++ );
-	c->channel = g_strdup( s );
-	g_free( s );
+	c->channel = g_strdup_printf( "&chat_%03d", gc->irc->c_id++ );
 	
 	if( set_getbool( &gc->irc->set, "debug" ) )
-		serv_got_crap( gc, "Creating new conversation: (id=%d,handle=%s)", id, handle );
-	
-	return( c );
+		serv_got_crap( gc, "Creating new conversation: (id=0x%x,handle=%s)", (int) c, handle );
+	
+	return c;
 }
 
@@ -781,5 +773,5 @@
 	
 	if( set_getbool( &b->gc->irc->set, "debug" ) )
-		serv_got_crap( b->gc, "User %s added to conversation %d", handle, b->id );
+		serv_got_crap( b->gc, "User %s added to conversation 0x%x", handle, (int) b );
 	
 	/* It might be yourself! */
@@ -815,5 +807,5 @@
 	
 	if( set_getbool( &b->gc->irc->set, "debug" ) )
-		serv_got_crap( b->gc, "User %s removed from conversation %d (%s)", handle, b->id, reason ? reason : "" );
+		serv_got_crap( b->gc, "User %s removed from conversation 0x%x (%s)", handle, (int) b, reason ? reason : "" );
 	
 	/* It might be yourself! */
@@ -858,5 +850,5 @@
 /* Misc. BitlBee stuff which shouldn't really be here */
 
-struct conversation *conv_findchannel( char *channel )
+struct conversation *chat_by_channel( char *channel )
 {
 	struct gaim_connection *gc;
@@ -870,8 +862,8 @@
 		for( c = gc->conversations; c && g_strcasecmp( c->channel, channel ) != 0; c = c->next );
 		if( c )
-			return( c );
-	}
-	
-	return( NULL );
+			return c;
+	}
+	
+	return NULL;
 }
 
@@ -958,10 +950,10 @@
 }
 
-int bim_chat_msg( struct gaim_connection *gc, int id, char *msg )
+int bim_chat_msg( struct conversation *c, char *msg )
 {
 	char *buf = NULL;
 	int st;
 	
-	if( ( gc->flags & OPT_CONN_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
+	if( ( c->gc->flags & OPT_CONN_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
 	{
 		buf = escape_html( msg );
@@ -969,5 +961,5 @@
 	}
 	
-	st = gc->acc->prpl->chat_send( gc, id, msg );
+	st = c->gc->acc->prpl->chat_send( c, msg );
 	g_free( buf );
 	
Index: protocols/nogaim.h
===================================================================
--- protocols/nogaim.h	(revision 723e611603236aab794ffbbc312705b8309b3f81)
+++ protocols/nogaim.h	(revision fa29d09342c79b886efacee4cfc3078be5f5a722)
@@ -100,14 +100,13 @@
 
 	/* stuff used just for chat */
-        GList *in_room;
-        GList *ignored;
-        int id;
-        
-        /* BitlBee */
-        struct conversation *next;
-        char *channel;
-        char *title;
-        char joined;
-        void *data;
+	GList *in_room;
+	GList *ignored;
+	
+	/* BitlBee */
+	struct conversation *next;
+	char *channel;
+	char *title;
+	char joined;
+	void *data;
 };
 
@@ -115,9 +114,9 @@
 	char name[80];
 	char show[BUDDY_ALIAS_MAXLEN];
-        int present;
+	int present;
 	int evil;
 	time_t signon;
 	time_t idle;
-        int uc;
+	int uc;
 	guint caps; /* woohoo! */
 	void *proto_data; /* what a hack */
@@ -153,9 +152,11 @@
 	
 	/* Group chat stuff. */
-	void (* join_chat)	(struct gaim_connection *, GList *data);
-	void (* chat_invite)	(struct gaim_connection *, int id, char *who, char *message);
-	void (* chat_leave)	(struct gaim_connection *, int id);
-	int  (* chat_send)	(struct gaim_connection *, int id, char *message);
-	int  (* chat_open)	(struct gaim_connection *, char *who);
+	void (* chat_invite)	(struct conversation *, char *who, char *message);
+	void (* chat_leave)	(struct conversation *);
+	int  (* chat_send)	(struct conversation *, char *message);
+	struct conversation *
+	     (* chat_open)	(struct gaim_connection *, char *who);
+	struct conversation *
+	     (* chat_join)	(struct gaim_connection *, char *chat, char *nick, char *password);
 	
 	/* DIE! */
@@ -183,5 +184,5 @@
 int bim_set_away( struct gaim_connection *gc, char *away );
 int bim_buddy_msg( struct gaim_connection *gc, char *handle, char *msg, int flags );
-int bim_chat_msg( struct gaim_connection *gc, int id, char *msg );
+int bim_chat_msg( struct conversation *c, char *msg );
 
 void bim_add_allow( struct gaim_connection *gc, char *handle );
@@ -224,14 +225,15 @@
 G_MODULE_EXPORT void show_got_added( struct gaim_connection *gc, char *handle, const char *realname );
 
-/* server.c */                    
+/* server.c */
 G_MODULE_EXPORT void serv_got_update( struct gaim_connection *gc, char *handle, int loggedin, int evil, time_t signon, time_t idle, int type, guint caps );
 G_MODULE_EXPORT void serv_got_im( struct gaim_connection *gc, char *handle, char *msg, guint32 flags, time_t mtime, gint len );
 G_MODULE_EXPORT void serv_got_typing( struct gaim_connection *gc, char *handle, int timeout, int type );
 G_MODULE_EXPORT void serv_got_chat_invite( struct gaim_connection *gc, char *handle, char *who, char *msg, GList *data );
-G_MODULE_EXPORT struct conversation *serv_got_joined_chat( struct gaim_connection *gc, int id, char *handle );
-G_MODULE_EXPORT void serv_got_chat_in( struct gaim_connection *gc, int id, char *who, int whisper, char *msg, time_t mtime );
-G_MODULE_EXPORT void serv_got_chat_left( struct gaim_connection *gc, int id );
-
-struct conversation *conv_findchannel( char *channel );
+G_MODULE_EXPORT struct conversation *serv_got_joined_chat( struct gaim_connection *gc, char *handle );
+G_MODULE_EXPORT void serv_got_chat_in( struct conversation *c, char *who, int whisper, char *msg, time_t mtime );
+G_MODULE_EXPORT void serv_got_chat_left( struct conversation *c );
+
+struct conversation *chat_by_channel( char *channel );
+struct conversation *chat_by_id( int id );
 
 #endif
Index: protocols/oscar/oscar.c
===================================================================
--- protocols/oscar/oscar.c	(revision 723e611603236aab794ffbbc312705b8309b3f81)
+++ protocols/oscar/oscar.c	(revision fa29d09342c79b886efacee4cfc3078be5f5a722)
@@ -157,20 +157,4 @@
 	return tmp;
 }
-
-static struct chat_connection *find_oscar_chat(struct gaim_connection *gc, int id) {
-	GSList *g = ((struct oscar_data *)gc->proto_data)->oscar_chats;
-	struct chat_connection *c = NULL;
-
-	while (g) {
-		c = (struct chat_connection *)g->data;
-		if (c->id == id)
-			break;
-		g = g->next;
-		c = NULL;
-	}
-
-	return c;
-}
-
 
 static struct chat_connection *find_oscar_chat_by_conn(struct gaim_connection *gc,
@@ -769,5 +753,6 @@
 	chatcon = find_oscar_chat_by_conn(gc, fr->conn);
 	chatcon->id = id;
-	chatcon->cnv = serv_got_joined_chat(gc, id++, chatcon->show);
+	chatcon->cnv = serv_got_joined_chat(gc, chatcon->show);
+	chatcon->cnv->data = chatcon;
 
 	return 1;
@@ -1580,5 +1565,5 @@
 	tmp = g_malloc(BUF_LONG);
 	g_snprintf(tmp, BUF_LONG, "%s", msg);
-	serv_got_chat_in(gc, ccon->id, info->sn, 0, tmp, time((time_t)NULL));
+	serv_got_chat_in(ccon->cnv, info->sn, 0, tmp, time((time_t)NULL));
 	g_free(tmp);
 
@@ -2521,6 +2506,7 @@
 }
 
-int oscar_chat_send(struct gaim_connection * gc, int id, char *message)
-{
+int oscar_chat_send(struct conversation *c, char *message)
+{
+	struct gaim_connection *gc = c->gc;
 	struct oscar_data * od = (struct oscar_data*)gc->proto_data;
 	struct chat_connection * ccon;
@@ -2530,6 +2516,5 @@
 	char *s;
 	
-	if(!(ccon = find_oscar_chat(gc, id)))
-		return -1;
+	ccon = c->data;
 	  	
 	for (s = message; *s; s++)
@@ -2568,11 +2553,9 @@
 }
 
-void oscar_chat_invite(struct gaim_connection * gc, int id, char *message, char *who)
-{
+void oscar_chat_invite(struct conversation *c, char *message, char *who)
+{
+	struct gaim_connection *gc = c->gc;
 	struct oscar_data * od = (struct oscar_data *)gc->proto_data;
-	struct chat_connection *ccon = find_oscar_chat(gc, id);
-	
-	if (ccon == NULL)
-		return;
+	struct chat_connection *ccon = c->data;
 	
 	aim_chat_invite(od->sess, od->conn, who, message ? message : "",
@@ -2585,5 +2568,5 @@
 
 	/* Notify the conversation window that we've left the chat */
-	serv_got_chat_left(gc, cc->id);
+	serv_got_chat_left(cc->cnv);
 
 	/* Destroy the chat_connection */
@@ -2597,17 +2580,12 @@
 }
 
-void oscar_chat_leave(struct gaim_connection * gc, int id)
-{
-	struct chat_connection * ccon = find_oscar_chat(gc, id);
-
-	if(ccon == NULL)
-		return;
-
-	oscar_chat_kill(gc, ccon);
+void oscar_chat_leave(struct conversation *c)
+{
+	oscar_chat_kill(c->gc, c->data);
 }
 
 int oscar_chat_join(struct gaim_connection * gc, char * name)
 {
-    struct oscar_data * od = (struct oscar_data *)gc->proto_data;
+	struct oscar_data * od = (struct oscar_data *)gc->proto_data;
 	
 	aim_conn_t * cur;
@@ -2627,5 +2605,5 @@
 }
 
-int oscar_chat_open(struct gaim_connection * gc, char *who)
+struct conversation *oscar_chat_open(struct gaim_connection * gc, char *who)
 {
 	struct oscar_data * od = (struct oscar_data *)gc->proto_data;
@@ -2642,5 +2620,5 @@
 	g_free(chatname);
 	
-	return ret;
+	return NULL;
 }
 
Index: protocols/yahoo/yahoo.c
===================================================================
--- protocols/yahoo/yahoo.c	(revision 723e611603236aab794ffbbc312705b8309b3f81)
+++ protocols/yahoo/yahoo.c	(revision fa29d09342c79b886efacee4cfc3078be5f5a722)
@@ -140,5 +140,5 @@
 	
 	while( gc->conversations )
-		serv_got_chat_left( gc, gc->conversations->id );
+		serv_got_chat_left( gc->conversations );
 	
 	for( l = yd->buddygroups; l; l = l->next )
@@ -332,11 +332,8 @@
 }
 
-static int byahoo_chat_send( struct gaim_connection *gc, int id, char *message )
-{
-	struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
-	struct conversation *c;
-	
-	for( c = gc->conversations; c && c->id != id; c = c->next );
-
+static int byahoo_chat_send( struct conversation *c, char *message )
+{
+	struct byahoo_data *yd = (struct byahoo_data *) c->gc->proto_data;
+	
 	yahoo_conference_message( yd->y2_id, NULL, c->data, c->title, message, 1 );
 	
@@ -344,26 +341,20 @@
 }
 
-static void byahoo_chat_invite( struct gaim_connection *gc, int id, char *msg, char *who )
-{
-	struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
-	struct conversation *c;
-	
-	for( c = gc->conversations; c && c->id != id; c = c->next );
+static void byahoo_chat_invite( struct conversation *c, char *msg, char *who )
+{
+	struct byahoo_data *yd = (struct byahoo_data *) c->gc->proto_data;
 	
 	yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg );
 }
 
-static void byahoo_chat_leave( struct gaim_connection *gc, int id )
-{
-	struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
-	struct conversation *c;
-	
-	for( c = gc->conversations; c && c->id != id; c = c->next );
+static void byahoo_chat_leave( struct conversation *c )
+{
+	struct byahoo_data *yd = (struct byahoo_data *) c->gc->proto_data;
 	
 	yahoo_conference_logoff( yd->y2_id, NULL, c->data, c->title );
-	serv_got_chat_left( gc, c->id );
-}
-
-static int byahoo_chat_open( struct gaim_connection *gc, char *who )
+	serv_got_chat_left( c );
+}
+
+static struct conversation *byahoo_chat_open( struct gaim_connection *gc, char *who )
 {
 	struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
@@ -375,5 +366,5 @@
 	g_snprintf( roomname, strlen( gc->username ) + 16, "%s-Bee-%d", gc->username, byahoo_chat_id );
 	
-	c = serv_got_joined_chat( gc, ++byahoo_chat_id, roomname );
+	c = serv_got_joined_chat( gc, roomname );
 	add_chat_buddy( c, gc->username );
 	
@@ -387,5 +378,5 @@
 	g_free( roomname );
 	
-	return( 1 );
+	return c;
 }
 
@@ -805,5 +796,5 @@
 {
 	yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
-	serv_got_chat_left( inv->gc, inv->c->id );
+	serv_got_chat_left( inv->c );
 	g_free( inv->name );
 	g_free( inv );
@@ -820,5 +811,5 @@
 	memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
 	inv->name = g_strdup( room );
-	inv->c = serv_got_joined_chat( gc, ++byahoo_chat_id, room );
+	inv->c = serv_got_joined_chat( gc, room );
 	inv->c->data = members;
 	inv->yid = id;
@@ -872,5 +863,6 @@
 	for( c = gc->conversations; c && strcmp( c->title, room ) != 0; c = c->next );
 	
-	serv_got_chat_in( gc, c ? c->id : 0, who, 0, m, 0 );
+	if( c )
+		serv_got_chat_in( c, who, 0, m, 0 );
 	g_free( m );
 }
Index: root_commands.c
===================================================================
--- root_commands.c	(revision 723e611603236aab794ffbbc312705b8309b3f81)
+++ root_commands.c	(revision fa29d09342c79b886efacee4cfc3078be5f5a722)
@@ -883,4 +883,51 @@
 		else
 			irc_usermsg( irc, "%d, BitlBee: %s", num, q->question );
+}
+
+static void cmd_join_chat( irc_t *irc, char **cmd )
+{
+	account_t *a;
+	struct gaim_connection *gc;
+	char *chat, *channel, *nick = NULL, *password = NULL;
+	struct conversation *c;
+	
+	if( !( a = account_get( irc, cmd[1] ) ) )
+	{
+		irc_usermsg( irc, "Invalid account" );
+		return;
+	}
+	else if( !( a->gc && ( a->gc->flags & OPT_LOGGED_IN ) ) )
+	{
+		irc_usermsg( irc, "That account is not on-line" );
+		return;
+	}
+	else if( a->prpl->chat_join == NULL )
+	{
+		irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
+		return;
+	}
+	gc = a->gc;
+	
+	chat = cmd[2];
+	if( cmd[3] )
+	{
+		channel = g_strdup( cmd[3] );
+	}
+	else
+	{
+		char *s;
+		
+		channel = g_strdup( chat );
+		if( ( s = strchr( channel, '@' ) ) )
+			*s = 0;
+	}
+	if( cmd[3] && cmd[4] )
+		nick = cmd[4];
+	if( cmd[3] && cmd[4] && cmd[5] )
+		password = cmd[5];
+	
+	c = a->prpl->chat_join( gc, chat, nick, password );
+	
+	g_free( channel );
 }
 
@@ -904,4 +951,5 @@
 	{ "nick",           1, cmd_nick,           0 },
 	{ "qlist",          0, cmd_qlist,          0 },
+	{ "join_chat",      2, cmd_join_chat,      0 },
 	{ NULL }
 };
