Index: protocols/msn/msn.c
===================================================================
--- protocols/msn/msn.c	(revision d97f51b59a3ac6d9557ebd1e42a45928fe064b4b)
+++ protocols/msn/msn.c	(revision ff27648aee17e649cdd1e47f503271e4fccbff43)
@@ -107,11 +107,17 @@
 		msn_msgq_purge( ic, &md->msgq );
 		
-		while( md->groupcount > 0 )
-			g_free( md->grouplist[--md->groupcount] );
-		g_free( md->grouplist );
 		g_free( md->tokens[0] );
 		g_free( md->tokens[1] );
 		g_free( md->tokens[2] );
 		g_free( md->lock_key );
+		
+		while( md->groups )
+		{
+			struct msn_group *mg = md->groups->data;
+			g_free( mg->id );
+			g_free( mg->name );
+			g_free( mg );
+			md->groups = g_slist_remove( md->groups, mg );
+		}
 		
 		g_tree_destroy( md->domaintree );
Index: protocols/msn/msn.h
===================================================================
--- protocols/msn/msn.h	(revision d97f51b59a3ac6d9557ebd1e42a45928fe064b4b)
+++ protocols/msn/msn.h	(revision ff27648aee17e649cdd1e47f503271e4fccbff43)
@@ -91,10 +91,7 @@
 	int sb_failures;
 	time_t first_sb_failure;
-	GSList *filetransfers;
 	
 	const struct msn_away_state *away_state;
-	int buddycount;
-	int groupcount;
-	char **grouplist;
+	GSList *groups;
 	GTree *domaintree;
 };
@@ -173,4 +170,10 @@
 	char *cid;
 	msn_buddy_flags_t flags;
+};
+
+struct msn_group
+{
+	char *name;
+	char *id;
 };
 
@@ -211,4 +214,6 @@
 char *msn_p11_challenge( char *challenge );
 gint msn_domaintree_cmp( gconstpointer a_, gconstpointer b_ );
+struct msn_group *msn_group_by_name( struct im_connection *ic, const char *name );
+struct msn_group *msn_group_by_id( struct im_connection *ic, const char *id );
 
 /* tables.c */
Index: protocols/msn/msn_util.c
===================================================================
--- protocols/msn/msn_util.c	(revision d97f51b59a3ac6d9557ebd1e42a45928fe064b4b)
+++ protocols/msn/msn_util.c	(revision ff27648aee17e649cdd1e47f503271e4fccbff43)
@@ -566,2 +566,34 @@
 	return ret;
 }
+
+struct msn_group *msn_group_by_name( struct im_connection *ic, const char *name )
+{
+	struct msn_data *md = ic->proto_data;
+	GSList *l;
+	
+	for( l = md->groups; l; l = l->next )
+	{
+		struct msn_group *mg = l->data;
+		
+		if( g_strcasecmp( mg->name, name ) == 0 )
+			return mg;
+	}
+	
+	return NULL;
+}
+
+struct msn_group *msn_group_by_id( struct im_connection *ic, const char *id )
+{
+	struct msn_data *md = ic->proto_data;
+	GSList *l;
+	
+	for( l = md->groups; l; l = l->next )
+	{
+		struct msn_group *mg = l->data;
+		
+		if( g_strcasecmp( mg->id, id ) == 0 )
+			return mg;
+	}
+	
+	return NULL;
+}
Index: protocols/msn/soap.c
===================================================================
--- protocols/msn/soap.c	(revision d97f51b59a3ac6d9557ebd1e42a45928fe064b4b)
+++ protocols/msn/soap.c	(revision ff27648aee17e649cdd1e47f503271e4fccbff43)
@@ -632,4 +632,5 @@
 	char *id = NULL, *name = NULL;
 	struct msn_soap_req_data *soap_req = data;
+	struct msn_data *md = soap_req->ic->proto_data;
 	
 	if( ( p = xt_find_path( node, "../groupId" ) ) )
@@ -638,4 +639,12 @@
 	if( ( p = xt_find_node( node->children, "name" ) ) )
 		name = p->text;
+	
+	if( id && name )
+	{
+		struct msn_group *mg = g_new0( struct msn_group, 1 );
+		mg->id = g_strdup( id );
+		mg->name = g_strdup( name );
+		md->groups = g_slist_prepend( md->groups, mg );
+	}
 	
 	printf( "%s %s\n", id, name );
@@ -649,7 +658,9 @@
 	struct msn_buddy_data *bd;
 	struct xt_node *p;
-	char *id = NULL, *type = NULL, *handle = NULL, *display_name = NULL;
+	char *id = NULL, *type = NULL, *handle = NULL,
+	     *display_name = NULL, *group_id = NULL;
 	struct msn_soap_req_data *soap_req = data;
 	struct im_connection *ic = soap_req->ic;
+	struct msn_group *group;
 	
 	if( ( p = xt_find_path( node, "../contactId" ) ) )
@@ -661,4 +672,6 @@
 	if( ( p = xt_find_node( node->children, "displayName" ) ) )
 		display_name = p->text;
+	if( ( p = xt_find_path( node, "groupIds/guid" ) ) )
+		group_id = p->text;
 	
 	if( type && g_strcasecmp( type, "me" ) == 0 )
@@ -685,4 +698,7 @@
 	imcb_rename_buddy( ic, handle, display_name );
 	
+	if( group_id && ( group = msn_group_by_id( ic, group_id ) ) )
+		imcb_add_buddy( ic, handle, group->name );
+	
 	printf( "%s %s %s %s\n", id, type, handle, display_name );
 	
