changeset 19662:aa3920f45ff3

merge of '906281124efc7c5fcab1d5a7b8066c6a99d7927d' and '9d3e08ca8d3c17d78b9671fdffc4a0769a0a1495'
author Kevin Stange <kevin@simguy.net>
date Thu, 06 Sep 2007 06:59:23 +0000
parents 2f7b3564bb7e (current diff) 3617681a2694 (diff)
children 9600414aca2e
files COPYRIGHT finch/libgnt/gntmenu.c libpurple/certificate.h libpurple/proxy.c libpurple/util.c pidgin/gtkmain.c
diffstat 75 files changed, 832 insertions(+), 549 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Thu Sep 06 06:58:31 2007 +0000
+++ b/COPYRIGHT	Thu Sep 06 06:59:23 2007 +0000
@@ -375,6 +375,7 @@
 Warren Togami
 Stu Tomlinson
 Bill Tompkins
+Gal Topper
 Chris Toshok
 Ken Tossell
 Tom Tromey
--- a/ChangeLog.API	Thu Sep 06 06:58:31 2007 +0000
+++ b/ChangeLog.API	Thu Sep 06 06:59:23 2007 +0000
@@ -9,9 +9,13 @@
 		* serv_send_attention(), serv_got_attention(), as well as send_attention 
 		  and attention_types in PurplePluginProtocolInfo. This new API is used
 		  for zapping in MySpaceIM, buzzing in Yahoo, and nudging in MSN.
+
 		Changed:
 		* purple_prefs_load is now called within purple_prefs_init.
 		  The UI no longer needs to call it.
+		* writing-im-msg now receives the conversation name as the who
+		  argument if the caller of purple_conversation_write didn't
+		  provide a value for who.
 
 	Pidgin:
 		Added:
@@ -21,6 +25,10 @@
 		  conversation
 		* conversation-hiding and conversation-displayed signals.
 
+		Changed:
+		* pidgin_conversations_fill_menu now also adds a separator and a 'Show
+		  All' item if there are more than one conversations in the list.
+
 	Finch:
 		Added:
 		* finch_sound_is_enabled
--- a/finch/gntconv.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/finch/gntconv.c	Thu Sep 06 06:59:23 2007 +0000
@@ -613,6 +613,7 @@
 		gnt_tree_set_col_width(GNT_TREE(tree), 0, 1);   /* The flag column */
 		gnt_tree_set_compare_func(GNT_TREE(tree), (GCompareFunc)g_utf8_collate);
 		gnt_tree_set_hash_fns(GNT_TREE(tree), g_str_hash, g_str_equal, g_free);
+		gnt_tree_set_search_column(GNT_TREE(tree), 1);
 		GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER);
 		gnt_box_add_widget(GNT_BOX(hbox), ggc->tv);
 		gnt_box_add_widget(GNT_BOX(hbox), tree);
--- a/finch/gntui.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/finch/gntui.c	Thu Sep 06 06:59:23 2007 +0000
@@ -91,8 +91,6 @@
 	gnt_register_action(_("Statuses"), finch_savedstatus_show_all);
 
 #ifdef STANDALONE
-
-	finch_plugins_save_loaded();
 }
 
 void gnt_ui_uninit()
--- a/finch/libgnt/gntmenu.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/finch/libgnt/gntmenu.c	Thu Sep 06 06:59:23 2007 +0000
@@ -221,8 +221,13 @@
 {
 	/* check for a trigger key */
 	GList *iter;
+	GList *find;
 	GList *nth = g_list_find(menu->list, gnt_tree_get_selection_data(GNT_TREE(menu)));
-	GList *find = find_item_with_trigger(nth->next, NULL, trigger);
+
+	if (nth == NULL)
+		return FALSE;
+		
+	find = find_item_with_trigger(nth->next, NULL, trigger);
 	if (!find)
 		find = find_item_with_trigger(menu->list, nth->next, trigger);
 	if (!find)
--- a/finch/plugins/gntclipboard.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/finch/plugins/gntclipboard.c	Thu Sep 06 06:59:23 2007 +0000
@@ -38,10 +38,12 @@
 #include <plugin.h>
 #include <version.h>
 #include <debug.h>
+#include <notify.h>
 #include <gntwm.h>
 
 #include <gntplugin.h>
 
+#ifdef HAVE_X11
 static pid_t child = 0;
 
 static gulong sig_handle;
@@ -49,7 +51,6 @@
 static void
 set_clip(gchar *string)
 {
-#ifdef HAVE_X11
 	Window w;
 	XEvent e, respond;
 	XSelectionRequestEvent *req;
@@ -89,14 +90,12 @@
 			return;
 		}
 	}
-#endif
 	return;
 }
 
 static void
 clipboard_changed(GntWM *wm, gchar *string)
 {
-#ifdef HAVE_X11
 	if (child) {
 		kill(child, SIGTERM);
 	}
@@ -104,8 +103,8 @@
 		set_clip(string);
 		_exit(0);
 	}
+}
 #endif
-}
 
 static gboolean
 plugin_load(PurplePlugin *plugin)
@@ -113,25 +112,35 @@
 #ifdef HAVE_X11
 	if (!XOpenDisplay(NULL)) {
 		purple_debug_warning("gntclipboard", "Couldn't find X display\n");
+		purple_notify_error(NULL, _("Error"), _("Error loading the plugin."),
+				_("Couldn't find X display"));
 		return FALSE;
 	}
-#endif
 	if (!getenv("WINDOWID")) {
 		purple_debug_warning("gntclipboard", "Couldn't find window\n");
+		purple_notify_error(NULL, _("Error"), _("Error loading the plugin."),
+				_("Couldn't find window"));
 		return FALSE;
 	}
 	sig_handle = g_signal_connect(G_OBJECT(gnt_get_clipboard()), "clipboard_changed", G_CALLBACK(clipboard_changed), NULL);
 	return TRUE;
+#else
+	purple_notify_error(NULL, _("Error"), _("Error loading the plugin."),
+			_("This plugin cannot be loaded because it was not built with X11 support."));
+	return FALSE;
+#endif
 }
 
 static gboolean
 plugin_unload(PurplePlugin *plugin)
 {
+#ifdef HAVE_X11
 	if (child) {
 		kill(child, SIGTERM);
 		child = 0;
 	}
 	g_signal_handler_disconnect(G_OBJECT(gnt_get_clipboard()), sig_handle);
+#endif
 	return TRUE;
 }
 
--- a/libpurple/account.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/account.c	Thu Sep 06 06:59:23 2007 +0000
@@ -1720,15 +1720,6 @@
 purple_account_get_protocol_id(const PurpleAccount *account)
 {
 	g_return_val_if_fail(account != NULL, NULL);
-	/*
-	 * HACK by Seanegan
-	 */
-	if (!strcmp(account->protocol_id, "prpl-oscar")) {
-		if (isdigit(account->username[0]))
-			return "prpl-icq";
-		else
-			return "prpl-aim";
-	}
 	return account->protocol_id;
 }
 
--- a/libpurple/certificate.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/certificate.c	Thu Sep 06 06:59:23 2007 +0000
@@ -580,7 +580,12 @@
 	"x509",                         /* Scheme name */
 	"singleuse",                    /* Verifier name */
 	x509_singleuse_start_verify,    /* start_verification function */
-	x509_singleuse_destroy_request  /* Request cleanup operation */
+	x509_singleuse_destroy_request, /* Request cleanup operation */
+
+	NULL,
+	NULL,
+	NULL,
+	NULL
 };
 
 
@@ -872,7 +877,13 @@
 	x509_ca_get_cert,             /* Cert retriever */
 	x509_ca_put_cert,             /* Cert writer */
 	x509_ca_delete_cert,          /* Cert remover */
-	x509_ca_get_idlist            /* idlist retriever */
+	x509_ca_get_idlist,           /* idlist retriever */
+
+	NULL,
+	NULL,
+	NULL,
+	NULL
+
 };
 
 
@@ -1034,7 +1045,12 @@
 	x509_tls_peers_get_cert,      /* Cert retriever */
 	x509_tls_peers_put_cert,      /* Cert writer */
 	x509_tls_peers_delete_cert,   /* Cert remover */
-	x509_tls_peers_get_idlist     /* idlist retriever */
+	x509_tls_peers_get_idlist,    /* idlist retriever */
+
+	NULL,
+	NULL,
+	NULL,
+	NULL
 };
 
 
@@ -1459,7 +1475,13 @@
 	"x509",                         /* Scheme name */
 	"tls_cached",                   /* Verifier name */
 	x509_tls_cached_start_verify,   /* Verification begin */
-	x509_tls_cached_destroy_request /* Request cleanup */
+	x509_tls_cached_destroy_request,/* Request cleanup */
+
+	NULL,
+	NULL,
+	NULL,
+	NULL
+
 };
 
 /****************************************************************************/
--- a/libpurple/certificate.h	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/certificate.h	Thu Sep 06 06:59:23 2007 +0000
@@ -123,6 +123,11 @@
 
 	/** Returns a list of IDs stored in the pool */
 	GList * (* get_idlist)(void);
+
+	void (*_purple_reserved1)(void);
+	void (*_purple_reserved2)(void);
+	void (*_purple_reserved3)(void);
+	void (*_purple_reserved4)(void);
 };
 
 /** A certificate type
@@ -241,7 +246,10 @@
 	/** Retrieve the certificate activation/expiration times */
 	gboolean (* get_times)(PurpleCertificate *crt, time_t *activation, time_t *expiration);
 	
-	/* TODO: Fill out this structure */
+	void (*_purple_reserved1)(void);
+	void (*_purple_reserved2)(void);
+	void (*_purple_reserved3)(void);
+	void (*_purple_reserved4)(void);
 };
 
 /** A set of operations used to provide logic for verifying a Certificate's
@@ -286,6 +294,11 @@
 	 * @param vrq       Request to destroy
 	 */
 	void (* destroy_request)(PurpleCertificateVerificationRequest *vrq);
+
+	void (*_purple_reserved1)(void);
+	void (*_purple_reserved2)(void);
+	void (*_purple_reserved3)(void);
+	void (*_purple_reserved4)(void);
 };
 
 /** Structure for a single certificate request
--- a/libpurple/cipher.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/cipher.c	Thu Sep 06 06:59:23 2007 +0000
@@ -2021,7 +2021,7 @@
 		if (client_nonce == NULL)
 		{
 			purple_cipher_context_destroy(context);
-			purple_debug_error("cipher", "Required client_nonce missing for MD5-sess digest calculation.");
+			purple_debug_error("cipher", "Required client_nonce missing for MD5-sess digest calculation.\n");
 			return NULL;
 		}
 
@@ -2091,7 +2091,7 @@
 		if (entity == NULL)
 		{
 			purple_cipher_context_destroy(context);
-			purple_debug_error("cipher", "Required entity missing for auth-int digest calculation.");
+			purple_debug_error("cipher", "Required entity missing for auth-int digest calculation.\n");
 			return NULL;
 		}
 
@@ -2118,14 +2118,14 @@
 		if (nonce_count == NULL)
 		{
 			purple_cipher_context_destroy(context);
-			purple_debug_error("cipher", "Required nonce_count missing for digest calculation.");
+			purple_debug_error("cipher", "Required nonce_count missing for digest calculation.\n");
 			return NULL;
 		}
 
 		if (client_nonce == NULL)
 		{
 			purple_cipher_context_destroy(context);
-			purple_debug_error("cipher", "Required client_nonce missing for digest calculation.");
+			purple_debug_error("cipher", "Required client_nonce missing for digest calculation.\n");
 			return NULL;
 		}
 
--- a/libpurple/connection.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/connection.c	Thu Sep 06 06:59:23 2007 +0000
@@ -436,7 +436,7 @@
 	g_return_if_fail(gc   != NULL);
 
 	if (text == NULL) {
-		purple_debug_error("connection", "purple_connection_error: check `text != NULL' failed");
+		purple_debug_error("connection", "purple_connection_error: check `text != NULL' failed\n");
 		text = _("Unknown error");
 	}
 
--- a/libpurple/conversation.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/conversation.c	Thu Sep 06 06:59:23 2007 +0000
@@ -869,6 +869,10 @@
 
 	displayed = g_strdup(message);
 
+	if (who == NULL || *who == '\0')
+		who = purple_conversation_get_name(conv);
+	alias = who;
+
 	plugin_return =
 		GPOINTER_TO_INT(purple_signal_emit_return_1(
 			purple_conversations_get_handle(),
@@ -883,11 +887,6 @@
 		return;
 	}
 
-	if (who == NULL || *who == '\0')
-		who = purple_conversation_get_name(conv);
-
-	alias = who;
-
 	if (account != NULL) {
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(account)));
 
--- a/libpurple/log.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/log.c	Thu Sep 06 06:59:23 2007 +0000
@@ -1380,7 +1380,7 @@
 				written += fprintf(data->file, "<font color=\"#16569E\"><font size=\"2\">(%s)</font> <b>%s:</b></font> %s<br/>\n",
 						date, from, msg_fixed);
 		} else {
-			purple_debug_error("log", "Unhandled message type.");
+			purple_debug_error("log", "Unhandled message type.\n");
 			written += fprintf(data->file, "<font size=\"2\">(%s)</font><b> %s:</b></font> %s<br/>\n",
 						date, from, msg_fixed);
 		}
--- a/libpurple/nat-pmp.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/nat-pmp.c	Thu Sep 06 06:59:23 2007 +0000
@@ -175,20 +175,20 @@
 	/* Determine the buffer side needed to get the full routing table */
     if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) 
 	{
-		purple_debug_warning("nat-pmp", "sysctl: net.route.0.0.dump estimate");
+		purple_debug_warning("nat-pmp", "sysctl: net.route.0.0.dump estimate\n");
 		return NULL;
     }
 
     if (!(buf = malloc(needed)))
 	{
-		purple_debug_warning("nat-pmp", "malloc");
+		purple_debug_warning("nat-pmp", "malloc\n");
 		return NULL;
     }
 
 	/* Read the routing table into buf */
     if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) 
 	{
-		purple_debug_warning("nat-pmp", "sysctl: net.route.0.0.dump");
+		purple_debug_warning("nat-pmp", "sysctl: net.route.0.0.dump\n");
 		return NULL;
     }
 
@@ -231,7 +231,7 @@
 						sin->sin_addr.s_addr = rti_sin->sin_addr.s_addr;
 						memcpy(sin, rti_info[RTAX_GATEWAY], sizeof(struct sockaddr_in));
 
-						purple_debug_info("nat-pmp", "found a default gateway");
+						purple_debug_info("nat-pmp", "found a default gateway\n");
 						found = TRUE;
 						break;
 					}
@@ -266,7 +266,7 @@
 	if ((pmp_info.status == PURPLE_PMP_STATUS_DISCOVERED) && (pmp_info.publicip != NULL))
 	{
 #ifdef PMP_DEBUG
-		purple_debug_info("nat-pmp", "Returning cached publicip %s",pmp_info.publicip);
+		purple_debug_info("nat-pmp", "Returning cached publicip %s\n",pmp_info.publicip);
 #endif
 		return pmp_info.publicip;
 	}
--- a/libpurple/network.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/network.c	Thu Sep 06 06:59:23 2007 +0000
@@ -351,12 +351,13 @@
 	listen_data->retry = TRUE;
 	listen_data->cb = cb;
 	listen_data->cb_data = cb_data;
+	listen_data->socket_type = socket_type;
 
 	/* Attempt a NAT-PMP Mapping, which will return immediately */
 	if (purple_pmp_create_map(((socket_type == SOCK_STREAM) ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP),
 							  actual_port, actual_port, PURPLE_PMP_LIFETIME))
 	{
-		purple_debug_info("network", "Created NAT-PMP mapping on port %i",actual_port);
+		purple_debug_info("network", "Created NAT-PMP mapping on port %i\n",actual_port);
 		/* We want to return listen_data now, and on the next run loop trigger the cb and destroy listen_data */
 		purple_timeout_add(0, purple_network_finish_pmp_map_cb, listen_data);
 	}
--- a/libpurple/plugins/offlinemsg.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/plugins/offlinemsg.c	Thu Sep 06 06:59:23 2007 +0000
@@ -113,6 +113,10 @@
 	PurpleConversation *conv;
 	OfflineMessageSetting setting;
 
+	if (message == NULL || *message == NULL ||
+			**message == '\0')
+		return;
+
 	buddy = purple_find_buddy(account, who);
 	if (!buddy)
 		return;
@@ -122,7 +126,7 @@
 
 	if (purple_account_supports_offline_message(account, buddy))
 	{
-		purple_debug_info("offlinemsg", "Account \"%s\" supports offline message.",
+		purple_debug_info("offlinemsg", "Account \"%s\" supports offline messages.\n",
 					purple_account_get_username(account));
 		return;
 	}
@@ -167,8 +171,8 @@
 static gboolean
 plugin_load(PurplePlugin *plugin)
 {
-	purple_signal_connect(purple_conversations_get_handle(), "sending-im-msg",
-					plugin, PURPLE_CALLBACK(sending_msg_cb), plugin);
+	purple_signal_connect_priority(purple_conversations_get_handle(), "sending-im-msg",
+					plugin, PURPLE_CALLBACK(sending_msg_cb), plugin, PURPLE_SIGNAL_PRIORITY_HIGHEST);
 	return TRUE;
 }
 
--- a/libpurple/plugins/psychic.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/plugins/psychic.c	Thu Sep 06 06:59:23 2007 +0000
@@ -49,7 +49,7 @@
   }
 
   if(FALSE == purple_privacy_check(acct, name)) {
-    purple_debug_info("psychic", "user %s is blocked", name);
+    purple_debug_info("psychic", "user %s is blocked\n", name);
     return;
   }
 
--- a/libpurple/plugins/ssl/ssl-gnutls.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/plugins/ssl/ssl-gnutls.c	Thu Sep 06 06:59:23 2007 +0000
@@ -911,7 +911,13 @@
 	x509_issuer_dn,                  /* Issuer Unique ID */
 	x509_common_name,                /* Subject name */
 	x509_check_name,                 /* Check subject name */
-	x509_times                       /* Activation/Expiration time */
+	x509_times,                      /* Activation/Expiration time */
+
+	NULL,
+	NULL,
+	NULL,
+	NULL
+
 };
 
 static PurpleSslOps ssl_ops =
--- a/libpurple/plugins/ssl/ssl-nss.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/plugins/ssl/ssl-nss.c	Thu Sep 06 06:59:23 2007 +0000
@@ -522,6 +522,9 @@
 
 	/* Make a hash! */
 	sha1sum = g_byte_array_sized_new(hashlen);
+	/* glib leaves the size as 0 by default */
+	sha1sum->len = hashlen;
+	
 	st = PK11_HashBuf(SEC_OID_SHA1, sha1sum->data,
 			  derCert->data, derCert->len);
 
@@ -638,7 +641,12 @@
 	NULL,                            /* Issuer Unique ID */
 	x509_common_name,                /* Subject name */
 	x509_check_name,                 /* Check subject name */
-	x509_times                       /* Activation/Expiration time */
+	x509_times,                      /* Activation/Expiration time */
+
+	NULL,
+	NULL,
+	NULL,
+	NULL
 };
 
 static PurpleSslOps ssl_ops =
--- a/libpurple/protocols/bonjour/bonjour.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/bonjour/bonjour.c	Thu Sep 06 06:59:23 2007 +0000
@@ -235,6 +235,13 @@
 	g_free(stripped);
 }
 
+static void bonjour_remove_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group) {
+	if (buddy->proto_data) {
+		bonjour_buddy_delete(buddy->proto_data);
+		buddy->proto_data = NULL;
+	}
+}
+
 static GList *
 bonjour_status_types(PurpleAccount *account)
 {
@@ -395,7 +402,7 @@
 	NULL,                                                    /* change_passwd */
 	NULL,                                                    /* add_buddy */
 	NULL,                                                    /* add_buddies */
-	NULL,                                                    /* remove_buddy */
+	bonjour_remove_buddy,                                    /* remove_buddy */
 	NULL,                                                    /* remove_buddies */
 	NULL,                                                    /* add_permit */
 	NULL,                                                    /* add_deny */
@@ -479,45 +486,50 @@
 	NULL
 };
 
-static void
-initialize_default_account_values()
-{
-#ifdef _WIN32
-	char *fullname = NULL;
-#else
-	struct passwd *info;
-	const char *fullname = NULL;
-#endif
-	char *splitpoint = NULL;
-	char *tmp;
-	char hostname[255];
+#ifdef WIN32
+static gboolean _set_default_name_cb(gpointer data) {
+	gchar *fullname = data;
+	const char *splitpoint;
+	GList *tmp = prpl_info.protocol_options;
+	PurpleAccountOption *option;
 
-#ifndef _WIN32
-	/* Try to figure out the user's real name */
-	info = getpwuid(getuid());
-	if ((info != NULL) && (info->pw_gecos != NULL) && (info->pw_gecos[0] != '\0'))
-		fullname = info->pw_gecos;
-	else if ((info != NULL) && (info->pw_name != NULL) && (info->pw_name[0] != '\0'))
-		fullname = info->pw_name;
-	else if (((fullname = getlogin()) != NULL) && (fullname[0] != '\0'))
-		;
-	else
-		fullname = _("Purple Person");
-	/* Make sure fullname is valid UTF-8.  If not, try to convert it. */
-	if (!g_utf8_validate(fullname, -1, NULL))
-	{
-		gchar *tmp;
-		tmp = g_locale_to_utf8(fullname, -1, NULL, NULL, NULL);
-		if ((tmp == NULL) || (*tmp == '\0'))
-			fullname = _("Purple Person");
+	if (!fullname) {
+		purple_debug_info("bonjour", "Unable to look up First and Last name or Username from system; using defaults.\n");
+		return FALSE;
 	}
 
-#else
+	g_free(default_firstname);
+	g_free(default_lastname);
+
+	/* Split the real name into a first and last name */
+	splitpoint = strchr(fullname, ' ');
+	if (splitpoint != NULL) {
+		default_firstname = g_strndup(fullname, splitpoint - fullname);
+		default_lastname = g_strdup(&splitpoint[1]);
+	} else {
+		default_firstname = g_strdup(fullname);
+		default_lastname = g_strdup("");
+	}
+	g_free(fullname);
+
+
+	for(; tmp != NULL; tmp = tmp->next) {
+		option = tmp->data;
+		if (strcmp("first", purple_account_option_get_setting(option)) == 0)
+			purple_account_option_set_default_string(option, default_firstname);
+		else if (strcmp("last", purple_account_option_get_setting(option)) == 0)
+			purple_account_option_set_default_string(option, default_lastname);
+	}
+
+	return FALSE;
+}
+
+static gpointer _win32_name_lookup_thread(gpointer data) {
+	gchar *fullname = NULL;
 	wchar_t username[UNLEN + 1];
 	DWORD dwLenUsername = UNLEN + 1;
 
-	if (!GetUserNameW((LPWSTR) &username, &dwLenUsername))
-		purple_debug_warning("bonjour", "Unable to look up username\n");
+	GetUserNameW((LPWSTR) &username, &dwLenUsername);
 
 	if (username != NULL && *username != '\0') {
 		LPBYTE servername = NULL;
@@ -525,7 +537,7 @@
 
 		NetGetDCName(NULL, NULL, &servername);
 
-		purple_debug_info("bonjour", "Looking up the full name from the %s.\n", (servername ? "domain controller" : "local machine"));
+		/* purple_debug_info("bonjour", "Looking up the full name from the %s.\n", (servername ? "domain controller" : "local machine")); */
 
 		if (NetUserGetInfo((LPCWSTR) servername, username, 10, &info) == NERR_Success
 				&& info != NULL && ((LPUSER_INFO_10) info)->usri10_full_name != NULL
@@ -536,7 +548,7 @@
 		}
 		/* Fall back to the local machine if we didn't get the full name from the domain controller */
 		else if (servername != NULL) {
-			purple_debug_info("bonjour", "Looking up the full name from the local machine");
+			/* purple_debug_info("bonjour", "Looking up the full name from the local machine"); */
 
 			if (info != NULL) NetApiBufferFree(info);
 			info = NULL;
@@ -552,20 +564,54 @@
 
 		if (info != NULL) NetApiBufferFree(info);
 		if (servername != NULL) NetApiBufferFree(servername);
+
+		if (!fullname)
+			fullname = g_utf16_to_utf8(username, -1, NULL, NULL, NULL);
 	}
 
-	if (!fullname) {
-		if (username != NULL && *username != '\0')
-			fullname = g_utf16_to_utf8(username, -1, NULL, NULL, NULL);
-		else
-			fullname = g_strdup(_("Purple Person"));
+	g_idle_add(_set_default_name_cb, fullname);
+
+	return NULL;
+}
+#endif
+
+static void
+initialize_default_account_values()
+{
+#ifndef _WIN32
+	struct passwd *info;
+#endif
+	const char *fullname = NULL, *splitpoint, *tmp;
+	char hostname[255];
+	gchar *conv = NULL;
+
+#ifndef _WIN32
+	/* Try to figure out the user's real name */
+	info = getpwuid(getuid());
+	if ((info != NULL) && (info->pw_gecos != NULL) && (info->pw_gecos[0] != '\0'))
+		fullname = info->pw_gecos;
+	else if ((info != NULL) && (info->pw_name != NULL) && (info->pw_name[0] != '\0'))
+		fullname = info->pw_name;
+	else if (((fullname = getlogin()) != NULL) && (fullname[0] != '\0'))
+		;
+#else
+	/* The Win32 username lookup functions are synchronous so we do it in a thread */
+	g_thread_create(_win32_name_lookup_thread, NULL, FALSE, NULL);
+#endif
+
+	/* Make sure fullname is valid UTF-8.  If not, try to convert it. */
+	if (fullname != NULL && !g_utf8_validate(fullname, -1, NULL)) {
+		fullname = conv = g_locale_to_utf8(fullname, -1, NULL, NULL, NULL);
+		if (conv == NULL || *conv == '\0')
+			fullname = NULL;
 	}
-#endif
+
+	if (fullname == NULL)
+		fullname = _("Purple Person");
 
 	/* Split the real name into a first and last name */
 	splitpoint = strchr(fullname, ' ');
-	if (splitpoint != NULL)
-	{
+	if (splitpoint != NULL) {
 		default_firstname = g_strndup(fullname, splitpoint - fullname);
 		tmp = &splitpoint[1];
 
@@ -577,16 +623,12 @@
 			default_lastname = g_strndup(tmp, splitpoint - tmp);
 		else
 			default_lastname = g_strdup(tmp);
-	}
-	else
-	{
+	} else {
 		default_firstname = g_strdup(fullname);
 		default_lastname = g_strdup("");
 	}
 
-#ifdef _WIN32
-	g_free(fullname);
-#endif
+	g_free(conv);
 
 	/* Try to figure out a good host name to use */
 	/* TODO: Avoid 'localhost,' if possible */
--- a/libpurple/protocols/bonjour/buddy.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/bonjour/buddy.c	Thu Sep 06 06:59:23 2007 +0000
@@ -121,9 +121,8 @@
  * the buddy.
  */
 void
-bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy)
+bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy, PurpleBuddy *buddy)
 {
-	PurpleBuddy *buddy;
 	PurpleGroup *group;
 	PurpleAccount *account = bonjour_buddy->account;
 	const char *status_id, *old_hash, *new_hash;
@@ -147,7 +146,8 @@
 	}
 
 	/* Make sure the buddy exists in our buddy list */
-	buddy = purple_find_buddy(account, bonjour_buddy->name);
+	if (buddy == NULL)
+		buddy = purple_find_buddy(account, bonjour_buddy->name);
 
 	if (buddy == NULL) {
 		buddy = purple_buddy_new(account, bonjour_buddy->name, NULL);
--- a/libpurple/protocols/bonjour/buddy.h	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/bonjour/buddy.h	Thu Sep 06 06:59:23 2007 +0000
@@ -92,8 +92,9 @@
 
 /**
  * If the buddy doesn't previoulsy exists, it is created. Else, its data is changed (???)
+ * purple_buddy is optional; it saves an additional lookup if we already have it
  */
-void bonjour_buddy_add_to_purple(BonjourBuddy *buddy);
+void bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy, PurpleBuddy *purple_buddy);
 
 /**
  * We got the buddy icon data; deal with it
--- a/libpurple/protocols/bonjour/jabber.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/bonjour/jabber.c	Thu Sep 06 06:59:23 2007 +0000
@@ -373,17 +373,19 @@
 
 	g_return_if_fail(bb != NULL);
 
-	/* Close the socket, clear the watcher and free memory */
-	bonjour_jabber_close_conversation(bb->conversation);
-	bb->conversation = NULL;
+	/* Inform the user that the conversation has been closed */
+	if (bb->conversation != NULL) {
+		conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, pb->name, pb->account);
+		if (conv != NULL) {
+			char *tmp = g_strdup_printf(_("%s has closed the conversation."), pb->name);
+			purple_conversation_write(conv, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL));
+			g_free(tmp);
+		}
+		/* Close the socket, clear the watcher and free memory */
+		bonjour_jabber_close_conversation(bb->conversation);
+		bb->conversation = NULL;
+	}
 
-	/* Inform the user that the conversation has been closed */
-	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, pb->name, pb->account);
-	if (conv != NULL) {
-		char *tmp = g_strdup_printf(_("%s has closed the conversation."), pb->name);
-		purple_conversation_write(conv, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL));
-		g_free(tmp);
-	}
 }
 
 void bonjour_jabber_stream_started(PurpleBuddy *pb) {
@@ -535,7 +537,7 @@
 
 	/* Look for the buddy that has opened the conversation and fill information */
 	address_text = inet_ntoa(their_addr.sin_addr);
-	purple_debug_info("bonjour", "Received incoming connection from %s\n.", address_text);
+	purple_debug_info("bonjour", "Received incoming connection from %s.\n", address_text);
 	cbba = g_new0(struct _check_buddy_by_address_t, 1);
 	cbba->address = address_text;
 	cbba->pb = &pb;
--- a/libpurple/protocols/bonjour/mdns_avahi.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/bonjour/mdns_avahi.c	Thu Sep 06 06:59:23 2007 +0000
@@ -33,7 +33,7 @@
 #include <avahi-glib/glib-malloc.h>
 #include <avahi-glib/glib-watch.h>
 
-/* For some reason, this is missing from the Avahi type defines */
+/* Avahi only defines the types that it actually uses (which at this time doesn't include NULL) */
 #ifndef AVAHI_DNS_TYPE_NULL
 #define AVAHI_DNS_TYPE_NULL 0x0A
 #endif
@@ -58,7 +58,8 @@
 		  const char *host_name, const AvahiAddress *a, uint16_t port, AvahiStringList *txt,
 		  AvahiLookupResultFlags flags, void *userdata) {
 
-	BonjourBuddy *buddy;
+	PurpleBuddy *pb;
+	BonjourBuddy *bb;
 	PurpleAccount *account = userdata;
 	AvahiStringList *l;
 	size_t size;
@@ -67,44 +68,62 @@
 
 	g_return_if_fail(r != NULL);
 
+	pb = purple_find_buddy(account, name);
+	bb = (pb != NULL) ? pb->proto_data : NULL;
+
 	switch (event) {
 		case AVAHI_RESOLVER_FAILURE:
 			purple_debug_error("bonjour", "_resolve_callback - Failure: %s\n",
 				avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
+
 			avahi_service_resolver_free(r);
+			if (bb != NULL) {
+				/* We've already freed the resolver */
+				if (r == ((AvahiBuddyImplData *)bb->mdns_impl_data)->resolver)
+					((AvahiBuddyImplData *)bb->mdns_impl_data)->resolver = NULL;
+				purple_blist_remove_buddy(pb);
+			}
 			break;
 		case AVAHI_RESOLVER_FOUND:
 			/* create a buddy record */
-			buddy = bonjour_buddy_new(name, account);
+			if (bb == NULL)
+				bb = bonjour_buddy_new(name, account);
 
-			((AvahiBuddyImplData *)buddy->mdns_impl_data)->resolver = r;
+			/* If we're reusing an existing buddy, make sure if it is a different resolver to clean up the old one.
+			 * I don't think this should ever happen, but I'm afraid we might get events out of sequence. */
+			if (((AvahiBuddyImplData *)bb->mdns_impl_data)->resolver != NULL
+					&& ((AvahiBuddyImplData *)bb->mdns_impl_data)->resolver != r) {
+				avahi_service_resolver_free(((AvahiBuddyImplData *)bb->mdns_impl_data)->resolver);
+			}
+			((AvahiBuddyImplData *)bb->mdns_impl_data)->resolver = r;
 
+			g_free(bb->ip);
 			/* Get the ip as a string */
-			buddy->ip = g_malloc(AVAHI_ADDRESS_STR_MAX);
-			avahi_address_snprint(buddy->ip, AVAHI_ADDRESS_STR_MAX, a);
+			bb->ip = g_malloc(AVAHI_ADDRESS_STR_MAX);
+			avahi_address_snprint(bb->ip, AVAHI_ADDRESS_STR_MAX, a);
 
-			buddy->port_p2pj = port;
+			bb->port_p2pj = port;
 
 			/* Obtain the parameters from the text_record */
-			clear_bonjour_buddy_values(buddy);
-			l = txt;
-			while (l != NULL) {
-				ret = avahi_string_list_get_pair(l, &key, &value, &size);
-				l = l->next;
-				if (ret < 0)
+			clear_bonjour_buddy_values(bb);
+			for(l = txt; l != NULL; l = l->next) {
+				if ((ret = avahi_string_list_get_pair(l, &key, &value, &size)) < 0)
 					continue;
-				set_bonjour_buddy_value(buddy, key, value, size);
+				set_bonjour_buddy_value(bb, key, value, size);
 				/* TODO: Since we're using the glib allocator, I think we
 				 * can use the values instead of re-copying them */
 				avahi_free(key);
 				avahi_free(value);
 			}
 
-			if (!bonjour_buddy_check(buddy))
-				bonjour_buddy_delete(buddy);
-			else
+			if (!bonjour_buddy_check(bb)) {
+				if (pb != NULL)
+					purple_blist_remove_buddy(pb);
+				else
+					bonjour_buddy_delete(bb);
+			} else
 				/* Add or update the buddy in our buddy list */
-				bonjour_buddy_add_to_purple(buddy);
+				bonjour_buddy_add_to_purple(bb, pb);
 
 			break;
 		default:
@@ -120,7 +139,7 @@
 		  AvahiLookupResultFlags flags, void *userdata) {
 
 	PurpleAccount *account = userdata;
-	PurpleBuddy *gb = NULL;
+	PurpleBuddy *pb = NULL;
 
 	switch (event) {
 		case AVAHI_BROWSER_FAILURE:
@@ -132,7 +151,7 @@
 			/* A new peer has joined the network and uses iChat bonjour */
 			purple_debug_info("bonjour", "_browser_callback - new service\n");
 			/* Make sure it isn't us */
-			if (g_ascii_strcasecmp(name, account->username) != 0) {
+			if (purple_utf8_strcasecmp(name, account->username) != 0) {
 				if (!avahi_service_resolver_new(avahi_service_browser_get_client(b),
 						interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC,
 						0, _resolver_callback, account)) {
@@ -143,16 +162,12 @@
 			break;
 		case AVAHI_BROWSER_REMOVE:
 			purple_debug_info("bonjour", "_browser_callback - Remove service\n");
-			gb = purple_find_buddy(account, name);
-			if (gb != NULL) {
-				bonjour_buddy_delete(gb->proto_data);
-				purple_blist_remove_buddy(gb);
-			}
+			pb = purple_find_buddy(account, name);
+			if (pb != NULL)
+				purple_blist_remove_buddy(pb);
 			break;
 		case AVAHI_BROWSER_ALL_FOR_NOW:
 		case AVAHI_BROWSER_CACHE_EXHAUSTED:
-			purple_debug_warning("bonjour", "(Browser) %s\n",
-				event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
 			break;
 		default:
 			purple_debug_info("bonjour", "Unrecognized Service browser event: %d.\n", event);
@@ -173,7 +188,7 @@
 			purple_debug_error("bonjour", "Collision registering buddy icon data.\n");
 			break;
 		case AVAHI_ENTRY_GROUP_FAILURE:
-			purple_debug_error("bonjour", "Error registering buddy icon data: %s\n.",
+			purple_debug_error("bonjour", "Error registering buddy icon data: %s.\n",
 				avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
 			break;
 		case AVAHI_ENTRY_GROUP_UNCOMMITED:
@@ -256,7 +271,7 @@
 	idata->client = avahi_client_new(poll_api, 0, NULL, data, &error);
 
 	if (idata->client == NULL) {
-		purple_debug_error("bonjour", "Error initializing Avahi: %s", avahi_strerror(error));
+		purple_debug_error("bonjour", "Error initializing Avahi: %s\n", avahi_strerror(error));
 		avahi_glib_poll_free(idata->glib_poll);
 		g_free(idata);
 		return FALSE;
@@ -339,7 +354,7 @@
 	if (!idata->sb) {
 
 		purple_debug_error("bonjour",
-			"Unable to initialize service browser.  Error: %s\n.",
+			"Unable to initialize service browser.  Error: %s.\n",
 			avahi_strerror(avahi_client_errno(idata->client)));
 		return FALSE;
 	}
@@ -473,7 +488,7 @@
 
 	if (!idata->buddy_icon_rec_browser) {
 		purple_debug_error("bonjour",
-			"Unable to initialize buddy icon record browser.  Error: %s\n.",
+			"Unable to initialize buddy icon record browser.  Error: %s.\n",
 			avahi_strerror(avahi_client_errno(session_idata->client)));
 	}
 
--- a/libpurple/protocols/bonjour/mdns_common.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/bonjour/mdns_common.c	Thu Sep 06 06:59:23 2007 +0000
@@ -207,7 +207,7 @@
 
 	/* Advise the daemon that we are waiting for connections */
 	if (!_mdns_browse(data)) {
-		purple_debug_error("bonjour", "Unable to get service.");
+		purple_debug_error("bonjour", "Unable to get service.\n");
 		return FALSE;
 	}
 
--- a/libpurple/protocols/bonjour/mdns_howl.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/bonjour/mdns_howl.c	Thu Sep 06 06:59:23 2007 +0000
@@ -71,6 +71,7 @@
 	char value[SW_TEXT_RECORD_MAX_LEN];
 	sw_uint32 value_length;
 
+	/* TODO: We want to keep listening for updates*/
 	sw_discovery_cancel(discovery, oid);
 
 	/* create a buddy record */
@@ -100,7 +101,7 @@
 	}
 
 	/* Add or update the buddy in our buddy list */
-	bonjour_buddy_add_to_purple(buddy);
+	bonjour_buddy_add_to_purple(buddy, NULL);
 
 	return SW_OKAY;
 }
@@ -149,10 +150,7 @@
 			purple_debug_info("bonjour", "_browser_reply --> Remove service\n");
 			gb = purple_find_buddy(account, name);
 			if (gb != NULL)
-			{
-				bonjour_buddy_delete(gb->proto_data);
 				purple_blist_remove_buddy(gb);
-			}
 			break;
 		case SW_DISCOVERY_BROWSE_RESOLVED:
 			purple_debug_info("bonjour", "_browse_reply --> Resolved\n");
--- a/libpurple/protocols/bonjour/mdns_win32.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/bonjour/mdns_win32.c	Thu Sep 06 06:59:23 2007 +0000
@@ -79,23 +79,23 @@
 	uint32_t ttl, void *context)
 {
 
-	if (kDNSServiceErr_NoError != errorCode)
+	if (kDNSServiceErr_NoError != errorCode) {
 		purple_debug_error("bonjour", "record query - callback error.\n");
-	else if (flags & kDNSServiceFlagsAdd)
-	{
+		/* TODO: Probably should remove the buddy when this happens */
+	} else if (flags & kDNSServiceFlagsAdd) {
 		if (rrtype == kDNSServiceType_TXT) {
 			/* New Buddy */
-			BonjourBuddy *buddy = (BonjourBuddy*) context;
-			_mdns_parse_text_record(buddy, rdata, rdlen);
-			bonjour_buddy_add_to_purple(buddy);
+			BonjourBuddy *bb = (BonjourBuddy*) context;
+			_mdns_parse_text_record(bb, rdata, rdlen);
+			bonjour_buddy_add_to_purple(bb, NULL);
 		} else if (rrtype == kDNSServiceType_NULL) {
 			/* Buddy Icon response */
-			BonjourBuddy *buddy = (BonjourBuddy*) context;
-			Win32BuddyImplData *idata = buddy->mdns_impl_data;
+			BonjourBuddy *bb = (BonjourBuddy*) context;
+			Win32BuddyImplData *idata = bb->mdns_impl_data;
 
 			g_return_if_fail(idata != NULL);
 
-			bonjour_buddy_got_buddy_icon(buddy, rdata, rdlen);
+			bonjour_buddy_got_buddy_icon(bb, rdata, rdlen);
 
 			/* We've got what we need; stop listening */
 			purple_input_remove(idata->null_query_handler);
@@ -110,32 +110,34 @@
 _mdns_resolve_host_callback(GSList *hosts, gpointer data, const char *error_message)
 {
 	ResolveCallbackArgs* args = (ResolveCallbackArgs*)data;
+	BonjourBuddy* bb = args->buddy;
 
-	if (!hosts || !hosts->data)
+	if (!hosts || !hosts->data) {
 		purple_debug_error("bonjour", "host resolution - callback error.\n");
-	else {
+		bonjour_buddy_delete(bb);
+	} else {
 		struct sockaddr_in *addr = (struct sockaddr_in*)g_slist_nth_data(hosts, 1);
-		BonjourBuddy* buddy = args->buddy;
-		Win32BuddyImplData *idata = buddy->mdns_impl_data;
+		Win32BuddyImplData *idata = bb->mdns_impl_data;
 
 		g_return_if_fail(idata != NULL);
 
-		buddy->ip = g_strdup(inet_ntoa(addr->sin_addr));
+		g_free(bb->ip);
+		bb->ip = g_strdup(inet_ntoa(addr->sin_addr));
 
 		/* finally, set up the continuous txt record watcher, and add the buddy to purple */
 
 		if (kDNSServiceErr_NoError == DNSServiceQueryRecord(&idata->txt_query, kDNSServiceFlagsLongLivedQuery,
 				kDNSServiceInterfaceIndexAny, args->full_service_name, kDNSServiceType_TXT,
-				kDNSServiceClass_IN, _mdns_record_query_callback, buddy)) {
+				kDNSServiceClass_IN, _mdns_record_query_callback, bb)) {
 
-			purple_debug_info("bonjour", "Found buddy %s at %s:%d\n", buddy->name, buddy->ip, buddy->port_p2pj);
+			purple_debug_info("bonjour", "Found buddy %s at %s:%d\n", bb->name, bb->ip, bb->port_p2pj);
 
 			idata->txt_query_handler = purple_input_add(DNSServiceRefSockFD(idata->txt_query),
 				PURPLE_INPUT_READ, _mdns_handle_event, idata->txt_query);
 
-			bonjour_buddy_add_to_purple(buddy);
+			bonjour_buddy_add_to_purple(bb, NULL);
 		} else
-			bonjour_buddy_delete(buddy);
+			bonjour_buddy_delete(bb);
 
 	}
 
@@ -202,18 +204,19 @@
     DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context)
 {
 	PurpleAccount *account = (PurpleAccount*)context;
-	PurpleBuddy *gb = NULL;
+	PurpleBuddy *pb = NULL;
 
 	if (kDNSServiceErr_NoError != errorCode)
-		purple_debug_error("bonjour", "service browser - callback error");
+		purple_debug_error("bonjour", "service browser - callback error\n");
 	else if (flags & kDNSServiceFlagsAdd) {
 		/* A presence service instance has been discovered... check it isn't us! */
-		if (g_ascii_strcasecmp(serviceName, account->username) != 0) {
+		if (purple_utf8_strcasecmp(serviceName, account->username) != 0) {
 			/* OK, lets go ahead and resolve it to add to the buddy list */
 			ResolveCallbackArgs *args = g_new0(ResolveCallbackArgs, 1);
 			args->buddy = bonjour_buddy_new(serviceName, account);
 
-			if (kDNSServiceErr_NoError != DNSServiceResolve(&args->resolver, 0, 0, serviceName, regtype, replyDomain, _mdns_service_resolve_callback, args)) {
+			if (kDNSServiceErr_NoError != DNSServiceResolve(&args->resolver, 0, 0, serviceName, regtype,
+					replyDomain, _mdns_service_resolve_callback, args)) {
 				bonjour_buddy_delete(args->buddy);
 				g_free(args);
 				purple_debug_error("bonjour", "service browser - failed to resolve service.\n");
@@ -226,11 +229,9 @@
 	} else {
 		/* A peer has sent a goodbye packet, remove them from the buddy list */
 		purple_debug_info("bonjour", "service browser - remove notification\n");
-		gb = purple_find_buddy(account, serviceName);
-		if (gb != NULL) {
-			bonjour_buddy_delete(gb->proto_data);
-			purple_blist_remove_buddy(gb);
-		}
+		pb = purple_find_buddy(account, serviceName);
+		if (pb != NULL)
+			purple_blist_remove_buddy(pb);
 	}
 }
 
--- a/libpurple/protocols/irc/irc.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/irc/irc.c	Thu Sep 06 06:59:23 2007 +0000
@@ -347,6 +347,7 @@
 	const char *username, *realname;
 	struct irc_conn *irc = gc->proto_data;
 	const char *pass = purple_connection_get_password(gc);
+	int ret;
 
 	if (pass && *pass) {
 		buf = irc_format(irc, "vv", "PASS", pass);
@@ -359,8 +360,12 @@
 	}
 
 
-	gethostname(hostname, sizeof(hostname));
+	ret = gethostname(hostname, sizeof(hostname));
 	hostname[sizeof(hostname) - 1] = '\0';
+	if (ret < 0 || hostname[0] == '\0') {
+		purple_debug_warning("irc", "gethostname() failed -- is your hostname set?");
+		strcpy(hostname, "localhost");
+	}
 	realname = purple_account_get_string(irc->account, "realname", "");
 	username = purple_account_get_string(irc->account, "username", "");
 
--- a/libpurple/protocols/jabber/disco.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/jabber/disco.c	Thu Sep 06 06:59:23 2007 +0000
@@ -273,7 +273,7 @@
 		g_free(js->server_name);
 		js->server_name = g_strdup(name);
 		if (!strcmp(name, "Google Talk")) {
-		  purple_debug_info("jabber", "Google Talk!");
+		  purple_debug_info("jabber", "Google Talk!\n");
 		  js->googletalk = TRUE;
 		}
 	}
--- a/libpurple/protocols/msn/httpconn.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/msn/httpconn.c	Thu Sep 06 06:59:23 2007 +0000
@@ -181,7 +181,7 @@
 		{
 			msn_session_set_error(httpconn->session,
 								  MSN_ERROR_HTTP_MALFORMED, NULL);
-			purple_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}",
+			purple_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}\n",
 							 buf);
 
 			g_free(body);
--- a/libpurple/protocols/msn/nexus.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/msn/nexus.c	Thu Sep 06 06:59:23 2007 +0000
@@ -188,7 +188,7 @@
 	purple_ssl_close(nexus->gsc);
 	nexus->gsc = NULL;
 
-	purple_debug_misc("msn", "ssl buffer: {%s}", nexus->read_buf);
+	purple_debug_misc("msn", "ssl buffer: {%s}\n", nexus->read_buf);
 
 	if (strstr(nexus->read_buf, "HTTP/1.1 302") != NULL)
 	{
--- a/libpurple/protocols/msn/slp.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/msn/slp.c	Thu Sep 06 06:59:23 2007 +0000
@@ -343,7 +343,7 @@
 		if (xfer)
 		{
 			bin = (char *)purple_base64_decode(context, &bin_len);
-			file_size = GUINT32_FROM_LE(*((gsize *)bin + 2));
+			file_size = GUINT32_FROM_LE(*(gsize *)(bin + 2));
 
 			uni_name = (gunichar2 *)(bin + 20);
 			while(*uni_name != 0 && ((char *)uni_name - (bin + 20)) < MAX_FILE_NAME_LEN) {
--- a/libpurple/protocols/msn/slplink.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/msn/slplink.c	Thu Sep 06 06:59:23 2007 +0000
@@ -49,7 +49,7 @@
 	tf = g_fopen(tmp, "wb");
 	if (tf == NULL)
 	{
-		purple_debug_error("msn", "could not open debug file");
+		purple_debug_error("msn", "could not open debug file\n");
 		return;
 	}
 	pload = msn_message_gen_payload(msg, &pload_size);
--- a/libpurple/protocols/msn/switchboard.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/msn/switchboard.c	Thu Sep 06 06:59:23 2007 +0000
@@ -771,7 +771,8 @@
 		msg->ack_cb(msg, msg->ack_data);
 
 	swboard = cmdproc->data;
-	swboard->ack_list = g_list_remove(swboard->ack_list, msg);
+	if (swboard)
+		swboard->ack_list = g_list_remove(swboard->ack_list, msg);
 	msn_message_unref(msg);
 }
 
--- a/libpurple/protocols/myspace/CHANGES	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/myspace/CHANGES	Thu Sep 06 06:59:23 2007 +0000
@@ -6,7 +6,7 @@
 * Support myim:sendIM and addContact URLs with cID and uID parameters.
 * Fix #2722, only check for mail if "New mail notifications" is enabled.
 * Modularize msimprpl.
-
+* Pidgin 2.1.1 only.
 
 2007-08-23 Jeff Connelly <pidgin@xyzzy.cjb.net> - 0.16
 * Add option to add all friends from myspace.com to your buddy list (#2660)
--- a/libpurple/protocols/myspace/markup.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/myspace/markup.c	Thu Sep 06 06:59:23 2007 +0000
@@ -321,7 +321,7 @@
 
 	color = xmlnode_get_attrib(root, "v");
 	if (!color) {
-		purple_debug_info("msim", "msim_markup_c_to_html: <c> tag w/o v attr");
+		purple_debug_info("msim", "msim_markup_c_to_html: <c> tag w/o v attr\n");
 		*begin = g_strdup("");
 		*end = g_strdup("");
 		/* TODO: log as unrecognized */
@@ -349,7 +349,7 @@
 	if (!color) {
 		*begin = g_strdup("");
 		*end = g_strdup("");
-		purple_debug_info("msim", "msim_markup_b_to_html: <b> w/o v attr");
+		purple_debug_info("msim", "msim_markup_b_to_html: <b> w/o v attr\n");
 		/* TODO: log as unrecognized. */
 		return;
 	}
@@ -374,7 +374,7 @@
 
 	name = xmlnode_get_attrib(root, "n");
 	if (!name) {
-		purple_debug_info("msim", "msim_markup_i_to_html: <i> w/o n");
+		purple_debug_info("msim", "msim_markup_i_to_html: <i> w/o n\n");
 		*begin = g_strdup("");
 		*end = g_strdup("");
 		/* TODO: log as unrecognized */
@@ -669,6 +669,8 @@
 
 /** High-level function to convert Purple (HTML) to MySpaceIM markup.
  *
+ * TODO: consider using purple_markup_html_to_xhtml() to make valid XML.
+ *
  * @return HTML markup string, must be g_free()'d. */
 gchar *
 html_to_msim_markup(MsimSession *session, const gchar *raw)
--- a/libpurple/protocols/myspace/myspace.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/myspace/myspace.c	Thu Sep 06 06:59:23 2007 +0000
@@ -932,7 +932,7 @@
 
 	username = msim_msg_get_string(msg, "user");
 	if (!username) {
-		purple_debug_info("msim", "msim_get_info_cb: no 'user' in msg");
+		purple_debug_info("msim", "msim_get_info_cb: no 'user' in msg\n");
 		return;
 	}
 
@@ -1066,9 +1066,12 @@
 	statstring = purple_status_get_attr_string(status, "message");
 
 	if (!statstring) {
-		statstring = g_strdup("");
+		statstring = "";
 	}
 
+	/* Status strings are plain text. */
+	statstring = purple_markup_strip_html(statstring);
+
 	msim_set_status_code(session, status_code, g_strdup(statstring));
 }
 
@@ -1117,7 +1120,7 @@
 			"locstring", MSIM_TYPE_STRING, g_strdup(""),
 			NULL))
 	{
-		purple_debug_info("msim", "msim_set_status: failed to set status");
+		purple_debug_info("msim", "msim_set_status: failed to set status\n");
 	}
 
 }
@@ -1179,7 +1182,7 @@
 
 	if (!buddies)
 	{
-		purple_debug_info("msim", "msim_uid2username_from_blist: no buddies?");
+		purple_debug_info("msim", "msim_uid2username_from_blist: no buddies?\n");
 		return NULL;
 	}
 
@@ -1407,6 +1410,91 @@
 	return TRUE;
 }
 
+#ifdef MSIM_CHECK_NEWER_VERSION
+/** Callback for when a currentversion.txt has been downloaded. */
+static void
+msim_check_newer_version_cb(PurpleUtilFetchUrlData *url_data,
+		gpointer user_data,
+		const gchar *url_text,
+		gsize len,
+		const gchar *error_message)
+{
+	GKeyFile *keyfile;
+	GError *error;
+	GString *data;
+	gchar *newest_filever;
+
+	if (!url_text) {
+		purple_debug_info("msim_check_newer_version_cb",
+				"got error: %s\n", error_message);
+		return;
+	}
+
+	purple_debug_info("msim_check_newer_version_cb",
+			"url_text=%s\n", url_text ? url_text : "(NULL)");
+
+	/* Prepend [group] so that GKeyFile can parse it (requires a group). */
+	data = g_string_new(url_text);
+	purple_debug_info("msim", "data=%s\n", data->str
+			? data->str : "(NULL)");
+	data = g_string_prepend(data, "[group]\n");
+
+	purple_debug_info("msim", "data=%s\n", data->str
+			? data->str : "(NULL)");
+
+	/* url_text is variable=data\n... */
+
+	/* Check FILEVER, 1.0.716.0. 716 is build, MSIM_CLIENT_VERSION */
+	/* New (english) version can be downloaded from SETUPURL+SETUPFILE */
+
+	error = NULL;
+	keyfile = g_key_file_new();
+
+	/* Default list seperator is ;, but currentversion.txt doesn't have
+	 * these, so set to an unused character to avoid parsing problems. */
+	g_key_file_set_list_separator(keyfile, '\0');
+
+	g_key_file_load_from_data(keyfile, data->str, data->len,
+				G_KEY_FILE_NONE, &error);
+	g_string_free(data, TRUE);
+
+	if (error != NULL) {
+		purple_debug_info("msim_check_newer_version_cb",
+				"couldn't parse, error: %d %d %s\n",
+				error->domain, error->code, error->message);
+		g_error_free(error);
+		return;
+	}
+
+	gchar **ks;
+	guint n;
+	ks = g_key_file_get_keys(keyfile, "group", &n, NULL);
+	purple_debug_info("msim", "n=%d\n", n);
+	guint i;
+	for (i = 0; ks[i] != NULL; ++i)
+	{
+		purple_debug_info("msim", "%d=%s\n", i, ks[i]);
+	}
+
+	newest_filever = g_key_file_get_string(keyfile, "group", 
+			"FILEVER", &error);
+
+	purple_debug_info("msim_check_newer_version_cb",
+			"newest filever: %s\n", newest_filever ?
+			newest_filever : "(NULL)");
+	if (error != NULL) {
+		purple_debug_info("msim_check_newer_version_cb",
+				"error: %d %d %s\n",
+				error->domain, error->code, error->message);
+		g_error_free(error);
+	}
+
+	g_key_file_free(keyfile);			
+
+	exit(0);
+}
+#endif
+
 /** Called when the session key arrives. */
 static gboolean
 msim_we_are_logged_on(MsimSession *session, MsimMessage *msg)
@@ -1441,7 +1529,7 @@
 
 	/* If a local alias wasn't set, set it to user's username. */
 	if (!session->account->alias || !strlen(session->account->alias))
-		session->account->alias = session->username;
+		purple_account_set_alias(session->account, session->username);
 
 	/* The session is now set up, ready to be connected. This emits the
 	 * signedOn signal, so clients can now do anything with msimprpl, and
@@ -1454,7 +1542,13 @@
 
 
 	if (msim_msg_get_integer(msg, "uniquenick") == session->userid) {
-		purple_debug_info("msim_we_are_logged_on", "TODO: pick username");
+		purple_debug_info("msim_we_are_logged_on", "TODO: pick username\n");
+		/* No username is set. */
+		purple_notify_error(session->account, 
+				_("No username set"),
+				_("Please go to http://editprofile.myspace.com/index.cfm?fuseaction=profile.username and choose a username and try to login again."), NULL);
+		purple_connection_error(session->gc, _("No username set"));
+		return FALSE;
 	}
 
 	body = msim_msg_new(
@@ -1687,15 +1781,23 @@
 	purple_debug_info("msim", "msim_error (sesskey=%d): %s\n", 
 			session->sesskey, full_errmsg);
 
-	purple_notify_error(session->account, g_strdup(_("MySpaceIM Error")), 
-			full_errmsg, NULL);
-
 	/* Destroy session if fatal. */
 	if (msim_msg_get(msg, "fatal")) {
 		purple_debug_info("msim", "fatal error, closing\n");
+		if (err == 260) {
+			/* Incorrect password */
+			session->gc->wants_to_die = TRUE;
+			if (!purple_account_get_remember_password(session->account))
+				purple_account_set_password(session->account, NULL);
+		}
 		purple_connection_error(session->gc, full_errmsg);
+	} else {
+		purple_notify_error(session->account, g_strdup(_("MySpaceIM Error")), 
+				full_errmsg, NULL);
 	}
 
+	g_free(full_errmsg);
+
 	return TRUE;
 }
 
@@ -1713,7 +1815,7 @@
 	PurpleBuddyList *blist;
 	MsimUser *user;
 	GList *list;
-	gchar *status_headline;
+	gchar *status_headline, *status_headline_escaped;
 	gint status_code, purple_status_code;
 	gchar *username;
 
@@ -1768,8 +1870,21 @@
 		purple_debug_info("msim", "msim_status: found buddy %s\n", username);
 	}
 
+	if (status_headline) {
+		/* The status headline is plaintext, but libpurple treats it as HTML,
+		 * so escape any HTML characters to their entity equivalents. */
+		status_headline_escaped = g_markup_escape_text(status_headline, strlen(status_headline));
+	} else {
+		status_headline_escaped = NULL;
+	}
+
+	g_free(status_headline);
+
+	if (user->headline) 
+		g_free(user->headline);
+
 	/* don't copy; let the MsimUser own the headline, memory-wise */
-	user->headline = status_headline;
+	user->headline = status_headline_escaped;
   
 	/* Set user status */
 	switch (status_code) {
@@ -1833,7 +1948,7 @@
 {
 	MsimSession *session;
 	MsimMessage *msg;
-	/* MsimMessage *msg_persist; */
+	MsimMessage *msg_persist;
 	MsimMessage *body;
 
 	session = (MsimSession *)gc->proto_data;
@@ -1868,12 +1983,12 @@
 
 	/* TODO: Update blocklist. */
 
-#if 0
 	msg_persist = msim_msg_new(
 		"persist", MSIM_TYPE_INTEGER, 1,
 		"sesskey", MSIM_TYPE_INTEGER, session->sesskey,
 		"cmd", MSIM_TYPE_INTEGER, MSIM_CMD_BIT_ACTION | MSIM_CMD_PUT,
 		"dsn", MSIM_TYPE_INTEGER, MC_CONTACT_INFO_DSN,
+		"uid", MSIM_TYPE_INTEGER, session->userid,
 		"lid", MSIM_TYPE_INTEGER, MC_CONTACT_INFO_LID,
 		/* TODO: Use msim_new_reply_callback to get rid. */
 		"rid", MSIM_TYPE_INTEGER, session->next_rid++,
@@ -1887,7 +2002,6 @@
 		return;
 	}
 	msim_msg_free(msg_persist);
-#endif
 
 }
 
@@ -2618,7 +2732,7 @@
 
 	switch (GPOINTER_TO_UINT(user_data)) {
 		case MSIM_CONTACT_LIST_IMPORT_ALL_FRIENDS:
-			msg = g_strdup_printf(_("%d buddies were added or updated"), buddy_count);
+			msg = g_strdup_printf(_("%d buddies were added or updated from the server (including buddies already on the server-side list)"), buddy_count);
 			purple_notify_info(session->account, _("Add contacts from server"), msg, NULL);
 			g_free(msg);
 			break;
@@ -3143,6 +3257,16 @@
 	PurpleAccountOption *option;
 	static gboolean initialized = FALSE;
 
+#ifdef MSIM_CHECK_NEWER_VERSION
+	/* PROBLEM: MySpace's servers always return Content-Location, and
+	 * libpurple redirects to it, infinitely, even though it is the same
+	 * location we requested! */
+	purple_util_fetch_url("http://im.myspace.com/nsis/currentversion.txt",
+			FALSE, /* not full URL */
+			"MSIMAutoUpdateAgent", /* user agent */
+			TRUE,  /* use HTTP/1.1 */
+			msim_check_newer_version_cb, NULL);
+#endif
 
 	/* TODO: default to automatically try different ports. Make the user be
 	 * able to set the first port to try (like LastConnectedPort in Windows client).  */
--- a/libpurple/protocols/myspace/myspace.h	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/myspace/myspace.h	Thu Sep 06 06:59:23 2007 +0000
@@ -91,12 +91,16 @@
 /* Build version of MySpaceIM to report to servers (1.0.xxx.0) */
 #define MSIM_CLIENT_VERSION         697
 
+/* Check for a newer official MySpaceIM client on startup?
+ * (Mostly useful for developers) */
+/*#define MSIM_CHECK_NEWER_VERSION*/
+
 /* Language codes from http://www.microsoft.com/globaldev/reference/oslocversion.mspx */
 #define MSIM_LANGUAGE_ID_ENGLISH    1033
 #define MSIM_LANGUAGE_NAME_ENGLISH  "ENGLISH"
 
 /* msimprpl version string of this plugin */
-#define MSIM_PRPL_VERSION_STRING    "0.16"
+#define MSIM_PRPL_VERSION_STRING    "0.18"
 
 /* Default server */
 #define MSIM_SERVER                 "im.myspace.akadns.net"
@@ -186,10 +190,10 @@
 /** A type of "attention" message (zap, nudge, buzz, etc. depending on the
  * protocol) that can be sent and received. */
 struct _MsimAttentionType {
-	PurpleStoredImage *icon;
-	const gchar *description;		/**< Shown before sending. */
+	const gchar *name;	 	        /**< Shown before sending. */
 	const gchar *incoming_description;	/**< Shown when sent. */
 	const gchar *outgoing_description;	/**< Shown when received. */
+	const gchar *icon_name;
 };
 #endif
 
--- a/libpurple/protocols/myspace/release.sh	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/myspace/release.sh	Thu Sep 06 06:59:23 2007 +0000
@@ -4,7 +4,7 @@
 
 # Package a new msimprpl for release. Must be run with bash.
 
-VERSION=0.16
+VERSION=0.18
 make
 # Include 'myspace' directory in archive, so it can easily be unextracted
 # into ~/pidgin/libpurple/protocols at the correct location.
--- a/libpurple/protocols/myspace/zap.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/myspace/zap.c	Thu Sep 06 06:59:23 2007 +0000
@@ -126,7 +126,7 @@
 	zap_string = g_strdup_printf("!!!ZAP_SEND!!!=RTE_BTN_ZAPS_%d", code);
 
 	if (!msim_send_bm(session, username, zap_string, MSIM_BM_ACTION)) {
-		purple_debug_info("msim_send_zap_from_menu", "msim_send_bm failed: zapping %s with %s",
+		purple_debug_info("msim_send_zap_from_menu", "msim_send_bm failed: zapping %s with %s\n",
 				username, zap_string);
 		rc = FALSE;
 	} else {
--- a/libpurple/protocols/novell/nmrtf.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/novell/nmrtf.c	Thu Sep 06 06:59:23 2007 +0000
@@ -233,7 +233,7 @@
 	if (status == NMRTF_OK)
 		return g_strdup(ctx->output->str);
 
-	purple_debug_info("novell", "RTF parser failed with error code %d", status);
+	purple_debug_info("novell", "RTF parser failed with error code %d\n", status);
 	return NULL;
 }
 
--- a/libpurple/protocols/null/nullprpl.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/null/nullprpl.c	Thu Sep 06 06:59:23 2007 +0000
@@ -321,7 +321,7 @@
 }
 
 static void blist_example_menu_item(PurpleBlistNode *node, gpointer userdata) {
-  purple_debug_info("nullprpl", "example menu item clicked on user",
+  purple_debug_info("nullprpl", "example menu item clicked on user\n",
                     ((PurpleBuddy *)node)->name);
 
   purple_notify_info(NULL,  /* plugin handle or PurpleConnection */
--- a/libpurple/protocols/oscar/family_auth.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/oscar/family_auth.c	Thu Sep 06 06:59:23 2007 +0000
@@ -211,7 +211,7 @@
 
 #ifdef USE_XOR_FOR_ICQ
 	/* If we're signing on an ICQ account then use the older, XOR login method */
-	if (aim_sn_is_icq(sn))
+	if (aim_snvalid_icq(sn))
 		return goddamnicq2(od, conn, sn, password, ci);
 #endif
 
@@ -224,7 +224,7 @@
 
 	/* Truncate ICQ and AOL passwords, if necessary */
 	password_len = strlen(password);
-	if (aim_sn_is_icq(sn) && (password_len > MAXICQPASSLEN))
+	if (aim_snvalid_icq(sn) && (password_len > MAXICQPASSLEN))
 		password_len = MAXICQPASSLEN;
 	else if (truncate_pass && password_len > 8)
 		password_len = 8;
@@ -477,7 +477,7 @@
 		return -EINVAL;
 
 #ifdef USE_XOR_FOR_ICQ
-	if (aim_sn_is_icq(sn))
+	if (aim_snvalid_icq(sn))
 		return goddamnicq(od, conn, sn);
 #endif
 
--- a/libpurple/protocols/oscar/family_feedbag.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/oscar/family_feedbag.c	Thu Sep 06 06:59:23 2007 +0000
@@ -505,13 +505,13 @@
 	 * buddy ID#s, which makes things more efficient.  I think.
 	 */
 
-	/* Additions */
+	/* Deletions */
 	if (!od->ssi.pending) {
-		for (cur1=od->ssi.local; cur1 && (n < 15); cur1=cur1->next) {
-			if (!aim_ssi_itemlist_find(od->ssi.official, cur1->gid, cur1->bid)) {
+		for (cur1=od->ssi.official; cur1 && (n < 15); cur1=cur1->next) {
+			if (!aim_ssi_itemlist_find(od->ssi.local, cur1->gid, cur1->bid)) {
 				n++;
 				new = (struct aim_ssi_tmp *)g_malloc(sizeof(struct aim_ssi_tmp));
-				new->action = SNAC_SUBTYPE_FEEDBAG_ADD;
+				new->action = SNAC_SUBTYPE_FEEDBAG_DEL;
 				new->ack = 0xffff;
 				new->name = NULL;
 				new->item = cur1;
@@ -525,13 +525,13 @@
 		}
 	}
 
-	/* Deletions */
+	/* Additions */
 	if (!od->ssi.pending) {
-		for (cur1=od->ssi.official; cur1 && (n < 15); cur1=cur1->next) {
-			if (!aim_ssi_itemlist_find(od->ssi.local, cur1->gid, cur1->bid)) {
+		for (cur1=od->ssi.local; cur1 && (n < 15); cur1=cur1->next) {
+			if (!aim_ssi_itemlist_find(od->ssi.official, cur1->gid, cur1->bid)) {
 				n++;
 				new = (struct aim_ssi_tmp *)g_malloc(sizeof(struct aim_ssi_tmp));
-				new->action = SNAC_SUBTYPE_FEEDBAG_DEL;
+				new->action = SNAC_SUBTYPE_FEEDBAG_ADD;
 				new->ack = 0xffff;
 				new->name = NULL;
 				new->item = cur1;
--- a/libpurple/protocols/oscar/family_icbm.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Thu Sep 06 06:59:23 2007 +0000
@@ -1461,7 +1461,7 @@
 		msglen = byte_stream_get16(&mbs);
 		if (msglen > byte_stream_empty(&mbs))
 		{
-			purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s.  They are probably trying to do something malicious.", userinfo->sn);
+			purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s.  They are probably trying to do something malicious.\n", userinfo->sn);
 			break;
 		}
 
@@ -2101,7 +2101,11 @@
 	args.uin = byte_stream_getle32(&meat);
 	args.type = byte_stream_getle8(&meat);
 	args.flags = byte_stream_getle8(&meat);
-	args.msglen = byte_stream_getle16(&meat);
+	if (args.type == 0x1a)
+		/* There seems to be a problem with the length in SMS msgs from server, this fixed it */
+		args.msglen = block->length - 6;
+	else
+		args.msglen = byte_stream_getle16(&meat);
 	args.msg = (gchar *)byte_stream_getraw(&meat, args.msglen);
 
 	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
--- a/libpurple/protocols/oscar/family_icq.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/oscar/family_icq.c	Thu Sep 06 06:59:23 2007 +0000
@@ -340,7 +340,6 @@
 }
 #endif
 
-#if 0
 /*
  * Send an SMS message.  This is the non-US way.  The US-way is to IM
  * their cell phone number (+19195551234).
@@ -369,6 +368,7 @@
 	const char *timestr;
 	time_t t;
 	struct tm *tm;
+	gchar *stripped;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
 		return -EINVAL;
@@ -380,22 +380,24 @@
 	tm = gmtime(&t);
 	timestr = purple_utf8_strftime("%a, %d %b %Y %T %Z", tm);
 
+	stripped = purple_markup_strip_html(msg);
+
 	/* The length of xml included the null terminating character */
-	xmllen = 225 + strlen(name) + strlen(msg) + strlen(od->sn) + strlen(alias) + strlen(timestr) + 1;
+	xmllen = 209 + strlen(name) + strlen(stripped) + strlen(od->sn) + strlen(alias) + strlen(timestr) + 1;
 
 	xml = g_new(char, xmllen);
-	snprintf(xml, xmllen, "<icq_sms_message>\n"
-		"\t<destination>%s</destination>\n"
-		"\t<text>%s</text>\n"
-		"\t<codepage>1252</codepage>\n"
-		"\t<senders_UIN>%s</senders_UIN>\n"
-		"\t<senders_name>%s</senders_name>\n"
-		"\t<delivery_receipt>Yes</delivery_receipt>\n"
-		"\t<time>%s</time>\n"
-		"</icq_sms_message>\n",
-		name, msg, od->sn, alias, timestr);
+	snprintf(xml, xmllen, "<icq_sms_message>"
+		"<destination>%s</destination>"
+		"<text>%s</text>"
+		"<codepage>1252</codepage>"
+		"<senders_UIN>%s</senders_UIN>"
+		"<senders_name>%s</senders_name>"
+		"<delivery_receipt>Yes</delivery_receipt>"
+		"<time>%s</time>"
+		"</icq_sms_message>",
+		name, stripped, od->sn, alias, timestr);
 
-	bslen = 37 + xmllen;
+	bslen = 36 + xmllen;
 
 	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
 
@@ -412,7 +414,7 @@
 	byte_stream_putle16(&frame->data, snacid); /* eh. */
 
 	/* From libicq200-0.3.2/src/SNAC-SRV.cpp */
-	byte_stream_putle16(&frame->data, 0x8214);
+	byte_stream_putle16(&frame->data, 0x1482);
 	byte_stream_put16(&frame->data, 0x0001);
 	byte_stream_put16(&frame->data, 0x0016);
 	byte_stream_put32(&frame->data, 0x00000000);
@@ -423,14 +425,15 @@
 	byte_stream_put16(&frame->data, 0x0000);
 	byte_stream_put16(&frame->data, xmllen);
 	byte_stream_putstr(&frame->data, xml);
+	byte_stream_put8(&frame->data, 0x00);
 
 	flap_connection_send(conn, frame);
 
 	g_free(xml);
+	g_free(stripped);
 
 	return 0;
 }
-#endif
 
 static void aim_icq_freeinfo(struct aim_icq_info *info) {
 	int i;
--- a/libpurple/protocols/oscar/oscar.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Thu Sep 06 06:59:23 2007 +0000
@@ -358,7 +358,7 @@
 	const char *charset = NULL;
 	char *ret = NULL;
 
-	if(aim_sn_is_icq(purple_account_get_username(account)))
+	if(aim_snvalid_icq(purple_account_get_username(account)))
 		charset = purple_account_get_string(account, "encoding", NULL);
 
 	if(charset && *charset)
@@ -424,7 +424,7 @@
 		charsetstr1 = "UCS-2BE";
 		charsetstr2 = "UTF-8";
 	} else if (charset == AIM_CHARSET_CUSTOM) {
-		if ((sourcesn != NULL) && aim_sn_is_icq(sourcesn))
+		if ((sourcesn != NULL) && aim_snvalid_icq(sourcesn))
 			charsetstr1 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
 		else
 			charsetstr1 = "ISO-8859-1";
@@ -495,7 +495,7 @@
 	 * capability, and they are online, then attempt to send
 	 * as UCS-2BE.
 	 */
-	if ((destsn != NULL) && aim_sn_is_icq(destsn))
+	if ((destsn != NULL) && aim_snvalid_icq(destsn))
 		userinfo = aim_locate_finduserinfo(od, destsn);
 
 	if ((userinfo != NULL) && (userinfo->capabilities & OSCAR_CAPABILITY_UNICODE))
@@ -520,7 +520,7 @@
 	 * ICQ then attempt to send as the user specified character encoding.
 	 */
 	charsetstr = "ISO-8859-1";
-	if ((destsn != NULL) && aim_sn_is_icq(destsn))
+	if ((destsn != NULL) && aim_snvalid_icq(destsn))
 		charsetstr = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
 
 	/*
@@ -815,7 +815,7 @@
 
 	if (b != NULL) {
 		if (purple_presence_is_online(presence)) {
-			if (aim_sn_is_icq(b->name)) {
+			if (aim_snvalid_icq(b->name)) {
 				PurpleStatus *status = purple_presence_get_active_status(presence);
 				oscar_user_info_add_pair(user_info, _("Status"),	purple_status_get_name(status));
 			}
@@ -1019,7 +1019,7 @@
 			PURPLE_INPUT_READ, flap_connection_recv_cb, conn);
 	if (conn->cookie == NULL)
 	{
-		if (!aim_sn_is_icq(purple_account_get_username(account)))
+		if (!aim_snvalid_icq(purple_account_get_username(account)))
 			/*
 			 * We don't send this when authenticating an ICQ account
 			 * because for some reason ICQ is still using the
@@ -1261,7 +1261,7 @@
 		g_free(buf);
 	}
 
-	if (aim_sn_is_icq((purple_account_get_username(account)))) {
+	if (aim_snvalid_icq((purple_account_get_username(account)))) {
 		od->icq = TRUE;
 	} else {
 		gc->flags |= PURPLE_CONNECTION_HTML;
@@ -1752,7 +1752,7 @@
 		}
 	}
 
-	if (aim_sn_is_icq(info->sn)) {
+	if (aim_snvalid_icq(info->sn)) {
 		if (type & AIM_ICQ_STATE_CHAT)
 			status_id = OSCAR_STATUS_ID_FREE4CHAT;
 		else if (type & AIM_ICQ_STATE_DND)
@@ -1987,7 +1987,7 @@
 	 * Note: There *may* be some clients which send messages as HTML formatted -
 	 *       they need to be special-cased somehow.
 	 */
-	if (aim_sn_is_icq(purple_account_get_username(account)) && aim_sn_is_icq(userinfo->sn)) {
+	if (aim_snvalid_icq(purple_account_get_username(account)) && aim_snvalid_icq(userinfo->sn)) {
 		/* being recevied by ICQ from ICQ - escape HTML so it is displayed as sent */
 		gchar *tmp2 = g_markup_escape_text(tmp, -1);
 		g_free(tmp);
@@ -2486,8 +2486,48 @@
 			}
 		} break;
 
-		case 0x1a: { /* Someone has sent you a greeting card or requested buddies? */
-			/* This is boring and silly. */
+		case 0x1a: { /* Handle SMS or someone has sent you a greeting card or requested buddies? */
+			ByteStream qbs;
+			int smstype, taglen, smslen;
+			char *tagstr = NULL, *smsmsg = NULL;
+			xmlnode *xmlroot = NULL, *xmltmp = NULL;
+			gchar *uin = NULL, *message = NULL;
+
+			/* From libicq2000-0.3.2/src/ICQ.cpp */
+			byte_stream_init(&qbs, (guint8 *)args->msg, args->msglen);
+			byte_stream_advance(&qbs, 21);
+			smstype = byte_stream_getle16(&qbs);
+			taglen = byte_stream_getle32(&qbs);
+			tagstr = byte_stream_getstr(&qbs, taglen);
+			byte_stream_advance(&qbs, 3);
+			byte_stream_advance(&qbs, 4);
+			smslen = byte_stream_getle32(&qbs);
+			smsmsg = byte_stream_getstr(&qbs, smslen);
+
+			/* Check if this is an SMS being sent from server */
+			if ((smstype == 0) && (!strcmp(tagstr, "ICQSMS")) && (smsmsg != NULL))
+			{
+				xmlroot = xmlnode_from_str(smsmsg, -1);
+				if (xmlroot != NULL)
+				{
+					xmltmp = xmlnode_get_child(xmlroot, "sender");
+					if (xmltmp != NULL)
+						uin = xmlnode_get_data(xmltmp);
+
+					xmltmp = xmlnode_get_child(xmlroot, "text");
+					if (xmltmp != NULL)
+						message = xmlnode_get_data(xmltmp);
+
+					if ((uin != NULL) && (message != NULL))
+							serv_got_im(gc, uin, message, 0, time(NULL));
+
+					g_free(uin);
+					g_free(message);
+					xmlnode_free(xmlroot);
+				}
+			}
+			g_free(tagstr);
+			g_free(smsmsg);
 		} break;
 
 		default: {
@@ -2963,7 +3003,7 @@
 	if (b == NULL)
 		return 1;
 
-	if (!aim_sn_is_icq(userinfo->sn))
+	if (!aim_snvalid_icq(userinfo->sn))
 	{
 		if (strcmp(purple_buddy_get_name(b), userinfo->sn))
 			serv_got_alias(gc, purple_buddy_get_name(b), userinfo->sn);
@@ -3574,7 +3614,7 @@
 	g_free(tmp);
 
 	presence = purple_status_get_presence(status);
-	aim_srv_setidle(od, purple_presence_is_idle(presence) ? 0 : time(NULL) - purple_presence_get_idle_time(presence));
+	aim_srv_setidle(od, !purple_presence_is_idle(presence) ? 0 : time(NULL) - purple_presence_get_idle_time(presence));
 
 	if (od->icq) {
 		aim_icq_reqofflinemsgs(od);
@@ -4154,6 +4194,17 @@
 	account = purple_connection_get_account(gc);
 	ret = 0;
 
+	if (od->icq && aim_snvalid_sms(name)) {
+		/*
+		 * We're sending to a phone number and this is ICQ,
+		 * so send the message as an SMS using aim_icq_sendsms()
+		 */
+		int ret;
+		purple_debug_info("oscar", "Sending SMS to %s.\n", name);
+		ret = aim_icq_sendsms(od, name, message, purple_account_get_username(account));
+		return (ret >= 0 ? 1 : ret);
+	}
+
 	if (imflags & PURPLE_MESSAGE_AUTO_RESP)
 		tmp1 = purple_str_sub_away_formatters(message, name);
 	else
@@ -4254,12 +4305,12 @@
 		/*
 		 * If we're IMing an SMS user or an ICQ user from an ICQ account, then strip HTML.
 		 */
-		if (aim_sn_is_sms(name)) {
+		if (aim_snvalid_sms(name)) {
 			/* Messaging an SMS (mobile) user */
 			tmp2 = purple_markup_strip_html(tmp1);
 			is_html = FALSE;
-		} else if (aim_sn_is_icq(purple_account_get_username(account))) {
-			if (aim_sn_is_icq(name)) {
+		} else if (aim_snvalid_icq(purple_account_get_username(account))) {
+			if (aim_snvalid_icq(name)) {
 				/* From ICQ to ICQ */
 				tmp2 = purple_markup_strip_html(tmp1);
 				is_html = FALSE;
@@ -4295,7 +4346,7 @@
 
 			purple_plugin_oscar_convert_to_best_encoding(gc, name, tmp1, (char **)&args.msg, &args.msglen, &args.charset, &args.charsubset);
 
-			purple_debug_info("oscar", "Sending %s as %s because the original was too long.",
+			purple_debug_info("oscar", "Sending %s as %s because the original was too long.\n",
 								  message, (char *)args.msg);
 		}
 
@@ -4321,7 +4372,7 @@
 void oscar_get_info(PurpleConnection *gc, const char *name) {
 	OscarData *od = (OscarData *)gc->proto_data;
 
-	if (od->icq && aim_sn_is_icq(name))
+	if (od->icq && aim_snvalid_icq(name))
 		aim_icq_getallinfo(od, name);
 	else
 		aim_locate_getinfoshort(od, name, 0x00000003);
@@ -4566,7 +4617,7 @@
 	oscar_set_info_and_status(account, FALSE, NULL, TRUE, status);
 
 	/* Set the ICQ status for ICQ accounts only */
-	if (aim_sn_is_icq(purple_account_get_username(account)))
+	if (aim_snvalid_icq(purple_account_get_username(account)))
 		oscar_set_status_icq(account, status);
 }
 
@@ -4776,7 +4827,7 @@
 			   "ssi: syncing local list and server list\n");
 
 	if ((timestamp == 0) || (numitems == 0)) {
-		purple_debug_info("oscar", "Got AIM SSI with a 0 timestamp or 0 numitems--not syncing.  This probably means your buddy list is empty.", NULL);
+		purple_debug_info("oscar", "Got AIM SSI with a 0 timestamp or 0 numitems--not syncing.  This probably means your buddy list is empty.\n");
 		return 1;
 	}
 
@@ -5379,14 +5430,14 @@
 		purple_plugin_oscar_convert_to_best_encoding(gc, NULL, buf, &buf2, &len, &charset, &charsubset);
 
 		if ((len > c->maxlen) || (len > c->maxvis)) {
-			purple_debug_warning("oscar", "Could not send %s because (%i > maxlen %i) or (%i > maxvis %i)",
+			purple_debug_warning("oscar", "Could not send %s because (%i > maxlen %i) or (%i > maxvis %i)\n",
 					buf2, len, c->maxlen, len, c->maxvis);
 			g_free(buf);
 			g_free(buf2);
 			return -E2BIG;
 		}
 
-		purple_debug_info("oscar", "Sending %s as %s because the original was too long.",
+		purple_debug_info("oscar", "Sending %s as %s because the original was too long.\n",
 				message, buf2);
 	}
 
@@ -5405,30 +5456,30 @@
 
 const char *oscar_list_icon_icq(PurpleAccount *a, PurpleBuddy *b)
 {
-	if ((b == NULL) || (b->name == NULL) || aim_sn_is_sms(b->name))
+	if ((b == NULL) || (b->name == NULL) || aim_snvalid_sms(b->name))
 	{
-		if (a == NULL || aim_sn_is_icq(purple_account_get_username(a)))
+		if (a == NULL || aim_snvalid_icq(purple_account_get_username(a)))
 			return "icq";
 		else
 			return "aim";
 	}
 
-	if (aim_sn_is_icq(b->name))
+	if (aim_snvalid_icq(b->name))
 		return "icq";
 	return "aim";
 }
 
 const char *oscar_list_icon_aim(PurpleAccount *a, PurpleBuddy *b)
 {
-	if ((b == NULL) || (b->name == NULL) || aim_sn_is_sms(b->name))
+	if ((b == NULL) || (b->name == NULL) || aim_snvalid_sms(b->name))
 	{
-		if (a != NULL && aim_sn_is_icq(purple_account_get_username(a)))
+		if (a != NULL && aim_snvalid_icq(purple_account_get_username(a)))
 			return "icq";
 		else
 			return "aim";
 	}
 
-	if (aim_sn_is_icq(b->name))
+	if (aim_snvalid_icq(b->name))
 		return "icq";
 	return "aim";
 }
@@ -5712,7 +5763,7 @@
 	g_return_val_if_fail(account != NULL, NULL);
 
 	/* Used to flag some statuses as "user settable" or not */
-	is_icq = aim_sn_is_icq(purple_account_get_username(account));
+	is_icq = aim_snvalid_icq(purple_account_get_username(account));
 
 	/* Common status types */
 	/* Really the available message should only be settable for AIM accounts */
@@ -5920,7 +5971,7 @@
 	userinfo = aim_locate_finduserinfo(od, buddy->name);
 	menu = NULL;
 
-	if (od->icq && aim_sn_is_icq(purple_buddy_get_name(buddy)))
+	if (od->icq && aim_snvalid_icq(purple_buddy_get_name(buddy)))
 	{
 		act = purple_menu_action_new(_("Get AIM Info"),
 								   PURPLE_CALLBACK(oscar_get_aim_info_cb),
@@ -6515,7 +6566,7 @@
 			od = (OscarData *)gc->proto_data;
 	}
 
-	return (od != NULL && od->icq && aim_sn_is_icq(purple_account_get_username(account)));
+	return (od != NULL && od->icq && aim_snvalid_icq(purple_account_get_username(account)));
 }
 
 /* TODO: Find somewhere to put this instead of including it in a bunch of places.
--- a/libpurple/protocols/oscar/oscar.h	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Thu Sep 06 06:59:23 2007 +0000
@@ -1320,6 +1320,7 @@
 int aim_icq_getsimpleinfo(OscarData *od, const char *uin);
 int aim_icq_getalias(OscarData *od, const char *uin);
 int aim_icq_getallinfo(OscarData *od, const char *uin);
+int aim_icq_sendsms(OscarData *od, const char *name, const char *msg, const char *alias);
 
 
 
@@ -1458,8 +1459,8 @@
 char *aimutil_itemindex(char *toSearch, int theindex, char dl);
 
 gboolean aim_snvalid(const char *sn);
-gboolean aim_sn_is_icq(const char *sn);
-gboolean aim_sn_is_sms(const char *sn);
+gboolean aim_snvalid_icq(const char *sn);
+gboolean aim_snvalid_sms(const char *sn);
 int aim_snlen(const char *sn);
 int aim_sncmp(const char *sn1, const char *sn2);
 
--- a/libpurple/protocols/oscar/oscarcommon.h	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/oscar/oscarcommon.h	Thu Sep 06 06:59:23 2007 +0000
@@ -30,7 +30,7 @@
 #include "version.h"
 #include "notify.h"
 
-#define OSCAR_DEFAULT_LOGIN_SERVER "login.oscar.aol.com"
+#define OSCAR_DEFAULT_LOGIN_SERVER "login.messaging.aol.com"
 #define OSCAR_DEFAULT_LOGIN_PORT 5190
 #ifndef _WIN32
 #define OSCAR_DEFAULT_CUSTOM_ENCODING "ISO-8859-1"
--- a/libpurple/protocols/oscar/util.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/oscar/util.c	Thu Sep 06 06:59:23 2007 +0000
@@ -171,7 +171,7 @@
  *
  * @return TRUE if the screen name is valid, FALSE if not.
  */
-static gboolean
+gboolean
 aim_snvalid_icq(const char *sn)
 {
 	int i;
@@ -190,7 +190,7 @@
  *
  * @return TRUE if the screen name is valid, FALSE if not.
  */
-static gboolean
+gboolean
 aim_snvalid_sms(const char *sn)
 {
 	int i;
@@ -221,34 +221,6 @@
 }
 
 /**
- * Determine if a given screen name is an ICQ screen name
- * (i.e. it is composed of only numbers).
- *
- * @param sn A valid AIM or ICQ screen name.
- * @return TRUE if the screen name is an ICQ screen name.  Otherwise
- *         FALSE is returned.
- */
-gboolean
-aim_sn_is_icq(const char *sn)
-{
-	return aim_snvalid_icq(sn);
-}
-
-/**
- * Determine if a given screen name is an SMS number
- * (i.e. it begins with a +).
- *
- * @param sn A valid AIM or ICQ screen name.
- * @return TRUE if the screen name is an SMS number.  Otherwise
- *         FALSE is returned.
- */
-gboolean
-aim_sn_is_sms(const char *sn)
-{
-	return (sn[0] == '+');
-}
-
-/**
  * This takes two screen names and compares them using the rules
  * on screen names for AIM/AOL.  Mainly, this means case and space
  * insensitivity (all case differences and spacing differences are
--- a/libpurple/protocols/qq/header_info.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/qq/header_info.c	Thu Sep 06 06:59:23 2007 +0000
@@ -35,6 +35,7 @@
 #define QQ_CLIENT_0B35 0x0b35	/* GB QQ2003iii build 0304 (offical release) */
 #define QQ_CLIENT_0B37 0x0b37	/* GB QQ2003iii build 0304 (April 05 updates) */
 #define QQ_CLIENT_0E1B 0x0e1b	/* QQ2005? QQ2006? */
+#define QQ_CLIENT_0E35 0x0e35	/* EN QQ2005 V05.0.200.020 */
 #define QQ_CLIENT_0F15 0x0f15	/* QQ2006 Spring Festival build */
 #define QQ_CLIENT_0F5F 0x0f5f	/* QQ2006 final build */
 
@@ -115,6 +116,8 @@
 		return "GB QQ2003iii build 0304 (April 5 update)";
 	case QQ_CLIENT_0E1B:
 		return "QQ2005 or QQ2006";
+	case QQ_CLIENT_0E35:
+		return "En QQ2005 V05.0.200.020";
 	case QQ_CLIENT_0F15:
 		return "QQ2006 Spring Festival build";
 	case QQ_CLIENT_0F5F:
--- a/libpurple/protocols/qq/login_logout.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/qq/login_logout.c	Thu Sep 06 06:59:23 2007 +0000
@@ -380,33 +380,33 @@
 
 void qq_process_request_login_token_reply(guint8 *buf, gint buf_len, PurpleConnection *gc)
 {
-        qq_data *qd;
+	qq_data *qd;
 	gchar *hex_dump;
 
-        g_return_if_fail(buf != NULL && buf_len != 0);
+	g_return_if_fail(buf != NULL && buf_len != 0);
 
-        qd = (qq_data *) gc->proto_data;
+	qd = (qq_data *) gc->proto_data;
 
 	if (buf[0] == QQ_REQUEST_LOGIN_TOKEN_REPLY_OK) {
 		if (buf[1] != buf_len-2) {
-			purple_debug(PURPLE_DEBUG_INFO, "QQ", 
+			purple_debug(PURPLE_DEBUG_INFO, "QQ",
 					"Malformed login token reply packet. Packet specifies length of %d, actual length is %d\n", buf[1], buf_len-2);
 			purple_debug(PURPLE_DEBUG_INFO, "QQ",
 					"Attempting to proceed with the actual packet length.\n");
 		}
 		hex_dump = hex_dump_to_str(buf+2, buf_len-2);
 		purple_debug(PURPLE_DEBUG_INFO, "QQ",
-                                   "<<< got a token with %d bytes -> [default] decrypt and dump\n%s", buf_len-2, hex_dump);
+				"<<< got a token with %d bytes -> [default] decrypt and dump\n%s", buf_len-2, hex_dump);
 		qq_send_packet_login(gc, buf_len-2, buf+2);
 	} else {
 		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown request login token reply code : %d\n", buf[0]);
 		hex_dump = hex_dump_to_str(buf, buf_len);
-                purple_debug(PURPLE_DEBUG_WARNING, "QQ",
-           		           ">>> %d bytes -> [default] decrypt and dump\n%s",
-	                           buf_len, hex_dump);
-               		try_dump_as_gbk(buf, buf_len);
+		purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+				">>> %d bytes -> [default] decrypt and dump\n%s",
+				buf_len, hex_dump);
+		try_dump_as_gbk(buf, buf_len);
 		purple_connection_error(gc, _("Error requesting login token"));
-	}		
+	}
 	g_free(hex_dump);
 }
 
@@ -463,11 +463,11 @@
 			default:
 				purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown reply code: %d\n", data[0]);
 				hex_dump = hex_dump_to_str(data, len);
-		                purple_debug(PURPLE_DEBUG_WARNING, "QQ",
-                		           ">>> %d bytes -> [default] decrypt and dump\n%s",
-		                           buf_len, hex_dump);
+				purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+						">>> %d bytes -> [default] decrypt and dump\n%s",
+						buf_len, hex_dump);
 				g_free(hex_dump);
-                		try_dump_as_gbk(data, len);
+				try_dump_as_gbk(data, len);
 
 				ret = QQ_LOGIN_REPLY_MISC_ERROR;
 			}
--- a/libpurple/protocols/silc/ops.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/silc/ops.c	Thu Sep 06 06:59:23 2007 +0000
@@ -868,7 +868,7 @@
 				/* Find buddy by nickname */
 				b = purple_find_buddy(sg->account, client_entry->nickname);
 				if (!b) {
-					purple_debug_warning("silc", "WATCH for %s, unknown buddy",
+					purple_debug_warning("silc", "WATCH for %s, unknown buddy\n",
 						client_entry->nickname);
 					break;
 				}
--- a/libpurple/protocols/silc10/ops.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/silc10/ops.c	Thu Sep 06 06:59:23 2007 +0000
@@ -902,7 +902,7 @@
 				/* Find buddy by nickname */
 				b = purple_find_buddy(sg->account, client_entry->nickname);
 				if (!b) {
-					purple_debug_warning("silc", "WATCH for %s, unknown buddy",
+					purple_debug_warning("silc", "WATCH for %s, unknown buddy\n",
 						client_entry->nickname);
 					break;
 				}
--- a/libpurple/protocols/simple/simple.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/simple/simple.c	Thu Sep 06 06:59:23 2007 +0000
@@ -1001,7 +1001,7 @@
 		found = TRUE;
 	}
 	if(!found) {
-		purple_debug_info("simple", "got unknown mime-type");
+		purple_debug_info("simple", "got unknown mime-type\n");
 		send_sip_response(sip->gc, msg, 415, "Unsupported media type", NULL);
 	}
 	g_free(from);
--- a/libpurple/protocols/yahoo/yahoo.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Thu Sep 06 06:59:23 2007 +0000
@@ -3446,7 +3446,7 @@
 
 	if (!set_cookie) {
 		struct yahoo_data *yd = gc->proto_data;
-		purple_debug_error("yahoo", "No mail login token; forwarding to login screen.");
+		purple_debug_error("yahoo", "No mail login token; forwarding to login screen.\n");
 		url = g_strdup(yd->jp ? YAHOOJP_MAIL_URL : YAHOO_MAIL_URL);
 	}
 
--- a/libpurple/protocols/yahoo/yahoo_packet.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo_packet.c	Thu Sep 06 06:59:23 2007 +0000
@@ -365,7 +365,7 @@
 	if (ret < 0 && errno == EAGAIN)
 		ret = 0;
 	else if (ret <= 0) {
-		purple_debug_warning("yahoo", "Only wrote %d of %d bytes!", ret, len);
+		purple_debug_warning("yahoo", "Only wrote %d of %d bytes!\n", ret, len);
 		g_free(data);
 		return ret;
 	}
--- a/libpurple/protocols/zephyr/zephyr.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/protocols/zephyr/zephyr.c	Thu Sep 06 06:59:23 2007 +0000
@@ -1117,7 +1117,7 @@
 		bufcur++;
 		if ((bufcur - buf) > (bufsize - 1)) {
 			if ((buf = realloc(buf, bufsize * 2)) == NULL) {
-				purple_debug_error("zephyr","Ran out of memory");
+				purple_debug_error("zephyr","Ran out of memory\n");
 				exit(-1);
 			} else {
 				bufcur = buf + bufsize;
@@ -2218,12 +2218,12 @@
 		notice.z_message_len = strlen(html_buf2) + strlen(sig) + 2;
 		notice.z_message = buf;
 		notice.z_opcode = g_strdup(opcode);
-		purple_debug_info("zephyr","About to send notice");
+		purple_debug_info("zephyr","About to send notice\n");
 		if (! ZSendNotice(&notice, ZAUTH) == ZERR_NONE) {
 			/* XXX handle errors here */
 			return 0;
 		}
-		purple_debug_info("zephyr","notice sent");
+		purple_debug_info("zephyr","notice sent\n");
 		g_free(buf);
 	}
 
@@ -2815,19 +2815,19 @@
 		title = g_strdup_printf("Server subscriptions for %s", zephyr->username);
 		
 		if (zephyr->port == 0) {
-			purple_debug_error("zephyr", "error while retrieving port");
+			purple_debug_error("zephyr", "error while retrieving port\n");
 			return;
 		} 
 		if ((retval = ZRetrieveSubscriptions(zephyr->port,&nsubs)) != ZERR_NONE) {
 			/* XXX better error handling */
-			purple_debug_error("zephyr", "error while retrieving subscriptions from server");
+			purple_debug_error("zephyr", "error while retrieving subscriptions from server\n");
 			return;
 		}
 		for(i=0;i<nsubs;i++) {
 			one = 1;
 			if ((retval = ZGetSubscriptions(&subs,&one)) != ZERR_NONE) {
 				/* XXX better error handling */
-				purple_debug_error("zephyr", "error while retrieving individual subscription");
+				purple_debug_error("zephyr", "error while retrieving individual subscription\n");
 				return;
 			}
 			g_string_append_printf(subout, "Class %s Instance %s Recipient %s<br>",
--- a/libpurple/proxy.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/proxy.c	Thu Sep 06 06:59:23 2007 +0000
@@ -420,7 +420,7 @@
 	if (ret == 0 && error == EINPROGRESS) {
 		/* No worries - we'll be called again later */
 		/* TODO: Does this ever happen? */
-		purple_debug_info("proxy", "(ret == 0 && error == EINPROGRESS)");
+		purple_debug_info("proxy", "(ret == 0 && error == EINPROGRESS)\n");
 		return;
 	}
 
--- a/libpurple/stun.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/stun.c	Thu Sep 06 06:59:23 2007 +0000
@@ -252,7 +252,7 @@
 				sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
 				if(sinptr->sin_addr.s_addr == in.s_addr) {
 					/* no NAT */
-					purple_debug_info("stun", "no nat");
+					purple_debug_info("stun", "no nat\n");
 					nattype.type = PURPLE_STUN_NAT_TYPE_PUBLIC_IP;
 				}
 			}
--- a/libpurple/util.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/util.c	Thu Sep 06 06:59:23 2007 +0000
@@ -673,7 +673,7 @@
 	locale = g_locale_from_utf8(format, -1, NULL, NULL, &err);
 	if (err != NULL)
 	{
-		purple_debug_error("util", "Format conversion failed in purple_utf8_strftime(): %s", err->message);
+		purple_debug_error("util", "Format conversion failed in purple_utf8_strftime(): %s\n", err->message);
 		g_error_free(err);
 		locale = g_strdup(format);
 	}
@@ -693,7 +693,7 @@
 	utf8 = g_locale_to_utf8(buf, len, NULL, NULL, &err);
 	if (err != NULL)
 	{
-		purple_debug_error("util", "Result conversion failed in purple_utf8_strftime(): %s", err->message);
+		purple_debug_error("util", "Result conversion failed in purple_utf8_strftime(): %s\n", err->message);
 		g_error_free(err);
 	}
 	else
@@ -4460,10 +4460,11 @@
 const char *_purple_oscar_convert(const char *act, const char *protocol)
 {
 	if (protocol && act && strcmp(protocol, "prpl-oscar") == 0) {
-		if (isdigit(*act))
-			protocol = "prpl-icq";
-		else
-			protocol = "prpl-aim";
+		int i;
+		for (i = 0; act[i] != '\0'; i++)
+			if (!isdigit(act[i]))
+				return "prpl-aim";
+		return "prpl-icq";
 	}
 	return protocol;
 }
--- a/libpurple/xmlnode.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/libpurple/xmlnode.c	Thu Sep 06 06:59:23 2007 +0000
@@ -549,7 +549,16 @@
 xmlnode_parser_error_libxml(void *user_data, const char *msg, ...)
 {
 	struct _xmlnode_parser_data *xpd = user_data;
+	char errmsg[2048];
+	va_list args;
+
 	xpd->error = TRUE;
+
+	va_start(args, msg);
+	vsnprintf(errmsg, sizeof(errmsg), msg, args);
+	va_end(args);
+
+	purple_debug_error("xmlnode", "Error parsing xml file: %s\n", errmsg);
 }
 
 static xmlSAXHandler xmlnode_parser_libxml = {
--- a/pidgin/gtkaccount.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/gtkaccount.c	Thu Sep 06 06:59:23 2007 +0000
@@ -652,8 +652,10 @@
 		if (!(dialog->prpl_info->options & OPT_PROTO_MAIL_CHECK))
 			gtk_widget_hide(dialog->new_mail_check);
 
-		if (dialog->prpl_info->icon_spec.format == NULL)
+		if (dialog->prpl_info->icon_spec.format == NULL) {
+			gtk_widget_hide(dialog->icon_check);
 			gtk_widget_hide(dialog->icon_hbox);
+		}
 	}
 
 	if (dialog->account != NULL) {
--- a/pidgin/gtkblist.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/gtkblist.c	Thu Sep 06 06:59:23 2007 +0000
@@ -2870,11 +2870,11 @@
 	{ N_("/Buddies/View User _Log..."), "<CTL>L", pidgin_dialogs_log, 0, "<Item>", NULL },
 	{ "/Buddies/sep1", NULL, NULL, 0, "<Separator>", NULL },
 	{ N_("/Buddies/Show"), NULL, NULL, 0, "<Branch>", NULL},
-	{ N_("/Buddies/Show/Show _Offline Buddies"), NULL, pidgin_blist_edit_mode_cb, 1, "<CheckItem>", NULL },
-	{ N_("/Buddies/Show/Show _Empty Groups"), NULL, pidgin_blist_show_empty_groups_cb, 1, "<CheckItem>", NULL },
-	{ N_("/Buddies/Show/Show Buddy _Details"), NULL, pidgin_blist_buddy_details_cb, 1, "<CheckItem>", NULL },
-	{ N_("/Buddies/Show/Show Idle _Times"), NULL, pidgin_blist_show_idle_time_cb, 1, "<CheckItem>", NULL },
-	{ N_("/Buddies/Show/Show _Protocol Icons"), NULL, pidgin_blist_show_protocol_icons_cb, 1, "<CheckItem>", NULL },
+	{ N_("/Buddies/Show/_Offline Buddies"), NULL, pidgin_blist_edit_mode_cb, 1, "<CheckItem>", NULL },
+	{ N_("/Buddies/Show/_Empty Groups"), NULL, pidgin_blist_show_empty_groups_cb, 1, "<CheckItem>", NULL },
+	{ N_("/Buddies/Show/Buddy _Details"), NULL, pidgin_blist_buddy_details_cb, 1, "<CheckItem>", NULL },
+	{ N_("/Buddies/Show/Idle _Times"), NULL, pidgin_blist_show_idle_time_cb, 1, "<CheckItem>", NULL },
+	{ N_("/Buddies/Show/_Protocol Icons"), NULL, pidgin_blist_show_protocol_icons_cb, 1, "<CheckItem>", NULL },
 	{ N_("/Buddies/_Sort Buddies"), NULL, NULL, 0, "<Branch>", NULL },
 	{ "/Buddies/sep2", NULL, NULL, 0, "<Separator>", NULL },
 	{ N_("/Buddies/_Add Buddy..."), "<CTL>B", pidgin_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD },
@@ -3101,7 +3101,8 @@
 			purple_notify_user_info_add_pair(user_info, _("Status"), _("Offline"));
 		}
 
-		if (prpl_info && prpl_info->tooltip_text)
+		if (purple_account_is_connected(b->account) &&
+				prpl_info && prpl_info->tooltip_text)
 		{
 			/* Additional text from the PRPL */
 			prpl_info->tooltip_text(b, user_info, full);
@@ -4590,22 +4591,22 @@
 	/* set the Show Offline Buddies option. must be done
 	 * after the treeview or faceprint gets mad. -Robot101
 	 */
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Show Offline Buddies"))),
+	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Offline Buddies"))),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies"));
 
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Show Empty Groups"))),
+	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Empty Groups"))),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_empty_groups"));
 
 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds"))),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/sound/mute"));
 
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Show Buddy Details"))),
+	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Buddy Details"))),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"));
 
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Show Idle Times"))),
+	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Idle Times"))),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time"));
 
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Show Protocol Icons"))),
+	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Protocol Icons"))),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"));
 
 	if(!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"))
--- a/pidgin/gtkcertmgr.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/gtkcertmgr.c	Thu Sep 06 06:59:23 2007 +0000
@@ -454,6 +454,9 @@
 			"text", TPM_HOSTNAME_COLUMN,
 			NULL);
 		gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);
+
+		gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store),
+				TPM_HOSTNAME_COLUMN, GTK_SORT_ASCENDING);
 	}
 	
 	/* Get the treeview selector into the struct */
--- a/pidgin/gtkconv.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/gtkconv.c	Thu Sep 06 06:59:23 2007 +0000
@@ -158,7 +158,6 @@
 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win);
 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv);
 static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv);
-static gboolean alias_double_click_cb(GtkWidget *widget, GdkEventButton *event, PidginConversation *gtkconv);
 static gboolean pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv);
 static void pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv);
 
@@ -2561,7 +2560,6 @@
 	gtkconv->u.im->show_icon = FALSE;
 
 	gtkwin = gtkconv->win;
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkwin->menu.show_icon), FALSE);
 }
 
 static void
@@ -2722,31 +2720,6 @@
 	return TRUE;
 }
 
-static void
-menu_buddyicon_cb(gpointer data, guint action, GtkWidget *widget)
-{
-	PidginWindow *win = data;
-	PurpleConversation *conv;
-	PidginConversation *gtkconv;
-	gboolean active;
-
-	conv = pidgin_conv_window_get_active_conversation(win);
-
-	if (!conv)
-		return;
-
-	g_return_if_fail(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM);
-
-	gtkconv = PIDGIN_CONVERSATION(conv);
-
-	active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
-	gtkconv->u.im->show_icon = active;
-	if (active)
-		pidgin_conv_update_buddy_icon(conv);
-	else
-		remove_icon(NULL, gtkconv);
-}
-
 /**************************************************************************
  * End of the bunch of buddy icon functions
  **************************************************************************/
@@ -2813,6 +2786,18 @@
 	pidgin_conv_present_conversation(conv);
 }
 
+static void
+unseen_all_conv_menu_cb(GtkMenuItem *item, GList *list)
+{
+	g_return_if_fail(list != NULL);
+	/* Do not free the list from here. It will be freed from the
+	 * 'destroy' callback on the menuitem. */
+	while (list) {
+		pidgin_conv_present_conversation(list->data);
+		list = list->next;
+	}
+}
+
 guint
 pidgin_conversations_fill_menu(GtkWidget *menu, GList *convs)
 {
@@ -2844,6 +2829,19 @@
 		ret++;
 	}
 
+	if (convs->next) {
+		/* There are more than one conversation. Add an option to show all conversations. */
+		GtkWidget *item;
+		GList *list = g_list_copy(convs);
+
+		pidgin_separator(menu);
+
+		item = gtk_menu_item_new_with_label(_("Show All"));
+		g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(unseen_all_conv_menu_cb), list);
+		g_signal_connect_swapped(G_OBJECT(item), "destroy", G_CALLBACK(g_list_free), list);
+		gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+	}
+
 	return ret;
 }
 
@@ -2906,7 +2904,7 @@
 
 
 	{ N_("/Conversation/_Hide"), NULL, menu_hide_conv_cb, 0,
-			"<StockItem>", NULL},
+			"<Item>", NULL},
 	{ N_("/Conversation/_Close"), NULL, menu_close_conv_cb, 0,
 			"<StockItem>", GTK_STOCK_CLOSE },
 
@@ -2914,7 +2912,6 @@
 	{ N_("/_Options"), NULL, NULL, 0, "<Branch>", NULL },
 	{ N_("/Options/Enable _Logging"), NULL, menu_logging_cb, 0, "<CheckItem>", NULL },
 	{ N_("/Options/Enable _Sounds"), NULL, menu_sounds_cb, 0, "<CheckItem>", NULL },
-	{ N_("/Options/Show Buddy _Icon"), NULL, menu_buddyicon_cb, 0, "<CheckItem>", NULL },
 	{ "/Options/sep0", NULL, NULL, 0, "<Separator>", NULL },
 	{ N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL },
 	{ N_("/Options/Show Ti_mestamps"), "F2", menu_timestamps_cb, 0, "<CheckItem>", NULL },
@@ -2954,31 +2951,6 @@
 	}
 }
 
-static void
-show_buddy_icons_pref_changed_cb(const char *name, PurplePrefType type,
-								 gconstpointer value, gpointer data)
-{
-	PidginWindow *win = data;
-	gboolean show_icons = GPOINTER_TO_INT(value);
-
-	if (!show_icons)
-	{
-		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_icon),
-		                               FALSE);
-		gtk_widget_set_sensitive(win->menu.show_icon, FALSE);
-	}
-	else
-	{
-		PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win);
-
-		if (gtkconv != NULL)
-			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_icon),
-			                               TRUE);
-		gtk_widget_set_sensitive(win->menu.show_icon, TRUE);
-
-	}
-}
-
 /* Returns TRUE if some items were added to the menu, FALSE otherwise */
 static gboolean
 populate_menu_with_options(GtkWidget *menu, PidginConversation *gtkconv, gboolean all)
@@ -3037,8 +3009,12 @@
 		node = (PurpleBlistNode *)buddy;
 
 	/* Now add the stuff */
-	if (all && buddy) {
-		pidgin_blist_make_buddy_menu(menu, buddy, TRUE);
+	if (all) {
+		if (buddy)
+			pidgin_blist_make_buddy_menu(menu, buddy, TRUE);
+		else if (chat) {
+			/* XXX: */
+		}
 	} else if (node) {
 		if (purple_account_is_connected(conv->account))
 			pidgin_append_blist_node_proto_menu(menu, conv->account->gc, node);
@@ -3271,17 +3247,7 @@
 	win->menu.show_timestamps =
 		gtk_item_factory_get_widget(win->menu.item_factory,
 		                            N_("/Options/Show Timestamps"));
-	win->menu.show_icon =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Options/Show Buddy Icon"));
-	if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons"))
-	{
-		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_icon),
-		                               FALSE);
-		gtk_widget_set_sensitive(win->menu.show_icon, FALSE);
-	}
-	purple_prefs_connect_callback(win, PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons",
-				    show_buddy_icons_pref_changed_cb, win);
+	win->menu.show_icon = NULL;
 
 	win->menu.tray = pidgin_menu_tray_new();
 	gtk_menu_shell_append(GTK_MENU_SHELL(win->menu.menubar),
@@ -4531,12 +4497,12 @@
 pidgin_conv_motion_cb (GtkWidget *infopane, GdkEventMotion *event, PidginConversation *gtkconv)
 {
 	int delay = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay");
-	
+
 	pidgin_blist_tooltip_destroy();
 	if (delay == 0)
 		return FALSE;
 
-	if (tooltip.timeout != 0) 
+	if (tooltip.timeout != 0)
 		g_source_remove(tooltip.timeout);
 
 	tooltip.timeout = g_timeout_add(delay, (GSourceFunc)pidgin_conv_tooltip_timeout, gtkconv);
@@ -4550,7 +4516,6 @@
 	PurplePluginProtocolInfo *prpl_info;
 	PurpleConversation *conv = gtkconv->active_conv;
 	PidginChatPane *gtkchat;
-	PurpleConnection *gc;
 	PurpleBlistNode *node = NULL;
 	PurpleAccount *account;
 	GtkTreePath *path;
@@ -4562,8 +4527,11 @@
 
 	gtkchat = gtkconv->u.chat;
 	account = purple_conversation_get_account(conv);
-	gc = account->gc;
-	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+
+	if (account->gc == NULL)
+		return FALSE;
+
+	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
 
 	model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
 
@@ -4577,7 +4545,7 @@
 	gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
 
 	node = (PurpleBlistNode*)(purple_find_buddy(conv->account, who));
-	if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) 
+	if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME))
 		pidgin_blist_draw_tooltip(node, gtkconv->infopane);
 
 	g_free(who);
@@ -4587,20 +4555,26 @@
 	return FALSE;
 }
 
-static gboolean 
+static gboolean
 pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv)
 {
 	PurpleConversation *conv;
+	PurpleAccount *account;
 	int delay = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay");
 	
 	pidgin_blist_tooltip_destroy();
 	if (delay == 0)
 		return FALSE;
 
-	if (tooltip.timeout != 0) 
+	if (tooltip.timeout != 0)
 		g_source_remove(tooltip.timeout);
-	
+	tooltip.timeout = 0;
+
 	conv = gtkconv->active_conv;
+	account = purple_conversation_get_account(conv);
+
+	if (account->gc == NULL)
+		return FALSE;
 
 	tooltip.timeout = g_timeout_add(delay, (GSourceFunc)pidgin_userlist_tooltip_timeout, gtkconv);
 	tooltip.gtkconv = gtkconv;
@@ -4640,7 +4614,7 @@
 	gtk_widget_show(gtkconv->infopane_hbox);
 	gtk_widget_add_events(event_box,
 	                      GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
-	g_signal_connect(G_OBJECT(event_box), "button_press_event",
+	g_signal_connect(G_OBJECT(event_box), "button-press-event",
 	                 G_CALLBACK(infopane_press_cb), gtkconv);
 
 	g_signal_connect(G_OBJECT(event_box), "motion-notify-event", 
@@ -6239,7 +6213,6 @@
 
 		gtk_widget_show(win->menu.insert_link);
 		gtk_widget_show(win->menu.insert_image);
-		gtk_widget_show(win->menu.show_icon);
 	} else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
 		/* Show stuff that applies to Chats, hide stuff that applies to IMs */
 
@@ -6252,7 +6225,6 @@
 		gtk_widget_show(win->menu.alias);
 		gtk_widget_hide(win->menu.block);
 		gtk_widget_hide(win->menu.unblock);
-		gtk_widget_hide(win->menu.show_icon);
 
 		if ((account == NULL) || purple_blist_find_chat(account, purple_conversation_get_name(conv)) == NULL) {
 			/* If the chat is NOT in the buddy list */
@@ -7019,7 +6991,8 @@
 	for (l = purple_get_ims(); l != NULL; l = l->next) {
 		conv = (PurpleConversation *)l->data;
 		gtkconv = PIDGIN_CONVERSATION(conv);
-		gtkconv->u.im->animate = GPOINTER_TO_INT(value);
+		if (gtkconv)
+			gtkconv->u.im->animate = GPOINTER_TO_INT(value);
 	}
 
 	/* Now either stop or start animation for the active conversation in each window */
@@ -7038,6 +7011,8 @@
 
 	for (l = purple_get_conversations(); l != NULL; l = l->next) {
 		PurpleConversation *conv = l->data;
+		if (!PIDGIN_CONVERSATION(conv))
+			continue;
 		if (GPOINTER_TO_INT(value)) 
 			gtk_widget_show(PIDGIN_CONVERSATION(conv)->infopane_hbox);
 		else
@@ -7056,7 +7031,8 @@
 	GList *l;
 	for (l = purple_get_conversations(); l != NULL; l = l->next) {
 		PurpleConversation *conv = l->data;
-		update_tab_icon(conv);
+		if (PIDGIN_CONVERSATION(conv))
+			update_tab_icon(conv);
 	}
 }
 
@@ -8222,10 +8198,11 @@
 
 			gtk_window_get_size(GTK_WINDOW(dest_win->window),
 			                    &win_width, &win_height);
-
+#ifdef WIN32  /* only override window manager placement on Windows */
 			gtk_window_move(GTK_WINDOW(dest_win->window),
 			                e->x_root - (win_width  / 2),
 			                e->y_root - (win_height / 2));
+#endif
 
 			pidgin_conv_window_show(dest_win);
 		}
@@ -8490,19 +8467,6 @@
 }
 
 static gboolean
-alias_double_click_cb(GtkWidget *widget, GdkEventButton *event, PidginConversation *gtkconv)
-{
-	/* I'm keeping this around in case we decide to handle double-clicking tabs
-	 *  (or some other label) this way. */
-	if (event->button != 1 || event->type != GDK_2BUTTON_PRESS) {
-		return FALSE;
-	}
-	
-	infopane_entry_activate(gtkconv);
-	return FALSE;
-}
-
-static gboolean
 window_keypress_cb(GtkWidget *widget, GdkEventKey *event, PidginWindow *win)
 {
 	PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win);
@@ -8552,13 +8516,6 @@
 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_timestamps),
 	                               purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
 
-	if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM &&
-	    purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons"))
-	{
-		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_icon),
-		                               gtkconv->u.im->show_icon);
-	}
-
 	/*
 	 * We pause icons when they are not visible.  If this icon should
 	 * be animated then start it back up again.
--- a/pidgin/gtkimhtmltoolbar.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/gtkimhtmltoolbar.c	Thu Sep 06 06:59:23 2007 +0000
@@ -28,6 +28,7 @@
 
 #include "imgstore.h"
 #include "notify.h"
+#include "prefs.h"
 #include "request.h"
 #include "pidginstock.h"
 #include "util.h"
@@ -1021,9 +1022,41 @@
 	if (menu)
 		gtk_widget_destroy(menu);
 
+	purple_prefs_disconnect_by_handle(object);
+
 	G_OBJECT_CLASS(parent_class)->finalize (object);
 }
 
+static void
+switch_toolbar_view(GtkWidget *item, GtkIMHtmlToolbar *toolbar)
+{
+	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/toolbar/wide",
+			!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/toolbar/wide"));
+}
+
+static gboolean
+gtk_imhtmltoolbar_popup_menu(GtkWidget *widget, GdkEventButton *event, GtkIMHtmlToolbar *toolbar)
+{
+	GtkWidget *menu;
+	GtkWidget *item;
+	gboolean wide;
+
+	if (event->button != 3)
+		return FALSE;
+
+	wide = GTK_WIDGET_VISIBLE(toolbar->bold);
+
+	menu = gtk_menu_new();
+	item = gtk_menu_item_new_with_mnemonic(wide ? _("Group Items") : _("Ungroup Items"));
+	g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(switch_toolbar_view), toolbar);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+	gtk_widget_show(item);
+
+	gtk_menu_popup(GTK_MENU(menu), NULL, NULL, pidgin_menu_position_func_helper,
+				widget, event->button, event->time);
+	return TRUE;
+}
+
 /* Boring GTK+ stuff */
 static void gtk_imhtmltoolbar_class_init (GtkIMHtmlToolbarClass *class)
 {
@@ -1033,90 +1066,58 @@
 	gobject_class = (GObjectClass*) class;
 	parent_class = gtk_type_class(GTK_TYPE_HBOX);
 	gobject_class->finalize = gtk_imhtmltoolbar_finalize;
+
+	purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations/toolbar");
+	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/toolbar/wide", FALSE);
 }
 
 static void gtk_imhtmltoolbar_create_old_buttons(GtkIMHtmlToolbar *toolbar)
 {
+	GtkWidget *hbox;
 	GtkWidget *button;
-	/* Bold */
-	button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_BOLD);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(do_bold), toolbar);
-	toolbar->bold = button;
-
-
-	/* Italic */
-	button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_ITALIC);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(do_italic), toolbar);
-	toolbar->italic = button;
-
-	/* Underline */
-	button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_UNDERLINE);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(do_underline), toolbar);
-	toolbar->underline = button;
-
-
-	/* Strikethrough */
-	button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_STRIKETHROUGH);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			G_CALLBACK(do_strikethrough), toolbar);
-	toolbar->strikethrough = button;
-
-	/* Increase font size */
-	button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_TEXT_LARGER);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(do_big), toolbar);
-	toolbar->larger_size = button;
-
-	/* Decrease font size */
-	button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(do_small), toolbar);
-	toolbar->smaller_size = button;
+	struct {
+		char *stock;
+		gpointer callback;
+		GtkWidget **button;
+		const char *tooltip;
+	} buttons[] = {
+		{GTK_STOCK_BOLD, G_CALLBACK(do_bold), &toolbar->bold, _("Bold")},
+		{GTK_STOCK_ITALIC, do_italic, &toolbar->italic, _("Italic")},
+		{GTK_STOCK_UNDERLINE, do_underline, &toolbar->underline, _("Underline")},
+		{GTK_STOCK_STRIKETHROUGH, do_strikethrough, &toolbar->strikethrough, _("Strikethrough")},
+		{"", NULL, NULL, NULL},
+		{PIDGIN_STOCK_TOOLBAR_TEXT_LARGER, do_big, &toolbar->larger_size, _("Increase Font Size")},
+		{PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER, do_small, &toolbar->smaller_size, _("Decrease Font Size")},
+		{"", NULL, NULL, NULL},
+		{PIDGIN_STOCK_TOOLBAR_FONT_FACE, toggle_font, &toolbar->font, _("Font Face")},
+		{PIDGIN_STOCK_TOOLBAR_FGCOLOR, toggle_bg_color, &toolbar->bgcolor, _("Background Color")},
+		{PIDGIN_STOCK_TOOLBAR_BGCOLOR, toggle_fg_color, &toolbar->fgcolor, _("Foreground Color")},
+		{"", NULL, NULL, NULL},
+		{PIDGIN_STOCK_CLEAR, clear_formatting_cb, &toolbar->clear, _("Reset Formatting")},
+		{"", NULL, NULL, NULL},
+		{PIDGIN_STOCK_TOOLBAR_INSERT_LINK, insert_link_cb, &toolbar->link, _("Insert Link")},
+		{PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, insert_image_cb, &toolbar->image, _("Insert IM Image")},
+		{PIDGIN_STOCK_TOOLBAR_SMILEY, insert_smiley_cb, &toolbar->smiley, _("Insert Smiley")},
+		{NULL, NULL, NULL, NULL}
+	};
+	int iter;
 
-	/* Font Face */
-
-	button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_FONT_FACE);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(toggle_font), toolbar);
-	toolbar->font = button;
-
-	/* Foreground Color */
-	button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_FGCOLOR);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(toggle_fg_color), toolbar);
-	toolbar->fgcolor = button;
-
-	/* Background Color */
-	button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_BGCOLOR);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(toggle_bg_color), toolbar);
-	toolbar->bgcolor = button;
+	hbox = gtk_hbox_new(FALSE, 0);
 
-	button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_INSERT_LINK);
-	g_signal_connect(G_OBJECT(button), "clicked",
-				 G_CALLBACK(insert_link_cb), toolbar);
-	toolbar->link = button;
-
-	/* Insert IM Image */
-	button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(insert_image_cb), toolbar);
-	toolbar->image = button;
+	for (iter = 0; buttons[iter].stock; iter++) {
+		if (buttons[iter].stock[0]) {
+			button = pidgin_pixbuf_toolbar_button_from_stock(buttons[iter].stock);
+			g_signal_connect(G_OBJECT(button), "clicked",
+					 G_CALLBACK(buttons[iter].callback), toolbar);
+			*(buttons[iter].button) = button;
+			gtk_tooltips_set_tip(toolbar->tooltips, button, buttons[iter].tooltip, NULL);
+		} else
+			button = gtk_vseparator_new();
+		gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+	}
 
-	/* Insert Smiley */
-	button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_SMILEY);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(insert_smiley_cb), toolbar);
-	toolbar->smiley = button;
-
-	/* Reset formatting */
-	button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_SMILEY);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(clear_formatting_cb), toolbar);
-	toolbar->clear = button;
+	gtk_box_pack_start(GTK_BOX(toolbar), hbox, FALSE, FALSE, 0);
+	g_object_set_data(G_OBJECT(toolbar), "wide-view", hbox);
 }
 
 static void
@@ -1140,10 +1141,23 @@
 		g_object_set(G_OBJECT(widget), "use-markup", TRUE, NULL);
 }
 
+static void
+imhtmltoolbar_view_pref_changed(const char *name, PurplePrefType type,
+		gconstpointer value, gpointer toolbar)
+{
+	if (value) {
+		gtk_widget_hide_all(g_object_get_data(G_OBJECT(toolbar), "lean-view"));
+		gtk_widget_show_all(g_object_get_data(G_OBJECT(toolbar), "wide-view"));
+	} else {
+		gtk_widget_hide_all(g_object_get_data(G_OBJECT(toolbar), "wide-view"));
+		gtk_widget_show_all(g_object_get_data(G_OBJECT(toolbar), "lean-view"));
+	}
+}
+
 static void gtk_imhtmltoolbar_init (GtkIMHtmlToolbar *toolbar)
 {
-	GtkWidget *hbox = GTK_WIDGET(toolbar);
-	GtkWidget *bbox;
+	GtkWidget *hbox = GTK_WIDGET(toolbar), *event = gtk_event_box_new();
+	GtkWidget *bbox, *box = gtk_hbox_new(FALSE, 0);
 	GtkWidget *image;
 	GtkWidget *label;
 	GtkWidget *insert_button;
@@ -1177,7 +1191,6 @@
 		{NULL, NULL, FALSE}
 	};
 
-
 	toolbar->imhtml = NULL;
 	toolbar->font_dialog = NULL;
 	toolbar->fgcolor_dialog = NULL;
@@ -1203,7 +1216,7 @@
 	gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
 	g_object_set_data(G_OBJECT(hbox), "font_label", label);
 	gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0);
-	gtk_box_pack_start(GTK_BOX(hbox), font_button, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(box), font_button, FALSE, FALSE, 0);
 	gtk_widget_show_all(font_button);
 
 	font_menu = gtk_menu_new();
@@ -1232,7 +1245,7 @@
 
 	/* Sep */
 	sep = gtk_vseparator_new();
-	gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(box), sep, FALSE, FALSE, 0);
 	gtk_widget_show_all(sep);
 
 	/* Insert */
@@ -1244,7 +1257,7 @@
 	gtk_box_pack_start(GTK_BOX(bbox), image, FALSE, FALSE, 0);
 	label = gtk_label_new_with_mnemonic(_("_Insert"));
 	gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0);
-	gtk_box_pack_start(GTK_BOX(hbox), insert_button, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(box), insert_button, FALSE, FALSE, 0);
 	gtk_widget_show_all(insert_button);
 
 	insert_menu = gtk_menu_new();
@@ -1277,6 +1290,18 @@
 	g_signal_connect(G_OBJECT(insert_button), "activate", G_CALLBACK(pidgin_menu_clicked), insert_menu);
 	g_signal_connect(G_OBJECT(insert_menu), "deactivate", G_CALLBACK(pidgin_menu_deactivate), insert_button);
 	toolbar->sml = NULL;
+
+	gtk_box_pack_start(GTK_BOX(hbox), box, FALSE, FALSE, 0);
+	g_object_set_data(G_OBJECT(hbox), "lean-view", box);
+
+	purple_prefs_connect_callback(toolbar, PIDGIN_PREFS_ROOT "/conversations/toolbar/wide",
+			imhtmltoolbar_view_pref_changed, toolbar);
+	purple_prefs_trigger_callback(PIDGIN_PREFS_ROOT "/conversations/toolbar/wide");
+
+	gtk_widget_add_events(event, GDK_BUTTON_PRESS_MASK);
+	gtk_box_pack_start(GTK_BOX(hbox), event, TRUE, TRUE, 0);
+	g_signal_connect(G_OBJECT(event), "button-press-event", G_CALLBACK(gtk_imhtmltoolbar_popup_menu), toolbar);
+	gtk_widget_show(event);
 }
 
 GtkWidget *gtk_imhtmltoolbar_new()
--- a/pidgin/gtkmain.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/gtkmain.c	Thu Sep 06 06:59:23 2007 +0000
@@ -774,21 +774,6 @@
 	/* TODO: Move pounces loading into purple_pounces_init() */
 	purple_pounces_load();
 
-	/* HACK BY SEANEGAN:
-	 * We've renamed prpl-oscar to prpl-aim and prpl-icq, accordingly.
-	 * Let's do that change right here... after everything's loaded, but
-	 * before anything has happened
-	 */
-	for (accounts = purple_accounts_get_all(); accounts != NULL; accounts = accounts->next) {
-		PurpleAccount *account = accounts->data;
-		if (!strcmp(purple_account_get_protocol_id(account), "prpl-oscar")) {
-			if (isdigit(*purple_account_get_username(account)))
-				purple_account_set_protocol_id(account, "prpl-icq");
-			else
-				purple_account_set_protocol_id(account, "prpl-aim");
-		}
-	}
-
 	ui_main();
 
 #ifdef USE_SM
--- a/pidgin/gtknotify.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/gtknotify.c	Thu Sep 06 06:59:23 2007 +0000
@@ -801,7 +801,7 @@
 				if(b->label) {
 					button = gtk_button_new_with_label(b->label);
 				} else {
-					purple_debug_warning("gtknotify", "Missing button label");
+					purple_debug_warning("gtknotify", "Missing button label\n");
 				}
 				break;
 			case PURPLE_NOTIFY_BUTTON_CONTINUE:
--- a/pidgin/gtkpounce.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/gtkpounce.c	Thu Sep 06 06:59:23 2007 +0000
@@ -975,7 +975,7 @@
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/pounces/default_actions/play-sound"));
 	}
 
-	gtk_widget_show_all(vbox2);
+	gtk_widget_show(vbox2);
 	gtk_widget_show(window);
 }
 
--- a/pidgin/gtkprefs.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/gtkprefs.c	Thu Sep 06 06:59:23 2007 +0000
@@ -1036,12 +1036,14 @@
 		gtk_widget_set_sensitive(hbox, FALSE);
 	g_signal_connect(G_OBJECT(fontpref), "clicked", G_CALLBACK(pidgin_toggle_sensitive), hbox);
 	g_signal_connect(G_OBJECT(font_button), "font-set", G_CALLBACK(pidgin_custom_font_set), NULL);
+	gtk_widget_show_all(hbox);
 #endif
 
 	vbox = pidgin_make_frame(ret, _("Default Formatting"));
 	gtk_box_set_child_packing(GTK_BOX(vbox->parent), vbox, TRUE, TRUE, 0, GTK_PACK_START);
 
 	frame = pidgin_create_imhtml(TRUE, &imhtml, &toolbar, NULL);
+	gtk_widget_show(frame);
 	gtk_widget_set_name(imhtml, "pidgin_prefs_font_imhtml");
 	gtk_widget_set_size_request(frame, 300, -1);
 	gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(imhtml), TRUE);
@@ -1068,7 +1070,7 @@
 					 G_CALLBACK(formatting_clear_cb), NULL);
 
 
-	gtk_widget_show_all(ret);
+	gtk_widget_show(ret);
 
 	return ret;
 }
--- a/pidgin/gtkrequest.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/gtkrequest.c	Thu Sep 06 06:59:23 2007 +0000
@@ -368,6 +368,8 @@
 	data->u.input.multiline = multiline;
 	data->u.input.hint = g_strdup(hint);
 
+	gtk_widget_show_all(hbox);
+
 	if ((data->u.input.hint != NULL) && (!strcmp(data->u.input.hint, "html"))) {
 		GtkWidget *frame;
 
@@ -429,13 +431,14 @@
 					gtk_entry_set_invisible_char(GTK_ENTRY(entry), PIDGIN_INVISIBLE_CHAR);
 			}
 		}
+		gtk_widget_show_all(vbox);
 	}
 
 	pidgin_set_accessible_label (entry, label);
 	data->u.input.entry = entry;
 
 	/* Show everything. */
-	gtk_widget_show_all(dialog);
+	gtk_widget_show(dialog);
 
 	return data;
 }
--- a/pidgin/plugins/mailchk.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/plugins/mailchk.c	Thu Sep 06 06:59:23 2007 +0000
@@ -118,7 +118,7 @@
 	void *conn_handle = purple_connections_get_handle();
 
 	if (!check_timeout(NULL)) {
-		purple_debug_warning("mailchk", "Could not read $MAIL or /var/spool/mail/$USER");
+		purple_debug_warning("mailchk", "Could not read $MAIL or /var/spool/mail/$USER\n");
 		return FALSE;
 	}
 
--- a/pidgin/plugins/musicmessaging/musicmessaging.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/plugins/musicmessaging/musicmessaging.c	Thu Sep 06 06:59:23 2007 +0000
@@ -113,7 +113,7 @@
 			
 			purple_conv_im_send(PURPLE_CONV_IM(mmconv->conv), to_send->str);
 			
-			purple_debug_misc("Sent request: %s\n", to_send->str);
+			purple_debug_misc("musicmessaging", "Sent request: %s\n", to_send->str);
 		}
 	}
 			
--- a/pidgin/win32/gtkdocklet-win32.c	Thu Sep 06 06:58:31 2007 +0000
+++ b/pidgin/win32/gtkdocklet-win32.c	Thu Sep 06 06:59:23 2007 +0000
@@ -450,7 +450,7 @@
 		hicon = pixbuf_to_hicon(pixbuf);
 		g_object_unref(pixbuf);
 	} else
-		purple_debug_error("Unable to load pixbuf for %s.\n", stock);
+		purple_debug_error("docklet", "Unable to load pixbuf for %s.\n", stock);
 
 	return hicon;
 }