Index: protocols/msn/msn.c
===================================================================
--- protocols/msn/msn.c	(revision d93c0eb9f3f5d2d2cd78f02422d0c0ed25743e3a)
+++ protocols/msn/msn.c	(revision 4452e69ab1f01793a37205db8227a2de2f211d3e)
@@ -25,4 +25,5 @@
 
 #include "nogaim.h"
+#include "soap.h"
 #include "msn.h"
 
@@ -35,6 +36,9 @@
 static void msn_init( account_t *acc )
 {
-	set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc );
-	set_add( &acc->set, "local_display_name", "false", set_eval_bool, acc );
+	set_t *s;
+	
+	s = set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc );
+	s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY;
+	
 	set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc );
 	set_add( &acc->set, "switchboard_keepalives", "false", set_eval_bool, acc );
@@ -203,9 +207,4 @@
 }
 
-static void msn_set_my_name( struct im_connection *ic, char *info )
-{
-	msn_set_display_name( ic, info );
-}
-
 static void msn_get_info(struct im_connection *ic, char *who) 
 {
@@ -332,8 +331,7 @@
 	account_t *acc = set->data;
 	struct im_connection *ic = acc->ic;
-	
-	/* Allow any name if we're offline. */
-	if( ic == NULL )
-		return value;
+	struct msn_data *md = ic->proto_data;
+	char buf[512];
+	char *fn;
 	
 	if( strlen( value ) > 129 )
@@ -343,8 +341,16 @@
 	}
 	
-	/* Returning NULL would be better, because the server still has to
-	   confirm the name change. However, it looks a bit confusing to the
-	   user. */
-	return msn_set_display_name( ic, value ) ? value : NULL;
+	msn_soap_addressbook_set_display_name( ic, value );
+
+	fn = g_malloc( strlen( value ) * 3 + 1 );
+	strcpy( fn, value );
+	http_encode( fn );
+	g_snprintf( buf, sizeof( buf ), "PRP %d MFN %s\r\n",
+	            ++md->trId, fn );
+	g_free( fn );
+	
+	/* Note: We don't actually know if the server accepted the new name,
+	   and won't give proper feedback yet if it doesn't. */
+	return msn_write( ic, buf, strlen( buf ) ) ? value : NULL;
 }
 
@@ -375,5 +381,4 @@
 	ret->set_away = msn_set_away;
 	ret->get_info = msn_get_info;
-	ret->set_my_name = msn_set_my_name;
 	ret->add_buddy = msn_add_buddy;
 	ret->remove_buddy = msn_remove_buddy;
Index: protocols/msn/msn.h
===================================================================
--- protocols/msn/msn.h	(revision d93c0eb9f3f5d2d2cd78f02422d0c0ed25743e3a)
+++ protocols/msn/msn.h	(revision 4452e69ab1f01793a37205db8227a2de2f211d3e)
@@ -207,5 +207,4 @@
 char **msn_linesplit( char *line );
 int msn_handler( struct msn_handler_data *h );
-char *msn_http_encode( const char *input );
 void msn_msgq_purge( struct im_connection *ic, GSList **list );
 gboolean msn_set_display_name( struct im_connection *ic, const char *rawname );
Index: protocols/msn/msn_util.c
===================================================================
--- protocols/msn/msn_util.c	(revision d93c0eb9f3f5d2d2cd78f02422d0c0ed25743e3a)
+++ protocols/msn/msn_util.c	(revision 4452e69ab1f01793a37205db8227a2de2f211d3e)
@@ -61,5 +61,5 @@
 {
 	struct msn_data *md = ic->proto_data;
-	char buf[1024], *realname, groupid[8];
+	char buf[1024], realname[strlen(realname_)*3+1], groupid[8];
 	
 	*groupid = '\0';
@@ -94,7 +94,8 @@
 			if( l == NULL )
 			{
-				char *groupname = msn_http_encode( group );
+				char groupname[strlen(group)+1];
+				strcpy( groupname, group );
+				http_encode( groupname );
 				g_snprintf( buf, sizeof( buf ), "ADG %d %s %d\r\n", ++md->trId, groupname, 0 );
-				g_free( groupname );
 				return msn_write( ic, buf, strlen( buf ) );
 			}
@@ -109,7 +110,7 @@
 	}
 	
-	realname = msn_http_encode( realname_ );
+	strcpy( realname, realname_ );
+	http_encode( realname );
 	g_snprintf( buf, sizeof( buf ), "ADD %d %s %s %s%s\r\n", ++md->trId, list, who, realname, groupid );
-	g_free( realname );
 	
 	return msn_write( ic, buf, strlen( buf ) );
@@ -380,30 +381,4 @@
 }
 
-/* The difference between this function and the normal http_encode() function
-   is that this one escapes every 7-bit ASCII character because this is said
-   to avoid some lame server-side checks when setting a real-name. Also,
-   non-ASCII characters are not escaped because MSN servers don't seem to
-   appreciate that! */
-char *msn_http_encode( const char *input )
-{
-	char *ret, *s;
-	int i;
-	
-	ret = s = g_new0( char, strlen( input ) * 3 + 1 );
-	for( i = 0; input[i]; i ++ )
-		if( input[i] & 128 )
-		{
-			*s = input[i];
-			s ++;
-		}
-		else
-		{
-			g_snprintf( s, 4, "%%%02X", input[i] );
-			s += 3;
-		}
-	
-	return ret;
-}
-
 void msn_msgq_purge( struct im_connection *ic, GSList **list )
 {
@@ -444,16 +419,4 @@
 		imcb_log( ic, "%s", ret->str );
 	g_string_free( ret, TRUE );
-}
-
-gboolean msn_set_display_name( struct im_connection *ic, const char *rawname )
-{
-	char *fn = msn_http_encode( rawname );
-	struct msn_data *md = ic->proto_data;
-	char buf[1024];
-	
-	g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, ic->acc->user, fn );
-	g_free( fn );
-	
-	return msn_write( ic, buf, strlen( buf ) ) != 0;
 }
 
Index: protocols/msn/ns.c
===================================================================
--- protocols/msn/ns.c	(revision d93c0eb9f3f5d2d2cd78f02422d0c0ed25743e3a)
+++ protocols/msn/ns.c	(revision 4452e69ab1f01793a37205db8227a2de2f211d3e)
@@ -35,5 +35,4 @@
 static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts );
 
-static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name );
 static void msn_ns_send_adl( struct im_connection *ic );
 
@@ -474,38 +473,4 @@
 		return( 0 );
 	}
-#if 0
-	/* Discard this one completely for now since I don't care about the ack
-	   and since MSN servers can apparently screw up the formatting. */
-	else if( strcmp( cmd[0], "REA" ) == 0 )
-	{
-		if( num_parts < 5 )
-		{
-			imcb_error( ic, "Syntax error" );
-			imc_logout( ic, TRUE );
-			return( 0 );
-		}
-		
-		if( g_strcasecmp( cmd[3], ic->acc->user ) == 0 )
-		{
-			set_t *s;
-			
-			http_decode( cmd[4] );
-			strncpy( ic->displayname, cmd[4], sizeof( ic->displayname ) );
-			ic->displayname[sizeof(ic->displayname)-1] = 0;
-			
-			if( ( s = set_find( &ic->acc->set, "display_name" ) ) )
-			{
-				g_free( s->value );
-				s->value = g_strdup( cmd[4] );
-			}
-		}
-		else
-		{
-			/* This is not supposed to happen, but let's handle it anyway... */
-			http_decode( cmd[4] );
-			imcb_rename_buddy( ic, cmd[3], cmd[4] );
-		}
-	}
-#endif
 	else if( strcmp( cmd[0], "IPG" ) == 0 )
 	{
@@ -801,47 +766,2 @@
 	xt_free_node( adl );
 }
-
-static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name )
-{
-	set_t *s;
-	
-	if( ( s = set_find( &ic->acc->set, "display_name" ) ) == NULL )
-		return FALSE; /* Shouldn't happen.. */
-	
-	http_decode( name );
-	
-	if( s->value && strcmp( s->value, name ) == 0 )
-	{
-		return TRUE;
-		/* The names match, nothing to worry about. */
-	}
-	else if( s->value != NULL &&
-	         ( strcmp( name, ic->acc->user ) == 0 ||
-	           set_getbool( &ic->acc->set, "local_display_name" ) ) )
-	{
-		/* The server thinks our display name is our e-mail address
-		   which is probably wrong, or the user *wants* us to do this:
-		   Always use the locally set display_name. */
-		return msn_set_display_name( ic, s->value );
-	}
-	else
-	{
-		if( s->value && *s->value )
-			imcb_log( ic, "BitlBee thinks your display name is `%s' but "
-			              "the MSN server says it's `%s'. Using the MSN "
-			              "server's name. Set local_display_name to true "
-			              "to use the local name.", s->value, name );
-		
-		if( g_utf8_validate( name, -1, NULL ) )
-		{
-			g_free( s->value );
-			s->value = g_strdup( name );
-		}
-		else
-		{
-			imcb_log( ic, "Warning: Friendly name in server response was corrupted" );
-		}
-		
-		return TRUE;
-	}
-}
Index: protocols/msn/soap.c
===================================================================
--- protocols/msn/soap.c	(revision d93c0eb9f3f5d2d2cd78f02422d0c0ed25743e3a)
+++ protocols/msn/soap.c	(revision 4452e69ab1f01793a37205db8227a2de2f211d3e)
@@ -609,2 +609,36 @@
 	                                 msn_soap_addressbook_free_data );
 }
+
+/* Variant: Change our display name. */
+static int msn_soap_ab_namechange_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_AB_NAMECHANGE_ACTION );
+	soap_req->payload = g_markup_printf_escaped( SOAP_AB_NAMECHANGE_PAYLOAD,
+		md->tokens[1], (char *) soap_req->data );
+	
+	return 1;
+}
+
+static int msn_soap_ab_namechange_handle_response( struct msn_soap_req_data *soap_req )
+{
+	/* TODO: Ack the change? Not sure what the NAKs look like.. */
+	return MSN_SOAP_OK;
+}
+
+static int msn_soap_ab_namechange_free_data( struct msn_soap_req_data *soap_req )
+{
+	g_free( soap_req->data );
+	return 0;
+}
+
+int msn_soap_addressbook_set_display_name( struct im_connection *ic, const char *new )
+{
+	return msn_soap_start( ic, g_strdup( new ),
+	                       msn_soap_ab_namechange_build_request,
+	                       NULL,
+	                       msn_soap_ab_namechange_handle_response,
+	                       msn_soap_ab_namechange_free_data );
+}
Index: protocols/msn/soap.h
===================================================================
--- protocols/msn/soap.h	(revision d93c0eb9f3f5d2d2cd78f02422d0c0ed25743e3a)
+++ protocols/msn/soap.h	(revision 4452e69ab1f01793a37205db8227a2de2f211d3e)
@@ -220,5 +220,38 @@
 "</soap:Envelope>"
 
+#define SOAP_AB_NAMECHANGE_ACTION "http://www.msn.com/webservices/AddressBook/ABContactUpdate"
+
+#define SOAP_AB_NAMECHANGE_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>" \
+        "<ABContactUpdate xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
+            "<abId>00000000-0000-0000-0000-000000000000</abId>" \
+            "<contacts>" \
+                "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
+                    "<contactInfo>" \
+                        "<contactType>Me</contactType>" \
+                        "<displayName>%s</displayName>" \
+                    "</contactInfo>" \
+                    "<propertiesChanged>DisplayName</propertiesChanged>" \
+                "</Contact>" \
+            "</contacts>" \
+        "</ABContactUpdate>" \
+    "</soap:Body>" \
+"</soap:Envelope>"
+
 int msn_soap_addressbook_request( struct im_connection *ic );
+int msn_soap_addressbook_set_display_name( struct im_connection *ic, const char *new );
 
 
Index: protocols/nogaim.h
===================================================================
--- protocols/nogaim.h	(revision d93c0eb9f3f5d2d2cd78f02422d0c0ed25743e3a)
+++ protocols/nogaim.h	(revision 4452e69ab1f01793a37205db8227a2de2f211d3e)
@@ -194,4 +194,6 @@
 	   this info via imcb_log(). Implementing these are optional. */
 	void (* get_info)	(struct im_connection *, char *who);
+	/* set_my_name is *DEPRECATED*, not used by the UI anymore. Use the
+	   display_name setting instead. */
 	void (* set_my_name)	(struct im_connection *, char *name);
 	void (* set_name)	(struct im_connection *, char *who, char *name);
