Index: protocols/msn/msn.c
===================================================================
--- protocols/msn/msn.c	(revision 523fb2324a351e9607ad2a803c6e866c5175aa16)
+++ protocols/msn/msn.c	(revision 7f34ce254c1a1587e5560456dd11acb29345206d)
@@ -332,4 +332,14 @@
 	   user. */
 	return msn_set_display_name( ic, value ) ? value : NULL;
+}
+
+static void msn_buddy_data_add( bee_user_t *bu )
+{
+	bu->data = g_new0( struct msn_buddy_data, 1 );
+}
+
+static void msn_buddy_data_free( bee_user_t *bu )
+{
+	g_free( bu->data );
 }
 
@@ -360,4 +370,7 @@
 	ret->send_typing = msn_send_typing;
 	ret->handle_cmp = g_strcasecmp;
+	ret->buddy_data_add = msn_buddy_data_add;
+	ret->buddy_data_free = msn_buddy_data_free;
+	
 	//ret->transfer_request = msn_ftp_transfer_request;
 
Index: protocols/msn/msn.h
===================================================================
--- protocols/msn/msn.h	(revision 523fb2324a351e9607ad2a803c6e866c5175aa16)
+++ protocols/msn/msn.h	(revision 7f34ce254c1a1587e5560456dd11acb29345206d)
@@ -149,4 +149,19 @@
 	int (*exec_command) ( gpointer data, char **cmd, int count );
 	int (*exec_message) ( gpointer data, char *msg, int msglen, char **cmd, int count );
+};
+
+typedef enum
+{
+	MSN_BUDDY_FL = 1,
+	MSN_BUDDY_AL = 2,
+	MSN_BUDDY_BL = 4,
+	MSN_BUDDY_RL = 8,
+	MSN_BUDDY_PL = 16,
+} msn_buddy_flags_t;
+
+struct msn_buddy_data
+{
+	char *cid;
+	msn_buddy_flags_t flags;
 };
 
Index: protocols/msn/soap.c
===================================================================
--- protocols/msn/soap.c	(revision 523fb2324a351e9607ad2a803c6e866c5175aa16)
+++ protocols/msn/soap.c	(revision 7f34ce254c1a1587e5560456dd11acb29345206d)
@@ -423,24 +423,51 @@
 /* memlist: Fetching the membership list (NOT address book) */
 
-#if 0
-struct msn_soap_oim_send_data
-{
-	char *to;
-	char *msg;
-	int number;
-	int need_retry;
-};
-#endif
-
 static int msn_soap_memlist_build_request( struct msn_soap_req_data *soap_req )
 {
+	struct msn_data *md = soap_req->ic->proto_data;
+	
 	soap_req->url = g_strdup( SOAP_MEMLIST_URL );
 	soap_req->action = g_strdup( SOAP_MEMLIST_ACTION );
-	soap_req->payload = g_strdup( SOAP_MEMLIST_PAYLOAD );
+	soap_req->payload = g_markup_printf_escaped( SOAP_MEMLIST_PAYLOAD, md->tokens[1] );
 	
 	return 1;
 }
 
+static xt_status msn_soap_memlist_member( struct xt_node *node, gpointer data )
+{
+	bee_user_t *bu;
+	struct msn_buddy_data *bd;
+	struct xt_node *p;
+	char *role = NULL, *handle = NULL;
+	struct msn_soap_req_data *soap_req = data;
+	struct im_connection *ic = soap_req->ic;
+	
+	if( ( p = node->parent ) && ( p = p->parent ) &&
+	    ( p = xt_find_node( p->children, "MemberRole" ) ) )
+		role = p->text;
+	
+	if( ( p = xt_find_node( node->children, "PassportName" ) ) )
+		handle = p->text;
+	
+	if( !role || !handle || 
+	    !( ( bu = bee_user_by_handle( ic->bee, ic, handle ) ) ||
+	       ( bu = bee_user_new( ic->bee, ic, handle, 0 ) ) ) )
+		return XT_HANDLED;
+	
+	bd = bu->data;
+	if( strcmp( role, "Allow" ) == 0 )
+		bd->flags |= MSN_BUDDY_AL;
+	else if( strcmp( role, "Block" ) == 0 )
+		bd->flags |= MSN_BUDDY_BL;
+	else if( strcmp( role, "Reverse" ) == 0 )
+		bd->flags |= MSN_BUDDY_RL;
+	else if( strcmp( role, "Pending" ) == 0 )
+		bd->flags |= MSN_BUDDY_PL;
+	
+	return XT_HANDLED;
+}
+
 static const struct xt_handler_entry msn_soap_memlist_parser[] = {
+	{ "Member", "Members", msn_soap_memlist_member },
 	{ NULL,               NULL,     NULL                        }
 };
@@ -448,5 +475,7 @@
 static int msn_soap_memlist_handle_response( struct msn_soap_req_data *soap_req )
 {
-	return 0;
+	msn_soap_addressbook_request( soap_req->ic );
+	
+	return MSN_SOAP_OK;
 }
 
@@ -463,2 +492,103 @@
 	                                 msn_soap_memlist_free_data );
 }
+
+
+/* addressbook: Fetching the membership list (NOT address book) */
+
+static int msn_soap_addressbook_build_request( struct msn_soap_req_data *soap_req )
+{
+	struct msn_data *md = soap_req->ic->proto_data;
+	
+	soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL );
+	soap_req->action = g_strdup( SOAP_ADDRESSBOOK_ACTION );
+	soap_req->payload = g_markup_printf_escaped( SOAP_ADDRESSBOOK_PAYLOAD, md->tokens[1] );
+	
+	return 1;
+}
+
+static xt_status msn_soap_addressbook_group( struct xt_node *node, gpointer data )
+{
+	struct xt_node *p;
+	char *id = NULL, *name = NULL;
+	struct msn_soap_req_data *soap_req = data;
+	struct im_connection *ic = soap_req->ic;
+	
+	if( ( p = node->parent ) &&
+	    ( p = xt_find_node( p->children, "groupId" ) ) )
+		id = p->text;
+	
+	if( ( p = xt_find_node( node->children, "name" ) ) )
+		name = p->text;
+	
+	printf( "%s %s\n", id, name );
+	
+	return XT_HANDLED;
+}
+
+static xt_status msn_soap_addressbook_contact( struct xt_node *node, gpointer data )
+{
+	bee_user_t *bu;
+	struct msn_buddy_data *bd;
+	struct xt_node *p;
+	char *id = NULL, *type = NULL, *handle = NULL, *display_name = NULL;
+	struct msn_soap_req_data *soap_req = data;
+	struct im_connection *ic = soap_req->ic;
+	
+	if( ( p = node->parent ) &&
+	    ( p = xt_find_node( p->children, "contactId" ) ) )
+		id = p->text;
+	if( ( p = xt_find_node( node->children, "contactType" ) ) )
+		type = p->text;
+	if( ( p = xt_find_node( node->children, "passportName" ) ) )
+		handle = p->text;
+	if( ( p = xt_find_node( node->children, "displayName" ) ) )
+		display_name = p->text;
+	
+	if( type && g_strcasecmp( type, "me" ) == 0 )
+	{
+		set_t *set = set_find( &ic->acc->set, "display_name" );
+		g_free( set->value );
+		set->value = g_strdup( display_name );
+		
+		return XT_HANDLED;
+	}
+	
+	if( !( bu = bee_user_by_handle( ic->bee, ic, handle ) ) &&
+	    !( bu = bee_user_new( ic->bee, ic, handle, 0 ) ) )
+		return XT_HANDLED;
+	
+	bd = bu->data;
+	bd->flags |= MSN_BUDDY_FL;
+	g_free( bd->cid );
+	bd->cid = g_strdup( id );
+	
+	imcb_rename_buddy( ic, handle, display_name );
+	
+	printf( "%s %s %s %s\n", id, type, handle, display_name );
+	
+	return XT_HANDLED;
+}
+
+static const struct xt_handler_entry msn_soap_addressbook_parser[] = {
+	{ "contactInfo", "Contact", msn_soap_addressbook_contact },
+	{ "groupInfo", "Group", msn_soap_addressbook_group },
+	{ NULL,               NULL,     NULL                        }
+};
+
+static int msn_soap_addressbook_handle_response( struct msn_soap_req_data *soap_req )
+{
+	return MSN_SOAP_OK;
+}
+
+static int msn_soap_addressbook_free_data( struct msn_soap_req_data *soap_req )
+{
+	return 0;
+}
+
+int msn_soap_addressbook_request( struct im_connection *ic )
+{
+	return msn_soap_start( ic, NULL, msn_soap_addressbook_build_request,
+	                                 msn_soap_addressbook_parser,
+	                                 msn_soap_addressbook_handle_response,
+	                                 msn_soap_addressbook_free_data );
+}
Index: protocols/msn/soap.h
===================================================================
--- protocols/msn/soap.h	(revision 523fb2324a351e9607ad2a803c6e866c5175aa16)
+++ protocols/msn/soap.h	(revision 7f34ce254c1a1587e5560456dd11acb29345206d)
@@ -152,5 +152,5 @@
 
 
-#define SOAP_MEMLIST_URL "https://byrdr.omega.contacts.msn.com/abservice/SharingService.asmx"
+#define SOAP_MEMLIST_URL "http://contacts.msn.com/abservice/SharingService.asmx"
 #define SOAP_MEMLIST_ACTION "http://www.msn.com/webservices/AddressBook/FindMembership"
 
@@ -166,4 +166,5 @@
     "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
       "<ManagedGroupRequest xmlns=\"http://www.msn.com/webservices/AddressBook\">false</ManagedGroupRequest>" \
+      "<TicketToken>%s</TicketToken>" \
     "</ABAuthHeader>" \
   "</soap:Header>" \
@@ -177,3 +178,33 @@
 
 
+#define SOAP_ADDRESSBOOK_URL "http://contacts.msn.com/abservice/abservice.asmx"
+#define SOAP_ADDRESSBOOK_ACTION "http://www.msn.com/webservices/AddressBook/ABFindAll"
+
+#define SOAP_ADDRESSBOOK_PAYLOAD \
+"<?xml version=\"1.0\" encoding=\"utf-8\"?>" \
+"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">" \
+  "<soap:Header>" \
+    "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
+      "<ApplicationId>CFE80F9D-180F-4399-82AB-413F33A1FA11</ApplicationId>" \
+      "<IsMigration>false</IsMigration>" \
+      "<PartnerScenario>Initial</PartnerScenario>" \
+    "</ABApplicationHeader>" \
+    "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
+      "<ManagedGroupRequest>false</ManagedGroupRequest>" \
+      "<TicketToken>%s</TicketToken>" \
+    "</ABAuthHeader>" \
+  "</soap:Header>" \
+  "<soap:Body>" \
+    "<ABFindAll xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
+      "<abId>00000000-0000-0000-0000-000000000000</abId>" \
+      "<abView>Full</abView>" \
+      "<deltasOnly>false</deltasOnly>" \
+      "<lastChange>0001-01-01T00:00:00.0000000-08:00</lastChange>" \
+    "</ABFindAll>" \
+  "</soap:Body>" \
+"</soap:Envelope>"
+
+int msn_soap_addressbook_request( struct im_connection *ic );
+
+
 #endif /* __SOAP_H__ */
