Index: protocols/Makefile
===================================================================
--- protocols/Makefile	(revision 4be823968d7f4cb1d11e4f6dda50ef606a0fd7b0)
+++ protocols/Makefile	(revision 10a96f44efbeb6af09e2728926ce15b6bda12131)
@@ -11,5 +11,5 @@
 # [SH] Program variables
 #objects = account.o nogaim.o user.o
-objects = bee.o
+objects = bee.o bee_user.o nogaim.o
 
 
Index: protocols/bee.h
===================================================================
--- protocols/bee.h	(revision 4be823968d7f4cb1d11e4f6dda50ef606a0fd7b0)
+++ protocols/bee.h	(revision 10a96f44efbeb6af09e2728926ce15b6bda12131)
@@ -1,6 +1,31 @@
-typedef struct bee_ui
-{
-	void *data;
-} bee_ui_t;
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2010 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* Stuff to handle, save and search buddies                             */
+
+/*
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __BEE_H__
+#define __BEE_H__
+
+struct bee_ui_funcs;
 
 typedef struct bee
@@ -11,5 +36,5 @@
 	GSList *accounts;
 	
-	//const bee_ui_funcs_t *ui;
+	const struct bee_ui_funcs *ui;
 	void *ui_data;
 } bee_t;
@@ -17,2 +42,40 @@
 bee_t *bee_new();
 void bee_free( bee_t *b );
+
+typedef enum
+{
+	BEE_USER_ONLINE = 1,
+	BEE_USER_AWAY = 2,
+} bee_user_flags_t;
+
+typedef struct bee_user
+{
+	struct im_connection *ic;
+	char *handle;
+	char *fullname;
+	char *group;
+
+	char *away;
+	char *status_msg;
+	
+	bee_t *bee;
+	void *ui_data;
+} bee_user_t;
+
+typedef struct bee_ui_funcs
+{
+	gboolean (*user_new)( bee_t *bee, struct bee_user *bu );
+	gboolean (*user_free)( bee_t *bee, struct bee_user *bu );
+} bee_ui_funcs_t;
+
+
+/* bee.c */
+bee_t *bee_new();
+void bee_free( bee_t *b );
+
+/* bee_user.c */
+bee_user_t *bee_user_new( bee_t *bee, struct im_connection *ic, const char *handle );
+int bee_user_free( bee_t *bee, struct im_connection *ic, const char *handle );
+bee_user_t *bee_user_by_handle( bee_t *bee, struct im_connection *ic, const char *handle );
+
+#endif /* __BEE_H__ */
Index: protocols/bee_user.c
===================================================================
--- protocols/bee_user.c	(revision 10a96f44efbeb6af09e2728926ce15b6bda12131)
+++ protocols/bee_user.c	(revision 10a96f44efbeb6af09e2728926ce15b6bda12131)
@@ -0,0 +1,82 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2010 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* Stuff to handle, save and search buddies                             */
+
+/*
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#define BITLBEE_CORE
+#include "bitlbee.h"
+
+bee_user_t *bee_user_new( bee_t *bee, struct im_connection *ic, const char *handle )
+{
+	bee_user_t *bu;
+	
+	if( bee_user_by_handle( bee, ic, handle ) != NULL )
+		return NULL;
+	
+	bu = g_new0( bee_user_t, 1 );
+	bu->bee = bee;
+	bu->ic = ic;
+	bu->handle = g_strdup( handle );
+	bee->users = g_slist_prepend( bee->users, bu );
+	
+	if( bee->ui->user_new )
+		bee->ui->user_new( bee, bu );
+	
+	return bu;
+}
+
+int bee_user_free( bee_t *bee, struct im_connection *ic, const char *handle )
+{
+	bee_user_t *bu;
+	
+	if( ( bu = bee_user_by_handle( bee, ic, handle ) ) == NULL )
+		return 0;
+	
+	if( bee->ui->user_free )
+		bee->ui->user_free( bee, bu );
+	
+	g_free( bu->handle );
+	g_free( bu->fullname );
+	g_free( bu->group );
+	g_free( bu->away );
+	g_free( bu->status_msg );
+	
+	bee->users = g_slist_remove( bee->users, bu );
+	
+	return 1;
+}
+
+bee_user_t *bee_user_by_handle( bee_t *bee, struct im_connection *ic, const char *handle )
+{
+	GSList *l;
+	
+	for( l = bee->users; l; l = l->next )
+	{
+		bee_user_t *bu = l->data;
+		
+		if( bu->ic == ic && ic->acc->prpl->handle_cmp( bu->handle, handle ) )
+			return bu;
+	}
+	
+	return NULL;
+}
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision 4be823968d7f4cb1d11e4f6dda50ef606a0fd7b0)
+++ protocols/nogaim.c	(revision 10a96f44efbeb6af09e2728926ce15b6bda12131)
@@ -199,6 +199,6 @@
 	va_end( params );
 
-	if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) ||
-	    ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
+	if( ( g_strcasecmp( set_getstr( &ic->irc->b->set, "strip_html" ), "always" ) == 0 ) ||
+	    ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->b->set, "strip_html" ) ) )
 		strip_html( text );
 	
@@ -265,5 +265,4 @@
 	irc_t *irc = ic->irc;
 	struct chat *c;
-	user_t *u;
 	
 	/* MSN servers sometimes redirect you to a different server and do
@@ -273,6 +272,4 @@
 		return;
 	
-	u = user_find( ic->irc, ic->irc->nick );
-	
 	imcb_log( ic, "Logged in" );
 	
@@ -287,4 +284,5 @@
 	ic->acc->auto_reconnect_delay = 0;
 	
+	/*
 	for( c = irc->chatrooms; c; c = c->next )
 	{
@@ -295,4 +293,5 @@
 			chat_join( irc, c, NULL );
 	}
+	*/
 }
 
@@ -360,5 +359,5 @@
 		/* Uhm... This is very sick. */
 	}
-	else if( allow_reconnect && set_getbool( &irc->set, "auto_reconnect" ) &&
+	else if( allow_reconnect && set_getbool( &irc->b->set, "auto_reconnect" ) &&
 	         set_getbool( &a->set, "auto_reconnect" ) &&
 	         ( delay = account_reconnect_delay( a ) ) > 0 )
@@ -391,5 +390,5 @@
 	if( user_findhandle( ic, handle ) )
 	{
-		if( set_getbool( &irc->set, "debug" ) )
+		if( set_getbool( &irc->b->set, "debug" ) )
 			imcb_log( ic, "User already exists, ignoring add request: %s", handle );
 		
@@ -470,5 +469,5 @@
 		u->realname = g_strdup( realname );
 		
-		if( ( ic->flags & OPT_LOGGED_IN ) && set_getbool( &ic->irc->set, "display_namechanges" ) )
+		if( ( ic->flags & OPT_LOGGED_IN ) && set_getbool( &ic->irc->b->set, "display_namechanges" ) )
 			imcb_log( ic, "User `%s' changed name to `%s'", u->nick, u->realname );
 	}
@@ -518,5 +517,5 @@
 		/* Some processing to make sure this string is a valid IRC nickname. */
 		nick_strip( newnick );
-		if( set_getbool( &ic->irc->set, "lcnicks" ) )
+		if( set_getbool( &ic->irc->b->set, "lcnicks" ) )
 			nick_lc( newnick );
 		
@@ -626,5 +625,5 @@
 	if( !u )
 	{
-		if( g_strcasecmp( set_getstr( &ic->irc->set, "handle_unknown" ), "add" ) == 0 )
+		if( g_strcasecmp( set_getstr( &ic->irc->b->set, "handle_unknown" ), "add" ) == 0 )
 		{
 			imcb_add_buddy( ic, (char*) handle, NULL );
@@ -633,5 +632,5 @@
 		else
 		{
-			if( set_getbool( &ic->irc->set, "debug" ) || g_strcasecmp( set_getstr( &ic->irc->set, "handle_unknown" ), "ignore" ) != 0 )
+			if( set_getbool( &ic->irc->b->set, "debug" ) || g_strcasecmp( set_getstr( &ic->irc->b->set, "handle_unknown" ), "ignore" ) != 0 )
 			{
 				imcb_log( ic, "imcb_buddy_status() for unknown handle %s:", handle );
@@ -693,5 +692,5 @@
 	
 	/* LISPy... */
-	if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */
+	if( ( set_getbool( &ic->irc->b->set, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */
 	    ( u->online ) &&						/* Don't touch offline people */
 	    ( ( ( u->online != oo ) && !u->away ) ||			/* Voice joining people */
@@ -700,5 +699,5 @@
 		char *from;
 		
-		if( set_getbool( &ic->irc->set, "simulate_netsplit" ) )
+		if( set_getbool( &ic->irc->b->set, "simulate_netsplit" ) )
 		{
 			from = g_strdup( ic->irc->myhost );
@@ -725,9 +724,9 @@
 	if( !u )
 	{
-		char *h = set_getstr( &irc->set, "handle_unknown" );
+		char *h = set_getstr( &irc->b->set, "handle_unknown" );
 		
 		if( g_strcasecmp( h, "ignore" ) == 0 )
 		{
-			if( set_getbool( &irc->set, "debug" ) )
+			if( set_getbool( &irc->b->set, "debug" ) )
 				imcb_log( ic, "Ignoring message from unknown handle %s", handle );
 			
@@ -736,5 +735,5 @@
 		else if( g_strncasecmp( h, "add", 3 ) == 0 )
 		{
-			int private = set_getbool( &irc->set, "private" );
+			int private = set_getbool( &irc->b->set, "private" );
 			
 			if( h[3] )
@@ -757,6 +756,6 @@
 	}
 	
-	if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) ||
-	    ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
+	if( ( g_strcasecmp( set_getstr( &ic->irc->b->set, "strip_html" ), "always" ) == 0 ) ||
+	    ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->b->set, "strip_html" ) ) )
 		strip_html( msg );
 
@@ -770,5 +769,5 @@
 	user_t *u;
 	
-	if( !set_getbool( &ic->irc->set, "typing_notice" ) )
+	if( !set_getbool( &ic->irc->b->set, "typing_notice" ) )
 		return;
 	
@@ -801,5 +800,5 @@
 	c->topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title );
 	
-	if( set_getbool( &ic->irc->set, "debug" ) )
+	if( set_getbool( &ic->irc->b->set, "debug" ) )
 		imcb_log( ic, "Creating new conversation: (id=%p,handle=%s)", c, handle );
 	
@@ -813,5 +812,5 @@
 	GList *ir;
 	
-	if( set_getbool( &ic->irc->set, "debug" ) )
+	if( set_getbool( &ic->irc->b->set, "debug" ) )
 		imcb_log( ic, "You were removed from conversation %p", c );
 	
@@ -860,6 +859,6 @@
 	u = user_findhandle( ic, who );
 	
-	if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) ||
-	    ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
+	if( ( g_strcasecmp( set_getstr( &ic->irc->b->set, "strip_html" ), "always" ) == 0 ) ||
+	    ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->b->set, "strip_html" ) ) )
 		strip_html( msg );
 	
@@ -906,6 +905,6 @@
 		u = user_findhandle( ic, who );
 	
-	if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) ||
-	    ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
+	if( ( g_strcasecmp( set_getstr( &ic->irc->b->set, "strip_html" ), "always" ) == 0 ) ||
+	    ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->b->set, "strip_html" ) ) )
 		strip_html( topic );
 	
@@ -925,5 +924,5 @@
 	int me = 0;
 	
-	if( set_getbool( &b->ic->irc->set, "debug" ) )
+	if( set_getbool( &b->ic->irc->b->set, "debug" ) )
 		imcb_log( b->ic, "User %s added to conversation %p", handle, b );
 	
@@ -960,5 +959,5 @@
 	int me = 0;
 	
-	if( set_getbool( &b->ic->irc->set, "debug" ) )
+	if( set_getbool( &b->ic->irc->b->set, "debug" ) )
 		imcb_log( b->ic, "User %s removed from conversation %p (%s)", handle, b, reason ? reason : "" );
 	
@@ -1018,5 +1017,5 @@
 	/* Horror.... */
 	
-	if( st != set_getbool( &irc->set, "away_devoice" ) )
+	if( st != set_getbool( &irc->b->set, "away_devoice" ) )
 	{
 		char list[80] = "";
@@ -1107,5 +1106,5 @@
 	
 	away = set_getstr( &ic->acc->set, "away" ) ?
-	     : set_getstr( &ic->irc->set, "away" );
+	     : set_getstr( &ic->irc->b->set, "away" );
 	if( away && *away )
 	{
@@ -1118,5 +1117,5 @@
 		away = NULL;
 		msg = set_getstr( &ic->acc->set, "status" ) ?
-		    : set_getstr( &ic->irc->set, "status" );
+		    : set_getstr( &ic->irc->b->set, "status" );
 	}
 	
Index: protocols/user.c
===================================================================
--- protocols/user.c	(revision 4be823968d7f4cb1d11e4f6dda50ef606a0fd7b0)
+++ 	(revision )
@@ -1,106 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* Stuff to handle, save and search buddies                             */
-
-/*
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#define BITLBEE_CORE
-#include "bitlbee.h"
-
-user_t *user_add( irc_t *irc, char *nick )
-{
-	user_t *u, *lu = NULL;
-	char *key;
-	
-	if( !nick_ok( nick ) )
-		return( NULL );
-	
-	if( user_find( irc, nick ) != NULL )
-		return( NULL );
-	
-	return( u );
-}
-
-int user_del( irc_t *irc, char *nick )
-{
-	user_t *u, *t;
-	char *key;
-	gpointer okey, ovalue;
-	
-	if( !nick_ok( nick ) )
-		return( 0 );
-	
-	u = irc->users;
-	t = NULL;
-	while( u )
-	{
-		if( nick_cmp( u->nick, nick ) == 0 )
-		{
-			/* Get this key now already, since "nick" might be free()d
-			   at the time we start playing with the hash... */
-			key = g_strdup( nick );
-			nick_lc( key );
-			
-			if( t )
-				t->next = u->next;
-			else
-				irc->users = u->next;
-			if( u->online )
-				irc_kill( irc, u );
-			g_free( u->nick );
-			if( u->nick != u->user ) g_free( u->user );
-			if( u->nick != u->host ) g_free( u->host );
-			if( u->nick != u->realname ) g_free( u->realname );
-			g_free( u->group );
-			g_free( u->away );
-			g_free( u->handle );
-			g_free( u->sendbuf );
-			if( u->sendbuf_timer ) b_event_remove( u->sendbuf_timer );
-			g_free( u );
-			
-			return( 1 );
-		}
-		u = (t=u)->next;
-	}
-	
-	return( 0 );
-}
-
-user_t *user_findhandle( struct im_connection *ic, const char *handle )
-{
-	user_t *u;
-	char *nick;
-	
-	/* First, let's try a hash lookup. If it works, it's probably faster. */
-	if( ( nick = g_hash_table_lookup( ic->acc->nicks, handle ) ) &&
-	    ( u = user_find( ic->irc, nick ) ) &&
-	    ( ic->acc->prpl->handle_cmp( handle, u->handle ) == 0 ) )
-		return u;
-	
-	/* However, it doesn't always work, so in that case we'll have to dig
-	   through the whole userlist. :-( */
-	for( u = ic->irc->users; u; u = u->next )
-		if( u->ic == ic && u->handle && ic->acc->prpl->handle_cmp( u->handle, handle ) == 0 )
-			return u;
-	
-	return NULL;
-}
Index: protocols/user.h
===================================================================
--- protocols/user.h	(revision 4be823968d7f4cb1d11e4f6dda50ef606a0fd7b0)
+++ 	(revision )
@@ -1,40 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* Stuff to handle, save and search buddies                             */
-
-/*
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef __USER_H__
-#define __USER_H__
-
-struct __USER
-{
-	struct im_connection *ic;
-	char *handle;
-	char *fullname;
-	char *group;
-
-	char *away;
-	char *status_msg;
-} user_t;
-
-#endif /* __USER_H__ */
