Index: protocols/jabber/conference.c
===================================================================
--- protocols/jabber/conference.c	(revision a6b2f13e38e75e7bca00a1e6c1963783f244c0b2)
+++ protocols/jabber/conference.c	(revision bb09b3c6b8190be09e0b7c7ef2f4b1b5a69b504f)
@@ -272,6 +272,8 @@
 		}
 		
-		if( bud != jc->me )
-		{
+		if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS )
+		{
+			/* If JIDs are anonymized, add them to the local
+			   list for the duration of this chat. */
 			imcb_add_buddy( ic, bud->ext_jid, NULL );
 			imcb_buddy_nick_hint( ic, bud->ext_jid, bud->resource );
Index: protocols/msn/passport.c
===================================================================
--- protocols/msn/passport.c	(revision a6b2f13e38e75e7bca00a1e6c1963783f244c0b2)
+++ protocols/msn/passport.c	(revision bb09b3c6b8190be09e0b7c7ef2f4b1b5a69b504f)
@@ -145,5 +145,7 @@
 	char *s;
 	
-	if( ( s = xt_find_attr( node, "Id" ) ) && strcmp( s, "PPToken1" ) == 0 )
+	if( ( s = xt_find_attr( node, "Id" ) ) &&
+	    ( strncmp( s, "Compact", 7 ) == 0 ||
+	      strncmp( s, "PPToken", 7 ) == 0 ) )
 		mad->token = g_memdup( node->text, node->text_len + 1 );
 	
Index: protocols/msn/sb.c
===================================================================
--- protocols/msn/sb.c	(revision a6b2f13e38e75e7bca00a1e6c1963783f244c0b2)
+++ protocols/msn/sb.c	(revision bb09b3c6b8190be09e0b7c7ef2f4b1b5a69b504f)
@@ -328,7 +328,11 @@
 	struct msn_data *md = ic->proto_data;
 	
-	if( msn_handler( sb->handler ) == -1 )
+	if( msn_handler( sb->handler ) != -1 )
+		return TRUE;
+	
+	if( sb->msgq != NULL )
 	{
 		time_t now = time( NULL );
+		char buf[1024];
 		
 		if( now - md->first_sb_failure > 600 )
@@ -347,35 +351,26 @@
 			              "There might be problems delivering your messages." );
 		
-		if( sb->msgq != NULL )
-		{
-			char buf[1024];
-			
-			if( md->msgq == NULL )
-			{
-				md->msgq = sb->msgq;
-			}
-			else
-			{
-				GSList *l;
-				
-				for( l = md->msgq; l->next; l = l->next );
-				l->next = sb->msgq;
-			}
-			sb->msgq = NULL;
-			
-			debug( "Moved queued messages back to the main queue, creating a new switchboard to retry." );
-			g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId );
-			if( !msn_write( ic, buf, strlen( buf ) ) )
-				return FALSE;
-		}
-		
-		msn_sb_destroy( sb );
-		
-		return FALSE;
-	}
-	else
-	{
-		return TRUE;
-	}
+		if( md->msgq == NULL )
+		{
+			md->msgq = sb->msgq;
+		}
+		else
+		{
+			GSList *l;
+			
+			for( l = md->msgq; l->next; l = l->next );
+			l->next = sb->msgq;
+		}
+		sb->msgq = NULL;
+		
+		debug( "Moved queued messages back to the main queue, "
+		       "creating a new switchboard to retry." );
+		g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId );
+		if( !msn_write( ic, buf, strlen( buf ) ) )
+			return FALSE;
+	}
+	
+	msn_sb_destroy( sb );
+	return FALSE;
 }
 
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision a6b2f13e38e75e7bca00a1e6c1963783f244c0b2)
+++ protocols/nogaim.c	(revision bb09b3c6b8190be09e0b7c7ef2f4b1b5a69b504f)
@@ -657,8 +657,19 @@
 	u->away = u->status_msg = NULL;
 	
-	if( ( flags & OPT_LOGGED_IN ) && !u->online )
-	{
+	if( set_getbool( &ic->irc->set, "show_offline" ) && !u->online )
+	{
+		/* always set users as online */
 		irc_spawn( ic->irc, u );
 		u->online = 1;
+		if( !( flags & OPT_LOGGED_IN ) )
+		{
+			/* set away message if user isn't really online */
+			u->away = g_strdup( "User is offline" );
+		}
+	}
+	else if( ( flags & OPT_LOGGED_IN ) && !u->online )
+	{
+		irc_spawn( ic->irc, u );
+		u->online = 1;
 	}
 	else if( !( flags & OPT_LOGGED_IN ) && u->online )
@@ -666,12 +677,28 @@
 		struct groupchat *c;
 		
-		irc_kill( ic->irc, u );
-		u->online = 0;
-		
-		/* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */
-		for( c = ic->groupchats; c; c = c->next )
-			remove_chat_buddy_silent( c, handle );
-	}
-	
+		if( set_getbool( &ic->irc->set, "show_offline" ) )
+		{
+			/* keep offline users in channel and set away message to "offline" */
+			u->away = g_strdup( "User is offline" );
+
+			/* Keep showing him/her in the control channel but not in groupchats. */
+			for( c = ic->groupchats; c; c = c->next )
+			{
+				if( remove_chat_buddy_silent( c, handle ) && c->joined )
+					irc_part( c->ic->irc, u, c->channel );
+			}
+		}
+		else
+		{
+			/* kill offline users */
+			irc_kill( ic->irc, u );
+			u->online = 0;
+
+			/* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */
+			for( c = ic->groupchats; c; c = c->next )
+				remove_chat_buddy_silent( c, handle );
+		}
+	}
+
 	if( flags & OPT_AWAY )
 	{
@@ -700,5 +727,5 @@
 	/* LISPy... */
 	if( ( u->online ) &&						/* Don't touch offline people */
-	    ( ( ( u->online != oo ) && !u->away ) ||			/* Do joining people */
+	    ( ( u->online != oo ) ||					/* Do joining people */
 	      ( ( u->online == oo ) && ( oa == !u->away ) ) ) )		/* Do people changing state */
 	{
@@ -714,4 +741,15 @@
 			                                    ic->irc->myhost );
 		}
+
+		if(!strcmp(set_getstr(&ic->irc->set, "voice_buddies"), "online")) {
+			irc_write( ic->irc, ":%s MODE %s +v %s", from, ic->irc->channel, u->nick );
+		}
+		if(!strcmp(set_getstr(&ic->irc->set, "halfop_buddies"), "online")) {
+			irc_write( ic->irc, ":%s MODE %s +h %s", from, ic->irc->channel, u->nick );
+		}
+		if(!strcmp(set_getstr(&ic->irc->set, "op_buddies"), "online")) {
+			irc_write( ic->irc, ":%s MODE %s +o %s", from, ic->irc->channel, u->nick );
+		}
+
 		if(!strcmp(set_getstr(&ic->irc->set, "voice_buddies"), "notaway")) {
 			irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel,
@@ -726,4 +764,5 @@
 		 	                                         u->away?'-':'+', u->nick );
 		}
+
 		g_free( from );
 	}
@@ -1156,5 +1195,5 @@
 		return g_strdup_printf( "\x02[\x02\x02\x02%04d-%02d-%02d "
 		                        "%02d:%02d:%02d\x02]\x02 ",
-		                        msg.tm_year + 1900, msg.tm_mon, msg.tm_mday,
+		                        msg.tm_year + 1900, msg.tm_mon + 1, msg.tm_mday,
 		                        msg.tm_hour, msg.tm_min, msg.tm_sec );
 }
Index: protocols/oscar/oscar.c
===================================================================
--- protocols/oscar/oscar.c	(revision a6b2f13e38e75e7bca00a1e6c1963783f244c0b2)
+++ protocols/oscar/oscar.c	(revision bb09b3c6b8190be09e0b7c7ef2f4b1b5a69b504f)
@@ -205,5 +205,4 @@
 static int gaim_icbm_param_info  (aim_session_t *, aim_frame_t *, ...);
 static int gaim_parse_genericerr (aim_session_t *, aim_frame_t *, ...);
-static int gaim_memrequest       (aim_session_t *, aim_frame_t *, ...);
 static int gaim_selfinfo         (aim_session_t *, aim_frame_t *, ...);
 static int gaim_offlinemsg       (aim_session_t *, aim_frame_t *, ...);
@@ -570,5 +569,4 @@
 	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ERROR, gaim_parse_genericerr, 0);
 	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BOS, AIM_CB_BOS_ERROR, gaim_parse_genericerr, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, 0x1f, gaim_memrequest, 0);
 	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SELFINFO, gaim_selfinfo, 0);
 	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG, gaim_offlinemsg, 0);
@@ -604,140 +602,6 @@
 }
 
-struct pieceofcrap {
-	struct im_connection *ic;
-	unsigned long offset;
-	unsigned long len;
-	char *modname;
-	int fd;
-	aim_conn_t *conn;
-	unsigned int inpa;
-};
-
-static gboolean damn_you(gpointer data, gint source, b_input_condition c)
-{
-	struct pieceofcrap *pos = data;
-	struct oscar_data *od = pos->ic->proto_data;
-	char in = '\0';
-	int x = 0;
-	unsigned char m[17];
-
-	while (read(pos->fd, &in, 1) == 1) {
-		if (in == '\n')
-			x++;
-		else if (in != '\r')
-			x = 0;
-		if (x == 2)
-			break;
-		in = '\0';
-	}
-	if (in != '\n') {
-		imcb_error(pos->ic, "Gaim was unable to get a valid hash for logging into AIM."
-				" You may be disconnected shortly.");
-		b_event_remove(pos->inpa);
-		closesocket(pos->fd);
-		g_free(pos);
-		return FALSE;
-	}
-	/* [WvG] Wheeeee! Who needs error checking anyway? ;-) */
-	read(pos->fd, m, 16);
-	m[16] = '\0';
-	b_event_remove(pos->inpa);
-	closesocket(pos->fd);
-	aim_sendmemblock(od->sess, pos->conn, 0, 16, m, AIM_SENDMEMBLOCK_FLAG_ISHASH);
-	g_free(pos);
-	
-	return FALSE;
-}
-
-static gboolean straight_to_hell(gpointer data, gint source, b_input_condition cond) {
-	struct pieceofcrap *pos = data;
-	char buf[BUF_LONG];
-
-	if (source < 0) {
-		imcb_error(pos->ic, "Gaim was unable to get a valid hash for logging into AIM."
-				" You may be disconnected shortly.");
-		if (pos->modname)
-			g_free(pos->modname);
-		g_free(pos);
-		return FALSE;
-	}
-
-	g_snprintf(buf, sizeof(buf), "GET " AIMHASHDATA
-			"?offset=%ld&len=%ld&modname=%s HTTP/1.0\n\n",
-			pos->offset, pos->len, pos->modname ? pos->modname : "");
-	write(pos->fd, buf, strlen(buf));
-	if (pos->modname)
-		g_free(pos->modname);
-	pos->inpa = b_input_add(pos->fd, GAIM_INPUT_READ, damn_you, pos);
-	return FALSE;
-}
-
 /* size of icbmui.ocm, the largest module in AIM 3.5 */
 #define AIM_MAX_FILE_SIZE 98304
-
-int gaim_memrequest(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	struct pieceofcrap *pos;
-	guint32 offset, len;
-	char *modname;
-	int fd;
-
-	va_start(ap, fr);
-	offset = (guint32)va_arg(ap, unsigned long);
-	len = (guint32)va_arg(ap, unsigned long);
-	modname = va_arg(ap, char *);
-	va_end(ap);
-
-	if (len == 0) {
-		aim_sendmemblock(sess, fr->conn, offset, len, NULL,
-				AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
-		return 1;
-	}
-	/* uncomment this when you're convinced it's right. remember, it's been wrong before.
-	if (offset > AIM_MAX_FILE_SIZE || len > AIM_MAX_FILE_SIZE) {
-		char *buf;
-		int i = 8;
-		if (modname)
-			i += strlen(modname);
-		buf = g_malloc(i);
-		i = 0;
-		if (modname) {
-			memcpy(buf, modname, strlen(modname));
-			i += strlen(modname);
-		}
-		buf[i++] = offset & 0xff;
-		buf[i++] = (offset >> 8) & 0xff;
-		buf[i++] = (offset >> 16) & 0xff;
-		buf[i++] = (offset >> 24) & 0xff;
-		buf[i++] = len & 0xff;
-		buf[i++] = (len >> 8) & 0xff;
-		buf[i++] = (len >> 16) & 0xff;
-		buf[i++] = (len >> 24) & 0xff;
-		aim_sendmemblock(sess, command->conn, offset, i, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
-		g_free(buf);
-		return 1;
-	}
-	*/
-
-	pos = g_new0(struct pieceofcrap, 1);
-	pos->ic = sess->aux_data;
-	pos->conn = fr->conn;
-
-	pos->offset = offset;
-	pos->len = len;
-	pos->modname = modname ? g_strdup(modname) : NULL;
-
-	fd = proxy_connect("gaim.sourceforge.net", 80, straight_to_hell, pos);
-	if (fd < 0) {
-		if (pos->modname)
-			g_free(pos->modname);
-		g_free(pos);
-		imcb_error(sess->aux_data, "Gaim was unable to get a valid hash for logging into AIM."
-				" You may be disconnected shortly.");
-	}
-	pos->fd = fd;
-
-	return 1;
-}
 
 static int gaim_parse_login(aim_session_t *sess, aim_frame_t *fr, ...) {
@@ -2651,5 +2515,6 @@
 	char * chatname;
 	
-	chatname = g_strdup_printf("%s%d", ic->acc->user, chat_id++);
+	chatname = g_strdup_printf("%s%s_%d", isdigit(*ic->acc->user) ? "icq_" : "",
+	                           ic->acc->user, chat_id++);
   
 	ret = oscar_chat_join(ic, chatname, NULL, NULL);
Index: protocols/twitter/twitter.c
===================================================================
--- protocols/twitter/twitter.c	(revision a6b2f13e38e75e7bca00a1e6c1963783f244c0b2)
+++ protocols/twitter/twitter.c	(revision bb09b3c6b8190be09e0b7c7ef2f4b1b5a69b504f)
@@ -23,8 +23,8 @@
 
 #include "nogaim.h"
+#include "oauth.h"
 #include "twitter.h"
 #include "twitter_http.h"
 #include "twitter_lib.h"
-
 
 /**
@@ -51,9 +51,92 @@
 }
 
+static void twitter_main_loop_start( struct im_connection *ic )
+{
+	struct twitter_data *td = ic->proto_data;
+	
+	imcb_log( ic, "Connecting to Twitter" );
+
+	// Run this once. After this queue the main loop function.
+	twitter_main_loop(ic, -1, 0);
+
+	// Queue the main_loop
+	// Save the return value, so we can remove the timeout on logout.
+	td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic);
+}
+
+
+static const struct oauth_service twitter_oauth =
+{
+	"http://api.twitter.com/oauth/request_token",
+	"http://api.twitter.com/oauth/access_token",
+	"http://api.twitter.com/oauth/authorize",
+	.consumer_key = "xsDNKJuNZYkZyMcu914uEA",
+	.consumer_secret = "FCxqcr0pXKzsF9ajmP57S3VQ8V6Drk4o2QYtqMcOszo",
+};
+
+static gboolean twitter_oauth_callback( struct oauth_info *info );
+
+static void twitter_oauth_start( struct im_connection *ic )
+{
+	struct twitter_data *td = ic->proto_data;
+	
+	imcb_log( ic, "Requesting OAuth request token" );
+
+	td->oauth_info = oauth_request_token( &twitter_oauth, twitter_oauth_callback, ic );
+}
+
+static gboolean twitter_oauth_callback( struct oauth_info *info )
+{
+	struct im_connection *ic = info->data;
+	struct twitter_data *td;
+	
+	if( !g_slist_find( twitter_connections, ic ) )
+		return FALSE;
+	
+	td = ic->proto_data;
+	if( info->stage == OAUTH_REQUEST_TOKEN )
+	{
+		char name[strlen(ic->acc->user)+9], *msg;
+		
+		if( info->request_token == NULL )
+		{
+			imcb_error( ic, "OAuth error: %s", info->http->status_string );
+			imc_logout( ic, TRUE );
+			return FALSE;
+		}
+		
+		sprintf( name, "twitter_%s", ic->acc->user );
+		msg = g_strdup_printf( "To finish OAuth authentication, please visit "
+		                       "%s and respond with the resulting PIN code.",
+		                       info->auth_url );
+		imcb_buddy_msg( ic, name, msg, 0, 0 );
+		g_free( msg );
+	}
+	else if( info->stage == OAUTH_ACCESS_TOKEN )
+	{
+		if( info->token == NULL || info->token_secret == NULL )
+		{
+			imcb_error( ic, "OAuth error: %s", info->http->status_string );
+			imc_logout( ic, TRUE );
+			return FALSE;
+		}
+		
+		/* IM mods didn't do this so far and it's ugly but I should
+		   be able to get away with it... */
+		g_free( ic->acc->pass );
+		ic->acc->pass = oauth_to_string( info );
+		
+		twitter_main_loop_start( ic );
+	}
+	
+	return TRUE;
+}
+
+
 static char *set_eval_mode( set_t *set, char *value )
 {
 	if( g_strcasecmp( value, "one" ) == 0 ||
 	    g_strcasecmp( value, "many" ) == 0 ||
-	    g_strcasecmp( value, "char" ) == 0 )
+	    g_strcasecmp( value, "chat" ) == 0 )
 		return value;
 	else
@@ -61,10 +144,26 @@
 }
 
+static gboolean twitter_length_check( struct im_connection *ic, gchar *msg )
+{
+	int max = set_getint( &ic->acc->set, "message_length" ), len;
+	
+	if( max == 0 || ( len = g_utf8_strlen( msg, -1 ) ) <= max )
+		return TRUE;
+	
+	imcb_error( ic, "Maximum message length exceeded: %d > %d", len, max );
+	
+	return FALSE;
+}
+
 static void twitter_init( account_t *acc )
 {
 	set_t *s;
+	
+	s = set_add( &acc->set, "message_length", "140", set_eval_int, acc );
 	
 	s = set_add( &acc->set, "mode", "one", set_eval_mode, acc );
 	s->flags |= ACC_SET_OFFLINE_ONLY;
+	
+	s = set_add( &acc->set, "oauth", "true", set_eval_bool, acc );
 }
 
@@ -80,23 +179,22 @@
 
 	twitter_connections = g_slist_append( twitter_connections, ic );
-
+	ic->proto_data = td;
+	ic->flags |= OPT_DOES_HTML;
+	
 	td->user = acc->user;
-	td->pass = acc->pass;
+	if( !set_getbool( &acc->set, "oauth" ) )
+		td->pass = g_strdup( acc->pass );
+	else if( strstr( acc->pass, "oauth_token=" ) )
+		td->oauth_info = oauth_from_string( acc->pass, &twitter_oauth );
 	td->home_timeline_id = 0;
-
-	ic->proto_data = td;
-
-	imcb_log( ic, "Connecting to Twitter" );
-
-	// Run this once. After this queue the main loop function.
-	twitter_main_loop(ic, -1, 0);
-
-	// Queue the main_loop
-	// Save the return value, so we can remove the timeout on logout.
-	td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic);
 	
 	sprintf( name, "twitter_%s", acc->user );
 	imcb_add_buddy( ic, name, NULL );
 	imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL );
+	
+	if( td->pass || td->oauth_info )
+		twitter_main_loop_start( ic );
+	else
+		twitter_oauth_start( ic );
 }
 
@@ -119,4 +217,6 @@
 	if( td )
 	{
+		oauth_info_free( td->oauth_info );
+		g_free( td->pass );
 		g_free( td );
 	}
@@ -130,10 +230,26 @@
 static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message, int away )
 {
+	struct twitter_data *td = ic->proto_data;
+	
 	if (g_strncasecmp(who, "twitter_", 8) == 0 &&
 	    g_strcasecmp(who + 8, ic->acc->user) == 0)
-		twitter_post_status(ic, message);
+	{
+		if( set_getbool( &ic->acc->set, "oauth" ) &&
+		    td->oauth_info && td->oauth_info->token == NULL )
+		{
+			if( !oauth_access_token( message, td->oauth_info ) )
+			{
+				imcb_error( ic, "OAuth error: %s", "Failed to send access token request" );
+				imc_logout( ic, TRUE );
+				return FALSE;
+			}
+		}
+		else if( twitter_length_check(ic, message) )
+			twitter_post_status(ic, message);
+	}
 	else
+	{
 		twitter_direct_messages_new(ic, who, message);
-	
+	}
 	return( 0 );
 }
@@ -160,5 +276,5 @@
 static void twitter_chat_msg( struct groupchat *c, char *message, int flags )
 {
-	if( c && message )
+	if( c && message && twitter_length_check(c->ic, message))
 		twitter_post_status(c->ic, message);
 }
Index: protocols/twitter/twitter.h
===================================================================
--- protocols/twitter/twitter.h	(revision a6b2f13e38e75e7bca00a1e6c1963783f244c0b2)
+++ protocols/twitter/twitter.h	(revision bb09b3c6b8190be09e0b7c7ef2f4b1b5a69b504f)
@@ -37,4 +37,5 @@
 	char* user;
 	char* pass;
+	struct oauth_info *oauth_info;
 	guint64 home_timeline_id;
 	gint main_loop_id;
Index: protocols/twitter/twitter_http.c
===================================================================
--- protocols/twitter/twitter_http.c	(revision a6b2f13e38e75e7bca00a1e6c1963783f244c0b2)
+++ protocols/twitter/twitter_http.c	(revision bb09b3c6b8190be09e0b7c7ef2f4b1b5a69b504f)
@@ -29,5 +29,4 @@
 ****************************************************************************/ 
 
-#include "twitter_http.h"
 #include "twitter.h"
 #include "bitlbee.h"
@@ -35,6 +34,9 @@
 #include "misc.h"
 #include "base64.h"
+#include "oauth.h"
 #include <ctype.h>
 #include <errno.h>
+
+#include "twitter_http.h"
 
 
@@ -45,5 +47,5 @@
  * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c
  */
-void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char** arguments, int arguments_len)
+void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, struct oauth_info* oi, char** arguments, int arguments_len)
 {
 	url_t *url = g_new0( url_t, 1 );
@@ -110,5 +112,17 @@
 
 	// If a pass and user are given we append them to the request.
-	if (userpass_base64)
+	if (oi)
+	{
+		char *full_header;
+		
+		full_header = oauth_http_header(oi, is_post ? "POST" : "GET",
+		                                url_string, url_arguments);
+		
+		tmp = g_strdup_printf("%sAuthorization: %s\r\n", request, full_header);
+		g_free(request);
+		g_free(full_header);
+		request = tmp;
+	}
+	else if (userpass_base64)
 	{
 		tmp = g_strdup_printf("%sAuthorization: Basic %s\r\n", request, userpass_base64);
Index: protocols/twitter/twitter_http.h
===================================================================
--- protocols/twitter/twitter_http.h	(revision a6b2f13e38e75e7bca00a1e6c1963783f244c0b2)
+++ protocols/twitter/twitter_http.h	(revision bb09b3c6b8190be09e0b7c7ef2f4b1b5a69b504f)
@@ -28,6 +28,8 @@
 #include "http_client.h"
 
+struct oauth_info;
+
 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, 
-					char* user, char* pass, char** arguments, int arguments_len);
+                   char* user, char* pass, struct oauth_info *oi, char** arguments, int arguments_len);
 
 #endif //_TWITTER_HTTP_H
Index: protocols/twitter/twitter_lib.c
===================================================================
--- protocols/twitter/twitter_lib.c	(revision a6b2f13e38e75e7bca00a1e6c1963783f244c0b2)
+++ protocols/twitter/twitter_lib.c	(revision bb09b3c6b8190be09e0b7c7ef2f4b1b5a69b504f)
@@ -130,5 +130,5 @@
 	args[0] = "cursor";
 	args[1] = g_strdup_printf ("%d", next_cursor);
-	twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, args, 2);
+	twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth_info, args, 2);
 
 	g_free(args[1]);
@@ -396,5 +396,5 @@
 	}
 
-	twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, args, td->home_timeline_id ? 4 : 2);
+	twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, td->oauth_info, args, td->home_timeline_id ? 4 : 2);
 
 	g_free(args[1]);
@@ -510,5 +510,5 @@
 	{
 		td->http_fails = 0;
-		if (!ic->flags & OPT_LOGGED_IN)
+		if (!(ic->flags & OPT_LOGGED_IN))
 			imcb_connected(ic);
 	}
@@ -620,5 +620,5 @@
 	args[1] = g_strdup_printf ("%d", next_cursor);
 
-	twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, args, 2);
+	twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth_info, args, 2);
 
 	g_free(args[1]);
@@ -654,5 +654,5 @@
 	args[0] = "status";
 	args[1] = msg;
-	twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 2);
+	twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 2);
 //	g_free(args[1]);
 }
@@ -672,5 +672,5 @@
 	args[3] = msg;
 	// Use the same callback as for twitter_post_status, since it does basically the same.
-	twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 4);
+	twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 4);
 //	g_free(args[1]);
 //	g_free(args[3]);
Index: protocols/yahoo/yahoo.c
===================================================================
--- protocols/yahoo/yahoo.c	(revision a6b2f13e38e75e7bca00a1e6c1963783f244c0b2)
+++ protocols/yahoo/yahoo.c	(revision bb09b3c6b8190be09e0b7c7ef2f4b1b5a69b504f)
@@ -138,7 +138,12 @@
 	struct im_connection *ic = imcb_new( acc );
 	struct byahoo_data *yd = ic->proto_data = g_new0( struct byahoo_data, 1 );
+	char *s;
 	
 	yd->logged_in = FALSE;
 	yd->current_status = YAHOO_STATUS_AVAILABLE;
+	
+	if( ( s = strchr( acc->user, '@' ) ) && g_strcasecmp( s, "@yahoo.com" ) == 0 )
+		imcb_error( ic, "Your Yahoo! username should just be a username. "
+		                "Do not include any @domain part." );
 	
 	imcb_log( ic, "Connecting" );
@@ -829,4 +834,8 @@
 	YList *m;
 	
+	if( g_strcasecmp( who, ic->acc->user ) == 0 )
+		/* WTF, Yahoo! seems to echo these now? */
+		return;
+	
 	inv = g_malloc( sizeof( struct byahoo_conf_invitation ) );
 	memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
