Index: lib/xmltree.c
===================================================================
--- lib/xmltree.c	(revision 9ead105e86e6ae332ebdcbc2f1582775b6ef6d38)
+++ lib/xmltree.c	(revision 4f7255d4bed610a77cefd9786fe13c1d673b11bb)
@@ -524,20 +524,4 @@
 }
 
-struct xt_node *xt_find_node_by_attr( struct xt_node *xt, const char *tag, const char *key, const char *value )
-{
-	struct xt_node *c;
-	char *s;
-
-	for( c = xt; ( c = xt_find_node( c, tag ) ); c = c->next )
-	{
-		if( ( s = xt_find_attr( c, key ) ) && strcmp( s, value ) == 0 )
-		{
-			return c;
-		}
-	}
-	return NULL;
-}
-
-
 /* Strip a few non-printable characters that aren't allowed in XML streams
    (and upset some XMPP servers for example). */
Index: lib/xmltree.h
===================================================================
--- lib/xmltree.h	(revision 9ead105e86e6ae332ebdcbc2f1582775b6ef6d38)
+++ lib/xmltree.h	(revision 4f7255d4bed610a77cefd9786fe13c1d673b11bb)
@@ -92,5 +92,4 @@
 struct xt_node *xt_find_path( struct xt_node *node, const char *name );
 char *xt_find_attr( struct xt_node *node, const char *key );
-struct xt_node *xt_find_node_by_attr( struct xt_node *xt, const char *tag, const char *key, const char *value );
 
 struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children );
Index: nick.c
===================================================================
--- nick.c	(revision 9ead105e86e6ae332ebdcbc2f1582775b6ef6d38)
+++ nick.c	(revision 4f7255d4bed610a77cefd9786fe13c1d673b11bb)
@@ -408,6 +408,6 @@
 	
 	for( i = 0; nick[i]; i ++ )
-		if( ((guchar)nick[i]) < 0x7f )
-			nick[i] = tab[(guchar)nick[i]];
+		if( nick[i] < 0x7f )
+			nick[i] = tab[(int)nick[i]];
 	
 	return nick_ok( irc, nick );
Index: protocols/jabber/io.c
===================================================================
--- protocols/jabber/io.c	(revision 9ead105e86e6ae332ebdcbc2f1582775b6ef6d38)
+++ protocols/jabber/io.c	(revision 4f7255d4bed610a77cefd9786fe13c1d673b11bb)
@@ -506,9 +506,4 @@
 		allow_reconnect = FALSE;
 	}
-	else if( strcmp( err->code, "not-authorized" ) == 0 )
-	{
-		imcb_error( ic, "Not authorized" );
-		allow_reconnect = FALSE;
-	}
 	else
 	{
Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision 9ead105e86e6ae332ebdcbc2f1582775b6ef6d38)
+++ protocols/jabber/jabber.c	(revision 4f7255d4bed610a77cefd9786fe13c1d673b11bb)
@@ -148,5 +148,7 @@
 		jd->fd = jd->r_inpa = jd->w_inpa = -1;
 		
-		if( strstr( jd->server, ".facebook.com" ) )
+		if( strstr( jd->server, ".live.com" ) )
+			jd->oauth2_service = &oauth2_service_mslive;
+		else if( strstr( jd->server, ".facebook.com" ) )
 			jd->oauth2_service = &oauth2_service_facebook;
 		else
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision 9ead105e86e6ae332ebdcbc2f1582775b6ef6d38)
+++ protocols/jabber/jabber.h	(revision 4f7255d4bed610a77cefd9786fe13c1d673b11bb)
@@ -229,6 +229,5 @@
 #define XMLNS_RECEIPTS     "urn:xmpp:receipts"                                   /* XEP-0184 */
 #define XMLNS_VCARD        "vcard-temp"                                          /* XEP-0054 */
-#define XMLNS_DELAY_OLD    "jabber:x:delay"                                      /* XEP-0091 */
-#define XMLNS_DELAY        "urn:xmpp:delay"                                      /* XEP-0203 */
+#define XMLNS_DELAY        "jabber:x:delay"                                      /* XEP-0091 */
 #define XMLNS_XDATA        "jabber:x:data"                                       /* XEP-0004 */
 #define XMLNS_CHATSTATES   "http://jabber.org/protocol/chatstates"               /* XEP-0085 */
@@ -339,4 +338,5 @@
 extern const struct oauth2_service oauth2_service_google;
 extern const struct oauth2_service oauth2_service_facebook;
+extern const struct oauth2_service oauth2_service_mslive;
 
 /* conference.c */
Index: protocols/jabber/jabber_util.c
===================================================================
--- protocols/jabber/jabber_util.c	(revision 9ead105e86e6ae332ebdcbc2f1582775b6ef6d38)
+++ protocols/jabber/jabber_util.c	(revision 4f7255d4bed610a77cefd9786fe13c1d673b11bb)
@@ -726,27 +726,17 @@
 	char *s = NULL;
 	struct tm tp;
-	gboolean is_old = TRUE;
-	const char *format;
-
-	/* XEP-0091 has <x> */
-	c = xt_find_node_by_attr( xt->children, "x", "xmlns", XMLNS_DELAY_OLD );
-
-	if( !c || !( s = xt_find_attr( c, "stamp" ) ) ) {
-		is_old = FALSE;
-
-		/* XEP-0203 has <delay> */
-		c = xt_find_node_by_attr( xt->children, "delay", "xmlns", XMLNS_DELAY );
-		if( !c || !( s = xt_find_attr( c, "stamp" ) ) ) {
-			return 0;
-		}
-	}
+	
+	for( c = xt->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
+	{
+		if( ( s = xt_find_attr( c, "xmlns" ) ) && strcmp( s, XMLNS_DELAY ) == 0 )
+			break;
+	}
+	
+	if( !c || !( s = xt_find_attr( c, "stamp" ) ) )
+		return 0;
 	
 	memset( &tp, 0, sizeof( tp ) );
-
-	/* The other main difference between XEPs is the timestamp format */
-	format = (is_old) ? "%4d%2d%2dT%2d:%2d:%2d" : "%4d-%2d-%2dT%2d:%2d:%2dZ";
-
-	if( sscanf( s, format, &tp.tm_year, &tp.tm_mon, &tp.tm_mday,
-	                       &tp.tm_hour, &tp.tm_min, &tp.tm_sec ) != 6 )
+	if( sscanf( s, "%4d%2d%2dT%2d:%2d:%2d", &tp.tm_year, &tp.tm_mon, &tp.tm_mday,
+	                                        &tp.tm_hour, &tp.tm_min, &tp.tm_sec ) != 6 )
 		return 0;
 	
Index: protocols/jabber/sasl.c
===================================================================
--- protocols/jabber/sasl.c	(revision 9ead105e86e6ae332ebdcbc2f1582775b6ef6d38)
+++ protocols/jabber/sasl.c	(revision 4f7255d4bed610a77cefd9786fe13c1d673b11bb)
@@ -47,4 +47,13 @@
 	"4b100f0f244d620bf3f15f8b217d4c32",
 };
+const struct oauth2_service oauth2_service_mslive =
+{
+	"https://oauth.live.com/authorize",
+	"https://oauth.live.com/token",
+	"http://www.bitlbee.org/main.php/Messenger/oauth2.html",
+	"wl.offline_access%20wl.messenger",
+	"000000004C06FCD1",
+	"IRKlBPzJJAWcY-TbZjiTEJu9tn7XCFaV",
+};
 
 xt_status sasl_pkt_mechanisms( struct xt_node *node, gpointer data )
@@ -54,5 +63,5 @@
 	struct xt_node *c, *reply;
 	char *s;
-	int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_fb = 0;
+	int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_fb = 0, sup_ms = 0;
 	int want_oauth = FALSE;
 	GString *mechs;
@@ -89,4 +98,6 @@
 		else if( c->text && g_strcasecmp( c->text, "X-FACEBOOK-PLATFORM" ) == 0 )
 			sup_fb = 1;
+		else if( c->text && g_strcasecmp( c->text, "X-MESSENGER-OAUTH2" ) == 0 )
+			sup_ms = 1;
 		
 		if( c->text )
@@ -98,5 +109,5 @@
 	if( !want_oauth && !sup_plain && !sup_digest )
 	{
-		if( !sup_gtalk && !sup_fb )
+		if( !sup_gtalk && !sup_fb && !sup_ms )
 			imcb_error( ic, "This server requires OAuth "
 			                "(supported schemes:%s)", mechs->str );
@@ -130,4 +141,10 @@
 		reply->text_len = strlen( reply->text );
 		g_free( s );
+	}
+	else if( sup_ms && want_oauth )
+	{
+		xt_add_attr( reply, "mechanism", "X-MESSENGER-OAUTH2" );
+		reply->text = g_strdup( jd->oauth2_access_token );
+		reply->text_len = strlen( jd->oauth2_access_token );
 	}
 	else if( sup_fb && want_oauth )
