Index: irc.h
===================================================================
--- irc.h	(revision f5d87ea5e4db1864cc9dd95c295f166af9944014)
+++ irc.h	(revision 5a75d1586478f78446b6c78b161572fc7cabe4d9)
@@ -193,10 +193,4 @@
 	struct bee_group *group;
 	struct account *account;
-};
-
-struct irc_groupchat_stub
-{
-	struct account *acc;
-	char *room;
 };
 
Index: irc_channel.c
===================================================================
--- irc_channel.c	(revision f5d87ea5e4db1864cc9dd95c295f166af9944014)
+++ irc_channel.c	(revision 5a75d1586478f78446b6c78b161572fc7cabe4d9)
@@ -29,5 +29,6 @@
 static gint irc_channel_user_cmp( gconstpointer a_, gconstpointer b_ );
 static const struct irc_channel_funcs control_channel_funcs;
-static const struct irc_channel_funcs groupchat_stub_funcs;
+
+extern const struct irc_channel_funcs irc_channel_im_chat_funcs;
 
 irc_channel_t *irc_channel_new( irc_t *irc, const char *name )
@@ -104,5 +105,5 @@
 		new = &control_channel_funcs;
 	else if( strcmp( value, "chat" ) == 0 )
-		new = &groupchat_stub_funcs;
+		new = &irc_channel_im_chat_funcs;
 	else
 		return SET_INVALID;
@@ -389,47 +390,2 @@
 	control_channel_free,
 };
-
-/* Groupchat stub: Only handles /INVITE at least for now. */
-static gboolean groupchat_stub_invite( irc_channel_t *ic, irc_user_t *iu )
-{
-	bee_user_t *bu = iu->bu;
-	
-	if( iu->bu->ic->acc->prpl->chat_with )
-	{
-		ic->flags |= IRC_CHANNEL_CHAT_PICKME;
-		iu->bu->ic->acc->prpl->chat_with( bu->ic, bu->handle );
-		ic->flags &= ~IRC_CHANNEL_CHAT_PICKME;
-		return TRUE;
-	}
-	else
-	{
-		irc_send_num( ic->irc, 482, "%s :IM protocol does not support room invitations", ic->name );
-		return FALSE;
-	}
-}
-
-static gboolean groupchat_stub_join( irc_channel_t *ic )
-{
-	struct irc_groupchat_stub *igs = ic->data;
-	
-	if( igs && igs->acc->ic && igs->acc->prpl->chat_join )
-	{
-		ic->flags |= IRC_CHANNEL_CHAT_PICKME;
-		igs->acc->prpl->chat_join( igs->acc->ic, igs->room, ic->irc->user->nick, NULL );
-		ic->flags &= ~IRC_CHANNEL_CHAT_PICKME;
-		return FALSE;
-	}
-	else
-	{
-		irc_send_num( ic->irc, 403, "%s :Can't join channel, account offline?", ic->name );
-		return FALSE;
-	}
-}
-
-static const struct irc_channel_funcs groupchat_stub_funcs = {
-	NULL,
-	groupchat_stub_join,
-	NULL,
-	NULL,
-	groupchat_stub_invite,
-};
Index: irc_commands.c
===================================================================
--- irc_commands.c	(revision f5d87ea5e4db1864cc9dd95c295f166af9944014)
+++ irc_commands.c	(revision 5a75d1586478f78446b6c78b161572fc7cabe4d9)
@@ -399,7 +399,5 @@
 	}
 	
-	if( ic->f->invite )
-		ic->f->invite( ic, iu );
-	else
+	if( !ic->f->invite || !ic->f->invite( ic, iu ) )
 		irc_send_num( irc, 482, "%s :Can't invite people here", cmd[2] );
 }
Index: irc_im.c
===================================================================
--- irc_im.c	(revision f5d87ea5e4db1864cc9dd95c295f166af9944014)
+++ irc_im.c	(revision 5a75d1586478f78446b6c78b161572fc7cabe4d9)
@@ -318,5 +318,5 @@
 
 /* IM->IRC: Groupchats */
-static const struct irc_channel_funcs irc_channel_im_chat_funcs;
+const struct irc_channel_funcs irc_channel_im_chat_funcs;
 
 static gboolean bee_irc_chat_new( bee_t *bee, struct groupchat *c )
@@ -341,5 +341,5 @@
 	{
 		char name[16];
-		sprintf( name, "&chat_%03d", i );
+		sprintf( name, "#chat_%03d", i );
 		if( ( ic = irc_channel_new( irc, name ) ) )
 			break;
@@ -351,5 +351,4 @@
 	c->ui_data = ic;
 	ic->data = c;
-	ic->f = &irc_channel_im_chat_funcs;
 	
 	topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title );
@@ -367,5 +366,8 @@
 		irc_channel_printf( ic, "Cleaning up channel, bye!" );
 	
-	irc_channel_free( ic );
+	/* irc_channel_free( ic ); */
+	
+	irc_channel_del_user( ic, ic->irc->user );
+	ic->data = NULL;
 	
 	return TRUE;
@@ -468,8 +470,41 @@
 	struct groupchat *c = ic->data;
 	
+	if( c == NULL )
+		return FALSE;
+	
 	bee_chat_msg( ic->irc->b, c, msg, 0 );
 	
 	return TRUE;
-	
+}
+
+static gboolean bee_irc_channel_chat_join( irc_channel_t *ic )
+{
+	char *acc_s, *room;
+	account_t *acc;
+	
+	if( strcmp( set_getstr( &ic->set, "chat_type" ), "room" ) != 0 )
+		return TRUE;
+	
+	if( ( acc_s = set_getstr( &ic->set, "account" ) ) &&
+	    ( room = set_getstr( &ic->set, "room" ) ) &&
+	    ( acc = account_get( ic->irc->b, acc_s ) ) &&
+	    acc->ic && acc->prpl->chat_join )
+	{
+		char *nick;
+		
+		if( !( nick = set_getstr( &ic->set, "nick" ) ) )
+			nick = ic->irc->user->nick;
+		
+		ic->flags |= IRC_CHANNEL_CHAT_PICKME;
+		acc->prpl->chat_join( acc->ic, room, nick, NULL );
+		ic->flags &= ~IRC_CHANNEL_CHAT_PICKME;
+		
+		return FALSE;
+	}
+	else
+	{
+		irc_send_num( ic->irc, 403, "%s :Can't join channel, account offline?", ic->name );
+		return FALSE;
+	}
 }
 
@@ -478,9 +513,8 @@
 	struct groupchat *c = ic->data;
 	
-	if( c->ic->acc->prpl->chat_leave )
+	if( c && c->ic->acc->prpl->chat_leave )
 		c->ic->acc->prpl->chat_leave( c );
 	
 	return TRUE;
-	
 }
 
@@ -488,5 +522,7 @@
 {
 	struct groupchat *c = ic->data;
-	char *topic = g_strdup( new ); /* TODO: Need more const goodness here, sigh */
+	
+	if( c == NULL )
+		return FALSE;
 	
 	if( c->ic->acc->prpl->chat_topic == NULL )
@@ -494,5 +530,8 @@
 	else
 	{
+		/* TODO: Need more const goodness here, sigh */
+		char *topic = g_strdup( new );
 		c->ic->acc->prpl->chat_topic( c, topic );
+		g_free( topic );
 		return TRUE;
 	}
@@ -504,21 +543,80 @@
 {
 	struct groupchat *c = ic->data;
-	
-	if( iu->bu->ic != c->ic )
-		irc_send_num( ic->irc, 482, "%s :Can't mix different IM networks in one groupchat", ic->name );
-	else if( c->ic->acc->prpl->chat_invite )
-		c->ic->acc->prpl->chat_invite( c, iu->bu->handle, NULL );
-	else
+	bee_user_t *bu = iu->bu;
+	
+	if( bu == NULL )
+		return FALSE;
+	
+	if( c )
+	{
+		if( iu->bu->ic != c->ic )
+			irc_send_num( ic->irc, 482, "%s :Can't mix different IM networks in one groupchat", ic->name );
+		else if( c->ic->acc->prpl->chat_invite )
+			c->ic->acc->prpl->chat_invite( c, iu->bu->handle, NULL );
+		else
+			irc_send_num( ic->irc, 482, "%s :IM protocol does not support room invitations", ic->name );
+	}
+	else if( bu->ic->acc->prpl->chat_with &&
+	         strcmp( set_getstr( &ic->set, "chat_type" ), "groupchat" ) == 0 )
+	{
+		ic->flags |= IRC_CHANNEL_CHAT_PICKME;
+		iu->bu->ic->acc->prpl->chat_with( bu->ic, bu->handle );
+		ic->flags &= ~IRC_CHANNEL_CHAT_PICKME;
+	}
+	else
+	{
 		irc_send_num( ic->irc, 482, "%s :IM protocol does not support room invitations", ic->name );
-	
-	return TRUE;
-}
-
-static const struct irc_channel_funcs irc_channel_im_chat_funcs = {
+	}
+	
+	return TRUE;
+}
+
+static char *set_eval_room_account( set_t *set, char *value );
+
+static gboolean bee_irc_channel_init( irc_channel_t *ic )
+{
+	set_add( &ic->set, "account", NULL, set_eval_room_account, ic );
+	set_add( &ic->set, "chat_type", "groupchat", NULL, ic );
+	set_add( &ic->set, "nick", NULL, NULL, ic );
+	set_add( &ic->set, "room", NULL, NULL, ic );
+	
+	return TRUE;
+}
+
+static char *set_eval_room_account( set_t *set, char *value )
+{
+	struct irc_channel *ic = set->data;
+	account_t *acc;
+	
+	if( !( acc = account_get( ic->irc->b, value ) ) )
+		return SET_INVALID;
+	else if( !acc->prpl->chat_join )
+	{
+		irc_usermsg( ic->irc, "Named chatrooms not supported on that account." );
+		return SET_INVALID;
+	}
+	
+	return g_strdup_printf( "%s(%s)", acc->prpl->name, acc->user );
+}
+
+static gboolean bee_irc_channel_free( irc_channel_t *ic )
+{
+	set_del( &ic->set, "account" );
+	set_del( &ic->set, "chat_type" );
+	set_del( &ic->set, "nick" );
+	set_del( &ic->set, "room" );
+	
+	return TRUE;
+}
+
+const struct irc_channel_funcs irc_channel_im_chat_funcs = {
 	bee_irc_channel_chat_privmsg,
-	NULL, /* join */
+	bee_irc_channel_chat_join,
 	bee_irc_channel_chat_part,
 	bee_irc_channel_chat_topic,
 	bee_irc_channel_chat_invite,
+
+	bee_irc_channel_init,
+	bee_irc_channel_free,
 };
 
Index: root_commands.c
===================================================================
--- root_commands.c	(revision f5d87ea5e4db1864cc9dd95c295f166af9944014)
+++ root_commands.c	(revision 5a75d1586478f78446b6c78b161572fc7cabe4d9)
@@ -980,4 +980,9 @@
 			return;
 		}
+		else if( !acc->prpl->chat_join )
+		{
+			irc_usermsg( irc, "Named chatrooms not supported on that account." );
+			return;
+		}
 		
 		if( cmd[4] == NULL )
@@ -999,11 +1004,17 @@
 		}
 		
-		if( ( ic = irc_channel_new( irc, channel ) ) )
-		{
-			struct irc_groupchat_stub *igs;
+		if( ( ic = irc_channel_new( irc, channel ) ) &&
+		    set_setstr( &ic->set, "chat_type", "room" ) &&
+		    set_setstr( &ic->set, "account", cmd[2] ) &&
+		    set_setstr( &ic->set, "room", cmd[3] ) )
+		{
+			irc_usermsg( irc, "Chatroom successfully added." );
+		}
+		else
+		{
+			if( ic )
+				irc_channel_free( ic );
 			
-			ic->data = igs = g_new0( struct irc_groupchat_stub, 1 );
-			igs->acc = acc;
-			igs->room = g_strdup( cmd[3] );
+			irc_usermsg( irc, "Could not add chatroom." );
 		}
 	}
