changeset 32608:513b8ec76077

propagate from branch 'im.pidgin.pidgin.2.x.y' (head be5e66abad2af29604bc794cc4c6600ab12751f3) to branch 'im.pidgin.pidgin' (head be7373160916cdcb9710432f506e4eac29df8296)
author John Bailey <rekkanoryo@rekkanoryo.org>
date Sun, 11 Sep 2011 04:19:01 +0000
parents 88a46649de3d (current diff) e21500d61347 (diff)
children 3d5a0e9654ed
files gaim-uninstalled.pc.in gaim.pc.in libpurple/gaim-compat.h libpurple/protocols/silc10/Makefile.am libpurple/protocols/silc10/Makefile.mingw libpurple/protocols/silc10/README libpurple/protocols/silc10/TODO libpurple/protocols/silc10/buddy.c libpurple/protocols/silc10/chat.c libpurple/protocols/silc10/ft.c libpurple/protocols/silc10/ops.c libpurple/protocols/silc10/pk.c libpurple/protocols/silc10/silc.c libpurple/protocols/silc10/silcpurple.h libpurple/protocols/silc10/util.c libpurple/protocols/silc10/wb.c libpurple/protocols/silc10/wb.h libpurple/protocols/yahoo/yahoo_picture.c libpurple/purple-2-uninstalled.pc.in libpurple/purple-2.pc.in libpurple/purple-uninstalled.pc.in libpurple/purple.pc.in pidgin/gtkdocklet-gtk.c pidgin/gtkgaim-compat.h pidgin/pidgin-2-uninstalled.pc.in pidgin/pidgin-2.pc.in pidgin/pidgin-uninstalled.pc.in pidgin/pidgin.pc.in
diffstat 261 files changed, 5142 insertions(+), 18155 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Sep 11 04:18:46 2011 +0000
+++ b/ChangeLog	Sun Sep 11 04:19:01 2011 +0000
@@ -1,5 +1,24 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
+version 3.0.0 (??/??/????):
+	AIM and ICQ:
+	* Make buddy list management code more efficient. (Oliver) (#4816)
+	* Don't try to format ICQ usernames entered as email addresses.
+	  Gets rid of an "Unable to format username" error at login. (#13883)
+
+	MXit:
+	* Remove all reference to Hidden Number.
+	* Fix decoding of font-size changes in the markup of received messages.
+	* Ignore new invites to join a GroupChat if you're already joined, or
+	  still have a pending invite.
+	* The buddy's name was not centered vertically in the buddy-list if they
+	  did not have a status-message or mood set.
+
+	XMPP:
+	* Strip element prefixes from XHTML-IM messages as they're presented
+	  to the core (and UIs) as incoming messages (Thijs Alkemade).
+	  (#14529)
+
 version 2.10.0 (08/18/2011):
 	Pidgin:
 	* Make the max size of incoming smileys a pref instead of hardcoding it.
--- a/ChangeLog.API	Sun Sep 11 04:18:46 2011 +0000
+++ b/ChangeLog.API	Sun Sep 11 04:19:01 2011 +0000
@@ -1,5 +1,165 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
+version 3.0.0 (??/??/????):
+	libpurple:
+		Added:
+		* purple_conversation_get_ui_data
+		* purple_conversation_set_ui_data
+		* purple_notify_searchresult_column_is_visible
+		* purple_notify_searchresult_column_set_visible
+		* purple_notify_user_info_prepend_pair_plaintext
+		* purple_menu_action_get_callback
+		* purple_menu_action_get_children
+		* purple_menu_action_get_data
+		* purple_menu_action_set_label
+		* purple_menu_action_set_data
+		* purple_menu_action_set_callback
+		* purple_menu_action_set_children
+		* purple_request_field_get_tooltip
+		* purple_request_field_group_get_fields_list
+		* purple_request_field_set_tooltip
+		* purple_request_fields_get_ui_data
+		* purple_request_fields_set_ui_data
+		* purple_roomlist_get_account
+		* purple_roomlist_get_proto_data
+		* purple_roomlist_get_ui_data
+		* purple_roomlist_room_get_expanded_once
+		* purple_roomlist_room_set_expanded_once
+		* purple_roomlist_set_proto_data
+		* purple_roomlist_set_ui_data
+		* purple_whiteboard_get_account
+		* purple_whiteboard_get_draw_list
+		* purple_whiteboard_set_draw_list
+		* purple_whiteboard_get_protocol_data
+		* purple_whiteboard_set_protocol_data
+		* purple_whiteboard_get_state
+		* purple_whiteboard_set_state
+		* purple_whiteboard_get_ui_data
+		* purple_whiteboard_set_ui_data
+		* purple_whiteboard_get_who
+		* purple_xfer_get_fd
+		* purple_xfer_get_protocol_data
+		* purple_xfer_get_ui_data
+		* purple_xfer_get_watcher
+		* purple_xfer_set_fd
+		* purple_Xfer_set_local_port
+		* purple_xfer_set_protocol_data
+		* purple_xfer_set_status
+		* purple_xfer_set_ui_data
+		* purple_xfer_set_watcher
+		* xmlnode_get_default_namespace
+		* xmlnode_strip_prefixes
+
+		Changed:
+		* purple_connection_error now takes a PurpleConnectionError
+		  as the second parameter
+		* purple_notify_user_info_add_pair renamed to
+		  purple_notify_user_info_add_pair_html
+		* purple_notify_user_info_get_entries returns a GQueue instead of
+		  a GList
+		* purple_notify_user_info_prepend_pair renamed to
+		  purple_notify_user_info_prepend_pair_html
+		* purple_util_fetch_url_request_len now takes a PurpleAccount as
+		  the first parameter
+		* PurpleConnectionUiOps.report_disconnect now passes a
+		  PurpleConnectionError as the second parameter
+		* purple_dnsquery_a now takes a PurpleAccount as the first parameter
+		* purple_srv_resolve now takes a PurpleAccount as the first parameter
+		* purple_txt_resolve now takes a PurpleAccount as the first parameter
+		* purple_account_add_buddy now takes an invite message as the last
+		  parameter
+		* purple_account_add_buddies now takes an invite message as the last
+		  parameter
+
+		Removed:
+		* _GntFileType
+		* _GntKeyPressMode
+		* _GntMouseEvent
+		* _GntParamFlags
+		* _GntProgressBarOrientation
+		* _GntTreeColumnFlag
+		* _GntWidgetFlags
+		* _PurpleCipherBatchMode
+		* _PurpleCipherCaps
+		* _PurpleCmdFlag
+		* _PurpleCmdPriority
+		* _PurpleCmdRet
+		* _PurpleCmdStatus
+		* _PurplePrefType
+		* _PurplePrivacyType
+		* _PurpleSoundEventID
+		* _XMLNodeType
+		* GtkIMHtml.clipboard_html_string
+		* GtkIMHtml.clipboard_text_string
+		* GtkIMHtmlFontDetail
+		* gtk_imhtml_animation_free
+		* gtk_imhtml_animation_new
+		* gtk_imhtml_image_add_to
+		* gtk_imhtml_image_free
+		* gtk_imhtml_image_new
+		* gtk_imhtml_image_scale
+		* pidgin_blist_update_account_error_state
+		* pidgin_check_if_dir
+		* PIDGIN_DIALOG
+		* pidgin_dialogs_alias_contact
+		* pidgin_set_custom_buddy_icon
+		* pidgin_setup_screenname_autocomplete
+		* PidginConversation.sg
+		* purple_account_add_buddies_with_invite
+		* purple_account_add_buddy_with_invite
+		* purple_buddy_icons_has_custom_icon
+		* purple_buddy_icons_find_custom_icon
+		* purple_buddy_icons_set_custom_icon
+		* purple_connection_error_reason
+		* purple_core_migrate
+		* purple_dnsquery_a_account
+		* purple_notify_searchresults_column_get_title
+		* purple_notify_searchresults_get_columns_count
+		* purple_notify_searchresults_get_rows_count
+		* purple_notify_searchresults_row_get
+		* purple_plugins_register_load_notify_cb
+		* purple_plugins_register_probe_notify_cb
+		* purple_plugins_register_unload_notify_cb
+		* purple_plugins_unregister_load_notify_cb
+		* purple_plugins_unregister_probe_notify_cb
+		* purple_plugins_unregister_unload_notify_cb
+		* purple_presence_add_status
+		* purple_presence_add_list
+		* purple_srv_cancel
+		* purple_srv_resolve_account
+		* purple_status_set_attr_boolean
+		* purple_status_set_attr_int
+		* purple_status_set_attr_string
+		* purple_status_type_add_attr
+		* purple_status_type_add_attrs
+		* purple_status_type_add_attrs_vargs
+		* purple_status_type_get_primary_attr
+		* purple_status_type_set_primary_attr
+		* purple_strlcat
+		* purple_strlcpy
+		* purple_txt_cancel
+		* purple_txt_resolve_account
+		* purple_util_fetch_url_request_len_with_account.  Use
+		  purple_util_fetch_url_request_len, instead.
+		* PurpleConnectionUiOps.report_disconnect_reason
+		* PurplePluginProtocolInfo.add_buddy_with_invite
+		* PurplePluginProtocolInfo.add_buddies_with_invite
+		* serv_got_attention
+		* serv_send_attention
+		* struct _GtkIMHtmlFontDetail
+		* struct _PidginChatPane
+		* struct _PidginImPane
+		* struct _PurpleAttentionType
+		* struct _PurpleMenuAction
+		* struct _PurplePounce
+		* struct _PurpleProxyInfo
+		* struct _PurpleRequestField
+		* struct _PurpleRoomlist
+		* struct _PurpleRoomlistField
+		* struct _PurpleRoomlistRoom
+		* xmlnode_set_attrib_with_namespace
+		* xmlnode_set_attrib_with_prefix
+
 version 2.10.0:
 	libpurple:
 		Added:
--- a/Makefile.am	Sun Sep 11 04:18:46 2011 +0000
+++ b/Makefile.am	Sun Sep 11 04:19:01 2011 +0000
@@ -11,8 +11,6 @@
 		config.h.mingw \
 		doxy2devhelp.xsl \
 		fix-casts.sh \
-		gaim.pc.in \
-		gaim-uninstalled.pc.in \
 		intltool-extract.in \
 		intltool-merge.in \
 		intltool-update.in \
--- a/configure.ac	Sun Sep 11 04:18:46 2011 +0000
+++ b/configure.ac	Sun Sep 11 04:19:01 2011 +0000
@@ -43,11 +43,11 @@
 #
 # Make sure to update finch/libgnt/configure.ac with libgnt version changes.
 #
-m4_define([purple_lt_current], [10])
-m4_define([purple_major_version], [2])
-m4_define([purple_minor_version], [10])
+m4_define([purple_lt_current], [20])
+m4_define([purple_major_version], [3])
+m4_define([purple_minor_version], [0])
 m4_define([purple_micro_version], [0])
-m4_define([purple_version_suffix], [])
+m4_define([purple_version_suffix], [devel])
 m4_define([purple_version],
           [purple_major_version.purple_minor_version.purple_micro_version])
 m4_define([purple_display_version], purple_version[]m4_ifdef([purple_version_suffix],[purple_version_suffix]))
@@ -56,7 +56,7 @@
 m4_define([gnt_major_version], [2])
 m4_define([gnt_minor_version], [8])
 m4_define([gnt_micro_version], [9])
-m4_define([gnt_version_suffix], [])
+m4_define([gnt_version_suffix], [devel])
 m4_define([gnt_version],
           [gnt_major_version.gnt_minor_version.gnt_micro_version])
 m4_define([gnt_display_version], gnt_version[]m4_ifdef([gnt_version_suffix],[gnt_version_suffix]))
@@ -328,6 +328,9 @@
 dnl #######################################################################
 dnl # Check for GLib 2.16 (required)
 dnl #######################################################################
+# TODO: gmodule-2.0 is only needed if enable_plugins is 'yes'.  It
+#       might be nice to change this check so that it's not required
+#       if enable_plugins is 'no'.
 PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.16.0 gobject-2.0 gmodule-2.0 gthread-2.0], , [
 	AC_MSG_RESULT(no)
 	AC_MSG_ERROR([
@@ -938,25 +941,6 @@
 	], [
 		have_silc="no"
 	])
-	if test "x$have_silc" = "xno"; then
-		PKG_CHECK_MODULES(SILC, silcclient, [
-			have_silc="yes"
-			silc10includes="yes"
-			silc10client="yes"
-		], [
-			have_silc="no"
-		])
-		dnl If silcclient.pc wasn't found, check for just silc.pc
-		if test "x$have_silc" = "xno"; then
-			PKG_CHECK_MODULES(SILC, silc, [
-				have_silc="yes"
-				silc10includes="yes"
-				silc10client="yes"
-			], [
-				have_silc="no"
-			])
-		fi
-	fi
 else
 	if test "$ac_silc_includes" != "no"; then
 		SILC_CFLAGS="-I$ac_silc_includes"
@@ -974,17 +958,6 @@
 
 	if test "x$silcincludes" = "xyes" -a "x$silcclient" = "xyes"; then
 		have_silc="yes"
-	else
-		CPPFLAGS_save="$CPPFLAGS"
-		CPPFLAGS="$CPPFLAGS $SILC_CFLAGS"
-		AC_CHECK_HEADER(silcincludes.h, [silc10includes=yes])
-		CPPFLAGS="$CPPFLAGS_save"
-
-		SILC_LIBS="$SILC_LIBS -lsilc -lsilcclient -lpthread $LIBDL"
-		AC_CHECK_LIB(silcclient, silc_client_init, [silc10client=yes], , $SILC_LIBS)
-		if test "x$silc10includes" = "xyes" -a "x$silc10client" = "xyes"; then
-			have_silc="yes"
-		fi
 	fi
 fi
 AC_SUBST(SILC_LIBS)
@@ -992,20 +965,6 @@
 dnl SILC Toolkit >= 1.0.1 has a new MIME API
 if test "x$silcclient" = "xyes"; then
 	AC_DEFINE(HAVE_SILCMIME_H, 1, [Define if we have silcmime.h])
-elif test "x$silc10client" = "xyes"; then
-	CPPFLAGS_save="$CPPFLAGS"
-	CPPFLAGS="$CPPFLAGS $SILC_CFLAGS"
-		AC_MSG_CHECKING(for silcmime.h)
-		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include <silcincludes.h>
-#include <silcmime.h>
-		]], [[]])], [
-		AC_MSG_RESULT(yes)
-		AC_DEFINE(HAVE_SILCMIME_H, 1, [Define if we have silcmime.h])
-		], [
-		AC_MSG_RESULT(no)
-		])
-	CPPFLAGS="$CPPFLAGS_save"
 fi
 
 dnl #######################################################################
@@ -1111,7 +1070,7 @@
 fi
 
 if test "x$STATIC_PRPLS" = "xall" ; then
-	STATIC_PRPLS="bonjour gg irc jabber msn myspace mxit novell oscar sametime silc simple yahoo zephyr"
+	STATIC_PRPLS="bonjour gg irc jabber msn mxit myspace novell oscar sametime silc simple yahoo zephyr"
 fi
 if test "x$have_meanwhile" != "xyes" ; then
 	STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/sametime//'`
@@ -1120,10 +1079,7 @@
 	STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/bonjour//'`
 fi
 if test "x$silcincludes" != "xyes" -o "x$silcclient" != "xyes"; then
-	STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/silc/silc10/'`
-fi
-if test "x$silc10includes" != "xyes" -o "x$silc10client" != "xyes"; then
-	STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/silc10//'`
+	STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/silc//'`
 fi
 AC_SUBST(STATIC_PRPLS)
 STATIC_LINK_LIBS=
@@ -1147,8 +1103,6 @@
 	else
 		if test "x$i" = "xsilc"; then
 			STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/$i/lib${i}purple.la"
-		elif test "x$i" = "xsilc10"; then
-			STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/$i/libsilcpurple.la"
 		else
 			STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/$i/lib$i.la"
 		fi
@@ -1161,15 +1115,14 @@
 		irc)		static_irc=yes ;;
 		jabber)		static_jabber=yes ;;
 		msn)		static_msn=yes ;;
+		mxit)		static_mxit=yes ;;
 		myspace)	static_myspace=yes ;;
-		mxit)		static_mxit=yes ;;
 		novell)		static_novell=yes ;;
 		oscar)		static_oscar=yes ;;
 		aim)		static_oscar=yes ;;
 		icq)		static_oscar=yes ;;
 		sametime)	static_sametime=yes ;;
 		silc)		static_silc=yes ;;
-		silc10)		static_silc=yes ;;
 		simple)		static_simple=yes ;;
 		yahoo)		static_yahoo=yes ;;
 		zephyr)		static_zephyr=yes ;;
@@ -1181,8 +1134,8 @@
 AM_CONDITIONAL(STATIC_IRC, test "x$static_irc" = "xyes")
 AM_CONDITIONAL(STATIC_JABBER, test "x$static_jabber" = "xyes")
 AM_CONDITIONAL(STATIC_MSN, test "x$static_msn" = "xyes")
+AM_CONDITIONAL(STATIC_MXIT, test "x$static_mxit" = "xyes")
 AM_CONDITIONAL(STATIC_MYSPACE, test "x$static_myspace" = "xyes")
-AM_CONDITIONAL(STATIC_MXIT, test "x$static_mxit" = "xyes")
 AM_CONDITIONAL(STATIC_NOVELL, test "x$static_novell" = "xyes")
 AM_CONDITIONAL(STATIC_OSCAR, test "x$static_oscar" = "xyes")
 AM_CONDITIONAL(STATIC_SAMETIME, test "x$static_sametime" = "xyes" -a "x$have_meanwhile" = "xyes")
@@ -1196,7 +1149,7 @@
 
 AC_ARG_WITH(dynamic_prpls, [AC_HELP_STRING([--with-dynamic-prpls], [specify which protocols to build dynamically])], [DYNAMIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`])
 if test "x$DYNAMIC_PRPLS" = "xall" ; then
-	DYNAMIC_PRPLS="bonjour gg irc jabber msn myspace mxit novell oscar sametime silc simple yahoo zephyr"
+	DYNAMIC_PRPLS="bonjour gg irc jabber msn mxit myspace novell oscar sametime silc simple yahoo zephyr"
 fi
 if test "x$have_meanwhile" != "xyes"; then
 	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/sametime//'`
@@ -1205,10 +1158,7 @@
 	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/bonjour//'`
 fi
 if test "x$silcincludes" != "xyes" -o "x$silcclient" != "xyes"; then
-	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/silc/silc10/'`
-fi
-if test "x$silc10includes" != "xyes" -o "x$silc10client" != "xyes"; then
-	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/silc10//'`
+	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/silc//'`
 fi
 AC_SUBST(DYNAMIC_PRPLS)
 for i in $DYNAMIC_PRPLS ; do
@@ -1218,8 +1168,8 @@
 		irc)		dynamic_irc=yes ;;
 		jabber)		dynamic_jabber=yes ;;
 		msn)		dynamic_msn=yes ;;
+		mxit)		dynamic_mxit=yes ;;
 		myspace)	dynamic_myspace=yes ;;
-		mxit)		dynamic_mxit=yes ;;
 		novell)		dynamic_novell=yes ;;
 		null)		dynamic_null=yes ;;
 		oscar)		dynamic_oscar=yes ;;
@@ -1227,7 +1177,6 @@
 		icq)		dynamic_oscar=yes ;;
 		sametime)	dynamic_sametime=yes ;;
 		silc)		dynamic_silc=yes ;;
-		silc10)		dynamic_silc=yes ;;
 		simple)		dynamic_simple=yes ;;
 		yahoo)		dynamic_yahoo=yes ;;
 		zephyr)		dynamic_zephyr=yes ;;
@@ -2530,10 +2479,8 @@
 		   m4macros/Makefile
 		   pidgin.apspec
 		   pidgin/Makefile
-		   pidgin/pidgin.pc
-		   pidgin/pidgin-uninstalled.pc
-		   pidgin/pidgin-2.pc
-		   pidgin/pidgin-2-uninstalled.pc
+		   pidgin/pidgin-3.pc
+		   pidgin/pidgin-3-uninstalled.pc
 		   pidgin/pixmaps/Makefile
 		   pidgin/pixmaps/emotes/default/24/Makefile
 		   pidgin/pixmaps/emotes/none/Makefile
@@ -2550,10 +2497,8 @@
 		   libpurple/ciphers/Makefile
 		   libpurple/example/Makefile
 		   libpurple/gconf/Makefile
-		   libpurple/purple.pc
-		   libpurple/purple-uninstalled.pc
-		   libpurple/purple-2.pc
-		   libpurple/purple-2-uninstalled.pc
+		   libpurple/purple-3.pc
+		   libpurple/purple-3-uninstalled.pc
 		   libpurple/plugins/Makefile
 		   libpurple/plugins/mono/Makefile
 		   libpurple/plugins/mono/api/Makefile
@@ -2576,7 +2521,6 @@
 		   libpurple/protocols/oscar/Makefile
 		   libpurple/protocols/sametime/Makefile
 		   libpurple/protocols/silc/Makefile
-		   libpurple/protocols/silc10/Makefile
 		   libpurple/protocols/simple/Makefile
 		   libpurple/protocols/yahoo/Makefile
 		   libpurple/protocols/zephyr/Makefile
--- a/finch/finch.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/finch.c	Sun Sep 11 04:19:01 2011 +0000
@@ -351,29 +351,6 @@
 	/* We don't want debug-messages to show up and corrupt the display */
 	purple_debug_set_enabled(debug_enabled);
 
-	/* If we're using a custom configuration directory, we
-	 * do NOT want to migrate, or weird things will happen. */
-	if (opt_config_dir_arg == NULL)
-	{
-		if (!purple_core_migrate())
-		{
-			char *old = g_strconcat(purple_home_dir(),
-			                        G_DIR_SEPARATOR_S ".gaim", NULL);
-			char *text = g_strdup_printf(_(
-				"%s encountered errors migrating your settings "
-				"from %s to %s. Please investigate and complete the "
-				"migration by hand. Please report this error at http://developer.pidgin.im"), _("Finch"),
-				old, purple_user_dir());
-
-			g_free(old);
-
-			purple_print_utf8_to_console(stderr, text);
-			g_free(text);
-
-			return 0;
-		}
-	}
-
 	purple_core_set_ui_ops(gnt_core_get_ui_ops());
 	purple_eventloop_set_ui_ops(gnt_eventloop_get_ui_ops());
 	purple_idle_set_ui_ops(finch_idle_get_ui_ops());
--- a/finch/gntblist.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/gntblist.c	Sun Sep 11 04:19:01 2011 +0000
@@ -663,7 +663,7 @@
 		purple_blist_add_buddy(buddy, NULL, grp, NULL);
 	}
 
-	purple_account_add_buddy_with_invite(account, buddy, invite);
+	purple_account_add_buddy(account, buddy, invite);
 }
 
 static void
@@ -1060,7 +1060,7 @@
 						purple_buddy_get_account(buddy),
 						purple_buddy_get_name(buddy));
 		} else {
-			FinchConv *ggconv = FINCH_GET_DATA(conv);
+			FinchConv *ggconv = FINCH_CONV(conv);
 			gnt_window_present(ggconv->window);
 		}
 		finch_conversation_set_active(conv);
@@ -1078,9 +1078,10 @@
 	PurpleBlistNode *node = ggblist->cnode;
 	if (action) {
 		void (*callback)(PurpleBlistNode *, gpointer);
-		callback = (void (*)(PurpleBlistNode *, gpointer))action->callback;
+		callback = (void (*)(PurpleBlistNode *, gpointer))
+			purple_menu_action_get_callback(action);
 		if (callback)
-			callback(node, action->data);
+			callback(node, purple_menu_action_get_data(action));
 		else
 			return;
 	}
@@ -1095,15 +1096,17 @@
 	if (action == NULL)
 		return;
 
-	item = gnt_menuitem_new(action->label);
-	if (action->callback)
+	item = gnt_menuitem_new(purple_menu_action_get_label(action));
+	if (purple_menu_action_get_callback(action))
 		gnt_menuitem_set_callback(GNT_MENU_ITEM(item), context_menu_callback, action);
 	gnt_menu_add_item(menu, GNT_MENU_ITEM(item));
 
-	if (action->children) {
+	list = purple_menu_action_get_children(action);
+
+	if (list) {
 		GntWidget *sub = gnt_menu_new(GNT_MENU_POPUP);
 		gnt_menuitem_set_submenu(item, GNT_MENU(sub));
-		for (list = action->children; list; list = list->next)
+		for (; list; list = list->next)
 			gnt_append_menu_action(GNT_MENU(sub), list->data, action);
 	}
 }
@@ -1123,7 +1126,7 @@
 		PurpleMenuAction *act = (PurpleMenuAction *) list->data;
 		if (!act)
 			continue;
-		act->data = node;
+		purple_menu_action_set_data(act, node);
 		gnt_append_menu_action(menu, act, NULL);
 		g_signal_connect_swapped(G_OBJECT(menu), "destroy",
 			G_CALLBACK(purple_menu_action_free), act);
@@ -1216,7 +1219,7 @@
 autojoin_toggled(GntMenuItem *item, gpointer data)
 {
 	PurpleMenuAction *action = data;
-	purple_blist_node_set_bool(action->data, "gnt-autojoin",
+	purple_blist_node_set_bool(purple_menu_action_get_data(action), "gnt-autojoin",
 				gnt_menuitem_check_get_checked(GNT_MENU_ITEM_CHECK(item)));
 }
 
@@ -1224,7 +1227,8 @@
 create_chat_menu(GntMenu *menu, PurpleChat *chat)
 {
 	PurpleMenuAction *action = purple_menu_action_new(_("Auto-join"), NULL, chat, NULL);
-	GntMenuItem *check = gnt_menuitem_check_new(action->label);
+	GntMenuItem *check = gnt_menuitem_check_new(
+			purple_menu_action_get_label(action));
 	gnt_menuitem_check_set_checked(GNT_MENU_ITEM_CHECK(check),
 				purple_blist_node_get_bool((PurpleBlistNode*)chat, "gnt-autojoin"));
 	gnt_menu_add_item(menu, check);
@@ -1268,7 +1272,7 @@
 {
 	PurpleNotifyUserInfo *info = purple_notify_user_info_new();
 	gpointer uihandle;
-	purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving..."));
+	purple_notify_user_info_add_pair_plaintext(info, _("Information"), _("Retrieving..."));
 	uihandle = purple_notify_userinfo(conn, name, info, NULL, NULL);
 	purple_notify_user_info_destroy(info);
 
@@ -1783,15 +1787,13 @@
 	presence = purple_buddy_get_presence(buddy);
 
 	if (!full || g_utf8_collate(purple_buddy_get_name(buddy), alias)) {
-		char *esc = g_markup_escape_text(alias, -1);
-		purple_notify_user_info_add_pair(user_info, _("Nickname"), esc);
-		g_free(esc);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Nickname"), alias);
 	}
 
 	tmp = g_strdup_printf("%s (%s)",
 			purple_account_get_username(account),
 			purple_account_get_protocol_name(account));
-	purple_notify_user_info_add_pair(user_info, _("Account"), tmp);
+	purple_notify_user_info_add_pair_plaintext(user_info, _("Account"), tmp);
 	g_free(tmp);
 
 	prpl = purple_find_prpl(purple_account_get_protocol_id(account));
@@ -1806,7 +1808,7 @@
 			time_t idle = purple_presence_get_idle_time(pre);
 			if (idle > 0) {
 				char *st = purple_str_seconds_to_string(time(NULL) - idle);
-				purple_notify_user_info_add_pair(user_info, _("Idle"), st);
+				purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), st);
 				g_free(st);
 			}
 		}
--- a/finch/gntconn.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/gntconn.c	Sun Sep 11 04:19:01 2011 +0000
@@ -165,7 +165,6 @@
 	NULL, /* connected */
 	NULL, /* disconnected */
 	NULL, /* notice */
-	NULL,
 	NULL, /* network_connected */
 	NULL, /* network_disconnected */
 	finch_connection_report_disconnect,
--- a/finch/gntconv.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/gntconv.c	Sun Sep 11 04:19:01 2011 +0000
@@ -282,7 +282,7 @@
 		return;
 
 	im = PURPLE_CONV_IM(conv);
-	ggc = FINCH_GET_DATA(conv);
+	ggc = FINCH_CONV(conv);
 
 	if (purple_conv_im_get_typing_state(im) == PURPLE_TYPING) {
 		int scroll;
@@ -321,7 +321,7 @@
 	PurpleConversation *conv = find_conv_with_contact(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy));
 	if (conv == NULL)
 		return;
-	generate_send_to_menu(FINCH_GET_DATA(conv));
+	generate_send_to_menu(FINCH_CONV(conv));
 }
 
 static void
@@ -333,7 +333,7 @@
 		PurpleConversation *cc = find_conv_with_contact(
 				purple_conversation_get_account(conv), purple_conversation_get_name(conv));
 		if (cc)
-			generate_send_to_menu(FINCH_GET_DATA(cc));
+			generate_send_to_menu(FINCH_CONV(cc));
 		list = list->next;
 	}
 
@@ -398,7 +398,7 @@
 static void
 cleared_message_history_cb(PurpleConversation *conv, gpointer data)
 {
-	FinchConv *ggc = FINCH_GET_DATA(conv);
+	FinchConv *ggc = FINCH_CONV(conv);
 	if (ggc)
 		gnt_text_view_clear(GNT_TEXT_VIEW(ggc->tv));
 }
@@ -749,7 +749,7 @@
 static void
 finch_create_conversation(PurpleConversation *conv)
 {
-	FinchConv *ggc = FINCH_GET_DATA(conv);
+	FinchConv *ggc = FINCH_CONV(conv);
 	char *title;
 	PurpleConversationType type;
 	PurpleConversation *cc;
@@ -763,8 +763,8 @@
 
 	account = purple_conversation_get_account(conv);
 	cc = find_conv_with_contact(account, purple_conversation_get_name(conv));
-	if (cc && FINCH_GET_DATA(cc))
-		ggc = FINCH_GET_DATA(cc);
+	if (cc && FINCH_CONV(cc))
+		ggc = FINCH_CONV(cc);
 	else
 		ggc = g_new0(FinchConv, 1);
 
@@ -776,9 +776,9 @@
 
 	ggc->list = g_list_prepend(ggc->list, conv);
 	ggc->active_conv = conv;
-	FINCH_SET_DATA(conv, ggc);
+	purple_conversation_set_ui_data(conv, ggc);
 
-	if (cc && FINCH_GET_DATA(cc) && cc != conv) {
+	if (cc && FINCH_CONV(cc) && cc != conv) {
 		finch_conversation_set_active(conv);
 		return;
 	}
@@ -885,7 +885,7 @@
 finch_destroy_conversation(PurpleConversation *conv)
 {
 	/* do stuff here */
-	FinchConv *ggc = FINCH_GET_DATA(conv);
+	FinchConv *ggc = FINCH_CONV(conv);
 	ggc->list = g_list_remove(ggc->list, conv);
 	if (ggc->list && conv == ggc->active_conv) {
 		ggc->active_conv = ggc->list->data;
@@ -905,7 +905,7 @@
 finch_write_common(PurpleConversation *conv, const char *who, const char *message,
 		PurpleMessageFlags flags, time_t mtime)
 {
-	FinchConv *ggconv = FINCH_GET_DATA(conv);
+	FinchConv *ggconv = FINCH_CONV(conv);
 	char *strip, *newline;
 	GntTextFormatFlags fl = 0;
 	int pos;
@@ -1069,7 +1069,7 @@
 static void
 finch_chat_add_users(PurpleConversation *conv, GList *users, gboolean new_arrivals)
 {
-	FinchConv *ggc = FINCH_GET_DATA(conv);
+	FinchConv *ggc = FINCH_CONV(conv);
 	GntEntry *entry = GNT_ENTRY(ggc->entry);
 
 	if (!new_arrivals)
@@ -1111,7 +1111,7 @@
 finch_chat_rename_user(PurpleConversation *conv, const char *old, const char *new_n, const char *new_a)
 {
 	/* Update the name for string completion */
-	FinchConv *ggc = FINCH_GET_DATA(conv);
+	FinchConv *ggc = FINCH_CONV(conv);
 	GntEntry *entry = GNT_ENTRY(ggc->entry);
 	GntTree *tree = GNT_TREE(ggc->u.chat->userlist);
 	PurpleConvChatBuddy *cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), new_n);
@@ -1129,7 +1129,7 @@
 finch_chat_remove_users(PurpleConversation *conv, GList *list)
 {
 	/* Remove the name from string completion */
-	FinchConv *ggc = FINCH_GET_DATA(conv);
+	FinchConv *ggc = FINCH_CONV(conv);
 	GntEntry *entry = GNT_ENTRY(ggc->entry);
 	for (; list; list = list->next) {
 		GntTree *tree = GNT_TREE(ggc->u.chat->userlist);
@@ -1142,7 +1142,7 @@
 finch_chat_update_user(PurpleConversation *conv, const char *user)
 {
 	PurpleConvChatBuddy *cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), user);
-	FinchConv *ggc = FINCH_GET_DATA(conv);
+	FinchConv *ggc = FINCH_CONV(conv);
 	gnt_tree_change_text(GNT_TREE(ggc->u.chat->userlist), (gpointer)user, 0, chat_flag_text(cb->flags));
 }
 
@@ -1368,7 +1368,7 @@
 static PurpleCmdRet
 users_command_cb(PurpleConversation *conv, const char *cmd, char **args, char **error, gpointer data)
 {
-	FinchConv *fc = FINCH_GET_DATA(conv);
+	FinchConv *fc = FINCH_CONV(conv);
 	FinchConvChat *ch;
 	if (!fc)
 		return PURPLE_CMD_RET_FAILED;
@@ -1494,7 +1494,7 @@
 
 void finch_conversation_set_active(PurpleConversation *conv)
 {
-	FinchConv *ggconv = FINCH_GET_DATA(conv);
+	FinchConv *ggconv = FINCH_CONV(conv);
 	PurpleAccount *account;
 	char *title;
 
@@ -1513,7 +1513,7 @@
 
 void finch_conversation_set_info_widget(PurpleConversation *conv, GntWidget *widget)
 {
-	FinchConv *fc = FINCH_GET_DATA(conv);
+	FinchConv *fc = FINCH_CONV(conv);
 	int height, width;
 
 	gnt_box_remove_all(GNT_BOX(fc->info));
--- a/finch/gntconv.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/gntconv.h	Sun Sep 11 04:19:01 2011 +0000
@@ -33,7 +33,7 @@
 #include "conversation.h"
 
 /* Grabs the conv out of a PurpleConverstation */
-#define FINCH_CONV(conv) ((FinchConv *)(conv)->ui_data)
+#define FINCH_CONV(conv) ((FinchConv *)purple_conversation_get_ui_data(conv))
 
 /***************************************************************************
  * @name GNT Conversations API
--- a/finch/gntft.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/gntft.c	Sun Sep 11 04:19:01 2011 +0000
@@ -42,9 +42,6 @@
 #include "gntft.h"
 #include "prefs.h"
 
-#define FINCHXFER(xfer) \
-	(PurpleGntXferUiData *)FINCH_GET_DATA(xfer)
-
 typedef struct
 {
 	gboolean keep_open;
@@ -262,7 +259,7 @@
 
 	for (iter = purple_xfers_get_all(); iter; iter = iter->next) {
 		PurpleXfer *xfer = (PurpleXfer *)iter->data;
-		PurpleGntXferUiData *data = FINCHXFER(xfer);
+		PurpleGntXferUiData *data = purple_xfer_get_ui_data(xfer);
 		if (data->in_list) {
 			finch_xfer_dialog_add_xfer(xfer);
 			finch_xfer_dialog_update_xfer(xfer);
@@ -302,7 +299,7 @@
 
 	purple_xfer_ref(xfer);
 
-	data = FINCHXFER(xfer);
+	data = purple_xfer_get_ui_data(xfer);
 	data->in_list = TRUE;
 
 	finch_xfer_dialog_show();
@@ -340,7 +337,7 @@
 	g_return_if_fail(xfer_dialog != NULL);
 	g_return_if_fail(xfer != NULL);
 
-	data = FINCHXFER(xfer);
+	data = purple_xfer_get_ui_data(xfer);
 
 	if (data == NULL)
 		return;
@@ -370,7 +367,7 @@
 	g_return_if_fail(xfer_dialog != NULL);
 	g_return_if_fail(xfer != NULL);
 
-	data = FINCHXFER(xfer);
+	data = purple_xfer_get_ui_data(xfer);
 
 	if (data == NULL)
 		return;
@@ -416,7 +413,7 @@
 	g_return_if_fail(xfer_dialog != NULL);
 	g_return_if_fail(xfer != NULL);
 
-	if ((data = FINCHXFER(xfer)) == NULL)
+	if ((data = purple_xfer_get_ui_data(xfer)) == NULL)
 		return;
 
 	if (data->in_list == FALSE || data->notified)
@@ -471,9 +468,9 @@
 {
 	PurpleGntXferUiData *data;
 
-	/* This is where we're setting xfer->ui_data for the first time. */
+	/* This is where we're setting xfer's "ui_data" for the first time. */
 	data = g_new0(PurpleGntXferUiData, 1);
-	FINCH_SET_DATA(xfer, data);
+	purple_xfer_set_ui_data(xfer, data);
 }
 
 static void
@@ -481,11 +478,11 @@
 {
 	PurpleGntXferUiData *data;
 
-	data = FINCHXFER(xfer);
+	data = purple_xfer_get_ui_data(xfer);
 	if (data) {
 		g_free(data->name);
 		g_free(data);
-		FINCH_SET_DATA(xfer, NULL);
+		purple_xfer_set_ui_data(xfer, NULL);
 	}
 }
 
--- a/finch/gntnotify.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/gntnotify.c	Sun Sep 11 04:19:01 2011 +0000
@@ -290,7 +290,7 @@
 
 	text = g_string_new("<span>");
 
-	for (l = purple_notify_user_info_get_entries(user_info); l != NULL;
+	for (l = purple_notify_user_info_get_entries(user_info)->head; l != NULL;
 			l = l->next) {
 		PurpleNotifyUserInfoEntry *user_info_entry = l->data;
 		PurpleNotifyUserInfoEntryType type = purple_notify_user_info_entry_get_type(user_info_entry);
@@ -430,6 +430,9 @@
 	{
 		PurpleNotifySearchColumn *column = iter->data;
 		gnt_tree_set_column_title(GNT_TREE(tree), i, column->title);
+
+		if (!purple_notify_searchresult_column_is_visible(column))
+			gnt_tree_set_column_visible(GNT_TREE(tree), i, FALSE);
 		i++;
 	}
 
--- a/finch/gntprefs.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/gntprefs.c	Sun Sep 11 04:19:01 2011 +0000
@@ -62,14 +62,6 @@
 
 void finch_prefs_update_old()
 {
-	const char *str = NULL;
-
-	purple_prefs_rename("/gaim/gnt", "/finch");
-	purple_prefs_rename("/purple/gnt", "/finch");
-
-	if ((str = purple_prefs_get_string("/purple/away/idle_reporting")) &&
-			strcmp(str, "gaim") == 0)
-		purple_prefs_set_string("/purple/away/idle_reporting", "purple");
 }
 
 typedef struct
--- a/finch/gntrequest.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/gntrequest.c	Sun Sep 11 04:19:01 2011 +0000
@@ -41,12 +41,6 @@
 #include "debug.h"
 #include "util.h"
 
-/* XXX: Until gobjectification ... */
-#undef FINCH_GET_DATA
-#undef FINCH_SET_DATA
-#define FINCH_GET_DATA(obj)  purple_request_field_get_ui_data(obj)
-#define FINCH_SET_DATA(obj, data)  purple_request_field_set_ui_data(obj, data)
-
 typedef struct
 {
 	void *user_data;
@@ -323,26 +317,26 @@
 				continue;
 			if (type == PURPLE_REQUEST_FIELD_BOOLEAN)
 			{
-				GntWidget *check = FINCH_GET_DATA(field);
+				GntWidget *check = purple_request_field_get_ui_data(field);
 				gboolean value = gnt_check_box_get_checked(GNT_CHECK_BOX(check));
 				purple_request_field_bool_set_value(field, value);
 			}
 			else if (type == PURPLE_REQUEST_FIELD_STRING)
 			{
-				GntWidget *entry = FINCH_GET_DATA(field);
+				GntWidget *entry = purple_request_field_get_ui_data(field);
 				const char *text = gnt_entry_get_text(GNT_ENTRY(entry));
 				purple_request_field_string_set_value(field, (text && *text) ? text : NULL);
 			}
 			else if (type == PURPLE_REQUEST_FIELD_INTEGER)
 			{
-				GntWidget *entry = FINCH_GET_DATA(field);
+				GntWidget *entry = purple_request_field_get_ui_data(field);
 				const char *text = gnt_entry_get_text(GNT_ENTRY(entry));
 				int value = (text && *text) ? atoi(text) : 0;
 				purple_request_field_int_set_value(field, value);
 			}
 			else if (type == PURPLE_REQUEST_FIELD_CHOICE)
 			{
-				GntWidget *combo = FINCH_GET_DATA(field);
+				GntWidget *combo = purple_request_field_get_ui_data(field);
 				int id;
 				id = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo)));
 				purple_request_field_choice_set_value(field, id);
@@ -352,7 +346,7 @@
 				GList *list = NULL, *iter;
 				if (purple_request_field_list_get_multi_select(field))
 				{
-					GntWidget *tree = FINCH_GET_DATA(field);
+					GntWidget *tree = purple_request_field_get_ui_data(field);
 
 					iter = purple_request_field_list_get_items(field);
 					for (; iter; iter = iter->next)
@@ -365,7 +359,7 @@
 				}
 				else
 				{
-					GntWidget *combo = FINCH_GET_DATA(field);
+					GntWidget *combo = purple_request_field_get_ui_data(field);
 					gpointer data = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo));
 
 					iter = purple_request_field_list_get_items(field);
@@ -384,7 +378,7 @@
 			}
 			else if (type == PURPLE_REQUEST_FIELD_ACCOUNT)
 			{
-				GntWidget *combo = FINCH_GET_DATA(field);
+				GntWidget *combo = purple_request_field_get_ui_data(field);
 				PurpleAccount *acc = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo));
 				purple_request_field_account_set_value(field, acc);
 			}
@@ -633,36 +627,36 @@
 
 			if (type == PURPLE_REQUEST_FIELD_BOOLEAN)
 			{
-				FINCH_SET_DATA(field, create_boolean_field(field));
+				purple_request_field_set_ui_data(field, create_boolean_field(field));
 			}
 			else if (type == PURPLE_REQUEST_FIELD_STRING)
 			{
-				FINCH_SET_DATA(field, create_string_field(field, &username));
+				purple_request_field_set_ui_data(field, create_string_field(field, &username));
 			}
 			else if (type == PURPLE_REQUEST_FIELD_INTEGER)
 			{
-				FINCH_SET_DATA(field, create_integer_field(field));
+				purple_request_field_set_ui_data(field, create_integer_field(field));
 			}
 			else if (type == PURPLE_REQUEST_FIELD_CHOICE)
 			{
-				FINCH_SET_DATA(field, create_choice_field(field));
+				purple_request_field_set_ui_data(field, create_choice_field(field));
 			}
 			else if (type == PURPLE_REQUEST_FIELD_LIST)
 			{
-				FINCH_SET_DATA(field, create_list_field(field));
+				purple_request_field_set_ui_data(field, create_list_field(field));
 			}
 			else if (type == PURPLE_REQUEST_FIELD_ACCOUNT)
 			{
 				accountlist = create_account_field(field);
-				FINCH_SET_DATA(field, accountlist);
+				purple_request_field_set_ui_data(field, accountlist);
 			}
 			else
 			{
-				FINCH_SET_DATA(field, gnt_label_new_with_format(_("Not implemented yet."),
+				purple_request_field_set_ui_data(field, gnt_label_new_with_format(_("Not implemented yet."),
 						GNT_TEXT_FLAG_BOLD));
 			}
 			gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
-			gnt_box_add_widget(GNT_BOX(hbox), GNT_WIDGET(FINCH_GET_DATA(field)));
+			gnt_box_add_widget(GNT_BOX(hbox), GNT_WIDGET(purple_request_field_get_ui_data(field)));
 		}
 		if (grlist->next)
 			gnt_box_add_widget(GNT_BOX(box), gnt_hline_new());
--- a/finch/gntroomlist.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/gntroomlist.c	Sun Sep 11 04:19:01 2011 +0000
@@ -41,6 +41,7 @@
 
 #define PREF_ROOT "/finch/roomlist"
 
+
 /* Yes, just one roomlist at a time. Let's not get greedy. Aight? */
 struct _FinchRoomlist
 {
@@ -146,9 +147,9 @@
 			purple_roomlist_room_join(froomlist.roomlist, room);
 			break;
 		case PURPLE_ROOMLIST_ROOMTYPE_CATEGORY:
-			if (!room->expanded_once) {
+			if (!purple_roomlist_room_get_expanded_once(room)) {
 				purple_roomlist_expand_category(froomlist.roomlist, room);
-				room->expanded_once = TRUE;
+				purple_roomlist_room_set_expanded_once(room, TRUE);
 			}
 			break;
 	}
@@ -343,7 +344,7 @@
 static void
 fl_create(PurpleRoomlist *list)
 {
-	FINCH_SET_DATA(list, &froomlist);
+	purple_roomlist_set_ui_data(list, &froomlist);
 	setup_roomlist(NULL);
 	update_roomlist(list);
 }
--- a/finch/libgnt/gntfilesel.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/libgnt/gntfilesel.h	Sun Sep 11 04:19:01 2011 +0000
@@ -81,7 +81,7 @@
 	void (*gnt_reserved4)(void);
 };
 
-typedef enum _GntFileType
+typedef enum
 {
 	GNT_FILE_REGULAR,
 	GNT_FILE_DIR
--- a/finch/libgnt/gntprogressbar.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/libgnt/gntprogressbar.h	Sun Sep 11 04:19:01 2011 +0000
@@ -37,7 +37,7 @@
 #define GNT_IS_PROGRESS_BAR_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), GNT_TYPE_PROGRESS_BAR))
 #define GNT_PROGRESS_BAR_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), GNT_TYPE_PROGRESS_BAR, GntProgressBarClass))
 
-typedef enum _GntProgressBarOrientation
+typedef enum
 {
    GNT_PROGRESS_LEFT_TO_RIGHT,
    GNT_PROGRESS_RIGHT_TO_LEFT,
--- a/finch/libgnt/gnttree.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/libgnt/gnttree.h	Sun Sep 11 04:19:01 2011 +0000
@@ -47,7 +47,7 @@
 typedef struct _GntTreeRow		GntTreeRow;
 typedef struct _GntTreeCol		GntTreeCol;
 
-typedef enum _GntTreeColumnFlag {
+typedef enum {
 	GNT_TREE_COLUMN_INVISIBLE    = 1 << 0,
 	GNT_TREE_COLUMN_FIXED_SIZE   = 1 << 1,
 	GNT_TREE_COLUMN_BINARY_DATA  = 1 << 2,
--- a/finch/libgnt/gntwidget.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/libgnt/gntwidget.h	Sun Sep 11 04:19:01 2011 +0000
@@ -49,7 +49,7 @@
 typedef struct _GntWidgetPriv		GntWidgetPriv;
 typedef struct _GntWidgetClass		GntWidgetClass;
 
-typedef enum _GntWidgetFlags
+typedef enum
 {
 	GNT_WIDGET_DESTROYING     = 1 << 0,
 	GNT_WIDGET_CAN_TAKE_FOCUS = 1 << 1,
@@ -69,7 +69,7 @@
 } GntWidgetFlags;
 
 /* XXX: This will probably move elsewhere */
-typedef enum _GntMouseEvent
+typedef enum
 {
 	GNT_LEFT_MOUSE_DOWN = 1,
 	GNT_RIGHT_MOUSE_DOWN,
@@ -80,7 +80,7 @@
 } GntMouseEvent;
 
 /* XXX: I'll have to ask grim what he's using this for in guifications. */
-typedef enum _GntParamFlags
+typedef enum
 {
 	GNT_PARAM_SERIALIZABLE	= 1 << G_PARAM_USER_SHIFT
 } GntParamFlags;
--- a/finch/libgnt/gntwm.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/libgnt/gntwm.h	Sun Sep 11 04:19:01 2011 +0000
@@ -41,7 +41,7 @@
 #define GNT_IS_WM_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WM))
 #define GNT_WM_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_WM, GntWMClass))
 
-typedef enum _GntKeyPressMode
+typedef enum
 {
 	GNT_KP_MODE_NORMAL,
 	GNT_KP_MODE_RESIZE,
--- a/finch/plugins/gntgf.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/plugins/gntgf.c	Sun Sep 11 04:19:01 2011 +0000
@@ -168,7 +168,7 @@
 		beep();
 
 	if (conv != NULL) {
-		FinchConv *fc = conv->ui_data;
+		FinchConv *fc = FINCH_CONV(conv);
 		if (gnt_widget_has_focus(fc->window))
 			return;
 	}
--- a/finch/plugins/lastlog.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/finch/plugins/lastlog.c	Sun Sep 11 04:19:01 2011 +0000
@@ -60,7 +60,7 @@
 static PurpleCmdRet
 lastlog_cb(PurpleConversation *conv, const char *cmd, char **args, char **error, gpointer null)
 {
-	FinchConv *ggconv = conv->ui_data;
+	FinchConv *ggconv = FINCH_CONV(conv);
 	char **strings = g_strsplit(GNT_TEXT_VIEW(ggconv->tv)->string->str, "\n", 0);
 	GntWidget *win, *tv;
 	int i, j;
--- a/gaim-uninstalled.pc.in	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
- 
-Name: Pidgin (Gaim compatibility)
-Description: Pidgin is a GTK2-based instant messenger application.
-Version: @VERSION@
-Requires: glib-2.0
-Cflags: -I${pc_top_builddir}/${pcfiledir}/libpurple -I${pc_top_builddir}/${pcfiledir}/pidgin
-Libs: ${pc_top_builddir}/${pcfiledir}/libpurple/libpurple.la
--- a/gaim.pc.in	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-Name: Pidgin (Gaim compatibility)
-Description: Pidgin is a GTK2-based instant messenger application.
-Version: @VERSION@
-Requires: glib-2.0
-Cflags: -I${includedir}/libpurple
-Libs: -L${libdir} -lpurple
--- a/libpurple/Makefile.am	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/Makefile.am	Sun Sep 11 04:19:01 2011 +0000
@@ -9,8 +9,8 @@
 		purple-send-async \
 		purple-url-handler \
 		purple.h.in \
-		purple.pc.in \
-		purple-uninstalled.pc.in \
+		purple-3.pc.in \
+		purple-3-uninstalled.pc.in \
 		version.h.in \
 		Makefile.mingw \
 		win32/global.mak \
@@ -30,7 +30,7 @@
 endif
 
 pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = purple.pc
+pkgconfig_DATA = purple-3.pc
 
 SUBDIRS = $(GCONF_DIR) plugins protocols ciphers . tests example
 
@@ -117,7 +117,6 @@
 	desktopitem.h \
 	eventloop.h \
 	ft.h \
-	gaim-compat.h \
 	idle.h \
 	imgstore.h \
 	log.h \
--- a/libpurple/account.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/account.c	Sun Sep 11 04:19:01 2011 +0000
@@ -874,7 +874,7 @@
 		return NULL;
 	}
 
-	ret = purple_account_new(name, _purple_oscar_convert(name, protocol_id)); /* XXX: */
+	ret = purple_account_new(name, protocol_id);
 	g_free(name);
 	g_free(protocol_id);
 
@@ -924,15 +924,6 @@
 		{
 			purple_buddy_icons_set_account_icon(ret, (guchar *)contents, len);
 		}
-		else
-		{
-			/* Try to see if the icon got left behind in the old cache. */
-			g_free(filename);
-			filename = g_build_filename(g_get_home_dir(), ".gaim", "icons", data, NULL);
-			if (g_file_get_contents(filename, &contents, &len, NULL)) {
-				purple_buddy_icons_set_account_icon(ret, (guchar*)contents, len);
-			}
-		}
 
 		g_free(filename);
 		g_free(data);
@@ -2527,7 +2518,7 @@
 }
 
 void
-purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy)
+purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy, const char *message)
 {
 	PurplePluginProtocolInfo *prpl_info = NULL;
 	PurpleConnection *gc;
@@ -2544,40 +2535,13 @@
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
 	if (prpl_info != NULL) {
-		if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy_with_invite))
-			prpl_info->add_buddy_with_invite(gc, buddy, purple_buddy_get_group(buddy), NULL);
-		else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy))
-			prpl_info->add_buddy(gc, buddy, purple_buddy_get_group(buddy));
+		if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy))
+			prpl_info->add_buddy(gc, buddy, purple_buddy_get_group(buddy), message);
 	}
 }
 
 void
-purple_account_add_buddy_with_invite(PurpleAccount *account, PurpleBuddy *buddy, const char *message)
-{
-	PurplePluginProtocolInfo *prpl_info = NULL;
-	PurpleConnection *gc;
-	PurplePlugin *prpl = NULL;
-
-	g_return_if_fail(account != NULL);
-	g_return_if_fail(buddy != NULL);
-
-	gc = purple_account_get_connection(account);
-	if (gc != NULL)
-		prpl = purple_connection_get_prpl(gc);
-
-	if (prpl != NULL)
-		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
-	if (prpl_info != NULL) {
-		if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy_with_invite))
-			prpl_info->add_buddy_with_invite(gc, buddy, purple_buddy_get_group(buddy), message);
-		else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy))
-			prpl_info->add_buddy(gc, buddy, purple_buddy_get_group(buddy));
-	}
-}
-
-void
-purple_account_add_buddies(PurpleAccount *account, GList *buddies)
+purple_account_add_buddies(PurpleAccount *account, GList *buddies, const char *message)
 {
 	PurplePluginProtocolInfo *prpl_info = NULL;
 	PurpleConnection *gc = purple_account_get_connection(account);
@@ -2598,73 +2562,13 @@
 			groups = g_list_append(groups, purple_buddy_get_group(buddy));
 		}
 
-		if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddies_with_invite))
-			prpl_info->add_buddies_with_invite(gc, buddies, groups, NULL);
-		else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddies))
-			prpl_info->add_buddies(gc, buddies, groups);
-		else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy_with_invite)) {
-			GList *curb = buddies, *curg = groups;
-
-			while ((curb != NULL) && (curg != NULL)) {
-				prpl_info->add_buddy_with_invite(gc, curb->data, curg->data, NULL);
-				curb = curb->next;
-				curg = curg->next;
-			}
-		}
+		if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddies))
+			prpl_info->add_buddies(gc, buddies, groups, message);
 		else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy)) {
 			GList *curb = buddies, *curg = groups;
 
 			while ((curb != NULL) && (curg != NULL)) {
-				prpl_info->add_buddy(gc, curb->data, curg->data);
-				curb = curb->next;
-				curg = curg->next;
-			}
-		}
-
-		g_list_free(groups);
-	}
-}
-
-void
-purple_account_add_buddies_with_invite(PurpleAccount *account, GList *buddies, const char *message)
-{
-	PurplePluginProtocolInfo *prpl_info = NULL;
-	PurpleConnection *gc = purple_account_get_connection(account);
-	PurplePlugin *prpl = NULL;
-
-	if (gc != NULL)
-		prpl = purple_connection_get_prpl(gc);
-
-	if (prpl != NULL)
-		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
-	if (prpl_info) {
-		GList *cur, *groups = NULL;
-
-		/* Make a list of what group each buddy is in */
-		for (cur = buddies; cur != NULL; cur = cur->next) {
-			PurpleBuddy *buddy = cur->data;
-			groups = g_list_append(groups, purple_buddy_get_group(buddy));
-		}
-
-		if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddies_with_invite))
-			prpl_info->add_buddies_with_invite(gc, buddies, groups, message);
-		else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy_with_invite)) {
-			GList *curb = buddies, *curg = groups;
-
-			while ((curb != NULL) && (curg != NULL)) {
-				prpl_info->add_buddy_with_invite(gc, curb->data, curg->data, message);
-				curb = curb->next;
-				curg = curg->next;
-			}
-		}
-		else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddies))
-			prpl_info->add_buddies(gc, buddies, groups);
-		else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy)) {
-			GList *curb = buddies, *curg = groups;
-
-			while ((curb != NULL) && (curg != NULL)) {
-				prpl_info->add_buddy(gc, curb->data, curg->data);
+				prpl_info->add_buddy(gc, curb->data, curg->data, message);
 				curb = curb->next;
 				curg = curg->next;
 			}
--- a/libpurple/account.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/account.h	Sun Sep 11 04:19:01 2011 +0000
@@ -958,40 +958,18 @@
  *
  * @param account The account.
  * @param buddy The buddy to add.
- *
- * @deprecated Use purple_account_add_buddy_with_invite and \c NULL message.
+ * @param message The invite message.  This may be ignored by a prpl.
  */
-void purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy);
-/**
- * Adds a buddy to the server-side buddy list for the specified account.
- *
- * @param account The account.
- * @param buddy The buddy to add.
- * @param message The invite message.  This may be ignored by a prpl.
- *
- * @since 2.8.0
- */
-void purple_account_add_buddy_with_invite(PurpleAccount *account, PurpleBuddy *buddy, const char *message);
+void purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy, const char *message);
 
 /**
  * Adds a list of buddies to the server-side buddy list.
  *
  * @param account The account.
  * @param buddies The list of PurpleBlistNodes representing the buddies to add.
- *
- * @deprecated Use purple_account_add_buddies_with_invite and \c NULL message.
+ * @param message The invite message.  This may be ignored by a prpl.
  */
-void purple_account_add_buddies(PurpleAccount *account, GList *buddies);
-/**
- * Adds a list of buddies to the server-side buddy list.
- *
- * @param account The account.
- * @param buddies The list of PurpleBlistNodes representing the buddies to add.
- * @param message The invite message.  This may be ignored by a prpl.
- *
- * @since 2.8.0
- */
-void purple_account_add_buddies_with_invite(PurpleAccount *account, GList *buddies, const char *message);
+void purple_account_add_buddies(PurpleAccount *account, GList *buddies, const char *message);
 
 /**
  * Removes a buddy from the server-side buddy list.
--- a/libpurple/blist.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/blist.c	Sun Sep 11 04:19:01 2011 +0000
@@ -461,19 +461,16 @@
 	PurpleAccount *account;
 	PurpleBuddy *buddy;
 	char *name = NULL, *alias = NULL;
-	const char *acct_name, *proto, *protocol;
+	const char *acct_name, *proto;
 	xmlnode *x;
 
 	acct_name = xmlnode_get_attrib(bnode, "account");
-	protocol = xmlnode_get_attrib(bnode, "protocol");
-	protocol = _purple_oscar_convert(acct_name, protocol); /* XXX: Remove */
 	proto = xmlnode_get_attrib(bnode, "proto");
-	proto = _purple_oscar_convert(acct_name, proto); /* XXX: Remove */
-
-	if (!acct_name || (!proto && !protocol))
+
+	if (!acct_name || !proto)
 		return;
 
-	account = purple_accounts_find(acct_name, proto ? proto : protocol);
+	account = purple_accounts_find(acct_name, proto);
 
 	if (!account)
 		return;
@@ -532,19 +529,18 @@
 {
 	PurpleChat *chat;
 	PurpleAccount *account;
-	const char *acct_name, *proto, *protocol;
+	const char *acct_name, *proto;
 	xmlnode *x;
 	char *alias = NULL;
 	GHashTable *components;
 
 	acct_name = xmlnode_get_attrib(cnode, "account");
-	protocol = xmlnode_get_attrib(cnode, "protocol");
 	proto = xmlnode_get_attrib(cnode, "proto");
 
-	if (!acct_name || (!proto && !protocol))
+	if (!acct_name || !proto)
 		return;
 
-	account = purple_accounts_find(acct_name, proto ? proto : protocol);
+	account = purple_accounts_find(acct_name, proto);
 
 	if (!account)
 		return;
@@ -630,17 +626,16 @@
 			xmlnode *x;
 			PurpleAccount *account;
 			int imode;
-			const char *acct_name, *proto, *mode, *protocol;
+			const char *acct_name, *proto, *mode;
 
 			acct_name = xmlnode_get_attrib(anode, "name");
-			protocol = xmlnode_get_attrib(anode, "protocol");
 			proto = xmlnode_get_attrib(anode, "proto");
 			mode = xmlnode_get_attrib(anode, "mode");
 
-			if (!acct_name || (!proto && !protocol) || !mode)
+			if (!acct_name || !proto || !mode)
 				continue;
 
-			account = purple_accounts_find(acct_name, proto ? proto : protocol);
+			account = purple_accounts_find(acct_name, proto);
 
 			if (!account)
 				continue;
@@ -1318,7 +1313,7 @@
 
 				purple_account_remove_buddies(account, buddies, groups);
 				g_list_free(groups);
-				purple_account_add_buddies(account, buddies);
+				purple_account_add_buddies(account, buddies, NULL);
 			}
 
 			g_list_free(buddies);
--- a/libpurple/buddyicon.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/buddyicon.c	Sun Sep 11 04:19:01 2011 +0000
@@ -105,9 +105,6 @@
 /** "Should icons be cached to disk?" */
 static gboolean    icon_caching  = TRUE;
 
-/* For ~/.gaim to ~/.purple migration. */
-static char *old_icons_dir = NULL;
-
 static void delete_buddy_icon_settings(PurpleBlistNode *node, const char *setting_name);
 
 /*
@@ -759,7 +756,7 @@
 	else
 		g_hash_table_remove(pointer_icon_cache, account);
 
-	if (purple_account_is_connected(account))
+	if (!purple_account_is_disconnected(account))
 	{
 		PurpleConnection *gc;
 		PurplePluginProtocolInfo *prpl_info;
@@ -958,31 +955,6 @@
 	return purple_buddy_icons_node_set_custom_icon(node, data, len);
 }
 
-gboolean
-purple_buddy_icons_has_custom_icon(PurpleContact *contact)
-{
-	return purple_buddy_icons_node_has_custom_icon((PurpleBlistNode*)contact);
-}
-
-PurpleStoredImage *
-purple_buddy_icons_find_custom_icon(PurpleContact *contact)
-{
-	return purple_buddy_icons_node_find_custom_icon((PurpleBlistNode*)contact);
-}
-
-PurpleStoredImage *
-purple_buddy_icons_set_custom_icon(PurpleContact *contact, guchar *icon_data,
-                                   size_t icon_len)
-{
-	return purple_buddy_icons_node_set_custom_icon((PurpleBlistNode*)contact, icon_data, icon_len);
-}
-
-void
-_purple_buddy_icon_set_old_icons_dir(const char *dirname)
-{
-	old_icons_dir = g_strdup(dirname);
-}
-
 static void
 delete_buddy_icon_settings(PurpleBlistNode *node, const char *setting_name)
 {
@@ -995,133 +967,6 @@
 	}
 }
 
-static void
-migrate_buddy_icon(PurpleBlistNode *node, const char *setting_name,
-                   const char *dirname, const char *filename)
-{
-	char *path;
-
-	if (filename[0] != '/')
-	{
-		path = g_build_filename(dirname, filename, NULL);
-		if (g_file_test(path, G_FILE_TEST_EXISTS))
-		{
-			g_free(path);
-			return;
-		}
-		g_free(path);
-
-		path = g_build_filename(old_icons_dir, filename, NULL);
-	}
-	else
-		path = g_strdup(filename);
-
-	if (g_file_test(path, G_FILE_TEST_EXISTS))
-	{
-		guchar *icon_data;
-		size_t icon_len;
-		FILE *file;
-		char *new_filename;
-
-		if (!read_icon_file(path, &icon_data, &icon_len))
-		{
-			g_free(path);
-			delete_buddy_icon_settings(node, setting_name);
-			return;
-		}
-
-		if (icon_data == NULL || icon_len <= 0)
-		{
-			/* This really applies to the icon_len check.
-			 * icon_data should never be NULL if
-			 * read_icon_file() returns TRUE. */
-			purple_debug_error("buddyicon", "Empty buddy icon file: %s\n", path);
-			delete_buddy_icon_settings(node, setting_name);
-			g_free(path);
-			return;
-		}
-
-		g_free(path);
-
-		new_filename = purple_util_get_image_filename(icon_data, icon_len);
-		if (new_filename == NULL)
-		{
-			purple_debug_error("buddyicon",
-				"New icon filename is NULL. This should never happen! "
-				"The old filename was: %s\n", path);
-			delete_buddy_icon_settings(node, setting_name);
-			g_return_if_reached();
-		}
-
-		path = g_build_filename(dirname, new_filename, NULL);
-		if ((file = g_fopen(path, "wb")) != NULL)
-		{
-			if (!fwrite(icon_data, icon_len, 1, file))
-			{
-				purple_debug_error("buddyicon", "Error writing %s: %s\n",
-				                   path, g_strerror(errno));
-			}
-			else
-				purple_debug_info("buddyicon", "Wrote migrated cache file: %s\n", path);
-
-			fclose(file);
-		}
-		else
-		{
-			purple_debug_error("buddyicon", "Unable to create file %s: %s\n",
-			                   path, g_strerror(errno));
-			g_free(new_filename);
-			g_free(path);
-
-			delete_buddy_icon_settings(node, setting_name);
-			return;
-		}
-		g_free(path);
-
-		purple_blist_node_set_string(node,
-		                             setting_name,
-		                             new_filename);
-		ref_filename(new_filename);
-
-		g_free(new_filename);
-
-		if (purple_strequal(setting_name, "buddy_icon"))
-		{
-			const char *hash;
-
-			hash = purple_blist_node_get_string(node, "avatar_hash");
-			if (hash != NULL)
-			{
-				purple_blist_node_set_string(node, "icon_checksum", hash);
-				purple_blist_node_remove_setting(node, "avatar_hash");
-			}
-			else
-			{
-				PurpleAccount *account = purple_buddy_get_account((PurpleBuddy *)node);
-				const char *prpl_id = purple_account_get_protocol_id(account);
-
-				if (g_str_equal(prpl_id, "prpl-yahoo") || g_str_equal(prpl_id, "prpl-yahoojp"))
-				{
-					int checksum = purple_blist_node_get_int(node, "icon_checksum");
-					if (checksum != 0)
-					{
-						char *checksum_str = g_strdup_printf("%i", checksum);
-						purple_blist_node_remove_setting(node, "icon_checksum");
-						purple_blist_node_set_string(node, "icon_checksum", checksum_str);
-						g_free(checksum_str);
-					}
-				}
-			}
-		}
-	}
-	else
-	{
-		purple_debug_error("buddyicon", "Old icon file doesn't exist: %s\n", path);
-		delete_buddy_icon_settings(node, setting_name);
-		g_free(path);
-	}
-}
-
 void
 _purple_buddy_icons_account_loaded_cb()
 {
@@ -1153,22 +998,6 @@
 	PurpleBlistNode *node = purple_blist_get_root();
 	const char *dirname = purple_buddy_icons_get_cache_dir();
 
-	/* Doing this once here saves having to check it inside a loop. */
-	if (old_icons_dir != NULL)
-	{
-		if (!g_file_test(dirname, G_FILE_TEST_IS_DIR))
-		{
-			purple_debug_info("buddyicon", "Creating icon cache directory.\n");
-
-			if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0)
-			{
-				purple_debug_error("buddyicon",
-				                   "Unable to create directory %s: %s\n",
-				                   dirname, g_strerror(errno));
-			}
-		}
-	}
-
 	while (node != NULL)
 	{
 		if (PURPLE_BLIST_NODE_IS_BUDDY(node))
@@ -1178,26 +1007,17 @@
 			filename = purple_blist_node_get_string(node, "buddy_icon");
 			if (filename != NULL)
 			{
-				if (old_icons_dir != NULL)
+				char *path = g_build_filename(dirname, filename, NULL);
+				if (!g_file_test(path, G_FILE_TEST_EXISTS))
 				{
-					migrate_buddy_icon(node,
-					                   "buddy_icon",
-					                   dirname, filename);
+					purple_blist_node_remove_setting(node,
+					                                 "buddy_icon");
+					purple_blist_node_remove_setting(node,
+					                                 "icon_checksum");
 				}
 				else
-				{
-					char *path = g_build_filename(dirname, filename, NULL);
-					if (!g_file_test(path, G_FILE_TEST_EXISTS))
-					{
-						purple_blist_node_remove_setting(node,
-						                                 "buddy_icon");
-						purple_blist_node_remove_setting(node,
-						                                 "icon_checksum");
-					}
-					else
-						ref_filename(filename);
-					g_free(path);
-				}
+					ref_filename(filename);
+				g_free(path);
 			}
 		}
 		else if (PURPLE_BLIST_NODE_IS_CONTACT(node) ||
@@ -1209,24 +1029,15 @@
 			filename = purple_blist_node_get_string(node, "custom_buddy_icon");
 			if (filename != NULL)
 			{
-				if (old_icons_dir != NULL)
+				char *path = g_build_filename(dirname, filename, NULL);
+				if (!g_file_test(path, G_FILE_TEST_EXISTS))
 				{
-					migrate_buddy_icon(node,
-					                   "custom_buddy_icon",
-					                   dirname, filename);
+					purple_blist_node_remove_setting(node,
+					                                 "custom_buddy_icon");
 				}
 				else
-				{
-					char *path = g_build_filename(dirname, filename, NULL);
-					if (!g_file_test(path, G_FILE_TEST_EXISTS))
-					{
-						purple_blist_node_remove_setting(node,
-						                                 "custom_buddy_icon");
-					}
-					else
-						ref_filename(filename);
-					g_free(path);
-				}
+					ref_filename(filename);
+				g_free(path);
 			}
 		}
 		node = purple_blist_node_next(node, TRUE);
@@ -1298,11 +1109,9 @@
 	g_hash_table_destroy(icon_data_cache);
 	g_hash_table_destroy(icon_file_cache);
 	g_hash_table_destroy(pointer_icon_cache);
-	g_free(old_icons_dir);
 	g_free(cache_dir);
 
 	cache_dir = NULL;
-	old_icons_dir = NULL;
 }
 
 void purple_buddy_icon_get_scale_size(PurpleBuddyIconSpec *spec, int *width, int *height)
--- a/libpurple/buddyicon.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/buddyicon.h	Sun Sep 11 04:19:01 2011 +0000
@@ -275,7 +275,6 @@
  * @param node The blist node.
  *
  * @return A boolean indicating if @a node has a custom buddy icon.
- * @since 2.5.0
  */
 gboolean
 purple_buddy_icons_node_has_custom_icon(PurpleBlistNode *node);
@@ -293,7 +292,6 @@
  * @param node The node.
  *
  * @return The custom buddy icon.
- * @since 2.5.0
  */
 PurpleStoredImage *
 purple_buddy_icons_node_find_custom_icon(PurpleBlistNode *node);
@@ -311,7 +309,6 @@
  *
  * @return The icon that was set. The caller does NOT own a reference to this,
  *         and must call purple_imgstore_ref() if it wants one.
- * @since 2.5.0
  */
 PurpleStoredImage *
 purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node,
@@ -329,45 +326,11 @@
  *
  * @return The icon that was set. The caller does NOT own a reference to this,
  *         and must call purple_imgstore_ref() if it wants one.
- * @since 2.5.0
  */
 PurpleStoredImage *
 purple_buddy_icons_node_set_custom_icon_from_file(PurpleBlistNode *node,
                                                   const gchar *filename);
 
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_BUDDYICON_C_)
-/**
- * PurpleContact version of purple_buddy_icons_node_has_custom_icon.
- *
- * @copydoc purple_buddy_icons_node_has_custom_icon()
- *
- * @deprecated Use purple_buddy_icons_node_has_custom_icon instead.
- */
-gboolean
-purple_buddy_icons_has_custom_icon(PurpleContact *contact);
-
-/**
- * PurpleContact version of purple_buddy_icons_node_find_custom_icon.
- *
- * @copydoc purple_buddy_icons_node_find_custom_icon()
- *
- * @deprecated Use purple_buddy_icons_node_find_custom_icon instead.
- */
-PurpleStoredImage *
-purple_buddy_icons_find_custom_icon(PurpleContact *contact);
-
-/**
- * PurpleContact version of purple_buddy_icons_node_set_custom_icon.
- *
- * @copydoc purple_buddy_icons_node_set_custom_icon()
- *
- * @deprecated Use purple_buddy_icons_node_set_custom_icon instead.
- */
-PurpleStoredImage *
-purple_buddy_icons_set_custom_icon(PurpleContact *contact,
-                                   guchar *icon_data, size_t icon_len);
-#endif
-
 /**
  * Sets whether or not buddy icon caching is enabled.
  *
--- a/libpurple/certificate.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/certificate.c	Sun Sep 11 04:19:01 2011 +0000
@@ -1704,7 +1704,7 @@
 		flags |= PURPLE_CERTIFICATE_CA_UNKNOWN;
 
 		purple_debug_warning("certificate/x509/tls_cached",
-				  "No Certificate Authorities with either DN found "
+				  "No Certificate Authorities with either DN "
 				  "found. I'll prompt the user, I guess.\n");
 
 		x509_tls_cached_check_subject_name(vrq, flags);
--- a/libpurple/cipher.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/cipher.h	Sun Sep 11 04:19:01 2011 +0000
@@ -41,7 +41,7 @@
 /**
  * Modes for batch encrypters
  */
-typedef enum _PurpleCipherBatchMode {
+typedef enum {
 	PURPLE_CIPHER_BATCH_MODE_ECB,
 	PURPLE_CIPHER_BATCH_MODE_CBC
 } PurpleCipherBatchMode;
@@ -49,7 +49,7 @@
 /**
  * The operation flags for a cipher
  */
-typedef enum _PurpleCipherCaps {
+typedef enum {
 	PURPLE_CIPHER_CAPS_SET_OPT          = 1 << 1,   /**< Set option flag	*/
 	PURPLE_CIPHER_CAPS_GET_OPT          = 1 << 2,   /**< Get option flag	*/
 	PURPLE_CIPHER_CAPS_INIT             = 1 << 3,   /**< Init flag			*/
--- a/libpurple/cmds.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/cmds.h	Sun Sep 11 04:19:01 2011 +0000
@@ -32,7 +32,7 @@
 /*@{*/
 
 /** The possible results of running a command with purple_cmd_do_command(). */
-typedef enum _PurpleCmdStatus {
+typedef enum {
 	PURPLE_CMD_STATUS_OK,
 	PURPLE_CMD_STATUS_FAILED,
 	PURPLE_CMD_STATUS_NOT_FOUND,
@@ -48,7 +48,7 @@
  *  #PURPLE_CMD_RET_CONTINUE to cause the core to fall through to other
  *  commands with the same name.
  */
-typedef enum _PurpleCmdRet {
+typedef enum {
 	PURPLE_CMD_RET_OK,       /**< Everything's okay; Don't look for another command to call. */
 	PURPLE_CMD_RET_FAILED,   /**< The command failed, but stop looking.*/
 	PURPLE_CMD_RET_CONTINUE /**< Continue, looking for other commands with the same name to call. */
@@ -68,7 +68,7 @@
  */
 typedef guint PurpleCmdId;
 
-typedef enum _PurpleCmdPriority {
+typedef enum {
 	PURPLE_CMD_P_VERY_LOW  = -1000,
 	PURPLE_CMD_P_LOW       =     0,
 	PURPLE_CMD_P_DEFAULT   =  1000,
@@ -85,7 +85,7 @@
  *
  *  @see purple_cmd_register
  */
-typedef enum _PurpleCmdFlag {
+typedef enum {
 	/** Command is usable in IMs. */
 	PURPLE_CMD_FLAG_IM               = 0x01,
 	/** Command is usable in multi-user chats. */
--- a/libpurple/connection.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/connection.c	Sun Sep 11 04:19:01 2011 +0000
@@ -528,22 +528,7 @@
 }
 
 void
-purple_connection_error(PurpleConnection *gc, const char *text)
-{
-	/* prpls that have not been updated to use disconnection reasons will
-	 * be setting wants_to_die before calling this function, so choose
-	 * PURPLE_CONNECTION_ERROR_OTHER_ERROR (which is fatal) if it's true,
-	 * and PURPLE_CONNECTION_ERROR_NETWORK_ERROR (which isn't) if not.  See
-	 * the documentation in connection.h.
-	 */
-	PurpleConnectionError reason = gc->wants_to_die
-	                             ? PURPLE_CONNECTION_ERROR_OTHER_ERROR
-	                             : PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
-	purple_connection_error_reason (gc, reason, text);
-}
-
-void
-purple_connection_error_reason (PurpleConnection *gc,
+purple_connection_error (PurpleConnection *gc,
                                 PurpleConnectionError reason,
                                 const char *description)
 {
@@ -557,13 +542,13 @@
 	 */
 	if (reason > PURPLE_CONNECTION_ERROR_OTHER_ERROR) {
 		purple_debug_error("connection",
-			"purple_connection_error_reason: reason %u isn't a "
+			"purple_connection_error: reason %u isn't a "
 			"valid reason\n", reason);
 		reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
 	}
 
 	if (description == NULL) {
-		purple_debug_error("connection", "purple_connection_error_reason called with NULL description\n");
+		purple_debug_error("connection", "purple_connection_error called with NULL description\n");
 		description = _("Unknown error");
 	}
 
@@ -578,13 +563,8 @@
 
 	ops = purple_connections_get_ui_ops();
 
-	if (ops != NULL)
-	{
-		if (ops->report_disconnect_reason != NULL)
-			ops->report_disconnect_reason (gc, reason, description);
-		if (ops->report_disconnect != NULL)
-			ops->report_disconnect (gc, description);
-	}
+	if (ops && ops->report_disconnect)
+		ops->report_disconnect(gc, reason, description);
 
 	purple_signal_emit(purple_connections_get_handle(), "connection-error",
 		gc, reason, description);
@@ -615,7 +595,7 @@
 			reason = PURPLE_CONNECTION_ERROR_CERT_OTHER_ERROR;
 	}
 
-	purple_connection_error_reason (gc, reason,
+	purple_connection_error (gc, reason,
 		purple_ssl_strerror(ssl_error));
 }
 
--- a/libpurple/connection.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/connection.h	Sun Sep 11 04:19:01 2011 +0000
@@ -128,7 +128,7 @@
 	/** Some other error occurred which fits into none of the other
 	 *  categories.
 	 */
-	/* purple_connection_error_reason() in connection.c uses the fact that
+	/* purple_connection_error() in connection.c uses the fact that
 	 * this is the last member of the enum when sanity-checking; if other
 	 * reasons are added after it, the check must be updated.
 	 */
@@ -194,16 +194,6 @@
 	void (*notice)(PurpleConnection *gc, const char *text);
 
 	/**
-	 * Called when an error causes a connection to be disconnected.
-	 * Called before #disconnected.
-	 * @param text  a localized error message.
-	 * @see #purple_connection_error
-	 * @deprecated in favour of
-	 *             #PurpleConnectionUiOps.report_disconnect_reason.
-	 */
-	void (*report_disconnect)(PurpleConnection *gc, const char *text);
-
-	/**
 	 * Called when libpurple discovers that the computer's network
 	 * connection is active.  On Linux, this uses Network Manager if
 	 * available; on Windows, it uses Win32's network change notification
@@ -219,21 +209,19 @@
 
 	/**
 	 * Called when an error causes a connection to be disconnected.
-	 *  Called before #disconnected.  This op is intended to replace
-	 *  #report_disconnect.  If both are implemented, this will be called
-	 *  first; however, there's no real reason to implement both.
+	 * Called before #disconnected.
 	 *
-	 *  @param reason  why the connection ended, if known, or
-	 *                 #PURPLE_CONNECTION_ERROR_OTHER_ERROR, if not.
-	 *  @param text  a localized message describing the disconnection
-	 *               in more detail to the user.
-	 *  @see #purple_connection_error_reason
+	 * @param reason  why the connection ended, if known, or
+	 *                #PURPLE_CONNECTION_ERROR_OTHER_ERROR, if not.
+	 * @param text  a localized message describing the disconnection
+	 *              in more detail to the user.
+	 * @see #purple_connection_error
 	 *
-	 *  @since 2.3.0
+	 * @since 2.3.0
 	 */
-	void (*report_disconnect_reason)(PurpleConnection *gc,
-	                                 PurpleConnectionError reason,
-	                                 const char *text);
+	void (*report_disconnect)(PurpleConnection *gc,
+	                          PurpleConnectionError reason,
+	                          const char *text);
 
 	void (*_purple_reserved1)(void);
 	void (*_purple_reserved2)(void);
@@ -264,7 +252,7 @@
 	/** Wants to Die state.  This is set when the user chooses to log out, or
 	 * when the protocol is disconnected and should not be automatically
 	 * reconnected (incorrect password, etc.).  prpls should rely on
-	 * purple_connection_error_reason() to set this for them rather than
+	 * purple_connection_error() to set this for them rather than
 	 * setting it themselves.
 	 * @see purple_connection_error_is_fatal
 	 */
@@ -465,21 +453,6 @@
 void purple_connection_notice(PurpleConnection *gc, const char *text);
 
 /**
- * Closes a connection with an error.
- *
- * @param gc     The connection.
- * @param reason The error text, which may not be @c NULL.
- * @deprecated in favour of #purple_connection_error_reason.  Calling
- *  @c purple_connection_error(gc, text) is equivalent to calling
- *  @c purple_connection_error_reason(gc, reason, text) where @c reason is
- *  #PURPLE_CONNECTION_ERROR_OTHER_ERROR if @c gc->wants_to_die is @c TRUE, and
- *  #PURPLE_CONNECTION_ERROR_NETWORK_ERROR if not.  (This is to keep
- *  auto-reconnection behaviour the same when using old prpls which don't use
- *  reasons yet.)
- */
-void purple_connection_error(PurpleConnection *gc, const char *reason);
-
-/**
  * Closes a connection with an error and a human-readable description of the
  * error.  It also sets @c gc->wants_to_die to the value of
  * #purple_connection_error_is_fatal(@a reason), mainly for
@@ -492,14 +465,14 @@
  * @since 2.3.0
  */
 void
-purple_connection_error_reason (PurpleConnection *gc,
-                                PurpleConnectionError reason,
-                                const char *description);
+purple_connection_error(PurpleConnection *gc,
+                        PurpleConnectionError reason,
+                        const char *description);
 
 /**
  * Closes a connection due to an SSL error; this is basically a shortcut to
  * turning the #PurpleSslErrorType into a #PurpleConnectionError and a
- * human-readable string and then calling purple_connection_error_reason().
+ * human-readable string and then calling purple_connection_error().
  *
  * @since 2.3.0
  */
--- a/libpurple/conversation.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/conversation.c	Sun Sep 11 04:19:01 2011 +0000
@@ -2323,6 +2323,21 @@
 	return msg->when;
 }
 
+void purple_conversation_set_ui_data(PurpleConversation *conv, gpointer ui_data)
+{
+	g_return_if_fail(conv != NULL);
+
+	conv->ui_data = ui_data;
+}
+
+gpointer purple_conversation_get_ui_data(const PurpleConversation *conv)
+{
+	g_return_val_if_fail(conv != NULL, NULL);
+
+	return conv->ui_data;
+}
+
+
 gboolean
 purple_conversation_do_command(PurpleConversation *conv, const gchar *cmdline,
 				const gchar *markup, gchar **error)
--- a/libpurple/conversation.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/conversation.h	Sun Sep 11 04:19:01 2011 +0000
@@ -802,6 +802,25 @@
  */
 time_t purple_conversation_message_get_timestamp(PurpleConvMessage *msg);
 
+/**
+ * Set the UI data associated with this conversation.
+ *
+ * @param conv			The conversation.
+ * @param ui_data		A pointer to associate with this conversation.
+ */
+void purple_conversation_set_ui_data(PurpleConversation *conv, gpointer ui_data);
+
+/**
+ * Get the UI data associated with this conversation.
+ *
+ * @param conv			The conversation.
+ *
+ * @return The UI data associated with this conversation.  This is a
+ *         convenience field provided to the UIs--it is not
+ *         used by the libpurple core.
+ */
+gpointer purple_conversation_get_ui_data(const PurpleConversation *conv);
+
 /*@}*/
 
 
--- a/libpurple/core.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/core.c	Sun Sep 11 04:19:01 2011 +0000
@@ -371,386 +371,6 @@
 	return is_single_instance;
 }
 
-static gboolean
-move_and_symlink_dir(const char *path, const char *basename, const char *old_base, const char *new_base, const char *relative)
-{
-	char *new_name = g_build_filename(new_base, basename, NULL);
-#ifndef _WIN32
-	char *old_name;
-#endif
-	if (g_rename(path, new_name))
-	{
-		purple_debug_error("core", "Error renaming %s to %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-		                   path, new_name, g_strerror(errno));
-		g_free(new_name);
-		return FALSE;
-	}
-	g_free(new_name);
-
-#ifndef _WIN32
-	/* NOTE: This new_name is relative. */
-	new_name = g_build_filename(relative, basename, NULL);
-	old_name = g_build_filename(old_base, basename, NULL);
-	if (symlink(new_name, old_name))
-	{
-		purple_debug_warning("core", "Error symlinking %s to %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-		                     old_name, new_name, g_strerror(errno));
-	}
-	g_free(old_name);
-	g_free(new_name);
-#endif
-
-	return TRUE;
-}
-
-gboolean
-purple_core_migrate(void)
-{
-	const char *user_dir = purple_user_dir();
-	char *old_user_dir = g_strconcat(purple_home_dir(),
-	                                 G_DIR_SEPARATOR_S ".gaim", NULL);
-	char *status_file;
-	FILE *fp;
-	GDir *dir;
-	GError *err;
-	const char *entry;
-#ifndef _WIN32
-	char *logs_dir;
-#endif
-	char *old_icons_dir;
-
-	if (!g_file_test(old_user_dir, G_FILE_TEST_EXISTS))
-	{
-		/* ~/.gaim doesn't exist, so there's nothing to migrate. */
-		g_free(old_user_dir);
-		return TRUE;
-	}
-
-	status_file = g_strconcat(user_dir, G_DIR_SEPARATOR_S "migrating", NULL);
-
-	if (g_file_test(user_dir, G_FILE_TEST_EXISTS))
-	{
-		/* If we're here, we have both ~/.gaim and .purple. */
-
-		if (!g_file_test(status_file, G_FILE_TEST_EXISTS))
-		{
-			/* There's no "migrating" status file,
-			 * so ~/.purple is all up to date. */
-			g_free(status_file);
-			g_free(old_user_dir);
-			return TRUE;
-		}
-	}
-
-	/* If we're here, it's time to migrate from ~/.gaim to ~/.purple. */
-
-        /* Ensure the user directory exists */
-	if (!g_file_test(user_dir, G_FILE_TEST_IS_DIR))
-	{
-		if (g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
-		{
-			purple_debug_error("core", "Error creating directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-			                   user_dir, g_strerror(errno));
-			g_free(status_file);
-			g_free(old_user_dir);
-			return FALSE;
-		}
-	}
-
-	/* This writes ~/.purple/migrating, which allows us to detect
-	 * incomplete migrations and properly retry. */
-	if (!(fp = g_fopen(status_file, "w")))
-	{
-		purple_debug_error("core", "Error opening file %s for writing: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-		                   status_file, g_strerror(errno));
-		g_free(status_file);
-		g_free(old_user_dir);
-		return FALSE;
-	}
-	fclose(fp);
-
-	/* Open ~/.gaim so we can loop over its contents. */
-	err = NULL;
-	if (!(dir = g_dir_open(old_user_dir, 0, &err)))
-	{
-		purple_debug_error("core", "Error opening directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-		                   status_file,
-		                   (err ? err->message : "Unknown error"));
-		if (err)
-			g_error_free(err);
-		g_free(status_file);
-		g_free(old_user_dir);
-		return FALSE;
-	}
-
-	/* Loop over the contents of ~/.gaim */
-	while ((entry = g_dir_read_name(dir)))
-	{
-		char *name = g_build_filename(old_user_dir, entry, NULL);
-
-#ifndef _WIN32
-		/* Deal with symlinks... */
-		if (g_file_test(name, G_FILE_TEST_IS_SYMLINK))
-		{
-			/* We're only going to duplicate a logs symlink. */
-			if (purple_strequal(entry, "logs"))
-			{
-				char *link;
-				err = NULL;
-
-				if ((link = g_file_read_link(name, &err)) == NULL)
-				{
-					char *name_utf8 = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
-					purple_debug_error("core", "Error reading symlink %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-					                   name_utf8 ? name_utf8 : name, err->message);
-					g_free(name_utf8);
-					g_error_free(err);
-					g_free(name);
-					g_dir_close(dir);
-					g_free(status_file);
-					g_free(old_user_dir);
-					return FALSE;
-				}
-
-				logs_dir = g_build_filename(user_dir, "logs", NULL);
-
-				if (purple_strequal(link, "../.purple/logs") ||
-				    purple_strequal(link, logs_dir))
-				{
-					/* If the symlink points to the new directory, we're
-					 * likely just trying again after a failed migration,
-					 * so there's no need to fail here. */
-					g_free(link);
-					g_free(logs_dir);
-					continue;
-				}
-
-				/* In case we are trying again after a failed migration, we need
-				 * to unlink any existing symlink.  If it's a directory, this
-				 * will fail, and so will the symlink below, which is good
-				 * because the user should sort things out. */
-				g_unlink(logs_dir);
-
-				/* Relative links will most likely still be
-				 * valid from ~/.purple, though it's not
-				 * guaranteed.  Oh well. */
-				if (symlink(link, logs_dir))
-				{
-					purple_debug_error("core", "Error symlinking %s to %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-					                   logs_dir, link, g_strerror(errno));
-					g_free(link);
-					g_free(name);
-					g_free(logs_dir);
-					g_dir_close(dir);
-					g_free(status_file);
-					g_free(old_user_dir);
-					return FALSE;
-				}
-
-				g_free(link);
-				g_free(logs_dir);
-				continue;
-			}
-
-			/* Ignore all other symlinks. */
-			continue;
-		}
-#endif
-
-		/* Deal with directories... */
-		if (g_file_test(name, G_FILE_TEST_IS_DIR))
-		{
-			if (purple_strequal(entry, "icons"))
-			{
-				/* This is a special case for the Album plugin, which
-				 * stores data in the icons folder.  We're not copying
-				 * the icons directory over because previous bugs
-				 * meant that it filled up with junk for many users.
-				 * This is a great time to purge it. */
-
-				GDir *icons_dir;
-				char *new_icons_dir;
-				const char *icons_entry;
-
-				err = NULL;
-				if (!(icons_dir = g_dir_open(name, 0, &err)))
-				{
-					purple_debug_error("core", "Error opening directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-					                   name,
-					                   (err ? err->message : "Unknown error"));
-					if (err)
-						g_error_free(err);
-					g_free(name);
-					g_dir_close(dir);
-					g_free(status_file);
-					g_free(old_user_dir);
-					return FALSE;
-				}
-
-				new_icons_dir = g_build_filename(user_dir, "icons", NULL);
-			        /* Ensure the new icon directory exists */
-				if (!g_file_test(new_icons_dir, G_FILE_TEST_IS_DIR))
-				{
-					if (g_mkdir(new_icons_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
-					{
-						purple_debug_error("core", "Error creating directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-						                   new_icons_dir, g_strerror(errno));
-						g_free(new_icons_dir);
-						g_dir_close(icons_dir);
-						g_free(name);
-						g_dir_close(dir);
-						g_free(status_file);
-						g_free(old_user_dir);
-						return FALSE;
-					}
-				}
-
-				while ((icons_entry = g_dir_read_name(icons_dir)))
-				{
-					char *icons_name = g_build_filename(name, icons_entry, NULL);
-
-					if (g_file_test(icons_name, G_FILE_TEST_IS_DIR))
-					{
-						if (!move_and_symlink_dir(icons_name, icons_entry,
-						                          name, new_icons_dir, "../../.purple/icons"))
-						{
-							g_free(icons_name);
-							g_free(new_icons_dir);
-							g_dir_close(icons_dir);
-							g_free(name);
-							g_dir_close(dir);
-							g_free(status_file);
-							g_free(old_user_dir);
-							return FALSE;
-						}
-					}
-					g_free(icons_name);
-				}
-
-				g_dir_close(icons_dir);
-			}
-			else if (purple_strequal(entry, "plugins"))
-			{
-				/* Do nothing, because we broke plugin compatibility.
-				 * This means that the plugins directory gets left behind. */
-			}
-			else
-			{
-				/* All other directories are moved and symlinked. */
-				if (!move_and_symlink_dir(name, entry, old_user_dir, user_dir, "../.purple"))
-				{
-					g_free(name);
-					g_dir_close(dir);
-					g_free(status_file);
-					g_free(old_user_dir);
-					return FALSE;
-				}
-			}
-		}
-		else if (g_file_test(name, G_FILE_TEST_IS_REGULAR))
-		{
-			/* Regular files are copied. */
-
-			char *new_name;
-			FILE *new_file;
-
-			if (!(fp = g_fopen(name, "rb")))
-			{
-				purple_debug_error("core", "Error opening file %s for reading: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-				                   name, g_strerror(errno));
-				g_free(name);
-				g_dir_close(dir);
-				g_free(status_file);
-				g_free(old_user_dir);
-				return FALSE;
-			}
-
-			new_name = g_build_filename(user_dir, entry, NULL);
-			if (!(new_file = g_fopen(new_name, "wb")))
-			{
-				purple_debug_error("core", "Error opening file %s for writing: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-				                   new_name, g_strerror(errno));
-				fclose(fp);
-				g_free(new_name);
-				g_free(name);
-				g_dir_close(dir);
-				g_free(status_file);
-				g_free(old_user_dir);
-				return FALSE;
-			}
-
-			while (!feof(fp))
-			{
-				unsigned char buf[256];
-				size_t size;
-
-				size = fread(buf, 1, sizeof(buf), fp);
-				if (size != sizeof(buf) && !feof(fp))
-				{
-					purple_debug_error("core", "Error reading %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-					                   name, g_strerror(errno));
-					fclose(new_file);
-					fclose(fp);
-					g_free(new_name);
-					g_free(name);
-					g_dir_close(dir);
-					g_free(status_file);
-					g_free(old_user_dir);
-					return FALSE;
-				}
-
-				if (!fwrite(buf, size, 1, new_file) && ferror(new_file) != 0)
-				{
-					purple_debug_error("core", "Error writing %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-					                   new_name, g_strerror(errno));
-					fclose(new_file);
-					fclose(fp);
-					g_free(new_name);
-					g_free(name);
-					g_dir_close(dir);
-					g_free(status_file);
-					g_free(old_user_dir);
-					return FALSE;
-				}
-			}
-
-			if (fclose(new_file))
-			{
-				purple_debug_error("core", "Error writing: %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-				                   new_name, g_strerror(errno));
-			}
-			if (fclose(fp))
-			{
-				purple_debug_warning("core", "Error closing %s: %s\n",
-				                     name, g_strerror(errno));
-			}
-			g_free(new_name);
-		}
-		else
-			purple_debug_warning("core", "Not a regular file or directory: %s\n", name);
-
-		g_free(name);
-	}
-
-	/* The migration was successful, so delete the status file. */
-	if (g_unlink(status_file))
-	{
-		purple_debug_error("core", "Error unlinking file %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
-		                   status_file, g_strerror(errno));
-		g_free(status_file);
-		return FALSE;
-	}
-
-	old_icons_dir = g_build_filename(old_user_dir, "icons", NULL);
-	_purple_buddy_icon_set_old_icons_dir(old_icons_dir);
-	g_free(old_icons_dir);
-
-	g_free(old_user_dir);
-
-	g_free(status_file);
-	return TRUE;
-}
-
 GHashTable* purple_core_get_ui_info() {
 	PurpleCoreUiOps *ops = purple_core_get_ui_ops();
 
--- a/libpurple/core.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/core.h	Sun Sep 11 04:19:01 2011 +0000
@@ -156,17 +156,6 @@
 PurpleCoreUiOps *purple_core_get_ui_ops(void);
 
 /**
- * Migrates from <tt>.gaim</tt> to <tt>.purple</tt>.
- *
- * UIs <strong>must not</strong> call this if they have been told to use a
- * custom user directory.
- *
- * @return A boolean indicating success or migration failure. On failure,
- *         the application must display an error to the user and then exit.
- */
-gboolean purple_core_migrate(void);
-
-/**
  * Ensures that only one instance is running.  If libpurple is built with D-Bus
  * support, this checks if another process owns the libpurple bus name and if
  * so whether that process is using the same configuration directory as this
--- a/libpurple/dbus-server.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/dbus-server.c	Sun Sep 11 04:19:01 2011 +0000
@@ -711,7 +711,7 @@
 			g_return_val_if_fail(ptr, TRUE);
 		}
 
-		switch (purple_values[i]->type)
+		switch (purple_value_get_type(purple_values[i]))
 		{
 		case PURPLE_TYPE_INT:
 		case PURPLE_TYPE_ENUM:
--- a/libpurple/dnsquery.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/dnsquery.c	Sun Sep 11 04:19:01 2011 +0000
@@ -297,6 +297,10 @@
 		}
 		rc = read(child_in, &dns_params, sizeof(dns_params_t));
 		if (rc < 0) {
+			if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
+				/* Try again */
+				continue;
+			}
 			fprintf(stderr, "dns[%d]: Error: Could not read dns_params: "
 					"%s\n", getpid(), strerror(errno));
 			break;
@@ -910,7 +914,7 @@
 }
 
 PurpleDnsQueryData *
-purple_dnsquery_a_account(PurpleAccount *account, const char *hostname, int port,
+purple_dnsquery_a(PurpleAccount *account, const char *hostname, int port,
 				PurpleDnsQueryConnectFunction callback, gpointer data)
 {
 	PurpleDnsQueryData *query_data;
@@ -940,13 +944,6 @@
 	return query_data;
 }
 
-PurpleDnsQueryData *
-purple_dnsquery_a(const char *hostname, int port,
-				PurpleDnsQueryConnectFunction callback, gpointer data)
-{
-	return purple_dnsquery_a_account(NULL, hostname, port, callback, data);
-}
-
 void
 purple_dnsquery_destroy(PurpleDnsQueryData *query_data)
 {
--- a/libpurple/dnsquery.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/dnsquery.h	Sun Sep 11 04:19:01 2011 +0000
@@ -88,7 +88,7 @@
 /**
  * Perform an asynchronous DNS query.
  *
- * @param account the account that the query is being done for (or NULL)
+ * @param account  The account that the query is being done for (or NULL)
  * @param hostname The hostname to resolve.
  * @param port     A port number which is stored in the struct sockaddr.
  * @param callback The callback function to call after resolving.
@@ -98,27 +98,8 @@
  *         a data structure that can be used to cancel the pending
  *         DNS query, if needed.
  *
- * @since 2.8.0
  */
-PurpleDnsQueryData *purple_dnsquery_a_account(PurpleAccount *account, const char *hostname, int port, PurpleDnsQueryConnectFunction callback, gpointer data);
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_DNSQUERY_C_)
-/**
- * Perform an asynchronous DNS query.
- *
- * @param hostname The hostname to resolve.
- * @param port     A port number which is stored in the struct sockaddr.
- * @param callback The callback function to call after resolving.
- * @param data     Extra data to pass to the callback function.
- *
- * @return NULL if there was an error, otherwise return a reference to
- *         a data structure that can be used to cancel the pending
- *         DNS query, if needed.
- *
- * @deprecated Use purple_dnsquery_a_account instead
- */
-PurpleDnsQueryData *purple_dnsquery_a(const char *hostname, int port, PurpleDnsQueryConnectFunction callback, gpointer data);
-#endif
+PurpleDnsQueryData *purple_dnsquery_a(PurpleAccount *account, const char *hostname, int port, PurpleDnsQueryConnectFunction callback, gpointer data);
 
 /**
  * Cancel a DNS query and destroy the associated data structure.
--- a/libpurple/dnssrv.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/dnssrv.c	Sun Sep 11 04:19:01 2011 +0000
@@ -725,15 +725,7 @@
 #endif
 
 PurpleSrvTxtQueryData *
-purple_srv_resolve(const char *protocol, const char *transport,
-	const char *domain, PurpleSrvCallback cb, gpointer extradata)
-{
-	return purple_srv_resolve_account(NULL, protocol, transport, domain,
-			cb, extradata);
-}
-
-PurpleSrvTxtQueryData *
-purple_srv_resolve_account(PurpleAccount *account, const char *protocol,
+purple_srv_resolve(PurpleAccount *account, const char *protocol,
 	const char *transport, const char *domain, PurpleSrvCallback cb,
 	gpointer extradata)
 {
@@ -798,6 +790,12 @@
 		return NULL;
 	}
 
+	/*
+	 * TODO: We should put a cap on the number of forked processes that we
+	 *       allow at any given time.  If we get too many requests they
+	 *       should be put into a queue and handled later.  (This is what
+	 *       we do for A record lookups.)
+	 */
 	pid = fork();
 	if (pid == -1) {
 		purple_debug_error("dnssrv", "Could not create process!\n");
@@ -863,13 +861,7 @@
 #endif
 }
 
-PurpleSrvTxtQueryData *purple_txt_resolve(const char *owner,
-	const char *domain, PurpleTxtCallback cb, gpointer extradata)
-{
-	return purple_txt_resolve_account(NULL, owner, domain, cb, extradata);
-}
-
-PurpleSrvTxtQueryData *purple_txt_resolve_account(PurpleAccount *account,
+PurpleSrvTxtQueryData *purple_txt_resolve(PurpleAccount *account,
 	const char *owner, const char *domain, PurpleTxtCallback cb,
 	gpointer extradata)
 {
@@ -929,6 +921,12 @@
 		return NULL;
 	}
 
+	/*
+	 * TODO: We should put a cap on the number of forked processes that we
+	 *       allow at any given time.  If we get too many requests they
+	 *       should be put into a queue and handled later.  (This is what
+	 *       we do for A record lookups.)
+	 */
 	pid = fork();
 	if (pid == -1) {
 		purple_debug_error("dnssrv", "Could not create process!\n");
@@ -994,18 +992,6 @@
 #endif
 }
 
-void
-purple_txt_cancel(PurpleSrvTxtQueryData *query_data)
-{
-	purple_srv_txt_query_destroy(query_data);
-}
-
-void
-purple_srv_cancel(PurpleSrvTxtQueryData *query_data)
-{
-	purple_srv_txt_query_destroy(query_data);
-}
-
 const gchar *
 purple_txt_response_get_content(PurpleTxtResponse *resp)
 {
--- a/libpurple/dnssrv.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/dnssrv.h	Sun Sep 11 04:19:01 2011 +0000
@@ -32,10 +32,6 @@
 typedef struct _PurpleSrvResponse PurpleSrvResponse;
 typedef struct _PurpleTxtResponse PurpleTxtResponse;
 
-/* For compatibility, should be removed for 3.0.0
- */
-typedef struct _PurpleSrvTxtQueryData PurpleSrvQueryData;
-
 #include <glib.h>
 
 enum PurpleDnsType {
@@ -103,86 +99,40 @@
 /**
  * Queries an SRV record.
  *
- * @param account the account that the query is being done for (or NULL)
- * @param protocol Name of the protocol (e.g. "sip")
+ * @param account   The account that the query is being done for (or NULL)
+ * @param protocol  Name of the protocol (e.g. "sip")
  * @param transport Name of the transport ("tcp" or "udp")
- * @param domain Domain name to query (e.g. "blubb.com")
- * @param cb A callback which will be called with the results
+ * @param domain    Domain name to query (e.g. "blubb.com")
+ * @param cb        A callback which will be called with the results
  * @param extradata Extra data to be passed to the callback
  *
- * @since 2.8.0
+ * @return NULL if there was an error, otherwise return a reference to
+ *         a data structure that can be used to cancel the pending
+ *         DNS query, if needed.
  */
-PurpleSrvTxtQueryData *purple_srv_resolve_account(PurpleAccount *account, const char *protocol, const char *transport, const char *domain, PurpleSrvCallback cb, gpointer extradata);
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_DNSSRV_C_)
-/**
- * Queries an SRV record.
- *
- * @param protocol Name of the protocol (e.g. "sip")
- * @param transport Name of the transport ("tcp" or "udp")
- * @param domain Domain name to query (e.g. "blubb.com")
- * @param cb A callback which will be called with the results
- * @param extradata Extra data to be passed to the callback
- *
- * @deprecated Use purple_srv_resolve_account instead
- */
-PurpleSrvTxtQueryData *purple_srv_resolve(const char *protocol, const char *transport, const char *domain, PurpleSrvCallback cb, gpointer extradata);
-#endif
-
-/**
- * Cancel an SRV or DNS query.
- *
- * @param query_data The request to cancel.
- *
- * @deprecated Use purple_srv_txt_query_destroy instead
- */
-void purple_srv_cancel(PurpleSrvTxtQueryData *query_data);
+PurpleSrvTxtQueryData *purple_srv_resolve(PurpleAccount *account, const char *protocol, const char *transport, const char *domain, PurpleSrvCallback cb, gpointer extradata);
 
 /**
  * Queries an TXT record.
  *
- * @param account the account that the query is being done for (or NULL)
- * @param owner Name of the protocol (e.g. "_xmppconnect")
- * @param domain Domain name to query (e.g. "blubb.com")
- * @param cb A callback which will be called with the results
+ * @param account   The account that the query is being done for (or NULL)
+ * @param owner     Name of the protocol (e.g. "_xmppconnect")
+ * @param domain    Domain name to query (e.g. "blubb.com")
+ * @param cb        A callback which will be called with the results
  * @param extradata Extra data to be passed to the callback
  *
- * @since 2.8.0
+ * @return NULL if there was an error, otherwise return a reference to
+ *         a data structure that can be used to cancel the pending
+ *         DNS query, if needed.
  */
-PurpleSrvTxtQueryData *purple_txt_resolve_account(PurpleAccount *account, const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata);
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_DNSSRV_C_)
-/**
- * Queries an TXT record.
- *
- * @param owner Name of the protocol (e.g. "_xmppconnect")
- * @param domain Domain name to query (e.g. "blubb.com")
- * @param cb A callback which will be called with the results
- * @param extradata Extra data to be passed to the callback
- *
- * @deprecated Use purple_txt_resolve_account instead
- *
- * @since 2.6.0
- */
-PurpleSrvTxtQueryData *purple_txt_resolve(const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata);
-#endif
-
-/**
- * Cancel an TXT DNS query.
- *
- * @param query_data The request to cancel.
- * @since 2.6.0
- *
- * @deprecated Use purple_srv_txt_query_destroy instead
- */
-void purple_txt_cancel(PurpleSrvTxtQueryData *query_data);
+PurpleSrvTxtQueryData *purple_txt_resolve(PurpleAccount *account, const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata);
 
 /**
  * Get the value of the current TXT record.
  *
  * @param response  The TXT response record
- * @returns The value of the current TXT record.
- * @since 2.6.0
+ *
+ * @return The value of the current TXT record.
  */
 const gchar *purple_txt_response_get_content(PurpleTxtResponse *response);
 
@@ -190,7 +140,6 @@
  * Destroy a TXT DNS response object.
  *
  * @param response The PurpleTxtResponse to destroy.
- * @since 2.6.0
  */
 void purple_txt_response_destroy(PurpleTxtResponse *response);
 
@@ -220,7 +169,7 @@
 PurpleSrvTxtQueryUiOps *purple_srv_txt_query_get_ui_ops(void);
 
 /**
- * Get the query from a PurpleDnsQueryData
+ * Get the query from a PurpleSrvTxtQueryData
  *
  * @param query_data The SRV/TXT query
  * @return The query.
@@ -228,7 +177,7 @@
 char *purple_srv_txt_query_get_query(PurpleSrvTxtQueryData *query_data);
 
 /**
- * Get the type from a PurpleDnsQueryData (TXT or SRV)
+ * Get the type from a PurpleSrvTxtQueryData (TXT or SRV)
  *
  * @param query_data The query
  * @return The query.
@@ -240,3 +189,4 @@
 #endif
 
 #endif /* _PURPLE_DNSSRV_H */
+
--- a/libpurple/ft.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/ft.c	Sun Sep 11 04:19:01 2011 +0000
@@ -220,7 +220,7 @@
 		purple_xfer_destroy(xfer);
 }
 
-static void
+void
 purple_xfer_set_status(PurpleXfer *xfer, PurpleXferStatusType status)
 {
 	g_return_if_fail(xfer != NULL);
@@ -720,6 +720,20 @@
 	purple_xfer_unref(xfer);
 }
 
+int purple_xfer_get_fd(PurpleXfer *xfer)
+{
+	g_return_val_if_fail(xfer != NULL, 0);
+
+	return xfer->fd;
+}
+
+int purple_xfer_get_watcher(PurpleXfer *xfer)
+{
+	g_return_val_if_fail(xfer != NULL, 0);
+
+	return xfer->watcher;
+}
+
 PurpleXferType
 purple_xfer_get_type(const PurpleXfer *xfer)
 {
@@ -864,6 +878,20 @@
 	return xfer->end_time;
 }
 
+void purple_xfer_set_fd(PurpleXfer *xfer, int fd)
+{
+	g_return_if_fail(xfer != NULL);
+
+	xfer->fd = fd;
+}
+
+void purple_xfer_set_watcher(PurpleXfer *xfer, int watcher)
+{
+	g_return_if_fail(xfer != NULL);
+
+	xfer->watcher = watcher;
+}
+
 void
 purple_xfer_set_completed(PurpleXfer *xfer, gboolean completed)
 {
@@ -947,6 +975,14 @@
 }
 
 void
+purple_xfer_set_local_port(PurpleXfer *xfer, unsigned int local_port)
+{
+	g_return_if_fail(xfer != NULL);
+
+	xfer->local_port = local_port;
+}
+
+void
 purple_xfer_set_bytes_sent(PurpleXfer *xfer, size_t bytes_sent)
 {
 	g_return_if_fail(xfer != NULL);
@@ -1701,6 +1737,37 @@
 	}
 }
 
+void
+purple_xfer_set_protocol_data(PurpleXfer *xfer, gpointer proto_data)
+{
+	g_return_if_fail(xfer != NULL);
+
+	xfer->proto_data = proto_data;
+}
+
+gpointer
+purple_xfer_get_protocol_data(const PurpleXfer *xfer)
+{
+	g_return_val_if_fail(xfer != NULL, NULL);
+
+	return xfer->proto_data;
+}
+
+void purple_xfer_set_ui_data(PurpleXfer *xfer, gpointer ui_data)
+{
+	g_return_if_fail(xfer != NULL);
+
+	xfer->ui_data = ui_data;
+}
+
+gpointer purple_xfer_get_ui_data(const PurpleXfer *xfer)
+{
+	g_return_val_if_fail(xfer != NULL, NULL);
+
+	return xfer->ui_data;
+}
+
+
 /**************************************************************************
  * File Transfer Subsystem API
  **************************************************************************/
--- a/libpurple/ft.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/ft.h	Sun Sep 11 04:19:01 2011 +0000
@@ -185,7 +185,7 @@
 	PurpleXferUiOps *ui_ops;            /**< UI-specific operations. */
 	void *ui_data;                    /**< UI-specific data.       */
 
-	void *data;                       /**< prpl-specific data.     */
+	void *proto_data;                 /**< prpl-specific data.     */
 };
 
 #ifdef __cplusplus
@@ -266,6 +266,24 @@
 void purple_xfer_request_denied(PurpleXfer *xfer);
 
 /**
+ * Returns the socket file descriptor.
+ *
+ * @param xfer The file transfer.
+ *
+ * @return The socket file descriptor.
+ */
+int purple_xfer_get_fd(PurpleXfer *xfer);
+
+/**
+ * Returns the Watcher for the transfer.
+ *
+ * @param xfer The file transfer.
+ *
+ * @return The watcher.
+ */
+int purple_xfer_get_watcher(PurpleXfer *xfer);
+
+/**
  * Returns the type of file transfer.
  *
  * @param xfer The file transfer.
@@ -426,6 +444,22 @@
 time_t purple_xfer_get_end_time(const PurpleXfer *xfer);
 
 /**
+ * Sets the socket file descriptor.
+ *
+ * @param xfer      The file transfer.
+ * @param fd        The file descriptor.
+ */
+void purple_xfer_set_fd(PurpleXfer *xfer, int fd);
+
+/**
+ * Sets the watcher for the file transfer.
+ *
+ * @param xfer      The file transfer.
+ * @param watcher   The watcher.
+ */
+void purple_xfer_set_watcher(PurpleXfer *xfer, int watcher);
+
+/**
  * Sets the completed state for the file transfer.
  *
  * @param xfer      The file transfer.
@@ -434,6 +468,14 @@
 void purple_xfer_set_completed(PurpleXfer *xfer, gboolean completed);
 
 /**
+ * Sets the current status for the file transfer.
+ *
+ * @param xfer      The file transfer.
+ * @param status    The current status.
+ */
+void purple_xfer_set_status(PurpleXfer *xfer, PurpleXferStatusType status);
+
+/**
  * Sets the filename for the file transfer.
  *
  * @param xfer     The file transfer.
@@ -466,6 +508,14 @@
 void purple_xfer_set_size(PurpleXfer *xfer, size_t size);
 
 /**
+ * Sets the local port of the file transfer.
+ *
+ * @param xfer          The file transfer.
+ * @param local_port    The local port.
+ */
+void purple_xfer_set_local_port(PurpleXfer *xfer, unsigned int local_port);
+
+/**
  * Sets the current working position in the active file transfer.  This
  * can be used to jump backward in the file if the protocol detects
  * that some bit of data needs to be resent or has been sent twice.
@@ -737,6 +787,45 @@
  */
 void purple_xfer_prepare_thumbnail(PurpleXfer *xfer, const gchar *formats);
 
+/**
+ * Sets the protocol data for a file transfer.
+ *
+ * @param xfer			The file transfer.
+ * @param protocol_data	The protocol data to set for the file transfer.
+ *
+ * @since 3.0.0
+ */
+void purple_xfer_set_protocol_data(PurpleXfer *xfer, gpointer proto_data);
+ 
+/**
+ * Gets the protocol data for a file transfer.
+ *
+ * @param xfer			The file transfer.
+ *
+ * @return The protocol data for the file transfer.
+ *
+ * @since 3.0.0
+ */
+gpointer purple_xfer_get_protocol_data(const PurpleXfer *xfer);
+
+/**
+ * Set the UI data associated with this file transfer.
+ *
+ * @param xfer			The file transfer.
+ * @param ui_data		A pointer to associate with this file transfer.
+ */
+void purple_xfer_set_ui_data(PurpleXfer *xfer, gpointer ui_data);
+
+/**
+ * Get the UI data associated with this file transfer.
+ *
+ * @param xfer			The file transfer.
+ *
+ * @return The UI data associated with this file transfer.  This is a
+ *         convenience field provided to the UIs--it is not
+ *         used by the libpurple core.
+ */
+gpointer purple_xfer_get_ui_data(const PurpleXfer *xfer);
 
 /*@}*/
 
--- a/libpurple/gaim-compat.h	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2317 +0,0 @@
-/**
- * @file gaim-compat.h Gaim Compat macros
- * @ingroup core
- */
-
-/* pidgin
- *
- * Pidgin is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- */
-#ifndef _GAIM_COMPAT_H_
-#define _GAIM_COMPAT_H_
-
-#include <glib.h>
-
-/* from account.h */
-#define GaimAccountUiOps PurpleAccountUiOps
-#define GaimAccount PurpleAccount
-
-#define GaimFilterAccountFunc PurpleFilterAccountFunc
-#define GaimAccountRequestAuthorizationCb PurpleAccountRequestAuthorizationCb
-
-#define gaim_account_new           purple_account_new
-#define gaim_account_destroy       purple_account_destroy
-#define gaim_account_connect       purple_account_connect
-#define gaim_account_register      purple_account_register
-#define gaim_account_disconnect    purple_account_disconnect
-#define gaim_account_notify_added  purple_account_notify_added
-#define gaim_account_request_add   purple_account_request_add
-#define gaim_account_request_close   purple_account_request_close
-
-#define gaim_account_request_authorization     purple_account_request_authorization
-#define gaim_account_request_change_password   purple_account_request_change_password
-#define gaim_account_request_change_user_info  purple_account_request_change_user_info
-
-#define gaim_account_set_username            purple_account_set_username
-#define gaim_account_set_password            purple_account_set_password
-#define gaim_account_set_alias               purple_account_set_alias
-#define gaim_account_set_user_info           purple_account_set_user_info
-#define gaim_account_set_buddy_icon_path     purple_account_set_buddy_icon_path
-#define gaim_account_set_protocol_id         purple_account_set_protocol_id
-#define gaim_account_set_connection          purple_account_set_connection
-#define gaim_account_set_remember_password   purple_account_set_remember_password
-#define gaim_account_set_check_mail          purple_account_set_check_mail
-#define gaim_account_set_enabled             purple_account_set_enabled
-#define gaim_account_set_proxy_info          purple_account_set_proxy_info
-#define gaim_account_set_status_types        purple_account_set_status_types
-#define gaim_account_set_status              purple_account_set_status
-#define gaim_account_set_status_list         purple_account_set_status_list
-
-#define gaim_account_clear_settings   purple_account_clear_settings
-
-#define gaim_account_set_int    purple_account_set_int
-#define gaim_account_set_string purple_account_set_string
-#define gaim_account_set_bool   purple_account_set_bool
-
-#define gaim_account_set_ui_int     purple_account_set_ui_int
-#define gaim_account_set_ui_string  purple_account_set_ui_string
-#define gaim_account_set_ui_bool    purple_account_set_ui_bool
-
-#define gaim_account_is_connected     purple_account_is_connected
-#define gaim_account_is_connecting    purple_account_is_connecting
-#define gaim_account_is_disconnected  purple_account_is_disconnected
-
-#define gaim_account_get_username           purple_account_get_username
-#define gaim_account_get_password           purple_account_get_password
-#define gaim_account_get_alias              purple_account_get_alias
-#define gaim_account_get_user_info          purple_account_get_user_info
-#define gaim_account_get_buddy_icon_path    purple_account_get_buddy_icon_path
-#define gaim_account_get_protocol_id        purple_account_get_protocol_id
-#define gaim_account_get_protocol_name      purple_account_get_protocol_name
-#define gaim_account_get_connection         purple_account_get_connection
-#define gaim_account_get_remember_password  purple_account_get_remember_password
-#define gaim_account_get_check_mail         purple_account_get_check_mail
-#define gaim_account_get_enabled            purple_account_get_enabled
-#define gaim_account_get_proxy_info         purple_account_get_proxy_info
-#define gaim_account_get_active_status      purple_account_get_active_status
-#define gaim_account_get_status             purple_account_get_status
-#define gaim_account_get_status_type        purple_account_get_status_type
-#define gaim_account_get_status_type_with_primitive \
-	purple_account_get_status_type_with_primitive
-
-#define gaim_account_get_presence       purple_account_get_presence
-#define gaim_account_is_status_active   purple_account_is_status_active
-#define gaim_account_get_status_types   purple_account_get_status_types
-
-#define gaim_account_get_int            purple_account_get_int
-#define gaim_account_get_string         purple_account_get_string
-#define gaim_account_get_bool           purple_account_get_bool
-
-#define gaim_account_get_ui_int     purple_account_get_ui_int
-#define gaim_account_get_ui_string  purple_account_get_ui_string
-#define gaim_account_get_ui_bool    purple_account_get_ui_bool
-
-
-#define gaim_account_get_log      purple_account_get_log
-#define gaim_account_destroy_log  purple_account_destroy_log
-
-#define gaim_account_add_buddy       purple_account_add_buddy
-#define gaim_account_add_buddies     purple_account_add_buddies
-#define gaim_account_remove_buddy    purple_account_remove_buddy
-#define gaim_account_remove_buddies  purple_account_remove_buddies
-
-#define gaim_account_remove_group  purple_account_remove_group
-
-#define gaim_account_change_password  purple_account_change_password
-
-#define gaim_account_supports_offline_message  purple_account_supports_offline_message
-
-#define gaim_accounts_add      purple_accounts_add
-#define gaim_accounts_remove   purple_accounts_remove
-#define gaim_accounts_delete   purple_accounts_delete
-#define gaim_accounts_reorder  purple_accounts_reorder
-
-#define gaim_accounts_get_all         purple_accounts_get_all
-#define gaim_accounts_get_all_active  purple_accounts_get_all_active
-
-#define gaim_accounts_find   purple_accounts_find
-
-#define gaim_accounts_restore_current_statuses  purple_accounts_restore_current_statuses
-
-#define gaim_accounts_set_ui_ops  purple_accounts_set_ui_ops
-#define gaim_accounts_get_ui_ops  purple_accounts_get_ui_ops
-
-#define gaim_accounts_get_handle  purple_accounts_get_handle
-
-#define gaim_accounts_init    purple_accounts_init
-#define gaim_accounts_uninit  purple_accounts_uninit
-
-/* from accountopt.h */
-
-#define GaimAccountOption     PurpleAccountOption
-#define GaimAccountUserSplit  PurpleAccountUserSplit
-
-#define gaim_account_option_new         purple_account_option_new
-#define gaim_account_option_bool_new    purple_account_option_bool_new
-#define gaim_account_option_int_new     purple_account_option_int_new
-#define gaim_account_option_string_new  purple_account_option_string_new
-#define gaim_account_option_list_new    purple_account_option_list_new
-
-#define gaim_account_option_destroy  purple_account_option_destroy
-
-#define gaim_account_option_set_default_bool    purple_account_option_set_default_bool
-#define gaim_account_option_set_default_int     purple_account_option_set_default_int
-#define gaim_account_option_set_default_string  purple_account_option_set_default_string
-
-#define gaim_account_option_set_masked  purple_account_option_set_masked
-
-#define gaim_account_option_set_list  purple_account_option_set_list
-
-#define gaim_account_option_add_list_item  purple_account_option_add_list_item
-
-#define gaim_account_option_get_type     purple_account_option_get_type
-#define gaim_account_option_get_text     purple_account_option_get_text
-#define gaim_account_option_get_setting  purple_account_option_get_setting
-
-#define gaim_account_option_get_default_bool        purple_account_option_get_default_bool
-#define gaim_account_option_get_default_int         purple_account_option_get_default_int
-#define gaim_account_option_get_default_string      purple_account_option_get_default_string
-#define gaim_account_option_get_default_list_value  purple_account_option_get_default_list_value
-
-#define gaim_account_option_get_masked  purple_account_option_get_masked
-#define gaim_account_option_get_list    purple_account_option_get_list
-
-#define gaim_account_user_split_new      purple_account_user_split_new
-#define gaim_account_user_split_destroy  purple_account_user_split_destroy
-
-#define gaim_account_user_split_get_text           purple_account_user_split_get_text
-#define gaim_account_user_split_get_default_value  purple_account_user_split_get_default_value
-#define gaim_account_user_split_get_separator      purple_account_user_split_get_separator
-
-/* from blist.h */
-
-#define GaimBuddyList    PurpleBuddyList
-#define GaimBlistUiOps   PurpleBlistUiOps
-#define GaimBlistNode    PurpleBlistNode
-
-#define GaimChat     PurpleChat
-#define GaimGroup    PurpleGroup
-#define GaimContact  PurpleContact
-#define GaimBuddy    PurpleBuddy
-
-#define GAIM_BLIST_GROUP_NODE     PURPLE_BLIST_GROUP_NODE
-#define GAIM_BLIST_CONTACT_NODE   PURPLE_BLIST_CONTACT_NODE
-#define GAIM_BLIST_BUDDY_NODE     PURPLE_BLIST_BUDDY_NODE
-#define GAIM_BLIST_CHAT_NODE      PURPLE_BLIST_CHAT_NODE
-#define GAIM_BLIST_OTHER_NODE     PURPLE_BLIST_OTHER_NODE
-#define GaimBlistNodeType         PurpleBlistNodeType
-
-#define GAIM_BLIST_NODE_IS_CHAT       PURPLE_BLIST_NODE_IS_CHAT
-#define GAIM_BLIST_NODE_IS_BUDDY      PURPLE_BLIST_NODE_IS_BUDDY
-#define GAIM_BLIST_NODE_IS_CONTACT    PURPLE_BLIST_NODE_IS_CONTACT
-#define GAIM_BLIST_NODE_IS_GROUP      PURPLE_BLIST_NODE_IS_GROUP
-
-#define GAIM_BUDDY_IS_ONLINE PURPLE_BUDDY_IS_ONLINE
-
-#define GAIM_BLIST_NODE_FLAG_NO_SAVE  PURPLE_BLIST_NODE_FLAG_NO_SAVE
-#define GaimBlistNodeFlags            PurpleBlistNodeFlags
-
-#define GAIM_BLIST_NODE_HAS_FLAG     PURPLE_BLIST_NODE_HAS_FLAG
-#define GAIM_BLIST_NODE_SHOULD_SAVE  PURPLE_BLIST_NODE_SHOULD_SAVE
-
-#define GAIM_BLIST_NODE_NAME   PURPLE_BLIST_NODE_NAME
-
-
-#define gaim_blist_new  purple_blist_new
-#define gaim_set_blist  purple_set_blist
-#define gaim_get_blist  purple_get_blist
-
-#define gaim_blist_get_root   purple_blist_get_root
-#define gaim_blist_node_next  purple_blist_node_next
-
-#define gaim_blist_show  purple_blist_show
-
-#define gaim_blist_destroy  purple_blist_destroy
-
-#define gaim_blist_set_visible  purple_blist_set_visible
-
-#define gaim_blist_update_buddy_status  purple_blist_update_buddy_status
-#define gaim_blist_update_buddy_icon    purple_blist_update_buddy_icon
-
-
-#define gaim_blist_alias_contact       purple_blist_alias_contact
-#define gaim_blist_alias_buddy         purple_blist_alias_buddy
-#define gaim_blist_server_alias_buddy  purple_blist_server_alias_buddy
-#define gaim_blist_alias_chat          purple_blist_alias_chat
-
-#define gaim_blist_rename_buddy  purple_blist_rename_buddy
-#define gaim_blist_rename_group  purple_blist_rename_group
-
-#define gaim_chat_new        purple_chat_new
-#define gaim_blist_add_chat  purple_blist_add_chat
-
-#define gaim_buddy_new           purple_buddy_new
-#define gaim_buddy_set_icon      purple_buddy_set_icon
-#define gaim_buddy_get_account   purple_buddy_get_account
-#define gaim_buddy_get_name      purple_buddy_get_name
-#define gaim_buddy_get_icon      purple_buddy_get_icon
-#define gaim_buddy_get_contact   purple_buddy_get_contact
-#define gaim_buddy_get_presence  purple_buddy_get_presence
-
-#define gaim_blist_add_buddy  purple_blist_add_buddy
-
-#define gaim_group_new  purple_group_new
-
-#define gaim_blist_add_group  purple_blist_add_group
-
-#define gaim_contact_new  purple_contact_new
-
-#define gaim_blist_add_contact    purple_blist_add_contact
-#define gaim_blist_merge_contact  purple_blist_merge_contact
-
-#define gaim_contact_get_priority_buddy  purple_contact_get_priority_buddy
-#define gaim_contact_set_alias           purple_contact_set_alias
-#define gaim_contact_get_alias           purple_contact_get_alias
-#define gaim_contact_on_account          purple_contact_on_account
-
-#define gaim_contact_invalidate_priority_buddy  purple_contact_invalidate_priority_buddy
-
-#define gaim_blist_remove_buddy    purple_blist_remove_buddy
-#define gaim_blist_remove_contact  purple_blist_remove_contact
-#define gaim_blist_remove_chat     purple_blist_remove_chat
-#define gaim_blist_remove_group    purple_blist_remove_group
-
-#define gaim_buddy_get_alias_only     purple_buddy_get_alias_only
-#define gaim_buddy_get_server_alias   purple_buddy_get_server_alias
-#define gaim_buddy_get_contact_alias  purple_buddy_get_contact_alias
-#define gaim_buddy_get_local_alias    purple_buddy_get_local_alias
-#define gaim_buddy_get_alias          purple_buddy_get_alias
-
-#define gaim_chat_get_name  purple_chat_get_name
-
-#define gaim_find_buddy           purple_find_buddy
-#define gaim_find_buddy_in_group  purple_find_buddy_in_group
-#define gaim_find_buddies         purple_find_buddies
-
-#define gaim_find_group  purple_find_group
-
-#define gaim_blist_find_chat  purple_blist_find_chat
-
-#define gaim_chat_get_group   purple_chat_get_group
-#define gaim_buddy_get_group  purple_buddy_get_group
-
-#define gaim_group_get_accounts  purple_group_get_accounts
-#define gaim_group_on_account    purple_group_on_account
-
-#define gaim_blist_add_account     purple_blist_add_account
-#define gaim_blist_remove_account  purple_blist_remove_account
-
-#define gaim_blist_get_group_size          purple_blist_get_group_size
-#define gaim_blist_get_group_online_count  purple_blist_get_group_online_count
-
-#define gaim_blist_load           purple_blist_load
-#define gaim_blist_schedule_save  purple_blist_schedule_save
-
-#define gaim_blist_request_add_buddy  purple_blist_request_add_buddy
-#define gaim_blist_request_add_chat   purple_blist_request_add_chat
-#define gaim_blist_request_add_group  purple_blist_request_add_group
-
-#define gaim_blist_node_set_bool    purple_blist_node_set_bool
-#define gaim_blist_node_get_bool    purple_blist_node_get_bool
-#define gaim_blist_node_set_int     purple_blist_node_set_int
-#define gaim_blist_node_get_int     purple_blist_node_get_int
-#define gaim_blist_node_set_string  purple_blist_node_set_string
-#define gaim_blist_node_get_string  purple_blist_node_get_string
-
-#define gaim_blist_node_remove_setting  purple_blist_node_remove_setting
-
-#define gaim_blist_node_set_flags  purple_blist_node_set_flags
-#define gaim_blist_node_get_flags  purple_blist_node_get_flags
-
-#define gaim_blist_node_get_extended_menu  purple_blist_node_get_extended_menu
-
-#define gaim_blist_set_ui_ops  purple_blist_set_ui_ops
-#define gaim_blist_get_ui_ops  purple_blist_get_ui_ops
-
-#define gaim_blist_get_handle  purple_blist_get_handle
-
-#define gaim_blist_init    purple_blist_init
-#define gaim_blist_uninit  purple_blist_uninit
-
-
-#define GaimBuddyIcon  PurpleBuddyIcon
-
-#define gaim_buddy_icon_new(account, username, icon_data, icon_len)\
-        purple_buddy_icon_new(account, username, g_memdup(icon_data, icon_len), icon_len)
-#define gaim_buddy_icon_ref      purple_buddy_icon_ref
-#define gaim_buddy_icon_unref    purple_buddy_icon_unref
-#define gaim_buddy_icon_update   purple_buddy_icon_update
-
-#define gaim_buddy_icon_set_data(icon, data, len) \
-        purple_buddy_icon_set_data(icon, g_memdup(data, len), len, NULL);
-
-#define gaim_buddy_icon_get_account   purple_buddy_icon_get_account
-#define gaim_buddy_icon_get_username  purple_buddy_icon_get_username
-#define gaim_buddy_icon_get_data      purple_buddy_icon_get_data
-#define gaim_buddy_icon_get_type      purple_buddy_icon_get_extension
-
-#define gaim_buddy_icons_set_for_user(icon, data, len) \
-        purple_buddy_icons_set_for_user(icon, g_memdup(data, len), len, NULL)
-#define gaim_buddy_icons_set_caching    purple_buddy_icons_set_caching
-#define gaim_buddy_icons_is_caching     purple_buddy_icons_is_caching
-#define gaim_buddy_icons_set_cache_dir  purple_buddy_icons_set_cache_dir
-#define gaim_buddy_icons_get_cache_dir  purple_buddy_icons_get_cache_dir
-#define gaim_buddy_icons_get_handle     purple_buddy_icons_get_handle
-
-#define gaim_buddy_icons_init    purple_buddy_icons_init
-#define gaim_buddy_icons_uninit  purple_buddy_icons_uninit
-
-#define gaim_buddy_icon_get_scale_size  purple_buddy_icon_get_scale_size
-
-/* from cipher.h */
-
-#define GAIM_CIPHER          PURPLE_CIPHER
-#define GAIM_CIPHER_OPS      PURPLE_CIPHER_OPS
-#define GAIM_CIPHER_CONTEXT  PURPLE_CIPHER_CONTEXT
-
-#define GaimCipher         PurpleCipher
-#define GaimCipherOps      PurpleCipherOps
-#define GaimCipherContext  PurpleCipherContext
-
-#define GAIM_CIPHER_CAPS_SET_OPT  PURPLE_CIPHER_CAPS_SET_OPT
-#define GAIM_CIPHER_CAPS_GET_OPT  PURPLE_CIPHER_CAPS_GET_OPT
-#define GAIM_CIPHER_CAPS_INIT     PURPLE_CIPHER_CAPS_INIT
-#define GAIM_CIPHER_CAPS_RESET    PURPLE_CIPHER_CAPS_RESET
-#define GAIM_CIPHER_CAPS_UNINIT   PURPLE_CIPHER_CAPS_UNINIT
-#define GAIM_CIPHER_CAPS_SET_IV   PURPLE_CIPHER_CAPS_SET_IV
-#define GAIM_CIPHER_CAPS_APPEND   PURPLE_CIPHER_CAPS_APPEND
-#define GAIM_CIPHER_CAPS_DIGEST   PURPLE_CIPHER_CAPS_DIGEST
-#define GAIM_CIPHER_CAPS_ENCRYPT  PURPLE_CIPHER_CAPS_ENCRYPT
-#define GAIM_CIPHER_CAPS_DECRYPT  PURPLE_CIPHER_CAPS_DECRYPT
-#define GAIM_CIPHER_CAPS_SET_SALT  PURPLE_CIPHER_CAPS_SET_SALT
-#define GAIM_CIPHER_CAPS_GET_SALT_SIZE  PURPLE_CIPHER_CAPS_GET_SALT_SIZE
-#define GAIM_CIPHER_CAPS_SET_KEY        PURPLE_CIPHER_CAPS_SET_KEY
-#define GAIM_CIPHER_CAPS_GET_KEY_SIZE   PURPLE_CIPHER_CAPS_GET_KEY_SIZE
-#define GAIM_CIPHER_CAPS_UNKNOWN        PURPLE_CIPHER_CAPS_UNKNOWN
-
-#define gaim_cipher_get_name          purple_cipher_get_name
-#define gaim_cipher_get_capabilities  purple_cipher_get_capabilities
-#define gaim_cipher_digest_region     purple_cipher_digest_region
-
-#define gaim_ciphers_find_cipher        purple_ciphers_find_cipher
-#define gaim_ciphers_register_cipher    purple_ciphers_register_cipher
-#define gaim_ciphers_unregister_cipher  purple_ciphers_unregister_cipher
-#define gaim_ciphers_get_ciphers        purple_ciphers_get_ciphers
-
-#define gaim_ciphers_get_handle  purple_ciphers_get_handle
-#define gaim_ciphers_init        purple_ciphers_init
-#define gaim_ciphers_uninit      purple_ciphers_uninit
-
-#define gaim_cipher_context_set_option  purple_cipher_context_set_option
-#define gaim_cipher_context_get_option  purple_cipher_context_get_option
-
-#define gaim_cipher_context_new            purple_cipher_context_new
-#define gaim_cipher_context_new_by_name    purple_cipher_context_new_by_name
-#define gaim_cipher_context_reset          purple_cipher_context_reset
-#define gaim_cipher_context_destroy        purple_cipher_context_destroy
-#define gaim_cipher_context_set_iv         purple_cipher_context_set_iv
-#define gaim_cipher_context_append         purple_cipher_context_append
-#define gaim_cipher_context_digest         purple_cipher_context_digest
-#define gaim_cipher_context_digest_to_str  purple_cipher_context_digest_to_str
-#define gaim_cipher_context_encrypt        purple_cipher_context_encrypt
-#define gaim_cipher_context_decrypt        purple_cipher_context_decrypt
-#define gaim_cipher_context_set_salt       purple_cipher_context_set_salt
-#define gaim_cipher_context_get_salt_size  purple_cipher_context_get_salt_size
-#define gaim_cipher_context_set_key        purple_cipher_context_set_key
-#define gaim_cipher_context_get_key_size   purple_cipher_context_get_key_size
-#define gaim_cipher_context_set_data       purple_cipher_context_set_data
-#define gaim_cipher_context_get_data       purple_cipher_context_get_data
-
-#define gaim_cipher_http_digest_calculate_session_key \
-	purple_cipher_http_digest_calculate_session_key
-
-#define gaim_cipher_http_digest_calculate_response \
-	purple_cipher_http_digest_calculate_response
-
-/* from circbuffer.h */
-
-#define GaimCircBuffer  PurpleCircBuffer
-
-#define gaim_circ_buffer_new           purple_circ_buffer_new
-#define gaim_circ_buffer_destroy       purple_circ_buffer_destroy
-#define gaim_circ_buffer_append        purple_circ_buffer_append
-#define gaim_circ_buffer_get_max_read  purple_circ_buffer_get_max_read
-#define gaim_circ_buffer_mark_read     purple_circ_buffer_mark_read
-
-/* from cmds.h */
-
-#define GaimCmdPriority  PurpleCmdPriority
-#define GaimCmdFlag      PurpleCmdFlag
-#define GaimCmdStatus    PurpleCmdStatus
-#define GaimCmdRet       PurpleCmdRet
-
-#define GAIM_CMD_STATUS_OK            PURPLE_CMD_STATUS_OK
-#define GAIM_CMD_STATUS_FAILED        PURPLE_CMD_STATUS_FAILED
-#define GAIM_CMD_STATUS_NOT_FOUND     PURPLE_CMD_STATUS_NOT_FOUND
-#define GAIM_CMD_STATUS_WRONG_ARGS    PURPLE_CMD_STATUS_WRONG_ARGS
-#define GAIM_CMD_STATUS_WRONG_PRPL    PURPLE_CMD_STATUS_WRONG_PRPL
-#define GAIM_CMD_STATUS_WRONG_TYPE    PURPLE_CMD_STATUS_WRONG_TYPE
-
-#define GAIM_CMD_FUNC  PURPLE_CMD_FUNC
-
-#define GAIM_CMD_RET_OK			PURPLE_CMD_RET_OK
-#define GAIM_CMD_RET_FAILED		PURPLE_CMD_RET_FAILED
-#define GAIM_CMD_RET_CONTINUE	PURPLE_CMD_RET_CONTINUE
-
-#define GAIM_CMD_P_VERY_LOW		PURPLE_CMD_P_VERY_LOW
-#define GAIM_CMD_P_LOW			PURPLE_CMD_P_LOW
-#define GAIM_CMD_P_DEFAULT		PURPLE_CMD_P_DEFAULT
-#define GAIM_CMD_P_PRPL			PURPLE_CMD_P_PRPL
-#define GAIM_CMD_P_PLUGIN		PURPLE_CMD_P_PLUGIN
-#define GAIM_CMD_P_ALIAS		PURPLE_CMD_P_ALIAS
-#define GAIM_CMD_P_HIGH			PURPLE_CMD_P_HIGH
-#define GAIM_CMD_P_VERY_HIGH	PURPLE_CMD_P_VERY_HIGH
-
-#define GAIM_CMD_FLAG_IM		PURPLE_CMD_FLAG_IM
-#define GAIM_CMD_FLAG_CHAT		PURPLE_CMD_FLAG_CHAT
-#define GAIM_CMD_FLAG_PRPL_ONLY	PURPLE_CMD_FLAG_PRPL_ONLY
-#define GAIM_CMD_FLAG_ALLOW_WRONG_ARGS	PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS
-
-
-#define GaimCmdFunc  PurpleCmdFunc
-
-#define GaimCmdId  PurpleCmdId
-
-#define gaim_cmd_register    purple_cmd_register
-#define gaim_cmd_unregister  purple_cmd_unregister
-#define gaim_cmd_do_command  purple_cmd_do_command
-#define gaim_cmd_list        purple_cmd_list
-#define gaim_cmd_help        purple_cmd_help
-
-/* from connection.h */
-
-#define GaimConnection  PurpleConnection
-
-#define GAIM_CONNECTION_HTML              PURPLE_CONNECTION_HTML
-#define GAIM_CONNECTION_NO_BGCOLOR        PURPLE_CONNECTION_NO_BGCOLOR
-#define GAIM_CONNECTION_AUTO_RESP         PURPLE_CONNECTION_AUTO_RESP
-#define GAIM_CONNECTION_FORMATTING_WBFO   PURPLE_CONNECTION_FORMATTING_WBFO
-#define GAIM_CONNECTION_NO_NEWLINES       PURPLE_CONNECTION_NO_NEWLINES
-#define GAIM_CONNECTION_NO_FONTSIZE       PURPLE_CONNECTION_NO_FONTSIZE
-#define GAIM_CONNECTION_NO_URLDESC        PURPLE_CONNECTION_NO_URLDESC
-#define GAIM_CONNECTION_NO_IMAGES         PURPLE_CONNECTION_NO_IMAGES
-
-#define GaimConnectionFlags  PurpleConnectionFlags
-
-#define GAIM_DISCONNECTED  PURPLE_DISCONNECTED
-#define GAIM_CONNECTED     PURPLE_CONNECTED
-#define GAIM_CONNECTING    PURPLE_CONNECTING
-
-#define GaimConnectionState  PurpleConnectionState
-
-#define GaimConnectionUiOps  PurpleConnectionUiOps
-
-#define gaim_connection_new      purple_connection_new
-#define gaim_connection_destroy  purple_connection_destroy
-
-#define gaim_connection_set_state         purple_connection_set_state
-#define gaim_connection_set_account       purple_connection_set_account
-#define gaim_connection_set_display_name  purple_connection_set_display_name
-#define gaim_connection_get_state         purple_connection_get_state
-
-#define GAIM_CONNECTION_IS_CONNECTED  PURPLE_CONNECTION_IS_CONNECTED
-
-#define gaim_connection_get_account       purple_connection_get_account
-#define gaim_connection_get_password      purple_connection_get_password
-#define gaim_connection_get_display_name  purple_connection_get_display_name
-
-#define gaim_connection_update_progress  purple_connection_update_progress
-
-#define gaim_connection_notice  purple_connection_notice
-#define gaim_connection_error   purple_connection_error
-
-#define gaim_connections_disconnect_all  purple_connections_disconnect_all
-
-#define gaim_connections_get_all         purple_connections_get_all
-#define gaim_connections_get_connecting  purple_connections_get_connecting
-
-#define GAIM_CONNECTION_IS_VALID  PURPLE_CONNECTION_IS_VALID
-
-#define gaim_connections_set_ui_ops  purple_connections_set_ui_ops
-#define gaim_connections_get_ui_ops  purple_connections_get_ui_ops
-
-#define gaim_connections_init    purple_connections_init
-#define gaim_connections_uninit  purple_connections_uninit
-#define gaim_connections_get_handle  purple_connections_get_handle
-
-
-/* from conversation.h */
-
-#define GaimConversationUiOps  PurpleConversationUiOps
-#define GaimConversation       PurpleConversation
-#define GaimConvIm             PurpleConvIm
-#define GaimConvChat           PurpleConvChat
-#define GaimConvChatBuddy      PurpleConvChatBuddy
-
-#define GAIM_CONV_TYPE_UNKNOWN  PURPLE_CONV_TYPE_UNKNOWN
-#define GAIM_CONV_TYPE_IM       PURPLE_CONV_TYPE_IM
-#define GAIM_CONV_TYPE_CHAT     PURPLE_CONV_TYPE_CHAT
-#define GAIM_CONV_TYPE_MISC     PURPLE_CONV_TYPE_MISC
-#define GAIM_CONV_TYPE_ANY      PURPLE_CONV_TYPE_ANY
-
-#define GaimConversationType  PurpleConversationType
-
-#define GAIM_CONV_UPDATE_ADD       PURPLE_CONV_UPDATE_ADD
-#define GAIM_CONV_UPDATE_REMOVE    PURPLE_CONV_UPDATE_REMOVE
-#define GAIM_CONV_UPDATE_ACCOUNT   PURPLE_CONV_UPDATE_ACCOUNT
-#define GAIM_CONV_UPDATE_TYPING    PURPLE_CONV_UPDATE_TYPING
-#define GAIM_CONV_UPDATE_UNSEEN    PURPLE_CONV_UPDATE_UNSEEN
-#define GAIM_CONV_UPDATE_LOGGING   PURPLE_CONV_UPDATE_LOGGING
-#define GAIM_CONV_UPDATE_TOPIC     PURPLE_CONV_UPDATE_TOPIC
-#define GAIM_CONV_ACCOUNT_ONLINE   PURPLE_CONV_ACCOUNT_ONLINE
-#define GAIM_CONV_ACCOUNT_OFFLINE  PURPLE_CONV_ACCOUNT_OFFLINE
-#define GAIM_CONV_UPDATE_AWAY      PURPLE_CONV_UPDATE_AWAY
-#define GAIM_CONV_UPDATE_ICON      PURPLE_CONV_UPDATE_ICON
-#define GAIM_CONV_UPDATE_TITLE     PURPLE_CONV_UPDATE_TITLE
-#define GAIM_CONV_UPDATE_CHATLEFT  PURPLE_CONV_UPDATE_CHATLEFT
-#define GAIM_CONV_UPDATE_FEATURES  PURPLE_CONV_UPDATE_FEATURES
-
-#define GaimConvUpdateType  PurpleConvUpdateType
-
-#define GAIM_NOT_TYPING  PURPLE_NOT_TYPING
-#define GAIM_TYPING      PURPLE_TYPING
-#define GAIM_TYPED       PURPLE_TYPED
-
-#define GaimTypingState  PurpleTypingState
-
-#define GAIM_MESSAGE_SEND         PURPLE_MESSAGE_SEND
-#define GAIM_MESSAGE_RECV         PURPLE_MESSAGE_RECV
-#define GAIM_MESSAGE_SYSTEM       PURPLE_MESSAGE_SYSTEM
-#define GAIM_MESSAGE_AUTO_RESP    PURPLE_MESSAGE_AUTO_RESP
-#define GAIM_MESSAGE_ACTIVE_ONLY  PURPLE_MESSAGE_ACTIVE_ONLY
-#define GAIM_MESSAGE_NICK         PURPLE_MESSAGE_NICK
-#define GAIM_MESSAGE_NO_LOG       PURPLE_MESSAGE_NO_LOG
-#define GAIM_MESSAGE_WHISPER      PURPLE_MESSAGE_WHISPER
-#define GAIM_MESSAGE_ERROR        PURPLE_MESSAGE_ERROR
-#define GAIM_MESSAGE_DELAYED      PURPLE_MESSAGE_DELAYED
-#define GAIM_MESSAGE_RAW          PURPLE_MESSAGE_RAW
-#define GAIM_MESSAGE_IMAGES       PURPLE_MESSAGE_IMAGES
-
-#define GaimMessageFlags  PurpleMessageFlags
-
-#define GAIM_CBFLAGS_NONE     PURPLE_CBFLAGS_NONE
-#define GAIM_CBFLAGS_VOICE    PURPLE_CBFLAGS_VOICE
-#define GAIM_CBFLAGS_HALFOP   PURPLE_CBFLAGS_HALFOP
-#define GAIM_CBFLAGS_OP       PURPLE_CBFLAGS_OP
-#define GAIM_CBFLAGS_FOUNDER  PURPLE_CBFLAGS_FOUNDER
-#define GAIM_CBFLAGS_TYPING   PURPLE_CBFLAGS_TYPING
-
-#define GaimConvChatBuddyFlags  PurpleConvChatBuddyFlags
-
-#define gaim_conversations_set_ui_ops  purple_conversations_set_ui_ops
-
-#define gaim_conversation_new          purple_conversation_new
-#define gaim_conversation_destroy      purple_conversation_destroy
-#define gaim_conversation_present      purple_conversation_present
-#define gaim_conversation_get_type     purple_conversation_get_type
-#define gaim_conversation_set_ui_ops   purple_conversation_set_ui_ops
-#define gaim_conversation_get_ui_ops   purple_conversation_get_ui_ops
-#define gaim_conversation_set_account  purple_conversation_set_account
-#define gaim_conversation_get_account  purple_conversation_get_account
-#define gaim_conversation_get_gc       purple_conversation_get_gc
-#define gaim_conversation_set_title    purple_conversation_set_title
-#define gaim_conversation_get_title    purple_conversation_get_title
-#define gaim_conversation_autoset_title  purple_conversation_autoset_title
-#define gaim_conversation_set_name       purple_conversation_set_name
-#define gaim_conversation_get_name       purple_conversation_get_name
-#define gaim_conversation_set_logging    purple_conversation_set_logging
-#define gaim_conversation_is_logging     purple_conversation_is_logging
-#define gaim_conversation_close_logs     purple_conversation_close_logs
-#define gaim_conversation_get_im_data    purple_conversation_get_im_data
-
-#define GAIM_CONV_IM    PURPLE_CONV_IM
-
-#define gaim_conversation_get_chat_data  purple_conversation_get_chat_data
-
-#define GAIM_CONV_CHAT  PURPLE_CONV_CHAT
-
-#define gaim_conversation_set_data       purple_conversation_set_data
-#define gaim_conversation_get_data       purple_conversation_get_data
-
-#define gaim_get_conversations  purple_get_conversations
-#define gaim_get_ims            purple_get_ims
-#define gaim_get_chats          purple_get_chats
-
-#define gaim_find_conversation_with_account \
-	purple_find_conversation_with_account
-
-#define gaim_conversation_write         purple_conversation_write
-#define gaim_conversation_set_features  purple_conversation_set_features
-#define gaim_conversation_get_features  purple_conversation_get_features
-#define gaim_conversation_has_focus     purple_conversation_has_focus
-#define gaim_conversation_update        purple_conversation_update
-#define gaim_conversation_foreach       purple_conversation_foreach
-
-#define gaim_conv_im_get_conversation  purple_conv_im_get_conversation
-#define gaim_conv_im_set_icon          purple_conv_im_set_icon
-#define gaim_conv_im_get_icon          purple_conv_im_get_icon
-#define gaim_conv_im_set_typing_state  purple_conv_im_set_typing_state
-#define gaim_conv_im_get_typing_state  purple_conv_im_get_typing_state
-
-#define gaim_conv_im_start_typing_timeout  purple_conv_im_start_typing_timeout
-#define gaim_conv_im_stop_typing_timeout   purple_conv_im_stop_typing_timeout
-#define gaim_conv_im_get_typing_timeout    purple_conv_im_get_typing_timeout
-#define gaim_conv_im_set_type_again        purple_conv_im_set_type_again
-#define gaim_conv_im_get_type_again        purple_conv_im_get_type_again
-
-#define gaim_conv_im_start_send_typed_timeout \
-	purple_conv_im_start_send_typed_timeout
-
-#define gaim_conv_im_stop_send_typed_timeout \
-	purple_conv_im_stop_send_typed_timeout
-
-#define gaim_conv_im_get_send_typed_timeout \
-	purple_conv_im_get_send_typed_timeout
-
-#define gaim_conv_present_error     purple_conv_present_error
-#define gaim_conv_send_confirm      purple_conv_send_confirm
-
-#define gaim_conv_im_update_typing    purple_conv_im_update_typing
-#define gaim_conv_im_write            purple_conv_im_write
-#define gaim_conv_im_send             purple_conv_im_send
-#define gaim_conv_im_send_with_flags  purple_conv_im_send_with_flags
-
-#define gaim_conv_custom_smiley_add    purple_conv_custom_smiley_add
-#define gaim_conv_custom_smiley_write  purple_conv_custom_smiley_write
-#define gaim_conv_custom_smiley_close  purple_conv_custom_smiley_close
-
-#define gaim_conv_chat_get_conversation  purple_conv_chat_get_conversation
-#define gaim_conv_chat_set_users         purple_conv_chat_set_users
-#define gaim_conv_chat_get_users         purple_conv_chat_get_users
-#define gaim_conv_chat_ignore            purple_conv_chat_ignore
-#define gaim_conv_chat_unignore          purple_conv_chat_unignore
-#define gaim_conv_chat_set_ignored       purple_conv_chat_set_ignored
-#define gaim_conv_chat_get_ignored       purple_conv_chat_get_ignored
-#define gaim_conv_chat_get_ignored_user  purple_conv_chat_get_ignored_user
-#define gaim_conv_chat_is_user_ignored   purple_conv_chat_is_user_ignored
-#define gaim_conv_chat_set_topic         purple_conv_chat_set_topic
-#define gaim_conv_chat_get_topic         purple_conv_chat_get_topic
-#define gaim_conv_chat_set_id            purple_conv_chat_set_id
-#define gaim_conv_chat_get_id            purple_conv_chat_get_id
-#define gaim_conv_chat_write             purple_conv_chat_write
-#define gaim_conv_chat_send              purple_conv_chat_send
-#define gaim_conv_chat_send_with_flags   purple_conv_chat_send_with_flags
-#define gaim_conv_chat_add_user          purple_conv_chat_add_user
-#define gaim_conv_chat_add_users         purple_conv_chat_add_users
-#define gaim_conv_chat_rename_user       purple_conv_chat_rename_user
-#define gaim_conv_chat_remove_user       purple_conv_chat_remove_user
-#define gaim_conv_chat_remove_users      purple_conv_chat_remove_users
-#define gaim_conv_chat_find_user         purple_conv_chat_find_user
-#define gaim_conv_chat_user_set_flags    purple_conv_chat_user_set_flags
-#define gaim_conv_chat_user_get_flags    purple_conv_chat_user_get_flags
-#define gaim_conv_chat_clear_users       purple_conv_chat_clear_users
-#define gaim_conv_chat_set_nick          purple_conv_chat_set_nick
-#define gaim_conv_chat_get_nick          purple_conv_chat_get_nick
-#define gaim_conv_chat_left              purple_conv_chat_left
-#define gaim_conv_chat_has_left          purple_conv_chat_has_left
-
-#define gaim_find_chat                   purple_find_chat
-
-#define gaim_conv_chat_cb_new            purple_conv_chat_cb_new
-#define gaim_conv_chat_cb_find           purple_conv_chat_cb_find
-#define gaim_conv_chat_cb_get_name       purple_conv_chat_cb_get_name
-#define gaim_conv_chat_cb_destroy        purple_conv_chat_cb_destroy
-
-#define gaim_conversations_get_handle    purple_conversations_get_handle
-#define gaim_conversations_init          purple_conversations_init
-#define gaim_conversations_uninit        purple_conversations_uninit
-
-/* from core.h */
-
-#define GaimCore  PurpleCore
-
-#define GaimCoreUiOps  PurpleCoreUiOps
-
-#define gaim_core_init  purple_core_init
-#define gaim_core_quit  purple_core_quit
-
-#define gaim_core_quit_cb      purple_core_quit_cb
-#define gaim_core_get_version  purple_core_get_version
-#define gaim_core_get_ui       purple_core_get_ui
-#define gaim_get_core          purple_get_core
-#define gaim_core_set_ui_ops   purple_core_set_ui_ops
-#define gaim_core_get_ui_ops   purple_core_get_ui_ops
-
-/* from debug.h */
-
-#define GAIM_DEBUG_ALL      PURPLE_DEBUG_ALL
-#define GAIM_DEBUG_MISC     PURPLE_DEBUG_MISC
-#define GAIM_DEBUG_INFO     PURPLE_DEBUG_INFO
-#define GAIM_DEBUG_WARNING  PURPLE_DEBUG_WARNING
-#define GAIM_DEBUG_ERROR    PURPLE_DEBUG_ERROR
-#define GAIM_DEBUG_FATAL    PURPLE_DEBUG_FATAL
-
-#define GaimDebugLevel  PurpleDebugLevel
-
-#define GaimDebugUiOps  PurpleDebugUiOps
-
-
-#define gaim_debug          purple_debug
-#define gaim_debug_misc     purple_debug_misc
-#define gaim_debug_info     purple_debug_info
-#define gaim_debug_warning  purple_debug_warning
-#define gaim_debug_error    purple_debug_error
-#define gaim_debug_fatal    purple_debug_fatal
-
-#define gaim_debug_set_enabled  purple_debug_set_enabled
-#define gaim_debug_is_enabled   purple_debug_is_enabled
-
-#define gaim_debug_set_ui_ops  purple_debug_set_ui_ops
-#define gaim_debug_get_ui_ops  purple_debug_get_ui_ops
-
-#define gaim_debug_init  purple_debug_init
-
-/* from desktopitem.h */
-
-#define GAIM_DESKTOP_ITEM_TYPE_NULL          PURPLE_DESKTOP_ITEM_TYPE_NULL
-#define GAIM_DESKTOP_ITEM_TYPE_OTHER         PURPLE_DESKTOP_ITEM_TYPE_OTHER
-#define GAIM_DESKTOP_ITEM_TYPE_APPLICATION   PURPLE_DESKTOP_ITEM_TYPE_APPLICATION
-#define GAIM_DESKTOP_ITEM_TYPE_LINK          PURPLE_DESKTOP_ITEM_TYPE_LINK
-#define GAIM_DESKTOP_ITEM_TYPE_FSDEVICE      PURPLE_DESKTOP_ITEM_TYPE_FSDEVICE
-#define GAIM_DESKTOP_ITEM_TYPE_MIME_TYPE     PURPLE_DESKTOP_ITEM_TYPE_MIME_TYPE
-#define GAIM_DESKTOP_ITEM_TYPE_DIRECTORY     PURPLE_DESKTOP_ITEM_TYPE_DIRECTORY
-#define GAIM_DESKTOP_ITEM_TYPE_SERVICE       PURPLE_DESKTOP_ITEM_TYPE_SERVICE
-#define GAIM_DESKTOP_ITEM_TYPE_SERVICE_TYPE  PURPLE_DESKTOP_ITEM_TYPE_SERVICE_TYPE
-
-#define GaimDesktopItemType  PurpleDesktopItemType
-
-#define GaimDesktopItem  PurpleDesktopItem
-
-#define GAIM_TYPE_DESKTOP_ITEM         PURPLE_TYPE_DESKTOP_ITEM
-#define gaim_desktop_item_get_type     purple_desktop_item_get_type
-
-/* standard */
-/* ugh, i'm just copying these as strings, rather than pidginifying them */
-#define GAIM_DESKTOP_ITEM_ENCODING	"Encoding" /* string */
-#define GAIM_DESKTOP_ITEM_VERSION	"Version"  /* numeric */
-#define GAIM_DESKTOP_ITEM_NAME		"Name" /* localestring */
-#define GAIM_DESKTOP_ITEM_GENERIC_NAME	"GenericName" /* localestring */
-#define GAIM_DESKTOP_ITEM_TYPE		"Type" /* string */
-#define GAIM_DESKTOP_ITEM_FILE_PATTERN "FilePattern" /* regexp(s) */
-#define GAIM_DESKTOP_ITEM_TRY_EXEC	"TryExec" /* string */
-#define GAIM_DESKTOP_ITEM_NO_DISPLAY	"NoDisplay" /* boolean */
-#define GAIM_DESKTOP_ITEM_COMMENT	"Comment" /* localestring */
-#define GAIM_DESKTOP_ITEM_EXEC		"Exec" /* string */
-#define GAIM_DESKTOP_ITEM_ACTIONS	"Actions" /* strings */
-#define GAIM_DESKTOP_ITEM_ICON		"Icon" /* string */
-#define GAIM_DESKTOP_ITEM_MINI_ICON	"MiniIcon" /* string */
-#define GAIM_DESKTOP_ITEM_HIDDEN	"Hidden" /* boolean */
-#define GAIM_DESKTOP_ITEM_PATH		"Path" /* string */
-#define GAIM_DESKTOP_ITEM_TERMINAL	"Terminal" /* boolean */
-#define GAIM_DESKTOP_ITEM_TERMINAL_OPTIONS "TerminalOptions" /* string */
-#define GAIM_DESKTOP_ITEM_SWALLOW_TITLE "SwallowTitle" /* string */
-#define GAIM_DESKTOP_ITEM_SWALLOW_EXEC	"SwallowExec" /* string */
-#define GAIM_DESKTOP_ITEM_MIME_TYPE	"MimeType" /* regexp(s) */
-#define GAIM_DESKTOP_ITEM_PATTERNS	"Patterns" /* regexp(s) */
-#define GAIM_DESKTOP_ITEM_DEFAULT_APP	"DefaultApp" /* string */
-#define GAIM_DESKTOP_ITEM_DEV		"Dev" /* string */
-#define GAIM_DESKTOP_ITEM_FS_TYPE	"FSType" /* string */
-#define GAIM_DESKTOP_ITEM_MOUNT_POINT	"MountPoint" /* string */
-#define GAIM_DESKTOP_ITEM_READ_ONLY	"ReadOnly" /* boolean */
-#define GAIM_DESKTOP_ITEM_UNMOUNT_ICON "UnmountIcon" /* string */
-#define GAIM_DESKTOP_ITEM_SORT_ORDER	"SortOrder" /* strings */
-#define GAIM_DESKTOP_ITEM_URL		"URL" /* string */
-#define GAIM_DESKTOP_ITEM_DOC_PATH	"X-GNOME-DocPath" /* string */
-
-#define gaim_desktop_item_new_from_file   purple_desktop_item_new_from_file
-#define gaim_desktop_item_get_entry_type  purple_desktop_item_get_entry_type
-#define gaim_desktop_item_get_string      purple_desktop_item_get_string
-#define gaim_desktop_item_copy            purple_desktop_item_copy
-#define gaim_desktop_item_unref           purple_desktop_item_unref
-
-/* from dnsquery.h */
-
-#define GaimDnsQueryData  PurpleDnsQueryData
-#define GaimDnsQueryConnectFunction  PurpleDnsQueryConnectFunction
-
-#define gaim_dnsquery_a        		purple_dnsquery_a
-#define gaim_dnsquery_destroy  		purple_dnsquery_destroy
-#define gaim_dnsquery_init     		purple_dnsquery_init
-#define gaim_dnsquery_uninit   		purple_dnsquery_uninit
-#define gaim_dnsquery_set_ui_ops	purple_dnsquery_set_ui_ops
-#define gaim_dnsquery_get_host 		purple_dnsquery_get_host
-#define gaim_dnsquery_get_port 		purple_dnsquery_get_port
-
-/* from dnssrv.h */
-
-#define GaimSrvResponse   PurpleSrvResponse
-#define GaimSrvQueryData  PurpleSrvTxtQueryData
-#define GaimSrvCallback   PurpleSrvCallback
-
-#define gaim_srv_resolve  purple_srv_resolve
-#define gaim_srv_cancel   purple_srv_cancel
-
-/* from eventloop.h */
-
-#define GAIM_INPUT_READ   PURPLE_INPUT_READ
-#define GAIM_INPUT_WRITE  PURPLE_INPUT_WRITE
-
-#define GaimInputCondition  PurpleInputCondition
-#define GaimInputFunction   PurpleInputFunction
-#define GaimEventLoopUiOps  PurpleEventLoopUiOps
-
-#define gaim_timeout_add     purple_timeout_add
-#define gaim_timeout_remove  purple_timeout_remove
-#define gaim_input_add       purple_input_add
-#define gaim_input_remove    purple_input_remove
-
-#define gaim_eventloop_set_ui_ops  purple_eventloop_set_ui_ops
-#define gaim_eventloop_get_ui_ops  purple_eventloop_get_ui_ops
-
-/* from ft.h */
-
-#define GaimXfer  PurpleXfer
-
-#define GAIM_XFER_UNKNOWN  PURPLE_XFER_UNKNOWN
-#define GAIM_XFER_SEND     PURPLE_XFER_SEND
-#define GAIM_XFER_RECEIVE  PURPLE_XFER_RECEIVE
-
-#define GaimXferType  PurpleXferType
-
-#define GAIM_XFER_STATUS_UNKNOWN        PURPLE_XFER_STATUS_UNKNOWN
-#define GAIM_XFER_STATUS_NOT_STARTED    PURPLE_XFER_STATUS_NOT_STARTED
-#define GAIM_XFER_STATUS_ACCEPTED       PURPLE_XFER_STATUS_ACCEPTED
-#define GAIM_XFER_STATUS_STARTED        PURPLE_XFER_STATUS_STARTED
-#define GAIM_XFER_STATUS_DONE           PURPLE_XFER_STATUS_DONE
-#define GAIM_XFER_STATUS_CANCEL_LOCAL   PURPLE_XFER_STATUS_CANCEL_LOCAL
-#define GAIM_XFER_STATUS_CANCEL_REMOTE  PURPLE_XFER_STATUS_CANCEL_REMOTE
-
-#define GaimXferStatusType  PurpleXferStatusType
-
-#define GaimXferUiOps  PurpleXferUiOps
-
-#define gaim_xfer_new                  purple_xfer_new
-#define gaim_xfer_ref                  purple_xfer_ref
-#define gaim_xfer_unref                purple_xfer_unref
-#define gaim_xfer_request              purple_xfer_request
-#define gaim_xfer_request_accepted     purple_xfer_request_accepted
-#define gaim_xfer_request_denied       purple_xfer_request_denied
-#define gaim_xfer_get_type             purple_xfer_get_type
-#define gaim_xfer_get_account          purple_xfer_get_account
-#define gaim_xfer_get_status           purple_xfer_get_status
-#define gaim_xfer_is_canceled          purple_xfer_is_canceled
-#define gaim_xfer_is_completed         purple_xfer_is_completed
-#define gaim_xfer_get_filename         purple_xfer_get_filename
-#define gaim_xfer_get_local_filename   purple_xfer_get_local_filename
-#define gaim_xfer_get_bytes_sent       purple_xfer_get_bytes_sent
-#define gaim_xfer_get_bytes_remaining  purple_xfer_get_bytes_remaining
-#define gaim_xfer_get_size             purple_xfer_get_size
-#define gaim_xfer_get_progress         purple_xfer_get_progress
-#define gaim_xfer_get_local_port       purple_xfer_get_local_port
-#define gaim_xfer_get_remote_ip        purple_xfer_get_remote_ip
-#define gaim_xfer_get_remote_port      purple_xfer_get_remote_port
-#define gaim_xfer_set_completed        purple_xfer_set_completed
-#define gaim_xfer_set_message          purple_xfer_set_message
-#define gaim_xfer_set_filename         purple_xfer_set_filename
-#define gaim_xfer_set_local_filename   purple_xfer_set_local_filename
-#define gaim_xfer_set_size             purple_xfer_set_size
-#define gaim_xfer_set_bytes_sent       purple_xfer_set_bytes_sent
-#define gaim_xfer_get_ui_ops           purple_xfer_get_ui_ops
-#define gaim_xfer_set_read_fnc         purple_xfer_set_read_fnc
-#define gaim_xfer_set_write_fnc        purple_xfer_set_write_fnc
-#define gaim_xfer_set_ack_fnc          purple_xfer_set_ack_fnc
-#define gaim_xfer_set_request_denied_fnc  purple_xfer_set_request_denied_fnc
-#define gaim_xfer_set_init_fnc         purple_xfer_set_init_fnc
-#define gaim_xfer_set_start_fnc        purple_xfer_set_start_fnc
-#define gaim_xfer_set_end_fnc          purple_xfer_set_end_fnc
-#define gaim_xfer_set_cancel_send_fnc  purple_xfer_set_cancel_send_fnc
-#define gaim_xfer_set_cancel_recv_fnc  purple_xfer_set_cancel_recv_fnc
-
-#define gaim_xfer_read                purple_xfer_read
-#define gaim_xfer_write               purple_xfer_write
-#define gaim_xfer_start               purple_xfer_start
-#define gaim_xfer_end                 purple_xfer_end
-#define gaim_xfer_add                 purple_xfer_add
-#define gaim_xfer_cancel_local        purple_xfer_cancel_local
-#define gaim_xfer_cancel_remote       purple_xfer_cancel_remote
-#define gaim_xfer_error               purple_xfer_error
-#define gaim_xfer_update_progress     purple_xfer_update_progress
-#define gaim_xfer_conversation_write  purple_xfer_conversation_write
-
-#define gaim_xfers_get_handle  purple_xfers_get_handle
-#define gaim_xfers_init        purple_xfers_init
-#define gaim_xfers_uninit      purple_xfers_uninit
-#define gaim_xfers_set_ui_ops  purple_xfers_set_ui_ops
-#define gaim_xfers_get_ui_ops  purple_xfers_get_ui_ops
-
-/* from gaim-client.h */
-
-#define gaim_init  purple_init
-
-/* from idle.h */
-
-#define GaimIdleUiOps  PurpleIdleUiOps
-
-#define gaim_idle_touch       purple_idle_touch
-#define gaim_idle_set         purple_idle_set
-#define gaim_idle_set_ui_ops  purple_idle_set_ui_ops
-#define gaim_idle_get_ui_ops  purple_idle_get_ui_ops
-#define gaim_idle_init        purple_idle_init
-#define gaim_idle_uninit      purple_idle_uninit
-
-/* from imgstore.h */
-
-#define GaimStoredImage  PurpleStoredImage
-
-#define gaim_imgstore_add(data, size, filename) \
-        purple_imgstore_add_with_id(g_memdup(data, size), size, filename)
-#define gaim_imgstore_get           purple_imgstore_find_by_id
-#define gaim_imgstore_get_data      purple_imgstore_get_data
-#define gaim_imgstore_get_size      purple_imgstore_get_size
-#define gaim_imgstore_get_filename  purple_imgstore_get_filename
-#define gaim_imgstore_ref           purple_imgstore_ref_by_id
-#define gaim_imgstore_unref         purple_imgstore_unref_by_id
-
-
-/* from log.h */
-
-#define GaimLog                  PurpleLog
-#define GaimLogLogger            PurpleLogLogger
-#define GaimLogCommonLoggerData  PurpleLogCommonLoggerData
-#define GaimLogSet               PurpleLogSet
-
-#define GAIM_LOG_IM      PURPLE_LOG_IM
-#define GAIM_LOG_CHAT    PURPLE_LOG_CHAT
-#define GAIM_LOG_SYSTEM  PURPLE_LOG_SYSTEM
-
-#define GaimLogType  PurpleLogType
-
-#define GAIM_LOG_READ_NO_NEWLINE  PURPLE_LOG_READ_NO_NEWLINE
-
-#define GaimLogReadFlags  PurpleLogReadFlags
-
-#define GaimLogSetCallback  PurpleLogSetCallback
-
-#define gaim_log_new    purple_log_new
-#define gaim_log_free   purple_log_free
-#define gaim_log_write  purple_log_write
-#define gaim_log_read   purple_log_read
-
-#define gaim_log_get_logs         purple_log_get_logs
-#define gaim_log_get_log_sets     purple_log_get_log_sets
-#define gaim_log_get_system_logs  purple_log_get_system_logs
-#define gaim_log_get_size         purple_log_get_size
-#define gaim_log_get_total_size   purple_log_get_total_size
-#define gaim_log_get_log_dir      purple_log_get_log_dir
-#define gaim_log_compare          purple_log_compare
-#define gaim_log_set_compare      purple_log_set_compare
-#define gaim_log_set_free         purple_log_set_free
-
-#define gaim_log_common_writer       purple_log_common_writer
-#define gaim_log_common_lister       purple_log_common_lister
-#define gaim_log_common_total_sizer  purple_log_common_total_sizer
-#define gaim_log_common_sizer        purple_log_common_sizer
-
-#define gaim_log_logger_new     purple_log_logger_new
-#define gaim_log_logger_free    purple_log_logger_free
-#define gaim_log_logger_add     purple_log_logger_add
-#define gaim_log_logger_remove  purple_log_logger_remove
-#define gaim_log_logger_set     purple_log_logger_set
-#define gaim_log_logger_get     purple_log_logger_get
-
-#define gaim_log_logger_get_options  purple_log_logger_get_options
-
-#define gaim_log_init        purple_log_init
-#define gaim_log_get_handle  purple_log_get_handle
-#define gaim_log_uninit      purple_log_uninit
-
-/* from mime.h */
-
-#define GaimMimeDocument  PurpleMimeDocument
-#define GaimMimePart      PurpleMimePart
-
-#define gaim_mime_document_new         purple_mime_document_new
-#define gaim_mime_document_free        purple_mime_document_free
-#define gaim_mime_document_parse       purple_mime_document_parse
-#define gaim_mime_document_parsen      purple_mime_document_parsen
-#define gaim_mime_document_write       purple_mime_document_write
-#define gaim_mime_document_get_fields  purple_mime_document_get_fields
-#define gaim_mime_document_get_field   purple_mime_document_get_field
-#define gaim_mime_document_set_field   purple_mime_document_set_field
-#define gaim_mime_document_get_parts   purple_mime_document_get_parts
-
-#define gaim_mime_part_new                purple_mime_part_new
-#define gaim_mime_part_get_fields         purple_mime_part_get_fields
-#define gaim_mime_part_get_field          purple_mime_part_get_field
-#define gaim_mime_part_get_field_decoded  purple_mime_part_get_field_decoded
-#define gaim_mime_part_set_field          purple_mime_part_set_field
-#define gaim_mime_part_get_data           purple_mime_part_get_data
-#define gaim_mime_part_get_data_decoded   purple_mime_part_get_data_decoded
-#define gaim_mime_part_get_length         purple_mime_part_get_length
-#define gaim_mime_part_set_data           purple_mime_part_set_data
-
-
-/* from network.h */
-
-#define GaimNetworkListenData  PurpleNetworkListenData
-
-#define GaimNetworkListenCallback  PurpleNetworkListenCallback
-
-#define gaim_network_ip_atoi              purple_network_ip_atoi
-#define gaim_network_set_public_ip        purple_network_set_public_ip
-#define gaim_network_get_public_ip        purple_network_get_public_ip
-#define gaim_network_get_local_system_ip  purple_network_get_local_system_ip
-#define gaim_network_get_my_ip            purple_network_get_my_ip
-
-#define gaim_network_listen            purple_network_listen
-#define gaim_network_listen_range      purple_network_listen_range
-#define gaim_network_listen_cancel     purple_network_listen_cancel
-#define gaim_network_get_port_from_fd  purple_network_get_port_from_fd
-
-#define gaim_network_is_available  purple_network_is_available
-
-#define gaim_network_init    purple_network_init
-#define gaim_network_uninit  purple_network_uninit
-
-/* from notify.h */
-
-
-#define GaimNotifyUserInfoEntry  PurpleNotifyUserInfoEntry
-#define GaimNotifyUserInfo       PurpleNotifyUserInfo
-
-#define GaimNotifyCloseCallback  PurpleNotifyCloseCallback
-
-#define GAIM_NOTIFY_MESSAGE        PURPLE_NOTIFY_MESSAGE
-#define GAIM_NOTIFY_EMAIL          PURPLE_NOTIFY_EMAIL
-#define GAIM_NOTIFY_EMAILS         PURPLE_NOTIFY_EMAILS
-#define GAIM_NOTIFY_FORMATTED      PURPLE_NOTIFY_FORMATTED
-#define GAIM_NOTIFY_SEARCHRESULTS  PURPLE_NOTIFY_SEARCHRESULTS
-#define GAIM_NOTIFY_USERINFO       PURPLE_NOTIFY_USERINFO
-#define GAIM_NOTIFY_URI            PURPLE_NOTIFY_URI
-
-#define GaimNotifyType  PurpleNotifyType
-
-#define GAIM_NOTIFY_MSG_ERROR    PURPLE_NOTIFY_MSG_ERROR
-#define GAIM_NOTIFY_MSG_WARNING  PURPLE_NOTIFY_MSG_WARNING
-#define GAIM_NOTIFY_MSG_INFO     PURPLE_NOTIFY_MSG_INFO
-
-#define GaimNotifyMsgType  PurpleNotifyMsgType
-
-#define GAIM_NOTIFY_BUTTON_LABELED   PURPLE_NOTIFY_BUTTON_LABELED
-#define GAIM_NOTIFY_BUTTON_CONTINUE  PURPLE_NOTIFY_BUTTON_CONTINUE
-#define GAIM_NOTIFY_BUTTON_ADD       PURPLE_NOTIFY_BUTTON_ADD
-#define GAIM_NOTIFY_BUTTON_INFO      PURPLE_NOTIFY_BUTTON_INFO
-#define GAIM_NOTIFY_BUTTON_IM        PURPLE_NOTIFY_BUTTON_IM
-#define GAIM_NOTIFY_BUTTON_JOIN      PURPLE_NOTIFY_BUTTON_JOIN
-#define GAIM_NOTIFY_BUTTON_INVITE    PURPLE_NOTIFY_BUTTON_INVITE
-
-#define GaimNotifySearchButtonType  PurpleNotifySearchButtonType
-
-#define GaimNotifySearchResults  PurpleNotifySearchResults
-
-#define GAIM_NOTIFY_USER_INFO_ENTRY_PAIR            PURPLE_NOTIFY_USER_INFO_ENTRY_PAIR
-#define GAIM_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK   PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK
-#define GAIM_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER  PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER
-
-#define GaimNotifyUserInfoEntryType  PurpleNotifyUserInfoEntryType
-
-#define GaimNotifySearchColumn           PurpleNotifySearchColumn
-#define GaimNotifySearchResultsCallback  PurpleNotifySearchResultsCallback
-#define GaimNotifySearchButton           PurpleNotifySearchButton
-
-#define GaimNotifyUiOps  PurpleNotifyUiOps
-
-#define gaim_notify_searchresults                     purple_notify_searchresults
-#define gaim_notify_searchresults_free                purple_notify_searchresults_free
-#define gaim_notify_searchresults_new_rows            purple_notify_searchresults_new_rows
-#define gaim_notify_searchresults_button_add          purple_notify_searchresults_button_add
-#define gaim_notify_searchresults_button_add_labeled  purple_notify_searchresults_button_add_labeled
-#define gaim_notify_searchresults_new                 purple_notify_searchresults_new
-#define gaim_notify_searchresults_column_new          purple_notify_searchresults_column_new
-#define gaim_notify_searchresults_column_add          purple_notify_searchresults_column_add
-#define gaim_notify_searchresults_row_add             purple_notify_searchresults_row_add
-#define gaim_notify_searchresults_get_rows_count      purple_notify_searchresults_get_rows_count
-#define gaim_notify_searchresults_get_columns_count   purple_notify_searchresults_get_columns_count
-#define gaim_notify_searchresults_row_get             purple_notify_searchresults_row_get
-#define gaim_notify_searchresults_column_get_title    purple_notify_searchresults_column_get_title
-
-#define gaim_notify_message    purple_notify_message
-#define gaim_notify_email      purple_notify_email
-#define gaim_notify_emails     purple_notify_emails
-#define gaim_notify_formatted  purple_notify_formatted
-#define gaim_notify_userinfo   purple_notify_userinfo
-
-#define gaim_notify_user_info_new                    purple_notify_user_info_new
-#define gaim_notify_user_info_destroy                purple_notify_user_info_destroy
-#define gaim_notify_user_info_get_entries            purple_notify_user_info_get_entries
-#define gaim_notify_user_info_get_text_with_newline  purple_notify_user_info_get_text_with_newline
-#define gaim_notify_user_info_add_pair               purple_notify_user_info_add_pair
-#define gaim_notify_user_info_prepend_pair           purple_notify_user_info_prepend_pair
-#define gaim_notify_user_info_remove_entry           purple_notify_user_info_remove_entry
-#define gaim_notify_user_info_entry_new              purple_notify_user_info_entry_new
-#define gaim_notify_user_info_add_section_break      purple_notify_user_info_add_section_break
-#define gaim_notify_user_info_add_section_header     purple_notify_user_info_add_section_header
-#define gaim_notify_user_info_remove_last_item       purple_notify_user_info_remove_last_item
-#define gaim_notify_user_info_entry_get_label        purple_notify_user_info_entry_get_label
-#define gaim_notify_user_info_entry_set_label        purple_notify_user_info_entry_set_label
-#define gaim_notify_user_info_entry_get_value        purple_notify_user_info_entry_get_value
-#define gaim_notify_user_info_entry_set_value        purple_notify_user_info_entry_set_value
-#define gaim_notify_user_info_entry_get_type         purple_notify_user_info_entry_get_type
-#define gaim_notify_user_info_entry_set_type         purple_notify_user_info_entry_set_type
-
-#define gaim_notify_uri                purple_notify_uri
-#define gaim_notify_close              purple_notify_close
-#define gaim_notify_close_with_handle  purple_notify_close_with_handle
-
-#define gaim_notify_info     purple_notify_info
-#define gaim_notify_warning  purple_notify_warning
-#define gaim_notify_error    purple_notify_error
-
-#define gaim_notify_set_ui_ops  purple_notify_set_ui_ops
-#define gaim_notify_get_ui_ops  purple_notify_get_ui_ops
-
-#define gaim_notify_get_handle  purple_notify_get_handle
-
-#define gaim_notify_init    purple_notify_init
-#define gaim_notify_uninit  purple_notify_uninit
-
-/* from ntlm.h */
-
-#define gaim_ntlm_gen_type1    purple_ntlm_gen_type1
-#define gaim_ntlm_parse_type2  purple_ntlm_parse_type2
-#define gaim_ntlm_gen_type3    purple_ntlm_gen_type3
-
-/* from plugin.h */
-
-#ifdef GAIM_PLUGINS
-#ifndef PURPLE_PLUGINS
-#define PURPLE_PLUGINS
-#endif
-#endif
-
-#define GaimPlugin            PurplePlugin
-#define GaimPluginInfo        PurplePluginInfo
-#define GaimPluginUiInfo      PurplePluginUiInfo
-#define GaimPluginLoaderInfo  PurplePluginLoaderInfo
-#define GaimPluginAction      PurplePluginAction
-#define GaimPluginPriority    PurplePluginPriority
-
-#define GAIM_PLUGIN_UNKNOWN   PURPLE_PLUGIN_UNKNOWN
-#define GAIM_PLUGIN_STANDARD  PURPLE_PLUGIN_STANDARD
-#define GAIM_PLUGIN_LOADER    PURPLE_PLUGIN_LOADER
-#define GAIM_PLUGIN_PROTOCOL  PURPLE_PLUGIN_PROTOCOL
-
-#define GaimPluginType        PurplePluginType
-
-#define GAIM_PRIORITY_DEFAULT  PURPLE_PRIORITY_DEFAULT
-#define GAIM_PRIORITY_HIGHEST  PURPLE_PRIORITY_HIGHEST
-#define GAIM_PRIORITY_LOWEST   PURPLE_PRIORITY_LOWEST
-
-#define GAIM_PLUGIN_FLAG_INVISIBLE  PURPLE_PLUGIN_FLAG_INVISIBLE
-
-#define GAIM_PLUGIN_MAGIC  PURPLE_PLUGIN_MAGIC
-
-#define GAIM_PLUGIN_LOADER_INFO     PURPLE_PLUGIN_LOADER_INFO
-#define GAIM_PLUGIN_HAS_PREF_FRAME  PURPLE_PLUGIN_HAS_PREF_FRAME
-#define GAIM_PLUGIN_UI_INFO         PURPLE_PLUGIN_UI_INFO
-
-#define GAIM_PLUGIN_HAS_ACTIONS  PURPLE_PLUGIN_HAS_ACTIONS
-#define GAIM_PLUGIN_ACTIONS      PURPLE_PLUGIN_ACTIONS
-
-#define GAIM_INIT_PLUGIN  PURPLE_INIT_PLUGIN
-
-#define gaim_plugin_new              purple_plugin_new
-#define gaim_plugin_probe            purple_plugin_probe
-#define gaim_plugin_register         purple_plugin_register
-#define gaim_plugin_load             purple_plugin_load
-#define gaim_plugin_unload           purple_plugin_unload
-#define gaim_plugin_reload           purple_plugin_reload
-#define gaim_plugin_destroy          purple_plugin_destroy
-#define gaim_plugin_is_loaded        purple_plugin_is_loaded
-#define gaim_plugin_is_unloadable    purple_plugin_is_unloadable
-#define gaim_plugin_get_id           purple_plugin_get_id
-#define gaim_plugin_get_name         purple_plugin_get_name
-#define gaim_plugin_get_version      purple_plugin_get_version
-#define gaim_plugin_get_summary      purple_plugin_get_summary
-#define gaim_plugin_get_description  purple_plugin_get_description
-#define gaim_plugin_get_author       purple_plugin_get_author
-#define gaim_plugin_get_homepage     purple_plugin_get_homepage
-
-#define gaim_plugin_ipc_register        purple_plugin_ipc_register
-#define gaim_plugin_ipc_unregister      purple_plugin_ipc_unregister
-#define gaim_plugin_ipc_unregister_all  purple_plugin_ipc_unregister_all
-#define gaim_plugin_ipc_get_params      purple_plugin_ipc_get_params
-#define gaim_plugin_ipc_call            purple_plugin_ipc_call
-
-#define gaim_plugins_add_search_path  purple_plugins_add_search_path
-#define gaim_plugins_unload_all       purple_plugins_unload_all
-#define gaim_plugins_destroy_all      purple_plugins_destroy_all
-#define gaim_plugins_save_loaded      purple_plugins_save_loaded
-#define gaim_plugins_load_saved       purple_plugins_load_saved
-#define gaim_plugins_probe            purple_plugins_probe
-#define gaim_plugins_enabled          purple_plugins_enabled
-
-#define gaim_plugins_register_probe_notify_cb     purple_plugins_register_probe_notify_cb
-#define gaim_plugins_unregister_probe_notify_cb   purple_plugins_unregister_probe_notify_cb
-#define gaim_plugins_register_load_notify_cb      purple_plugins_register_load_notify_cb
-#define gaim_plugins_unregister_load_notify_cb    purple_plugins_unregister_load_notify_cb
-#define gaim_plugins_register_unload_notify_cb    purple_plugins_register_unload_notify_cb
-#define gaim_plugins_unregister_unload_notify_cb  purple_plugins_unregister_unload_notify_cb
-
-#define gaim_plugins_find_with_name      purple_plugins_find_with_name
-#define gaim_plugins_find_with_filename  purple_plugins_find_with_filename
-#define gaim_plugins_find_with_basename  purple_plugins_find_with_basename
-#define gaim_plugins_find_with_id        purple_plugins_find_with_id
-
-#define gaim_plugins_get_loaded     purple_plugins_get_loaded
-#define gaim_plugins_get_protocols  purple_plugins_get_protocols
-#define gaim_plugins_get_all        purple_plugins_get_all
-
-#define gaim_plugins_get_handle  purple_plugins_get_handle
-#define gaim_plugins_init        purple_plugins_init
-#define gaim_plugins_uninit      purple_plugins_uninit
-
-#define gaim_plugin_action_new   purple_plugin_action_new
-#define gaim_plugin_action_free  purple_plugin_action_free
-
-/* pluginpref.h */
-
-#define GaimPluginPrefFrame  PurplePluginPrefFrame
-#define GaimPluginPref       PurplePluginPref
-
-#define GAIM_STRING_FORMAT_TYPE_NONE       PURPLE_STRING_FORMAT_TYPE_NONE
-#define GAIM_STRING_FORMAT_TYPE_MULTILINE  PURPLE_STRING_FORMAT_TYPE_MULTILINE
-#define GAIM_STRING_FORMAT_TYPE_HTML       PURPLE_STRING_FORMAT_TYPE_HTML
-
-#define GaimStringFormatType  PurpleStringFormatType
-
-#define GAIM_PLUGIN_PREF_NONE           PURPLE_PLUGIN_PREF_NONE
-#define GAIM_PLUGIN_PREF_CHOICE         PURPLE_PLUGIN_PREF_CHOICE
-#define GAIM_PLUGIN_PREF_INFO           PURPLE_PLUGIN_PREF_INFO
-#define GAIM_PLUGIN_PREF_STRING_FORMAT  PURPLE_PLUGIN_PREF_STRING_FORMAT
-
-#define GaimPluginPrefType  PurplePluginPrefType
-
-#define gaim_plugin_pref_frame_new        purple_plugin_pref_frame_new
-#define gaim_plugin_pref_frame_destroy    purple_plugin_pref_frame_destroy
-#define gaim_plugin_pref_frame_add        purple_plugin_pref_frame_add
-#define gaim_plugin_pref_frame_get_prefs  purple_plugin_pref_frame_get_prefs
-
-#define gaim_plugin_pref_new                      purple_plugin_pref_new
-#define gaim_plugin_pref_new_with_name            purple_plugin_pref_new_with_name
-#define gaim_plugin_pref_new_with_label           purple_plugin_pref_new_with_label
-#define gaim_plugin_pref_new_with_name_and_label  purple_plugin_pref_new_with_name_and_label
-#define gaim_plugin_pref_destroy                  purple_plugin_pref_destroy
-#define gaim_plugin_pref_set_name                 purple_plugin_pref_set_name
-#define gaim_plugin_pref_get_name                 purple_plugin_pref_get_name
-#define gaim_plugin_pref_set_label                purple_plugin_pref_set_label
-#define gaim_plugin_pref_get_label                purple_plugin_pref_get_label
-#define gaim_plugin_pref_set_bounds               purple_plugin_pref_set_bounds
-#define gaim_plugin_pref_get_bounds               purple_plugin_pref_get_bounds
-#define gaim_plugin_pref_set_type                 purple_plugin_pref_set_type
-#define gaim_plugin_pref_get_type                 purple_plugin_pref_get_type
-#define gaim_plugin_pref_add_choice               purple_plugin_pref_add_choice
-#define gaim_plugin_pref_get_choices              purple_plugin_pref_get_choices
-#define gaim_plugin_pref_set_max_length           purple_plugin_pref_set_max_length
-#define gaim_plugin_pref_get_max_length           purple_plugin_pref_get_max_length
-#define gaim_plugin_pref_set_masked               purple_plugin_pref_set_masked
-#define gaim_plugin_pref_get_masked               purple_plugin_pref_get_masked
-#define gaim_plugin_pref_set_format_type          purple_plugin_pref_set_format_type
-#define gaim_plugin_pref_get_format_type          purple_plugin_pref_get_format_type
-
-/* from pounce.h */
-
-#define GaimPounce  PurplePounce
-
-#define GAIM_POUNCE_NONE              PURPLE_POUNCE_NONE
-#define GAIM_POUNCE_SIGNON            PURPLE_POUNCE_SIGNON
-#define GAIM_POUNCE_SIGNOFF           PURPLE_POUNCE_SIGNOFF
-#define GAIM_POUNCE_AWAY              PURPLE_POUNCE_AWAY
-#define GAIM_POUNCE_AWAY_RETURN       PURPLE_POUNCE_AWAY_RETURN
-#define GAIM_POUNCE_IDLE              PURPLE_POUNCE_IDLE
-#define GAIM_POUNCE_IDLE_RETURN       PURPLE_POUNCE_IDLE_RETURN
-#define GAIM_POUNCE_TYPING            PURPLE_POUNCE_TYPING
-#define GAIM_POUNCE_TYPED             PURPLE_POUNCE_TYPED
-#define GAIM_POUNCE_TYPING_STOPPED    PURPLE_POUNCE_TYPING_STOPPED
-#define GAIM_POUNCE_MESSAGE_RECEIVED  PURPLE_POUNCE_MESSAGE_RECEIVED
-#define GaimPounceEvent  PurplePounceEvent
-
-#define GAIM_POUNCE_OPTION_NONE  PURPLE_POUNCE_OPTION_NONE
-#define GAIM_POUNCE_OPTION_AWAY  PURPLE_POUNCE_OPTION_AWAY
-#define GaimPounceOption  PurplePounceOption
-
-#define GaimPounceCb  PurplePounceCb
-
-#define gaim_pounce_new                     purple_pounce_new
-#define gaim_pounce_destroy                 purple_pounce_destroy
-#define gaim_pounce_destroy_all_by_account  purple_pounce_destroy_all_by_account
-#define gaim_pounce_set_events              purple_pounce_set_events
-#define gaim_pounce_set_options             purple_pounce_set_options
-#define gaim_pounce_set_pouncer             purple_pounce_set_pouncer
-#define gaim_pounce_set_pouncee             purple_pounce_set_pouncee
-#define gaim_pounce_set_save                purple_pounce_set_save
-#define gaim_pounce_action_register         purple_pounce_action_register
-#define gaim_pounce_action_set_enabled      purple_pounce_action_set_enabled
-#define gaim_pounce_action_set_attribute    purple_pounce_action_set_attribute
-#define gaim_pounce_set_data                purple_pounce_set_data
-#define gaim_pounce_get_events              purple_pounce_get_events
-#define gaim_pounce_get_options             purple_pounce_get_options
-#define gaim_pounce_get_pouncer             purple_pounce_get_pouncer
-#define gaim_pounce_get_pouncee             purple_pounce_get_pouncee
-#define gaim_pounce_get_save                purple_pounce_get_save
-#define gaim_pounce_action_is_enabled       purple_pounce_action_is_enabled
-#define gaim_pounce_action_get_attribute    purple_pounce_action_get_attribute
-#define gaim_pounce_get_data                purple_pounce_get_data
-#define gaim_pounce_execute                 purple_pounce_execute
-
-#define gaim_find_pounce                 purple_find_pounce
-#define gaim_pounces_load                purple_pounces_load
-#define gaim_pounces_register_handler    purple_pounces_register_handler
-#define gaim_pounces_unregister_handler  purple_pounces_unregister_handler
-#define gaim_pounces_get_all             purple_pounces_get_all
-#define gaim_pounces_get_handle          purple_pounces_get_handle
-#define gaim_pounces_init                purple_pounces_init
-#define gaim_pounces_uninit              purple_pounces_uninit
-
-/* from prefs.h */
-
-
-#define GAIM_PREF_NONE         PURPLE_PREF_NONE
-#define GAIM_PREF_BOOLEAN      PURPLE_PREF_BOOLEAN
-#define GAIM_PREF_INT          PURPLE_PREF_INT
-#define GAIM_PREF_STRING       PURPLE_PREF_STRING
-#define GAIM_PREF_STRING_LIST  PURPLE_PREF_STRING_LIST
-#define GAIM_PREF_PATH         PURPLE_PREF_PATH
-#define GAIM_PREF_PATH_LIST    PURPLE_PREF_PATH_LIST
-#define GaimPrefType  PurplePrefType
-
-#define GaimPrefCallback  PurplePrefCallback
-
-#define gaim_prefs_get_handle             purple_prefs_get_handle
-#define gaim_prefs_init                   purple_prefs_init
-#define gaim_prefs_uninit                 purple_prefs_uninit
-#define gaim_prefs_add_none               purple_prefs_add_none
-#define gaim_prefs_add_bool               purple_prefs_add_bool
-#define gaim_prefs_add_int                purple_prefs_add_int
-#define gaim_prefs_add_string             purple_prefs_add_string
-#define gaim_prefs_add_string_list        purple_prefs_add_string_list
-#define gaim_prefs_add_path               purple_prefs_add_path
-#define gaim_prefs_add_path_list          purple_prefs_add_path_list
-#define gaim_prefs_remove                 purple_prefs_remove
-#define gaim_prefs_rename                 purple_prefs_rename
-#define gaim_prefs_rename_boolean_toggle  purple_prefs_rename_boolean_toggle
-#define gaim_prefs_destroy                purple_prefs_destroy
-#define gaim_prefs_set_generic            purple_prefs_set_generic
-#define gaim_prefs_set_bool               purple_prefs_set_bool
-#define gaim_prefs_set_int                purple_prefs_set_int
-#define gaim_prefs_set_string             purple_prefs_set_string
-#define gaim_prefs_set_string_list        purple_prefs_set_string_list
-#define gaim_prefs_set_path               purple_prefs_set_path
-#define gaim_prefs_set_path_list          purple_prefs_set_path_list
-#define gaim_prefs_exists                 purple_prefs_exists
-#define gaim_prefs_get_type               purple_prefs_get_type
-#define gaim_prefs_get_bool               purple_prefs_get_bool
-#define gaim_prefs_get_int                purple_prefs_get_int
-#define gaim_prefs_get_string             purple_prefs_get_string
-#define gaim_prefs_get_string_list        purple_prefs_get_string_list
-#define gaim_prefs_get_path               purple_prefs_get_path
-#define gaim_prefs_get_path_list          purple_prefs_get_path_list
-#define gaim_prefs_connect_callback       purple_prefs_connect_callback
-#define gaim_prefs_disconnect_callback    purple_prefs_disconnect_callback
-#define gaim_prefs_disconnect_by_handle   purple_prefs_disconnect_by_handle
-#define gaim_prefs_trigger_callback       purple_prefs_trigger_callback
-#define gaim_prefs_load                   purple_prefs_load
-#define gaim_prefs_update_old             purple_prefs_update_old
-
-/* from privacy.h */
-
-#define GAIM_PRIVACY_ALLOW_ALL        PURPLE_PRIVACY_ALLOW_ALL
-#define GAIM_PRIVACY_DENY_ALL         PURPLE_PRIVACY_DENY_ALL
-#define GAIM_PRIVACY_ALLOW_USERS      PURPLE_PRIVACY_ALLOW_USERS
-#define GAIM_PRIVACY_DENY_USERS       PURPLE_PRIVACY_DENY_USERS
-#define GAIM_PRIVACY_ALLOW_BUDDYLIST  PURPLE_PRIVACY_ALLOW_BUDDYLIST
-#define GaimPrivacyType  PurplePrivacyType
-
-#define GaimPrivacyUiOps  PurplePrivacyUiOps
-
-#define gaim_privacy_permit_add     purple_privacy_permit_add
-#define gaim_privacy_permit_remove  purple_privacy_permit_remove
-#define gaim_privacy_deny_add       purple_privacy_deny_add
-#define gaim_privacy_deny_remove    purple_privacy_deny_remove
-#define gaim_privacy_allow          purple_privacy_allow
-#define gaim_privacy_deny           purple_privacy_deny
-#define gaim_privacy_check          purple_privacy_check
-#define gaim_privacy_set_ui_ops     purple_privacy_set_ui_ops
-#define gaim_privacy_get_ui_ops     purple_privacy_get_ui_ops
-#define gaim_privacy_init           purple_privacy_init
-
-/* from proxy.h */
-
-#define GAIM_PROXY_USE_GLOBAL  PURPLE_PROXY_USE_GLOBAL
-#define GAIM_PROXY_NONE        PURPLE_PROXY_NONE
-#define GAIM_PROXY_HTTP        PURPLE_PROXY_HTTP
-#define GAIM_PROXY_SOCKS4      PURPLE_PROXY_SOCKS4
-#define GAIM_PROXY_SOCKS5      PURPLE_PROXY_SOCKS5
-#define GAIM_PROXY_USE_ENVVAR  PURPLE_PROXY_USE_ENVVAR
-#define GaimProxyType  PurpleProxyType
-
-#define GaimProxyInfo  PurpleProxyInfo
-
-#define GaimProxyConnectData      PurpleProxyConnectData
-#define GaimProxyConnectFunction  PurpleProxyConnectFunction
-
-#define gaim_proxy_info_new           purple_proxy_info_new
-#define gaim_proxy_info_destroy       purple_proxy_info_destroy
-#define gaim_proxy_info_set_type      purple_proxy_info_set_type
-#define gaim_proxy_info_set_host      purple_proxy_info_set_host
-#define gaim_proxy_info_set_port      purple_proxy_info_set_port
-#define gaim_proxy_info_set_username  purple_proxy_info_set_username
-#define gaim_proxy_info_set_password  purple_proxy_info_set_password
-#define gaim_proxy_info_get_type      purple_proxy_info_get_type
-#define gaim_proxy_info_get_host      purple_proxy_info_get_host
-#define gaim_proxy_info_get_port      purple_proxy_info_get_port
-#define gaim_proxy_info_get_username  purple_proxy_info_get_username
-#define gaim_proxy_info_get_password  purple_proxy_info_get_password
-
-#define gaim_global_proxy_get_info    purple_global_proxy_get_info
-#define gaim_proxy_get_handle         purple_proxy_get_handle
-#define gaim_proxy_init               purple_proxy_init
-#define gaim_proxy_uninit             purple_proxy_uninit
-#define gaim_proxy_get_setup          purple_proxy_get_setup
-
-#define gaim_proxy_connect                     purple_proxy_connect
-#define gaim_proxy_connect_socks5              purple_proxy_connect_socks5
-#define gaim_proxy_connect_cancel              purple_proxy_connect_cancel
-#define gaim_proxy_connect_cancel_with_handle  purple_proxy_connect_cancel_with_handle
-
-/* from prpl.h */
-
-#define GaimPluginProtocolInfo  PurplePluginProtocolInfo
-
-#define GAIM_ICON_SCALE_DISPLAY  PURPLE_ICON_SCALE_DISPLAY
-#define GAIM_ICON_SCALE_SEND     PURPLE_ICON_SCALE_SEND
-#define GaimIconScaleRules  PurpleIconScaleRules
-
-#define GaimBuddyIconSpec  PurpleBuddyIconSpec
-
-#define GaimProtocolOptions  PurpleProtocolOptions
-
-#define GAIM_IS_PROTOCOL_PLUGIN  PURPLE_IS_PROTOCOL_PLUGIN
-
-#define GAIM_PLUGIN_PROTOCOL_INFO  PURPLE_PLUGIN_PROTOCOL_INFO
-
-#define gaim_prpl_got_account_idle        purple_prpl_got_account_idle
-#define gaim_prpl_got_account_login_time  purple_prpl_got_account_login_time
-#define gaim_prpl_got_account_status      purple_prpl_got_account_status
-#define gaim_prpl_got_user_idle           purple_prpl_got_user_idle
-#define gaim_prpl_got_user_login_time     purple_prpl_got_user_login_time
-#define gaim_prpl_got_user_status         purple_prpl_got_user_status
-#define gaim_prpl_change_account_status   purple_prpl_change_account_status
-#define gaim_prpl_get_statuses            purple_prpl_get_statuses
-
-#define gaim_find_prpl  purple_find_prpl
-
-/* from request.h */
-
-#define GAIM_DEFAULT_ACTION_NONE  PURPLE_DEFAULT_ACTION_NONE
-
-#define GAIM_REQUEST_INPUT   PURPLE_REQUEST_INPUT
-#define GAIM_REQUEST_CHOICE  PURPLE_REQUEST_CHOICE
-#define GAIM_REQUEST_ACTION  PURPLE_REQUEST_ACTION
-#define GAIM_REQUEST_FIELDS  PURPLE_REQUEST_FIELDS
-#define GAIM_REQUEST_FILE    PURPLE_REQUEST_FILE
-#define GAIM_REQUEST_FOLDER  PURPLE_REQUEST_FOLDER
-#define GaimRequestType  PurpleRequestType
-
-#define GAIM_REQUEST_FIELD_NONE     PURPLE_REQUEST_FIELD_NONE
-#define GAIM_REQUEST_FIELD_STRING   PURPLE_REQUEST_FIELD_STRING
-#define GAIM_REQUEST_FIELD_INTEGER  PURPLE_REQUEST_FIELD_INTEGER
-#define GAIM_REQUEST_FIELD_BOOLEAN  PURPLE_REQUEST_FIELD_BOOLEAN
-#define GAIM_REQUEST_FIELD_CHOICE   PURPLE_REQUEST_FIELD_CHOICE
-#define GAIM_REQUEST_FIELD_LIST     PURPLE_REQUEST_FIELD_LIST
-#define GAIM_REQUEST_FIELD_LABEL    PURPLE_REQUEST_FIELD_LABEL
-#define GAIM_REQUEST_FIELD_IMAGE    PURPLE_REQUEST_FIELD_IMAGE
-#define GAIM_REQUEST_FIELD_ACCOUNT  PURPLE_REQUEST_FIELD_ACCOUNT
-#define GaimRequestFieldType  PurpleRequestFieldType
-
-#define GaimRequestFields  PurpleRequestFields
-
-#define GaimRequestFieldGroup  PurpleRequestFieldGroup
-
-#define GaimRequestField  PurpleRequestField
-
-#define GaimRequestUiOps  PurpleRequestUiOps
-
-#define GaimRequestInputCb   PurpleRequestInputCb
-#define GaimRequestActionCb  PurpleRequestActionCb
-#define GaimRequestChoiceCb  PurpleRequestChoiceCb
-#define GaimRequestFieldsCb  PurpleRequestFieldsCb
-#define GaimRequestFileCb    PurpleRequestFileCb
-
-#define gaim_request_fields_new                  purple_request_fields_new
-#define gaim_request_fields_destroy              purple_request_fields_destroy
-#define gaim_request_fields_add_group            purple_request_fields_add_group
-#define gaim_request_fields_get_groups           purple_request_fields_get_groups
-#define gaim_request_fields_exists               purple_request_fields_exists
-#define gaim_request_fields_get_required         purple_request_fields_get_required
-#define gaim_request_fields_is_field_required    purple_request_fields_is_field_required
-#define gaim_request_fields_all_required_filled  purple_request_fields_all_required_filled
-#define gaim_request_fields_get_field            purple_request_fields_get_field
-#define gaim_request_fields_get_string           purple_request_fields_get_string
-#define gaim_request_fields_get_integer          purple_request_fields_get_integer
-#define gaim_request_fields_get_bool             purple_request_fields_get_bool
-#define gaim_request_fields_get_choice           purple_request_fields_get_choice
-#define gaim_request_fields_get_account          purple_request_fields_get_account
-
-#define gaim_request_field_group_new         purple_request_field_group_new
-#define gaim_request_field_group_destroy     purple_request_field_group_destroy
-#define gaim_request_field_group_add_field   purple_request_field_group_add_field
-#define gaim_request_field_group_get_title   purple_request_field_group_get_title
-#define gaim_request_field_group_get_fields  purple_request_field_group_get_fields
-
-#define gaim_request_field_new            purple_request_field_new
-#define gaim_request_field_destroy        purple_request_field_destroy
-#define gaim_request_field_set_label      purple_request_field_set_label
-#define gaim_request_field_set_visible    purple_request_field_set_visible
-#define gaim_request_field_set_type_hint  purple_request_field_set_type_hint
-#define gaim_request_field_set_required   purple_request_field_set_required
-#define gaim_request_field_get_type       purple_request_field_get_type
-#define gaim_request_field_get_id         purple_request_field_get_id
-#define gaim_request_field_get_label      purple_request_field_get_label
-#define gaim_request_field_is_visible     purple_request_field_is_visible
-#define gaim_request_field_get_type_hint  purple_request_field_get_type_hint
-#define gaim_request_field_is_required    purple_request_field_is_required
-
-#define gaim_request_field_string_new           purple_request_field_string_new
-#define gaim_request_field_string_set_default_value \
-	purple_request_field_string_set_default_value
-#define gaim_request_field_string_set_value     purple_request_field_string_set_value
-#define gaim_request_field_string_set_masked    purple_request_field_string_set_masked
-#define gaim_request_field_string_set_editable  purple_request_field_string_set_editable
-#define gaim_request_field_string_get_default_value \
-	purple_request_field_string_get_default_value
-#define gaim_request_field_string_get_value     purple_request_field_string_get_value
-#define gaim_request_field_string_is_multiline  purple_request_field_string_is_multiline
-#define gaim_request_field_string_is_masked     purple_request_field_string_is_masked
-#define gaim_request_field_string_is_editable   purple_request_field_string_is_editable
-
-#define gaim_request_field_int_new        purple_request_field_int_new
-#define gaim_request_field_int_set_default_value \
-	purple_request_field_int_set_default_value
-#define gaim_request_field_int_set_value  purple_request_field_int_set_value
-#define gaim_request_field_int_get_default_value \
-	purple_request_field_int_get_default_value
-#define gaim_request_field_int_get_value  purple_request_field_int_get_value
-
-#define gaim_request_field_bool_new        purple_request_field_bool_new
-#define gaim_request_field_bool_set_default_value \
-	purple_request_field_book_set_default_value
-#define gaim_request_field_bool_set_value  purple_request_field_bool_set_value
-#define gaim_request_field_bool_get_default_value \
-	purple_request_field_bool_get_default_value
-#define gaim_request_field_bool_get_value  purple_request_field_bool_get_value
-
-#define gaim_request_field_choice_new         purple_request_field_choice_new
-#define gaim_request_field_choice_add         purple_request_field_choice_add
-#define gaim_request_field_choice_set_default_value \
-	purple_request_field_choice_set_default_value
-#define gaim_request_field_choice_set_value   purple_request_field_choice_set_value
-#define gaim_request_field_choice_get_default_value \
-	purple_request_field_choice_get_default_value
-#define gaim_request_field_choice_get_value   purple_request_field_choice_get_value
-#define gaim_request_field_choice_get_labels  purple_request_field_choice_get_labels
-
-#define gaim_request_field_list_new               purple_request_field_list_new
-#define gaim_request_field_list_set_multi_select  purple_request_field_list_set_multi_select
-#define gaim_request_field_list_get_multi_select  purple_request_field_list_get_multi_select
-#define gaim_request_field_list_get_data          purple_request_field_list_get_data
-#define gaim_request_field_list_add               purple_request_field_list_add
-#define gaim_request_field_list_add_selected      purple_request_field_list_add_selected
-#define gaim_request_field_list_clear_selected    purple_request_field_list_clear_selected
-#define gaim_request_field_list_set_selected      purple_request_field_list_set_selected
-#define gaim_request_field_list_is_selected       purple_request_field_list_is_selected
-#define gaim_request_field_list_get_selected      purple_request_field_list_get_selected
-#define gaim_request_field_list_get_items         purple_request_field_list_get_items
-
-#define gaim_request_field_label_new  purple_request_field_label_new
-
-#define gaim_request_field_image_new          purple_request_field_image_new
-#define gaim_request_field_image_set_scale    purple_request_field_image_set_scale
-#define gaim_request_field_image_get_buffer   purple_request_field_image_get_buffer
-#define gaim_request_field_image_get_size     purple_request_field_image_get_size
-#define gaim_request_field_image_get_scale_x  purple_request_field_image_get_scale_x
-#define gaim_request_field_image_get_scale_y  purple_request_field_image_get_scale_y
-
-#define gaim_request_field_account_new                purple_request_field_account_new
-#define gaim_request_field_account_set_default_value  purple_request_field_account_set_default_value
-#define gaim_request_field_account_set_value          purple_request_field_account_set_value
-#define gaim_request_field_account_set_show_all       purple_request_field_account_set_show_all
-#define gaim_request_field_account_set_filter         purple_request_field_account_set_filter
-#define gaim_request_field_account_get_default_value  purple_request_field_account_get_default_value
-#define gaim_request_field_account_get_value          purple_request_field_account_get_value
-#define gaim_request_field_account_get_show_all       purple_request_field_account_get_show_all
-#define gaim_request_field_account_get_filter         purple_request_field_account_get_filter
-
-#define gaim_request_input              purple_request_input
-#define gaim_request_choice             purple_request_choice
-#define gaim_request_choice_varg        purple_request_choice_varg
-#define gaim_request_action             purple_request_action
-#define gaim_request_action_varg        purple_request_action_varg
-#define gaim_request_fields(handle, title, primary, secondary, fields, ok_text, ok_cb, cancel_text, cancel_cb, user_data)             purple_request_fields(handle, title, primary, secondary, fields, ok_text, ok_cb, cancel_text, cancel_cb, NULL, NULL, NULL, user_data)
-#define gaim_request_close              purple_request_close
-#define gaim_request_close_with_handle  purple_request_close_with_handle
-
-#define gaim_request_yes_no         purple_request_yes_no
-#define gaim_request_ok_cancel      purple_request_ok_cancel
-#define gaim_request_accept_cancel  purple_request_accept_cancel
-
-#define gaim_request_file    purple_request_file
-#define gaim_request_folder  purple_request_folder
-
-#define gaim_request_set_ui_ops  purple_request_set_ui_ops
-#define gaim_request_get_ui_ops  purple_request_get_ui_ops
-
-/* from roomlist.h */
-
-#define GaimRoomlist       PurpleRoomlist
-#define GaimRoomlistRoom   PurpleRoomlistRoom
-#define GaimRoomlistField  PurpleRoomlistField
-#define GaimRoomlistUiOps  PurpleRoomlistUiOps
-
-#define GAIM_ROOMLIST_ROOMTYPE_CATEGORY  PURPLE_ROOMLIST_ROOMTYPE_CATEGORY
-#define GAIM_ROOMLIST_ROOMTYPE_ROOM      PURPLE_ROOMLIST_ROOMTYPE_ROOM
-#define GaimRoomlistRoomType  PurpleRoomlistRoomType
-
-#define GAIM_ROOMLIST_FIELD_BOOL    PURPLE_ROOMLIST_BOOL
-#define GAIM_ROOMLIST_FIELD_INT     PURPLE_ROOMLIST_INT
-#define GAIM_ROOMLIST_FIELD_STRING  PURPLE_ROOMLIST_STRING
-#define GaimRoomlistFieldType  PurpleRoomlistFieldType
-
-#define gaim_roomlist_show_with_account  purple_roomlist_show_with_account
-#define gaim_roomlist_new                purple_roomlist_new
-#define gaim_roomlist_ref                purple_roomlist_ref
-#define gaim_roomlist_unref              purple_roomlist_unref
-#define gaim_roomlist_set_fields         purple_roomlist_set_fields
-#define gaim_roomlist_set_in_progress    purple_roomlist_set_in_progress
-#define gaim_roomlist_get_in_progress    purple_roomlist_get_in_progress
-#define gaim_roomlist_room_add           purple_roomlist_room_add
-
-#define gaim_roomlist_get_list         purple_roomlist_get_list
-#define gaim_roomlist_cancel_get_list  purple_roomlist_cancel_get_list
-#define gaim_roomlist_expand_category  purple_roomlist_expand_category
-
-#define gaim_roomlist_room_new        purple_roomlist_room_new
-#define gaim_roomlist_room_add_field  purple_roomlist_room_add_field
-#define gaim_roomlist_room_join       purple_roomlist_room_join
-#define gaim_roomlist_field_new       purple_roomlist_field_new
-
-#define gaim_roomlist_set_ui_ops  purple_roomlist_set_ui_ops
-#define gaim_roomlist_get_ui_ops  purple_roomlist_get_ui_ops
-
-/* from savedstatuses.h */
-
-#define GaimSavedStatus     PurpleSavedStatus
-#define GaimSavedStatusSub  PurpleSavedStatusSub
-
-#define gaim_savedstatus_new              purple_savedstatus_new
-#define gaim_savedstatus_set_title        purple_savedstatus_set_title
-#define gaim_savedstatus_set_type         purple_savedstatus_set_type
-#define gaim_savedstatus_set_message      purple_savedstatus_set_message
-#define gaim_savedstatus_set_substatus    purple_savedstatus_set_substatus
-#define gaim_savedstatus_unset_substatus  purple_savedstatus_unset_substatus
-#define gaim_savedstatus_delete           purple_savedstatus_delete
-
-#define gaim_savedstatuses_get_all              purple_savedstatuses_get_all
-#define gaim_savedstatuses_get_popular          purple_savedstatuses_get_popular
-#define gaim_savedstatus_get_current            purple_savedstatus_get_current
-#define gaim_savedstatus_get_default            purple_savedstatus_get_default
-#define gaim_savedstatus_get_idleaway           purple_savedstatus_get_idleaway
-#define gaim_savedstatus_is_idleaway            purple_savedstatus_is_idleaway
-#define gaim_savedstatus_set_idleaway           purple_savedstatus_set_idleaway
-#define gaim_savedstatus_get_startup            purple_savedstatus_get_startup
-#define gaim_savedstatus_find                   purple_savedstatus_find
-#define gaim_savedstatus_find_by_creation_time  purple_savedstatus_find_by_creation_time
-#define gaim_savedstatus_find_transient_by_type_and_message \
-	purple_savedstatus_find_transient_by_type_and_message
-
-#define gaim_savedstatus_is_transient           purple_savedstatus_is_transient
-#define gaim_savedstatus_get_title              purple_savedstatus_get_title
-#define gaim_savedstatus_get_type               purple_savedstatus_get_type
-#define gaim_savedstatus_get_message            purple_savedstatus_get_message
-#define gaim_savedstatus_get_creation_time      purple_savedstatus_get_creation_time
-#define gaim_savedstatus_has_substatuses        purple_savedstatus_has_substatuses
-#define gaim_savedstatus_get_substatus          purple_savedstatus_get_substatus
-#define gaim_savedstatus_substatus_get_type     purple_savedstatus_substatus_get_type
-#define gaim_savedstatus_substatus_get_message  purple_savedstatus_substatus_get_message
-#define gaim_savedstatus_activate               purple_savedstatus_activate
-#define gaim_savedstatus_activate_for_account   purple_savedstatus_activate_for_account
-
-#define gaim_savedstatuses_get_handle  purple_savedstatuses_get_handle
-#define gaim_savedstatuses_init        purple_savedstatuses_init
-#define gaim_savedstatuses_uninit      purple_savedstatuses_uninit
-
-/* from signals.h */
-
-#define GAIM_CALLBACK  PURPLE_CALLBACK
-
-#define GaimCallback           PurpleCallback
-#define GaimSignalMarshalFunc  PurpleSignalMarshalFunc
-
-#define GAIM_SIGNAL_PRIORITY_DEFAULT  PURPLE_SIGNAL_PRIORITY_DEFAULT
-#define GAIM_SIGNAL_PRIORITY_HIGHEST  PURPLE_SIGNAL_PRIORITY_HIGHEST
-#define GAIM_SIGNAL_PRIORITY_LOWEST   PURPLE_SIGNAL_PRIORITY_LOWEST
-
-#define gaim_signal_register    purple_signal_register
-#define gaim_signal_unregister  purple_signal_unregister
-
-#define gaim_signals_unregister_by_instance  purple_signals_unregister_by_instance
-
-#define gaim_signal_get_values              purple_signal_get_values
-#define gaim_signal_connect_priority        purple_signal_connect_priority
-#define gaim_signal_connect                 purple_signal_connect
-#define gaim_signal_connect_priority_vargs  purple_signal_connect_priority_vargs
-#define gaim_signal_connect_vargs           purple_signal_connect_vargs
-#define gaim_signal_disconnect              purple_signal_disconnect
-
-#define gaim_signals_disconnect_by_handle  purple_signals_disconnect_by_handle
-
-#define gaim_signal_emit                 purple_signal_emit
-#define gaim_signal_emit_vargs           purple_signal_emit_vargs
-#define gaim_signal_emit_return_1        purple_signal_emit_vargs
-#define gaim_signal_emit_vargs_return_1  purple_signal_emit_vargs_return_1
-
-#define gaim_signals_init    purple_signals_init
-#define gaim_signals_uninit  purple_signals_uninit
-
-#define gaim_marshal_VOID \
-	purple_marshal_VOID
-#define gaim_marshal_VOID__INT \
-	purple_marshal_VOID__INT
-#define gaim_marshal_VOID__INT_INT \
-	purple_marshal_VOID_INT_INT
-#define gaim_marshal_VOID__POINTER \
-	purple_marshal_VOID__POINTER
-#define gaim_marshal_VOID__POINTER_UINT \
-	purple_marshal_VOID__POINTER_UINT
-#define gaim_marshal_VOID__POINTER_INT_INT \
-	purple_marshal_VOID__POINTER_INT_INT
-#define gaim_marshal_VOID__POINTER_POINTER \
-	purple_marshal_VOID__POINTER_POINTER
-#define gaim_marshal_VOID__POINTER_POINTER_UINT \
-	purple_marshal_VOID__POINTER_POINTER_UINT
-#define gaim_marshal_VOID__POINTER_POINTER_UINT_UINT \
-	purple_marshal_VOID__POINTER_POINTER_UINT_UINT
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER \
-	purple_marshal_VOID__POINTER_POINTER_POINTER
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER \
-	purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER \
-	purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT \
-	purple_marshal_VOID__POINTER_POINTER_POINTER_UINT
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT \
-	purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT \
-	purple_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT
-
-#define gaim_marshal_INT__INT \
-	purple_marshal_INT__INT
-#define gaim_marshal_INT__INT_INT \
-	purple_marshal_INT__INT_INT
-#define gaim_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER \
-	purple_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER
-
-#define gaim_marshal_BOOLEAN__POINTER \
-	purple_marshal_BOOLEAN__POINTER
-#define gaim_marshal_BOOLEAN__POINTER_POINTER \
-	purple_marshal_BOOLEAN__POINTER_POINTER
-#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER \
-	purple_marshal_BOOLEAN__POINTER_POINTER_POINTER
-#define gaim_marshal_BOOLEAN__POINTER_POINTER_UINT \
-	purple_marshal_BOOLEAN__POINTER_POINTER_UINT
-#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_UINT \
-	purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_UINT
-#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER \
-	purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER
-#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER \
-	purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER
-
-#define gaim_marshal_BOOLEAN__INT_POINTER \
-	purple_marshal_BOOLEAN__INT_POINTER
-
-#define gaim_marshal_POINTER__POINTER_INT \
-	purple_marshal_POINTER__POINTER_INT
-#define gaim_marshal_POINTER__POINTER_INT64 \
-	purple_marshal_POINTER__POINTER_INT64
-#define gaim_marshal_POINTER__POINTER_INT_BOOLEAN \
-	purple_marshal_POINTER__POINTER_INT_BOOLEAN
-#define gaim_marshal_POINTER__POINTER_INT64_BOOLEAN \
-	purple_marshal_POINTER__POINTER_INT64_BOOLEAN
-#define gaim_marshal_POINTER__POINTER_POINTER \
-	purple_marshal_POINTER__POINTER_POINTER
-
-/* from sound.h */
-
-#define GAIM_SOUND_BUDDY_ARRIVE    PURPLE_SOUND_BUDDY_ARRIVE
-#define GAIM_SOUND_BUDDY_LEAVE     PURPLE_SOUND_BUDDY_LEAVE
-#define GAIM_SOUND_RECEIVE         PURPLE_SOUND_RECEIVE
-#define GAIM_SOUND_FIRST_RECEIVE   PURPLE_SOUND_FIRST_RECEIVE
-#define GAIM_SOUND_SEND            PURPLE_SOUND_SEND
-#define GAIM_SOUND_CHAT_JOIN       PURPLE_SOUND_CHAT_JOIN
-#define GAIM_SOUND_CHAT_LEAVE      PURPLE_SOUND_CHAT_LEAVE
-#define GAIM_SOUND_CHAT_YOU_SAY    PURPLE_SOUND_CHAT_YOU_SAY
-#define GAIM_SOUND_CHAT_SAY        PURPLE_SOUND_CHAT_SAY
-#define GAIM_SOUND_POUNCE_DEFAULT  PURPLE_SOUND_POUNCE_DEFAULT
-#define GAIM_SOUND_CHAT_NICK       PURPLE_SOUND_CHAT_NICK
-#define GAIM_NUM_SOUNDS            PURPLE_NUM_SOUNDS
-#define GaimSoundEventID  PurpleSoundEventID
-
-#define GaimSoundUiOps  PurpleSoundUiOps
-
-#define gaim_sound_play_file   purple_sound_play_file
-#define gaim_sound_play_event  purple_sound_play_event
-#define gaim_sound_set_ui_ops  purple_sound_set_ui_ops
-#define gaim_sound_get_ui_ops  purple_sound_get_ui_ops
-#define gaim_sound_init        purple_sound_init
-#define gaim_sound_uninit      purple_sound_uninit
-
-#define gaim_sounds_get_handle  purple_sounds_get_handle
-
-/* from sslconn.h */
-
-#define GAIM_SSL_DEFAULT_PORT  PURPLE_SSL_DEFAULT_PORT
-
-#define GAIM_SSL_HANDSHAKE_FAILED  PURPLE_SSL_HANDSHAKE_FAILED
-#define GAIM_SSL_CONNECT_FAILED    PURPLE_SSL_CONNECT_FAILED
-#define GaimSslErrorType  PurpleSslErrorType
-
-#define GaimSslConnection  PurpleSslConnection
-
-#define GaimSslInputFunction  PurpleSslInputFunction
-#define GaimSslErrorFunction  PurpleSslErrorFunction
-
-#define GaimSslOps  PurpleSslOps
-
-#define gaim_ssl_is_supported  purple_ssl_is_supported
-#define gaim_ssl_connect       purple_ssl_connect
-#define gaim_ssl_connect_fd    purple_ssl_connect_fd
-#define gaim_ssl_input_add     purple_ssl_input_add
-#define gaim_ssl_close         purple_ssl_close
-#define gaim_ssl_read          purple_ssl_read
-#define gaim_ssl_write         purple_ssl_write
-
-#define gaim_ssl_set_ops  purple_ssl_set_ops
-#define gaim_ssl_get_ops  purple_ssl_get_ops
-#define gaim_ssl_init     purple_ssl_init
-#define gaim_ssl_uninit   purple_ssl_uninit
-
-/* from status.h */
-
-#define GaimStatusType  PurpleStatusType
-#define GaimStatusAttr  PurpleStatusAttr
-#define GaimPresence    PurplePresence
-#define GaimStatus      PurpleStatus
-
-#define GAIM_PRESENCE_CONTEXT_UNSET    PURPLE_PRESENCE_CONTEXT_UNSET
-#define GAIM_PRESENCE_CONTEXT_ACCOUNT  PURPLE_PRESENCE_CONTEXT_ACCOUNT
-#define GAIM_PRESENCE_CONTEXT_CONV     PURPLE_PRESENCE_CONTEXT_CONV
-#define GAIM_PRESENCE_CONTEXT_BUDDY    PURPLE_PRESENCE_CONTEXT_BUDDY
-#define GaimPresenceContext  PurplePresenceContext
-
-#define GAIM_STATUS_UNSET           PURPLE_STATUS_UNSET
-#define GAIM_STATUS_OFFLINE         PURPLE_STATUS_OFFLINE
-#define GAIM_STATUS_AVAILABLE       PURPLE_STATUS_AVAILABLE
-#define GAIM_STATUS_UNAVAILABLE     PURPLE_STATUS_UNAVAILABLE
-#define GAIM_STATUS_INVISIBLE       PURPLE_STATUS_INVISIBLE
-#define GAIM_STATUS_AWAY            PURPLE_STATUS_AWAY
-#define GAIM_STATUS_EXTENDED_AWAY   PURPLE_STATUS_EXTENDED_AWAY
-#define GAIM_STATUS_MOBILE          PURPLE_STATUS_MOBILE
-#define GAIM_STATUS_NUM_PRIMITIVES  PURPLE_STATUS_NUM_PRIMITIVES
-#define GaimStatusPrimitive  PurpleStatusPrimitive
-
-#define gaim_primitive_get_id_from_type    purple_primitive_get_id_from_type
-#define gaim_primitive_get_name_from_type  purple_primitive_get_name_from_type
-#define gaim_primitive_get_type_from_id    purple_primitive_get_type_from_id
-
-#define gaim_status_type_new_full          purple_status_type_new_full
-#define gaim_status_type_new               purple_status_type_new
-#define gaim_status_type_new_with_attrs    purple_status_type_new_with_attrs
-#define gaim_status_type_destroy           purple_status_type_destroy
-#define gaim_status_type_set_primary_attr  purple_status_type_set_primary_attr
-#define gaim_status_type_add_attr          purple_status_type_add_attr
-#define gaim_status_type_add_attrs         purple_status_type_add_attrs
-#define gaim_status_type_add_attrs_vargs   purple_status_type_add_attrs_vargs
-#define gaim_status_type_get_primitive     purple_status_type_get_primitive
-#define gaim_status_type_get_id            purple_status_type_get_id
-#define gaim_status_type_get_name          purple_status_type_get_name
-#define gaim_status_type_is_saveable       purple_status_type_is_saveable
-#define gaim_status_type_is_user_settable  purple_status_type_is_user_settable
-#define gaim_status_type_is_independent    purple_status_type_is_independent
-#define gaim_status_type_is_exclusive      purple_status_type_is_exclusive
-#define gaim_status_type_is_available      purple_status_type_is_available
-#define gaim_status_type_get_primary_attr  purple_status_type_get_primary_attr
-#define gaim_status_type_get_attr          purple_status_type_get_attr
-#define gaim_status_type_get_attrs         purple_status_type_get_attrs
-#define gaim_status_type_find_with_id      purple_status_type_find_with_id
-
-#define gaim_status_attr_new        purple_status_attr_new
-#define gaim_status_attr_destroy    purple_status_attr_destroy
-#define gaim_status_attr_get_id     purple_status_attr_get_id
-#define gaim_status_attr_get_name   purple_status_attr_get_name
-#define gaim_status_attr_get_value  purple_status_attr_get_value
-
-#define gaim_status_new                         purple_status_new
-#define gaim_status_destroy                     purple_status_destroy
-#define gaim_status_set_active                  purple_status_set_active
-#define gaim_status_set_active_with_attrs       purple_status_set_active_with_attrs
-#define gaim_status_set_active_with_attrs_list  purple_status_set_active_with_attrs_list
-#define gaim_status_set_attr_boolean            purple_status_set_attr_boolean
-#define gaim_status_set_attr_int                purple_status_set_attr_int
-#define gaim_status_set_attr_string             purple_status_set_attr_string
-#define gaim_status_get_type                    purple_status_get_type
-#define gaim_status_get_presence                purple_status_get_presence
-#define gaim_status_get_id                      purple_status_get_id
-#define gaim_status_get_name                    purple_status_get_name
-#define gaim_status_is_independent              purple_status_is_independent
-#define gaim_status_is_exclusive                purple_status_is_exclusive
-#define gaim_status_is_available                purple_status_is_available
-#define gaim_status_is_active                   purple_status_is_active
-#define gaim_status_is_online                   purple_status_is_online
-#define gaim_status_get_attr_value              purple_status_get_attr_value
-#define gaim_status_get_attr_boolean            purple_status_get_attr_boolean
-#define gaim_status_get_attr_int                purple_status_get_attr_int
-#define gaim_status_get_attr_string             purple_status_get_attr_string
-#define gaim_status_compare                     purple_status_compare
-
-#define gaim_presence_new                purple_presence_new
-#define gaim_presence_new_for_account    purple_presence_new_for_account
-#define gaim_presence_new_for_conv       purple_presence_new_for_conv
-#define gaim_presence_new_for_buddy      purple_presence_new_for_buddy
-#define gaim_presence_destroy            purple_presence_destroy
-#define gaim_presence_add_status         purple_presence_add_status
-#define gaim_presence_add_list           purple_presence_add_list
-#define gaim_presence_set_status_active  purple_presence_set_status_active
-#define gaim_presence_switch_status      purple_presence_switch_status
-#define gaim_presence_set_idle           purple_presence_set_idle
-#define gaim_presence_set_login_time     purple_presence_set_login_time
-#define gaim_presence_get_context        purple_presence_get_context
-#define gaim_presence_get_account        purple_presence_get_account
-#define gaim_presence_get_conversation   purple_presence_get_conversation
-#define gaim_presence_get_chat_user      purple_presence_get_chat_user
-#define gaim_presence_get_statuses       purple_presence_get_statuses
-#define gaim_presence_get_status         purple_presence_get_status
-#define gaim_presence_get_active_status  purple_presence_get_active_status
-#define gaim_presence_is_available       purple_presence_is_available
-#define gaim_presence_is_online          purple_presence_is_online
-#define gaim_presence_is_status_active   purple_presence_is_status_active
-#define gaim_presence_is_status_primitive_active \
-	purple_presence_is_status_primitive_active
-#define gaim_presence_is_idle            purple_presence_is_idle
-#define gaim_presence_get_idle_time      purple_presence_get_idle_time
-#define gaim_presence_get_login_time     purple_presence_get_login_time
-#define gaim_presence_compare            purple_presence_compare
-
-#define gaim_status_get_handle  purple_status_get_handle
-#define gaim_status_init        purple_status_init
-#define gaim_status_uninit      purple_status_uninit
-
-/* from stringref.h */
-
-#define GaimStringref  PurpleStringref
-
-#define gaim_stringref_new        purple_stringref_new
-#define gaim_stringref_new_noref  purple_stringref_new_noref
-#define gaim_stringref_printf     purple_stringref_printf
-#define gaim_stringref_ref        purple_stringref_ref
-#define gaim_stringref_unref      purple_stringref_unref
-#define gaim_stringref_value      purple_stringref_value
-#define gaim_stringref_cmp        purple_stringref_cmp
-#define gaim_stringref_len        purple_stringref_len
-
-/* from stun.h */
-
-#define GaimStunNatDiscovery  PurpleStunNatDiscovery
-
-#define GAIM_STUN_STATUS_UNDISCOVERED  PURPLE_STUN_STATUS_UNDISCOVERED
-#define GAIM_STUN_STATUS_UNKNOWN       PURPLE_STUN_STATUS_UNKNOWN
-#define GAIM_STUN_STATUS_DISCOVERING   PURPLE_STUN_STATUS_DISCOVERING
-#define GAIM_STUN_STATUS_DISCOVERED    PURPLE_STUN_STATUS_DISCOVERED
-#define GaimStunStatus  PurpleStunStatus
-
-#define GAIM_STUN_NAT_TYPE_PUBLIC_IP             PURPLE_STUN_NAT_TYPE_PUBLIC_IP
-#define GAIM_STUN_NAT_TYPE_UNKNOWN_NAT           PURPLE_STUN_NAT_TYPE_UNKNOWN_NAT
-#define GAIM_STUN_NAT_TYPE_FULL_CONE             PURPLE_STUN_NAT_TYPE_FULL_CONE
-#define GAIM_STUN_NAT_TYPE_RESTRICTED_CONE       PURPLE_STUN_NAT_TYPE_RESTRICTED_CONE
-#define GAIM_STUN_NAT_TYPE_PORT_RESTRICTED_CONE  PURPLE_STUN_NAT_TYPE_PORT_RESTRICTED_CONE
-#define GAIM_STUN_NAT_TYPE_SYMMETRIC             PURPLE_STUN_NAT_TYPE_SYMMETRIC
-#define GaimStunNatType  PurpleStunNatType
-
-/* why didn't this have a Gaim prefix before? */
-#define StunCallback  PurpleStunCallback
-
-#define gaim_stun_discover  purple_stun_discover
-#define gaim_stun_init      purple_stun_init
-
-/* from upnp.h */
-
-/* suggested rename: PurpleUPnpMappingHandle */
-#define UPnPMappingAddRemove  PurpleUPnPMappingAddRemove
-
-#define GaimUPnPCallback  PurpleUPnPCallback
-
-#define gaim_upnp_discover             purple_upnp_discover
-#define gaim_upnp_get_public_ip        purple_upnp_get_public_ip
-#define gaim_upnp_cancel_port_mapping  purple_upnp_cancel_port_mapping
-#define gaim_upnp_set_port_mapping     purple_upnp_set_port_mapping
-
-#define gaim_upnp_remove_port_mapping  purple_upnp_remove_port_mapping
-
-/* from util.h */
-
-#define GaimUtilFetchUrlData  PurpleUtilFetchUrlData
-#define GaimMenuAction        PurpleMenuAction
-
-#define GaimInfoFieldFormatCallback  PurpleIntoFieldFormatCallback
-
-#define GaimKeyValuePair  PurpleKeyValuePair
-
-#define gaim_menu_action_new   purple_menu_action_new
-#define gaim_menu_action_free  purple_menu_action_free
-
-#define gaim_base16_encode   purple_base16_encode
-#define gaim_base16_decode   purple_base16_decode
-#define gaim_base64_encode   purple_base64_encode
-#define gaim_base64_decode   purple_base64_decode
-#define gaim_quotedp_decode  purple_quotedp_decode
-
-#define gaim_mime_decode_field  purple_mime_deco_field
-
-#define gaim_utf8_strftime      purple_utf8_strftime
-#define gaim_date_format_short  purple_date_format_short
-#define gaim_date_format_long   purple_date_format_long
-#define gaim_date_format_full   purple_date_format_full
-#define gaim_time_format        purple_time_format
-#define gaim_time_build         purple_time_build
-
-#define GAIM_NO_TZ_OFF  PURPLE_NO_TZ_OFF
-
-#define gaim_str_to_time  purple_str_to_time
-
-#define gaim_markup_find_tag            purple_markup_find_tag
-#define gaim_markup_extract_info_field  purple_markup_extract_info_field
-#define gaim_markup_html_to_xhtml       purple_markup_html_to_xhtml
-#define gaim_markup_strip_html          purple_markup_strip_html
-#define gaim_markup_linkify             purple_markup_linkify
-#define gaim_markup_slice               purple_markup_slice
-#define gaim_markup_get_tag_name        purple_markup_get_tag_name
-#define gaim_unescape_html              purple_unescape_html
-
-#define gaim_home_dir  purple_home_dir
-#define gaim_user_dir  purple_user_dir
-
-#define gaim_util_set_user_dir  purple_util_set_user_dir
-
-#define gaim_build_dir  purple_build_dir
-
-#define gaim_util_write_data_to_file  purple_util_write_data_to_file
-
-#define gaim_util_read_xml_from_file  purple_util_read_xml_from_file
-
-#define gaim_mkstemp  purple_mkstemp
-
-#define gaim_program_is_valid  purple_program_is_valid
-
-#define gaim_running_gnome  purple_running_gnome
-#define gaim_running_kde    purple_running_kde
-#define gaim_running_osx    purple_running_osx
-
-#define gaim_fd_get_ip  purple_fd_get_ip
-
-#define gaim_normalize         purple_normalize
-#define gaim_normalize_nocase  purple_normalize_nocase
-
-#define gaim_strdup_withhtml  purple_strdup_withhtml
-
-#define gaim_str_has_prefix  purple_str_has_prefix
-#define gaim_str_has_suffix  purple_str_has_suffix
-#define gaim_str_add_cr      purple_str_add_cr
-#define gaim_str_strip_char  purple_str_strip_char
-
-#define gaim_util_chrreplace  purple_util_chrreplace
-
-#define gaim_strreplace  purple_strreplace
-
-#define gaim_utf8_ncr_encode  purple_utf8_ncr_encode
-#define gaim_utf8_ncr_decode  purple_utf8_ncr_decode
-
-#define gaim_strcasereplace  purple_strcasereplace
-#define gaim_strcasestr      purple_strcasestr
-
-#define gaim_str_size_to_units      purple_str_size_to_units
-#define gaim_str_seconds_to_string  purple_str_seconds_to_string
-#define gaim_str_binary_to_ascii    purple_str_binary_to_ascii
-
-
-#define gaim_got_protocol_handler_uri  purple_got_protocol_handler_uri
-
-#define gaim_url_parse  purple_url_parse
-
-#define GaimUtilFetchUrlCallback  PurpleUtilFetchUrlCallback
-#define gaim_util_fetch_url          purple_util_fetch_url
-#define gaim_util_fetch_url_request  purple_util_fetch_url_request
-#define gaim_util_fetch_url_cancel   purple_util_fetch_url_cancel
-
-#define gaim_url_decode  purple_url_decode
-#define gaim_url_encode  purple_url_encode
-
-#define gaim_email_is_valid  purple_email_is_valid
-
-#define gaim_uri_list_extract_uris       purple_uri_list_extract_uris
-#define gaim_uri_list_extract_filenames  purple_uri_list_extract_filenames
-
-#define gaim_utf8_try_convert  purple_utf8_try_convert
-#define gaim_utf8_salvage      purple_utf8_salvage
-#define gaim_utf8_strcasecmp   purple_utf8_strcasecmp
-#define gaim_utf8_has_word     purple_utf8_has_word
-
-#define gaim_print_utf8_to_console  purple_print_utf8_to_console
-
-#define gaim_message_meify  purple_message_meify
-
-#define gaim_text_strip_mnemonic  purple_text_strip_mnemonic
-
-#define gaim_unescape_filename  purple_unescape_filename
-#define gaim_escape_filename    purple_escape_filename
-
-/* from value.h */
-
-#define GAIM_TYPE_UNKNOWN  PURPLE_TYPE_UNKNOWN
-#define GAIM_TYPE_SUBTYPE  PURPLE_TYPE_SUBTYPE
-#define GAIM_TYPE_CHAR     PURPLE_TYPE_CHAR
-#define GAIM_TYPE_UCHAR    PURPLE_TYPE_UCHAR
-#define GAIM_TYPE_BOOLEAN  PURPLE_TYPE_BOOLEAN
-#define GAIM_TYPE_SHORT    PURPLE_TYPE_SHORT
-#define GAIM_TYPE_USHORT   PURPLE_TYPE_USHORT
-#define GAIM_TYPE_INT      PURPLE_TYPE_INT
-#define GAIM_TYPE_UINT     PURPLE_TYPE_UINT
-#define GAIM_TYPE_LONG     PURPLE_TYPE_LONG
-#define GAIM_TYPE_ULONG    PURPLE_TYPE_ULONG
-#define GAIM_TYPE_INT64    PURPLE_TYPE_INT64
-#define GAIM_TYPE_UINT64   PURPLE_TYPE_UINT64
-#define GAIM_TYPE_STRING   PURPLE_TYPE_STRING
-#define GAIM_TYPE_OBJECT   PURPLE_TYPE_OBJECT
-#define GAIM_TYPE_POINTER  PURPLE_TYPE_POINTER
-#define GAIM_TYPE_ENUM     PURPLE_TYPE_ENUM
-#define GAIM_TYPE_BOXED    PURPLE_TYPE_BOXED
-#define GaimType  PurpleType
-
-
-#define GAIM_SUBTYPE_UNKNOWN       PURPLE_SUBTYPE_UNKNOWN
-#define GAIM_SUBTYPE_ACCOUNT       PURPLE_SUBTYPE_ACCOUNT
-#define GAIM_SUBTYPE_BLIST         PURPLE_SUBTYPE_BLIST
-#define GAIM_SUBTYPE_BLIST_BUDDY   PURPLE_SUBTYPE_BLIST_BUDDY
-#define GAIM_SUBTYPE_BLIST_GROUP   PURPLE_SUBTYPE_BLIST_GROUP
-#define GAIM_SUBTYPE_BLIST_CHAT    PURPLE_SUBTYPE_BLIST_CHAT
-#define GAIM_SUBTYPE_BUDDY_ICON    PURPLE_SUBTYPE_BUDDY_ICON
-#define GAIM_SUBTYPE_CONNECTION    PURPLE_SUBTYPE_CONNECTION
-#define GAIM_SUBTYPE_CONVERSATION  PURPLE_SUBTYPE_CONVERSATION
-#define GAIM_SUBTYPE_PLUGIN        PURPLE_SUBTYPE_PLUGIN
-#define GAIM_SUBTYPE_BLIST_NODE    PURPLE_SUBTYPE_BLIST_NODE
-#define GAIM_SUBTYPE_CIPHER        PURPLE_SUBTYPE_CIPHER
-#define GAIM_SUBTYPE_STATUS        PURPLE_SUBTYPE_STATUS
-#define GAIM_SUBTYPE_LOG           PURPLE_SUBTYPE_LOG
-#define GAIM_SUBTYPE_XFER          PURPLE_SUBTYPE_XFER
-#define GAIM_SUBTYPE_SAVEDSTATUS   PURPLE_SUBTYPE_SAVEDSTATUS
-#define GAIM_SUBTYPE_XMLNODE       PURPLE_SUBTYPE_XMLNODE
-#define GAIM_SUBTYPE_USERINFO      PURPLE_SUBTYPE_USERINFO
-#define GaimSubType  PurpleSubType
-
-#define GaimValue  PurpleValue
-
-#define gaim_value_new                purple_value_new
-#define gaim_value_new_outgoing       purple_value_new_outgoing
-#define gaim_value_destroy            purple_value_destroy
-#define gaim_value_dup                purple_value_dup
-#define gaim_value_purple_buddy_icon_get_extensionget_type           purple_value_get_type
-#define gaim_value_get_subtype        purple_value_get_subtype
-#define gaim_value_get_specific_type  purple_value_get_specific_type
-#define gaim_value_is_outgoing        purple_value_is_outgoing
-#define gaim_value_set_char           purple_value_set_char
-#define gaim_value_set_uchar          purple_value_set_uchar
-#define gaim_value_set_boolean        purple_value_set_boolean
-#define gaim_value_set_short          purple_value_set_short
-#define gaim_value_set_ushort         purple_value_set_ushort
-#define gaim_value_set_int            purple_value_set_int
-#define gaim_value_set_uint           purple_value_set_uint
-#define gaim_value_set_long           purple_value_set_long
-#define gaim_value_set_ulong          purple_value_set_ulong
-#define gaim_value_set_int64          purple_value_set_int64
-#define gaim_value_set_uint64         purple_value_set_uint64
-#define gaim_value_set_string         purple_value_set_string
-#define gaim_value_set_object         purple_value_set_object
-#define gaim_value_set_pointer        purple_value_set_pointer
-#define gaim_value_set_enum           purple_value_set_enum
-#define gaim_value_set_boxed          purple_value_set_boxed
-#define gaim_value_get_char           purple_value_get_char
-#define gaim_value_get_uchar          purple_value_get_uchar
-#define gaim_value_get_boolean        purple_value_get_boolean
-#define gaim_value_get_short          purple_value_get_short
-#define gaim_value_get_ushort         purple_value_get_ushort
-#define gaim_value_get_int            purple_value_get_int
-#define gaim_value_get_uint           purple_value_get_uint
-#define gaim_value_get_long           purple_value_get_long
-#define gaim_value_get_ulong          purple_value_get_ulong
-#define gaim_value_get_int64          purple_value_get_int64
-#define gaim_value_get_uint64         purple_value_get_uint64
-#define gaim_value_get_string         purple_value_get_string
-#define gaim_value_get_object         purple_value_get_object
-#define gaim_value_get_pointer        purple_value_get_pointer
-#define gaim_value_get_enum           purple_value_get_enum
-#define gaim_value_get_boxed          purple_value_get_boxed
-
-/* from version.h */
-
-#define GAIM_MAJOR_VERSION  PURPLE_MAJOR_VERSION
-#define GAIM_MINOR_VERSION  PURPLE_MINOR_VERSION
-#define GAIM_MICRO_VERSION  PURPLE_MICRO_VERSION
-
-#define GAIM_VERSION_CHECK  PURPLE_VERSION_CHECK
-
-/* from whiteboard.h */
-
-#define GaimWhiteboardPrplOps  PurpleWhiteboardPrplOps
-#define GaimWhiteboard         PurpleWhiteboard
-#define GaimWhiteboardUiOps    PurpleWhiteboardUiOps
-
-#define gaim_whiteboard_set_ui_ops    purple_whiteboard_set_ui_ops
-#define gaim_whiteboard_set_prpl_ops  purple_whiteboard_set_prpl_ops
-
-#define gaim_whiteboard_create             purple_whiteboard_create
-#define gaim_whiteboard_destroy            purple_whiteboard_destroy
-#define gaim_whiteboard_start              purple_whiteboard_start
-#define gaim_whiteboard_get_session        purple_whiteboard_get_session
-#define gaim_whiteboard_draw_list_destroy  purple_whiteboard_draw_list_destroy
-#define gaim_whiteboard_get_dimensions     purple_whiteboard_get_dimensions
-#define gaim_whiteboard_set_dimensions     purple_whiteboard_set_dimensions
-#define gaim_whiteboard_draw_point         purple_whiteboard_draw_point
-#define gaim_whiteboard_send_draw_list     purple_whiteboard_send_draw_list
-#define gaim_whiteboard_draw_line          purple_whiteboard_draw_line
-#define gaim_whiteboard_clear              purple_whiteboard_clear
-#define gaim_whiteboard_send_clear         purple_whiteboard_send_clear
-#define gaim_whiteboard_send_brush         purple_whiteboard_send_brush
-#define gaim_whiteboard_get_brush          purple_whiteboard_get_brush
-#define gaim_whiteboard_set_brush          purple_whiteboard_set_brush
-
-/* for static plugins */
-#define gaim_init_ssl_plugin			purple_init_ssl_plugin
-#define gaim_init_ssl_openssl_plugin	purple_init_ssl_openssl_plugin
-#define gaim_init_ssl_gnutls_plugin		purple_init_ssl_gnutls_plugin
-#define gaim_init_gg_plugin				purple_init_gg_plugin
-#define gaim_init_jabber_plugin			purple_init_jabber_plugin
-#define gaim_init_sametime_plugin		purple_init_sametime_plugin
-#define gaim_init_msn_plugin			purple_init_msn_plugin
-#define gaim_init_novell_plugin			purple_init_novell_plugin
-#define gaim_init_qq_plugin				purple_init_qq_plugin
-#define gaim_init_simple_plugin			purple_init_simple_plugin
-#define gaim_init_yahoo_plugin			purple_init_yahoo_plugin
-#define gaim_init_zephyr_plugin			purple_init_zephyr_plugin
-#define gaim_init_aim_plugin			purple_init_aim_plugin
-#define gaim_init_icq_plugin			purple_init_icq_plugin
-
-#endif /* _GAIM_COMPAT_H_ */
--- a/libpurple/imgstore.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/imgstore.h	Sun Sep 11 04:19:01 2011 +0000
@@ -68,7 +68,6 @@
  * @param path  The path to the image.
  *
  * @return  The stored image.
- * @since 2.X.X
  */
 PurpleStoredImage *
 purple_imgstore_new_from_file(const char *path);
--- a/libpurple/internal.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/internal.h	Sun Sep 11 04:19:01 2011 +0000
@@ -151,12 +151,6 @@
 
 #include <glib-object.h>
 
-/* Safer ways to work with static buffers. When using non-static
- * buffers, either use g_strdup_* functions (preferred) or use
- * g_strlcpy/g_strlcpy directly. */
-#define purple_strlcpy(dest, src) g_strlcpy(dest, src, sizeof(dest))
-#define purple_strlcat(dest, src) g_strlcat(dest, src, sizeof(dest))
-
 #define PURPLE_WEBSITE "http://pidgin.im/"
 #define PURPLE_DEVEL_WEBSITE "http://developer.pidgin.im/"
 
@@ -176,12 +170,6 @@
 void
 _purple_buddy_icons_blist_loaded_cb(void);
 
-/* This is for the purple_core_migrate() code to tell the buddy
- * icon subsystem about the old icons directory so it can
- * migrate any icons in use. */
-void
-_purple_buddy_icon_set_old_icons_dir(const char *dirname);
-
 /**
  * Creates a connection to the specified account and either connects
  * or attempts to register a new account.  If you are logging in,
--- a/libpurple/network.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/network.c	Sun Sep 11 04:19:01 2011 +0000
@@ -991,7 +991,7 @@
 	if (stun_server && stun_server[0] != '\0') {
 		if (purple_network_is_available()) {
 			purple_debug_info("network", "running DNS query for STUN server\n");
-			purple_dnsquery_a_account(NULL, stun_server, 3478, purple_network_ip_lookup_cb,
+			purple_dnsquery_a(NULL, stun_server, 3478, purple_network_ip_lookup_cb,
 				&stun_ip);
 		} else {
 			purple_debug_info("network",
@@ -1009,7 +1009,7 @@
 	if (turn_server && turn_server[0] != '\0') {
 		if (purple_network_is_available()) {
 			purple_debug_info("network", "running DNS query for TURN server\n");
-			purple_dnsquery_a_account(NULL, turn_server,
+			purple_dnsquery_a(NULL, turn_server,
 				purple_prefs_get_int("/purple/network/turn_port"),
 				purple_network_ip_lookup_cb, &turn_ip);
 		} else {
--- a/libpurple/notify.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/notify.c	Sun Sep 11 04:19:01 2011 +0000
@@ -53,7 +53,7 @@
 
 struct _PurpleNotifyUserInfo
 {
-	GList *user_info_entries;
+	GQueue entries;
 };
 
 void *
@@ -363,42 +363,24 @@
 
 	sc = g_new0(PurpleNotifySearchColumn, 1);
 	sc->title = g_strdup(title);
+	sc->visible = TRUE;
 
 	return sc;
 }
 
-guint
-purple_notify_searchresults_get_columns_count(PurpleNotifySearchResults *results)
+void purple_notify_searchresult_column_set_visible(PurpleNotifySearchColumn *column, gboolean visible)
 {
-	g_return_val_if_fail(results != NULL, 0);
+	g_return_if_fail(column != NULL);
 
-	return g_list_length(results->columns);
-}
-
-guint
-purple_notify_searchresults_get_rows_count(PurpleNotifySearchResults *results)
-{
-	g_return_val_if_fail(results != NULL, 0);
-
-	return g_list_length(results->rows);
+	column->visible = visible;
 }
 
-char *
-purple_notify_searchresults_column_get_title(PurpleNotifySearchResults *results,
-										   unsigned int column_id)
+gboolean
+purple_notify_searchresult_column_is_visible(const PurpleNotifySearchColumn *column)
 {
-	g_return_val_if_fail(results != NULL, NULL);
+	g_return_val_if_fail(column != NULL, FALSE);
 
-	return ((PurpleNotifySearchColumn *)g_list_nth_data(results->columns, column_id))->title;
-}
-
-GList *
-purple_notify_searchresults_row_get(PurpleNotifySearchResults *results,
-								  unsigned int row_id)
-{
-	g_return_val_if_fail(results != NULL, NULL);
-
-	return g_list_nth_data(results->rows, row_id);
+	return column->visible;
 }
 
 void *
@@ -472,7 +454,7 @@
 
 	user_info = g_new0(PurpleNotifyUserInfo, 1);
 	PURPLE_DBUS_REGISTER_POINTER(user_info, PurpleNotifyUserInfo);
-	user_info->user_info_entries = NULL;
+	g_queue_init(&user_info->entries);
 
 	return user_info;
 }
@@ -482,23 +464,23 @@
 {
 	GList *l;
 
-	for (l = user_info->user_info_entries; l != NULL; l = l->next) {
+	for (l = user_info->entries.head; l != NULL; l = l->next) {
 		PurpleNotifyUserInfoEntry *user_info_entry = l->data;
 
 		purple_notify_user_info_entry_destroy(user_info_entry);
 	}
 
-	g_list_free(user_info->user_info_entries);
+	g_queue_clear(&user_info->entries);
 	PURPLE_DBUS_UNREGISTER_POINTER(user_info);
 	g_free(user_info);
 }
 
-GList *
+GQueue *
 purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info)
 {
 	g_return_val_if_fail(user_info != NULL, NULL);
 
-	return user_info->user_info_entries;
+	return &user_info->entries;
 }
 
 char *
@@ -509,7 +491,7 @@
 
 	text = g_string_new("");
 
-	for (l = user_info->user_info_entries; l != NULL; l = l->next) {
+	for (l = user_info->entries.head; l != NULL; l = l->next) {
 		PurpleNotifyUserInfoEntry *user_info_entry = l->data;
 		/* Add a newline before a section header */
 		if (user_info_entry->type == PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER)
@@ -593,33 +575,41 @@
 }
 
 void
-purple_notify_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
+purple_notify_user_info_add_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
 {
 	PurpleNotifyUserInfoEntry *entry;
 
 	entry = purple_notify_user_info_entry_new(label, value);
-	user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry);
+	g_queue_push_tail(&user_info->entries, entry);
 }
 
 void
 purple_notify_user_info_add_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
 {
 	gchar *escaped;
-	PurpleNotifyUserInfoEntry *entry;
 
 	escaped = g_markup_escape_text(value, -1);
-	entry = purple_notify_user_info_entry_new(label, escaped);
+	purple_notify_user_info_add_pair_html(user_info, label, escaped);
 	g_free(escaped);
-	user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry);
 }
 
 void
-purple_notify_user_info_prepend_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
+purple_notify_user_info_prepend_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
 {
 	PurpleNotifyUserInfoEntry *entry;
 
 	entry = purple_notify_user_info_entry_new(label, value);
-	user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry);
+	g_queue_push_head(&user_info->entries, entry);
+}
+
+void
+purple_notify_user_info_prepend_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
+{
+	gchar *escaped;
+
+	escaped = g_markup_escape_text(value, -1);
+	purple_notify_user_info_prepend_pair_html(user_info, label, escaped);
+	g_free(escaped);
 }
 
 void
@@ -628,7 +618,7 @@
 	g_return_if_fail(user_info != NULL);
 	g_return_if_fail(entry != NULL);
 
-	user_info->user_info_entries = g_list_remove(user_info->user_info_entries, entry);
+	g_queue_remove(&user_info->entries, entry);
 }
 
 void
@@ -639,7 +629,7 @@
 	entry = purple_notify_user_info_entry_new(label, NULL);
 	entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER;
 
-	user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry);
+	g_queue_push_tail(&user_info->entries, entry);
 }
 
 void
@@ -650,7 +640,7 @@
 	entry = purple_notify_user_info_entry_new(label, NULL);
 	entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER;
 
-	user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry);
+	g_queue_push_head(&user_info->entries, entry);
 }
 
 void
@@ -661,7 +651,7 @@
 	entry = purple_notify_user_info_entry_new(NULL, NULL);
 	entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK;
 
-	user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry);
+	g_queue_push_tail(&user_info->entries, entry);
 }
 
 void
@@ -672,17 +662,17 @@
 	entry = purple_notify_user_info_entry_new(NULL, NULL);
 	entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK;
 
-	user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry);
+	g_queue_push_head(&user_info->entries, entry);
 }
 
 void
 purple_notify_user_info_remove_last_item(PurpleNotifyUserInfo *user_info)
 {
-	GList *last = g_list_last(user_info->user_info_entries);
-	if (last) {
-		purple_notify_user_info_entry_destroy(last->data);
-		user_info->user_info_entries = g_list_delete_link(user_info->user_info_entries, last);
-	}
+	PurpleNotifyUserInfoEntry *entry;
+
+	entry = g_queue_pop_tail(&user_info->entries);
+	if (entry)
+		purple_notify_user_info_entry_destroy(entry);
 }
 
 void *
--- a/libpurple/notify.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/notify.h	Sun Sep 11 04:19:01 2011 +0000
@@ -111,7 +111,8 @@
  */
 typedef struct
 {
-	char *title; /**< Title of the column. */
+	char *title;           /**< Title of the column. */
+	gboolean visible;      /**< Should the column be visible to the user. Defaults to TRUE. */
 
 } PurpleNotifySearchColumn;
 
@@ -266,7 +267,8 @@
 PurpleNotifySearchResults *purple_notify_searchresults_new(void);
 
 /**
- * Returns a newly created search result column object.
+ * Returns a newly created search result column object.  The column defaults
+ * to being visible.
  *
  * @param title Title of the column. NOTE: Title will get g_strdup()ed.
  *
@@ -275,6 +277,23 @@
 PurpleNotifySearchColumn *purple_notify_searchresults_column_new(const char *title);
 
 /**
+ * Sets whether or not a search result column is visible.
+ *
+ * @param field   The search column object.
+ * @param visible TRUE if visible, or FALSE if not.
+ */
+void purple_notify_searchresult_column_set_visible(PurpleNotifySearchColumn *column, gboolean visible);
+
+/**
+ * Returns whether or not a search result column is visible.
+ *
+ * @param field The search column object.
+ *
+ * @return TRUE if the search result column is visible. FALSE otherwise.
+ */
+gboolean purple_notify_searchresult_column_is_visible(const PurpleNotifySearchColumn *column);
+
+/**
  * Adds a new column to the search result object.
  *
  * @param results The result object to which the column will be added.
@@ -292,92 +311,6 @@
 void purple_notify_searchresults_row_add(PurpleNotifySearchResults *results,
 									   GList *row);
 
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_)
-/**
- * Returns a number of the rows in the search results object.
- *
- * @deprecated This function will be removed in Pidgin 3.0.0 unless
- *             there is sufficient demand to keep it.  Using this
- *             function encourages looping through the results
- *             inefficiently.  Instead of using this function you
- *             should iterate through the results using a loop
- *             similar to this:
- *                for (l = results->rows; l != NULL; l = l->next)
- *             If you really need to get the number of rows you
- *             can use g_list_length(results->rows).
- *
- * @param results The search results object.
- *
- * @return Number of the result rows.
- */
-guint purple_notify_searchresults_get_rows_count(PurpleNotifySearchResults *results);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_)
-/**
- * Returns a number of the columns in the search results object.
- *
- * @deprecated This function will be removed in Pidgin 3.0.0 unless
- *             there is sufficient demand to keep it.  Using this
- *             function encourages looping through the columns
- *             inefficiently.  Instead of using this function you
- *             should iterate through the columns using a loop
- *             similar to this:
- *                for (l = results->columns; l != NULL; l = l->next)
- *             If you really need to get the number of columns you
- *             can use g_list_length(results->columns).
- *
- * @param results The search results object.
- *
- * @return Number of the columns.
- */
-guint purple_notify_searchresults_get_columns_count(PurpleNotifySearchResults *results);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_)
-/**
- * Returns a row of the results from the search results object.
- *
- * @deprecated This function will be removed in Pidgin 3.0.0 unless
- *             there is sufficient demand to keep it.  Using this
- *             function encourages looping through the results
- *             inefficiently.  Instead of using this function you
- *             should iterate through the results using a loop
- *             similar to this:
- *                for (l = results->rows; l != NULL; l = l->next)
- *             If you really need to get the data for a particular
- *             row you can use g_list_nth_data(results->rows, row_id).
- *
- * @param results The search results object.
- * @param row_id  Index of the row to be returned.
- *
- * @return Row of the results.
- */
-GList *purple_notify_searchresults_row_get(PurpleNotifySearchResults *results,
-										 unsigned int row_id);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_)
-/**
- * Returns a title of the search results object's column.
- *
- * @deprecated This function will be removed in Pidgin 3.0.0 unless
- *             there is sufficient demand to keep it.  Using this
- *             function encourages looping through the columns
- *             inefficiently.  Instead of using this function you
- *             should iterate through the name of a particular
- *             column you can use
- *             g_list_nth_data(results->columns, row_id).
- *
- * @param results   The search results object.
- * @param column_id Index of the column.
- *
- * @return Title of the column.
- */
-char *purple_notify_searchresults_column_get_title(PurpleNotifySearchResults *results,
-												 unsigned int column_id);
-#endif
-
 /*@}*/
 
 /**************************************************************************/
@@ -506,20 +439,20 @@
  * Retrieve the array of PurpleNotifyUserInfoEntry objects from a
  * PurpleNotifyUserInfo
  *
- * This GList may be manipulated directly with normal GList functions such
- * as g_list_insert(). Only PurpleNotifyUserInfoEntry are allowed in the
- * list.  If a PurpleNotifyUserInfoEntry item is added to the list, it
- * should not be g_free()'d by the caller; PurpleNotifyUserInfo will g_free
- * it when destroyed.
+ * This GQueue may be manipulated directly with normal GQueue functions such
+ * as g_queue_push_tail(). Only PurpleNotifyUserInfoEntry are allowed in the
+ * queue.  If a PurpleNotifyUserInfoEntry item is added to the queue, it
+ * should not be freed by the caller; PurpleNotifyUserInfo will free it when
+ * destroyed.
  *
  * To remove a PurpleNotifyUserInfoEntry, use
- * purple_notify_user_info_remove_entry(). Do not use the GList directly.
+ * purple_notify_user_info_remove_entry(). Do not use the GQueue directly.
  *
  * @param user_info  The PurpleNotifyUserInfo
  *
- * @constreturn A GList of PurpleNotifyUserInfoEntry objects
+ * @constreturn A GQueue of PurpleNotifyUserInfoEntry objects.
  */
-GList *purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info);
+GQueue *purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info);
 
 /**
  * Create a textual representation of a PurpleNotifyUserInfo, separating
@@ -547,34 +480,25 @@
  *                   the UI should treat label as independent and not
  *                   include a colon if it would otherwise.
  */
-/*
- * TODO: In 3.0.0 this function should be renamed to
- *       purple_notify_user_info_add_pair_html().  And optionally
- *       purple_notify_user_info_add_pair_plaintext() could be renamed to
- *       purple_notify_user_info_add_pair().
- */
-void purple_notify_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
+void purple_notify_user_info_add_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
 
 /**
- * Like purple_notify_user_info_add_pair, but value should be plaintext
+ * Like purple_notify_user_info_add_pair_html, but value should be plaintext
  * and will be escaped using g_markup_escape_text().
  */
 void purple_notify_user_info_add_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
 
 /**
- * Prepend a label/value pair to a PurpleNotifyUserInfo object
- *
- * @param user_info  The PurpleNotifyUserInfo
- * @param label      A label, which for example might be displayed by a
- *                   UI with a colon after it ("Status:"). Do not include
- *                   a colon.  If NULL, value will be displayed without a
- *                   label.
- * @param value      The value, which might be displayed by a UI after
- *                   the label.  If NULL, label will still be displayed;
- *                   the UI should then treat label as independent and not
- *                   include a colon if it would otherwise.
+ * Like purple_notify_user_info_add_pair_html, but the pair is inserted
+ * at the beginning of the list.
  */
-void purple_notify_user_info_prepend_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
+void purple_notify_user_info_prepend_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
+
+/**
+ * Like purple_notify_user_info_prepend_pair_html, but value should be plaintext
+ * and will be escaped using g_markup_escape_text().
+ */
+void purple_notify_user_info_prepend_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
 
 #if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_)
 /**
@@ -597,9 +521,11 @@
  *
  * If added to a PurpleNotifyUserInfo object, this should not be free()'d,
  * as PurpleNotifyUserInfo will do so when destroyed.
- * purple_notify_user_info_add_pair() and
- * purple_notify_user_info_prepend_pair() are convenience methods for
- * creating entries and adding them to a PurpleNotifyUserInfo.
+ * purple_notify_user_info_add_pair_html(),
+ * purple_notify_user_info_add_pair_plaintext(),
+ * purple_notify_user_info_prepend_pair_html() and
+ * purple_notify_user_info_prepend_pair_plaintext() are convenience
+ * methods for creating entries and adding them to a PurpleNotifyUserInfo.
  *
  * @param label  A label, which for example might be displayed by a UI
  *               with a colon after it ("Status:"). Do not include a
--- a/libpurple/plugin.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/plugin.c	Sun Sep 11 04:19:01 2011 +0000
@@ -64,13 +64,6 @@
 static GList *plugins_to_disable = NULL;
 #endif
 
-static void (*probe_cb)(void *) = NULL;
-static void *probe_cb_data = NULL;
-static void (*load_cb)(PurplePlugin *, void *) = NULL;
-static void *load_cb_data = NULL;
-static void (*unload_cb)(PurplePlugin *, void *) = NULL;
-static void *unload_cb_data = NULL;
-
 #ifdef PURPLE_PLUGINS
 
 static gboolean
@@ -615,9 +608,6 @@
 
 	plugin->loaded = TRUE;
 
-	if (load_cb != NULL)
-		load_cb(plugin, load_cb_data);
-
 	purple_signal_emit(purple_plugins_get_handle(), "plugin-load", plugin);
 
 	return TRUE;
@@ -745,9 +735,6 @@
 	g_free(plugin->error);
 	plugin->error = NULL;
 
-	if (unload_cb != NULL)
-		unload_cb(plugin, unload_cb_data);
-
 	purple_signal_emit(purple_plugins_get_handle(), "plugin-unload", plugin);
 
 	purple_prefs_disconnect_by_handle(plugin);
@@ -1439,10 +1426,6 @@
 													(GCompareFunc)compare_prpl);
 		}
 	}
-
-	if (probe_cb != NULL)
-		probe_cb(probe_cb_data);
-
 #endif /* PURPLE_PLUGINS */
 }
 
@@ -1513,50 +1496,6 @@
 #endif
 }
 
-void
-purple_plugins_register_probe_notify_cb(void (*func)(void *), void *data)
-{
-	probe_cb = func;
-	probe_cb_data = data;
-}
-
-void
-purple_plugins_unregister_probe_notify_cb(void (*func)(void *))
-{
-	probe_cb = NULL;
-	probe_cb_data = NULL;
-}
-
-void
-purple_plugins_register_load_notify_cb(void (*func)(PurplePlugin *, void *),
-									 void *data)
-{
-	load_cb = func;
-	load_cb_data = data;
-}
-
-void
-purple_plugins_unregister_load_notify_cb(void (*func)(PurplePlugin *, void *))
-{
-	load_cb = NULL;
-	load_cb_data = NULL;
-}
-
-void
-purple_plugins_register_unload_notify_cb(void (*func)(PurplePlugin *, void *),
-									   void *data)
-{
-	unload_cb = func;
-	unload_cb_data = data;
-}
-
-void
-purple_plugins_unregister_unload_notify_cb(void (*func)(PurplePlugin *, void *))
-{
-	unload_cb = NULL;
-	unload_cb_data = NULL;
-}
-
 PurplePlugin *
 purple_plugins_find_with_name(const char *name)
 {
--- a/libpurple/plugin.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/plugin.h	Sun Sep 11 04:19:01 2011 +0000
@@ -566,72 +566,6 @@
  */
 gboolean purple_plugins_enabled(void);
 
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Registers a function that will be called when probing is finished.
- *
- * @param func The callback function.
- * @param data Data to pass to the callback.
- * @deprecated If you need this, ask for a plugin-probe signal to be added.
- */
-void purple_plugins_register_probe_notify_cb(void (*func)(void *), void *data);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Unregisters a function that would be called when probing is finished.
- *
- * @param func The callback function.
- * @deprecated If you need this, ask for a plugin-probe signal to be added.
- */
-void purple_plugins_unregister_probe_notify_cb(void (*func)(void *));
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Registers a function that will be called when a plugin is loaded.
- *
- * @param func The callback function.
- * @param data Data to pass to the callback.
- * @deprecated Use the plugin-load signal instead.
- */
-void purple_plugins_register_load_notify_cb(void (*func)(PurplePlugin *, void *),
-										  void *data);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Unregisters a function that would be called when a plugin is loaded.
- *
- * @param func The callback function.
- * @deprecated Use the plugin-load signal instead.
- */
-void purple_plugins_unregister_load_notify_cb(void (*func)(PurplePlugin *, void *));
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Registers a function that will be called when a plugin is unloaded.
- *
- * @param func The callback function.
- * @param data Data to pass to the callback.
- * @deprecated Use the plugin-unload signal instead.
- */
-void purple_plugins_register_unload_notify_cb(void (*func)(PurplePlugin *, void *),
-											void *data);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Unregisters a function that would be called when a plugin is unloaded.
- *
- * @param func The callback function.
- * @deprecated Use the plugin-unload signal instead.
- */
-void purple_plugins_unregister_unload_notify_cb(void (*func)(PurplePlugin *,
-														   void *));
-#endif
-
 /**
  * Finds a plugin with the specified name.
  *
--- a/libpurple/plugins/log_reader.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/plugins/log_reader.c	Sun Sep 11 04:19:01 2011 +0000
@@ -92,7 +92,7 @@
 
 	prpl_name = g_ascii_strup(prpl_info->list_icon(account, NULL), -1);
 
-	temp = g_strdup_printf("%s.%s", prpl_name, account->username);
+	temp = g_strdup_printf("%s.%s", prpl_name, purple_account_get_username(account));
 	path = g_build_filename(logdir, temp, sn, NULL);
 	g_free(temp);
 
@@ -635,7 +635,7 @@
 	g_return_val_if_fail(sn != NULL, NULL);
 	g_return_val_if_fail(account != NULL, NULL);
 
-	if (strcmp(account->protocol_id, "prpl-msn"))
+	if (strcmp(purple_account_get_protocol_id(account), "prpl-msn"))
 		return NULL;
 
 	logdir = purple_prefs_get_string("/plugins/core/log_reader/msn/log_directory");
@@ -658,7 +658,7 @@
 			return list;
 		}
 	} else {
-		username = g_strdup(purple_normalize(account, account->username));
+		username = g_strdup(purple_normalize(account, purple_account_get_username(account)));
 	}
 
 	if (buddy) {
@@ -974,7 +974,7 @@
 
 		their_name = from_name;
 		if (from_name && purple_prefs_get_bool("/plugins/core/log_reader/use_name_heuristics")) {
-			const char *friendly_name = purple_connection_get_display_name(log->account->gc);
+			const char *friendly_name = purple_connection_get_display_name(purple_account_get_connection(log->account));
 
 			if (friendly_name != NULL) {
 				int friendly_name_length = strlen(friendly_name);
@@ -987,13 +987,10 @@
 				if (buddy)
 					their_name = purple_buddy_get_alias(buddy);
 
-				if (log->account->alias)
-				{
-					alias = log->account->alias;
+				alias = purple_account_get_alias(log->account);
+				if (alias) {
 					alias_length = strlen(alias);
-				}
-				else
-				{
+				} else {
 					alias = "";
 					alias_length = 0;
 				}
@@ -1115,10 +1112,10 @@
 			text = g_string_append(text, "<b>");
 
 			if (name_guessed == NAME_GUESS_ME) {
-				if (log->account->alias)
-					text = g_string_append(text, log->account->alias);
+				if (purple_account_get_alias(log->account))
+					text = g_string_append(text, purple_account_get_alias(log->account));
 				else
-					text = g_string_append(text, log->account->username);
+					text = g_string_append(text, purple_account_get_username(log->account));
 			}
 			else if (name_guessed == NAME_GUESS_THEM)
 				text = g_string_append(text, their_name);
@@ -1781,7 +1778,7 @@
 	g_return_val_if_fail(account != NULL, NULL);
 
 	/* QIP only supports ICQ. */
-	if (strcmp(account->protocol_id, "prpl-icq"))
+	if (strcmp(purple_account_get_protocol_id(account), "prpl-icq"))
 		return NULL;
 
 	logdir = purple_prefs_get_string("/plugins/core/log_reader/qip/log_directory");
@@ -1798,7 +1795,7 @@
 	if (!prpl_info->list_icon)
 		return NULL;
 
-	username = g_strdup(purple_normalize(account, account->username));
+	username = g_strdup(purple_normalize(account, purple_account_get_username(account)));
 	filename = g_strdup_printf("%s.txt", purple_normalize(account, sn));
 	path = g_build_filename(logdir, username, "History", filename, NULL);
 	g_free(username);
@@ -2241,10 +2238,10 @@
 		return NULL;
 
 	/* aMSN only works with MSN/WLM */
-	if (strcmp(account->protocol_id, "prpl-msn"))
+	if (strcmp(purple_account_get_protocol_id(account), "prpl-msn"))
 		return NULL;
 
-	username = g_strdup(purple_normalize(account, account->username));
+	username = g_strdup(purple_normalize(account, purple_account_get_username(account)));
 	buddy_log = g_strdup_printf("%s.log", purple_normalize(account, sn));
 	log_path = g_build_filename(logdir, username, "logs", NULL);
 
--- a/libpurple/plugins/perl/common/Account.xs	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/plugins/perl/common/Account.xs	Sun Sep 11 04:19:01 2011 +0000
@@ -199,9 +199,10 @@
     Purple::Account account
 
 void
-purple_account_add_buddies(account, list)
+purple_account_add_buddies(account, list, message)
     Purple::Account account
     SV * list
+    const char *message
 PREINIT:
     GList *t_GL;
     int i, t_len;
@@ -212,13 +213,14 @@
     for (i = 0; i <= t_len; i++)
         t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(list), i, 0)));
 
-    purple_account_add_buddies(account, t_GL);
+    purple_account_add_buddies(account, t_GL, message);
     g_list_free(t_GL);
 
 void
-purple_account_add_buddy(account, buddy)
-    Purple::Account account
-    Purple::BuddyList::Buddy  buddy
+purple_account_add_buddy(account, buddy, message)
+    Purple::Account          account
+    Purple::BuddyList::Buddy buddy
+    const char *             message
 
 void
 purple_account_change_password(account, a, b)
--- a/libpurple/plugins/perl/common/Connection.xs	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/plugins/perl/common/Connection.xs	Sun Sep 11 04:19:01 2011 +0000
@@ -36,11 +36,6 @@
 	const char *text
 
 void
-purple_connection_error(gc, reason)
-	Purple::Connection gc
-	const char *reason
-
-void
 purple_connection_destroy(gc)
 	Purple::Connection gc
 
--- a/libpurple/plugins/perl/common/Notify.xs	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/plugins/perl/common/Notify.xs	Sun Sep 11 04:19:01 2011 +0000
@@ -135,7 +135,7 @@
 PREINIT:
 	GList *l;
 PPCODE:
-	l = purple_notify_user_info_get_entries(user_info);
+	l = purple_notify_user_info_get_entries(user_info)->head;
 	for (; l != NULL; l = l->next) {
 		XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::NotifyUserInfoEntry")));
 	}
@@ -145,12 +145,12 @@
 	Purple::NotifyUserInfo user_info
 	const char *newline
 
-void purple_notify_user_info_add_pair(user_info, label, value)
+void purple_notify_user_info_add_pair_html(user_info, label, value)
 	Purple::NotifyUserInfo user_info
 	const char *label
 	const char *value
 
-void purple_notify_user_info_prepend_pair(user_info, label, value)
+void purple_notify_user_info_prepend_pair_html(user_info, label, value)
 	Purple::NotifyUserInfo user_info
 	const char *label
 	const char *value
--- a/libpurple/plugins/perl/common/Status.xs	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/plugins/perl/common/Status.xs	Sun Sep 11 04:19:01 2011 +0000
@@ -74,28 +74,6 @@
 		newCONSTSUB(primitive_stash, (char *)civ->name, newSViv(civ->iv));
 }
 
-void
-purple_presence_add_list(presence, source_list)
-	Purple::Presence presence
-	SV *source_list
-PREINIT:
-	GList *t_GL;
-	int i, t_len;
-PPCODE:
-	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(source_list));
-
-	for (i = 0; i <= t_len; i++) {
-		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(source_list), i, 0)));
-	}
-	purple_presence_add_list(presence, t_GL);
-	g_list_free(t_GL);
-
-void
-purple_presence_add_status(presence, status)
-	Purple::Presence presence
-	Purple::Status status
-
 gint
 purple_presence_compare(presence1, presence2)
 	Purple::Presence presence1
@@ -329,29 +307,10 @@
 	Purple::Status status
 	gboolean active
 
-void
-purple_status_set_attr_boolean(status, id, value)
-	Purple::Status status
-	const char *id
-	gboolean value
-
-void
-purple_status_set_attr_string(status, id, value)
-	Purple::Status status
-	const char *id
-	const char *value
-
 MODULE = Purple::Status  PACKAGE = Purple::StatusType  PREFIX = purple_status_type_
 PROTOTYPES: ENABLE
 
 void
-purple_status_type_add_attr(status_type, id, name, value)
-	Purple::StatusType status_type
-	const char *id
-	const char *name
-	Purple::Value value
-
-void
 purple_status_type_destroy(status_type)
 	Purple::StatusType status_type
 
@@ -397,10 +356,6 @@
 purple_status_type_get_name(status_type)
 	Purple::StatusType status_type
 
-const char *
-purple_status_type_get_primary_attr(status_type)
-	Purple::StatusType status_type
-
 Purple::StatusPrimitive
 purple_status_type_get_primitive(status_type)
 	Purple::StatusType status_type
@@ -440,8 +395,3 @@
 	gboolean saveable
 	gboolean user_settable
 	gboolean independent
-
-void
-purple_status_type_set_primary_attr(status_type, attr_id)
-	Purple::StatusType status_type
-	const char *attr_id
--- a/libpurple/plugins/tcl/tcl_cmds.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/plugins/tcl/tcl_cmds.c	Sun Sep 11 04:19:01 2011 +0000
@@ -1640,13 +1640,13 @@
 int tcl_cmd_status_type(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
 {
 	const char *cmds[] = { "attr", "attrs", "available", "exclusive", "id",
-	                       "independent", "name", "primary_attr",
+	                       "independent", "name",
 	                       "primitive", "saveable", "user_settable",
 	                       NULL };
 	enum { CMD_STATUS_TYPE_ATTR, CMD_STATUS_TYPE_ATTRS,
 	       CMD_STATUS_TYPE_AVAILABLE, CMD_STATUS_TYPE_EXCLUSIVE,
 	       CMD_STATUS_TYPE_ID, CMD_STATUS_TYPE_INDEPENDENT,
-	       CMD_STATUS_TYPE_NAME, CMD_STATUS_TYPE_PRIMARY_ATTR,
+	       CMD_STATUS_TYPE_NAME,
 	       CMD_STATUS_TYPE_PRIMITIVE, CMD_STATUS_TYPE_SAVEABLE,
 	       CMD_STATUS_TYPE_USER_SETTABLE } cmd;
 	PurpleStatusType *status_type;
@@ -1751,18 +1751,6 @@
 				 Tcl_NewStringObj(purple_primitive_get_id_from_type
 						  (purple_status_type_get_primitive(status_type)), -1));
 		break;
-	case CMD_STATUS_TYPE_PRIMARY_ATTR:
-#if !(defined PURPLE_DISABLE_DEPRECATED)
-		if (objc != 3) {
-			Tcl_WrongNumArgs(interp, 2, objv, "statustype");
-			return TCL_ERROR;
-		}
-		if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL)
-			return TCL_ERROR;
-		Tcl_SetObjResult(interp,
-				 Tcl_NewStringObj(purple_status_type_get_primary_attr(status_type), -1));
-#endif
-		break;
 	case CMD_STATUS_TYPE_SAVEABLE:
 		if (objc != 3) {
 			Tcl_WrongNumArgs(interp, 2, objv, "statustype");
--- a/libpurple/pounce.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/pounce.c	Sun Sep 11 04:19:01 2011 +0000
@@ -32,6 +32,31 @@
 #include "pounce.h"
 #include "util.h"
 
+/**
+ * A buddy pounce structure.
+ *
+ * Buddy pounces are actions triggered by a buddy-related event. For
+ * example, a sound can be played or an IM window opened when a buddy
+ * signs on or returns from away. Such responses are handled in the
+ * UI. The events themselves are done in the core.
+ */
+struct _PurplePounce
+{
+	char *ui_type;                /**< The type of UI.            */
+
+	PurplePounceEvent events;       /**< The event(s) to pounce on. */
+	PurplePounceOption options;     /**< The pounce options         */
+	PurpleAccount *pouncer;         /**< The user who is pouncing.  */
+
+	char *pouncee;                /**< The buddy to pounce on.    */
+
+	GHashTable *actions;          /**< The registered actions.    */
+
+	gboolean save;                /**< Whether or not the pounce should
+	                                   be saved after activation. */
+	void *data;                   /**< Pounce-specific data.      */
+};
+
 typedef struct
 {
 	GString *buffer;
@@ -405,12 +430,8 @@
 	}
 
 	if (purple_strequal(element_name, "account")) {
-		char *tmp;
 		g_free(data->account_name);
 		data->account_name = g_strdup(buffer);
-		tmp = data->protocol_id;
-		data->protocol_id = g_strdup(_purple_oscar_convert(buffer, tmp));
-		g_free(tmp);
 	}
 	else if (purple_strequal(element_name, "pouncee")) {
 		g_free(data->pouncee);
--- a/libpurple/pounce.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/pounce.h	Sun Sep 11 04:19:01 2011 +0000
@@ -59,31 +59,6 @@
 /** A pounce callback. */
 typedef void (*PurplePounceCb)(PurplePounce *, PurplePounceEvent, void *);
 
-/**
- * A buddy pounce structure.
- *
- * Buddy pounces are actions triggered by a buddy-related event. For
- * example, a sound can be played or an IM window opened when a buddy
- * signs on or returns from away. Such responses are handled in the
- * UI. The events themselves are done in the core.
- */
-struct _PurplePounce
-{
-	char *ui_type;                /**< The type of UI.            */
-
-	PurplePounceEvent events;       /**< The event(s) to pounce on. */
-	PurplePounceOption options;     /**< The pounce options         */
-	PurpleAccount *pouncer;         /**< The user who is pouncing.  */
-
-	char *pouncee;                /**< The buddy to pounce on.    */
-
-	GHashTable *actions;          /**< The registered actions.    */
-
-	gboolean save;                /**< Whether or not the pounce should
-	                                   be saved after activation. */
-	void *data;                   /**< Pounce-specific data.      */
-};
-
 #ifdef __cplusplus
 extern "C" {
 #endif
--- a/libpurple/prefs.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/prefs.h	Sun Sep 11 04:19:01 2011 +0000
@@ -32,7 +32,7 @@
 /**
  * Preference data types.
  */
-typedef enum _PurplePrefType
+typedef enum
 {
 	PURPLE_PREF_NONE,        /**< No type.         */
 	PURPLE_PREF_BOOLEAN,     /**< Boolean.         */
--- a/libpurple/privacy.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/privacy.h	Sun Sep 11 04:19:01 2011 +0000
@@ -29,7 +29,7 @@
 /**
  * Privacy data types.
  */
-typedef enum _PurplePrivacyType
+typedef enum
 {
 	PURPLE_PRIVACY_ALLOW_ALL = 1,
 	PURPLE_PRIVACY_DENY_ALL,
--- a/libpurple/protocols/Makefile.am	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/Makefile.am	Sun Sep 11 04:19:01 2011 +0000
@@ -1,5 +1,5 @@
 EXTRA_DIST = Makefile.mingw
 
-DIST_SUBDIRS = bonjour gg irc jabber msn myspace mxit novell null oscar sametime silc silc10 simple yahoo zephyr
+DIST_SUBDIRS = bonjour gg irc jabber msn mxit myspace novell null oscar sametime silc simple yahoo zephyr
 
 SUBDIRS = $(DYNAMIC_PRPLS) $(STATIC_PRPLS)
--- a/libpurple/protocols/bonjour/bonjour.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/bonjour/bonjour.c	Sun Sep 11 04:19:01 2011 +0000
@@ -51,7 +51,7 @@
 bonjour_get_jid(PurpleAccount *account)
 {
 	PurpleConnection *conn = purple_account_get_connection(account);
-	BonjourData *bd = conn->proto_data;
+	BonjourData *bd = purple_connection_get_protocol_data(conn);
 	return bd->jid;
 }
 
@@ -94,7 +94,7 @@
 
 #ifdef _WIN32
 	if (!dns_sd_available()) {
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 				_("Unable to find Apple's \"Bonjour for Windows\" toolkit, see "
 				  "http://d.pidgin.im/BonjourWindows for more information."));
@@ -103,7 +103,8 @@
 #endif /* _WIN32 */
 
 	gc->flags |= PURPLE_CONNECTION_HTML;
-	gc->proto_data = bd = g_new0(BonjourData, 1);
+	bd = g_new0(BonjourData, 1);
+	purple_connection_set_protocol_data(gc, bd);
 
 	/* Start waiting for jabber connections (iChat style) */
 	bd->jabber_data = g_new0(BonjourJabber, 1);
@@ -114,7 +115,7 @@
 
 	if (bonjour_jabber_start(bd->jabber_data) == -1) {
 		/* Send a message about the connection error */
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Unable to listen for incoming IM connections"));
 		return;
@@ -141,7 +142,7 @@
 	bd->dns_sd_data->account = account;
 	if (!bonjour_dns_sd_start(bd->dns_sd_data))
 	{
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to establish connection with the local mDNS server.  Is it running?"));
 		return;
@@ -157,7 +158,7 @@
 bonjour_close(PurpleConnection *connection)
 {
 	PurpleGroup *bonjour_group;
-	BonjourData *bd = connection->proto_data;
+	BonjourData *bd = purple_connection_get_protocol_data(connection);
 
 	bonjour_group = purple_find_group(BONJOUR_GROUP_NAME);
 
@@ -192,7 +193,7 @@
 	if (bd != NULL)
 		g_free(bd->jid);
 	g_free(bd);
-	connection->proto_data = NULL;
+	purple_connection_set_protocol_data(connection, NULL);
 }
 
 static const char *
@@ -204,10 +205,12 @@
 static int
 bonjour_send_im(PurpleConnection *connection, const char *to, const char *msg, PurpleMessageFlags flags)
 {
+	BonjourData *bd = purple_connection_get_protocol_data(connection);
+
 	if(!to || !msg)
 		return 0;
 
-	return bonjour_jabber_send_message(((BonjourData*)(connection->proto_data))->jabber_data, to, msg);
+	return bonjour_jabber_send_message(bd->jabber_data, to, msg);
 }
 
 static void
@@ -220,7 +223,7 @@
 	gchar *stripped;
 
 	gc = purple_account_get_connection(account);
-	bd = gc->proto_data;
+	bd = purple_connection_get_protocol_data(gc);
 	presence = purple_account_get_presence(account);
 
 	message = purple_status_get_attr_string(status, "message");
@@ -253,7 +256,7 @@
  * if there is no add_buddy callback.
  */
 static void
-bonjour_fake_add_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group) {
+bonjour_fake_add_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group, const char *message) {
 	purple_debug_error("bonjour", "Buddy '%s' manually added; removing.  "
 				      "Bonjour buddies must be discovered and not manually added.\n",
 			   purple_buddy_get_name(buddy));
@@ -325,7 +328,7 @@
 static
 void bonjour_set_buddy_icon(PurpleConnection *conn, PurpleStoredImage *img)
 {
-	BonjourData *bd = conn->proto_data;
+	BonjourData *bd = purple_connection_get_protocol_data(conn);
 	bonjour_dns_sd_update_buddy_icon(bd->dns_sd_data);
 }
 
@@ -371,9 +374,12 @@
 	else
 		status_description = purple_status_get_name(status);
 
-	purple_notify_user_info_add_pair(user_info, _("Status"), status_description);
-	if (message != NULL)
-		purple_notify_user_info_add_pair(user_info, _("Message"), message);
+	purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status_description);
+	if (message != NULL) {
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, _("Message"), message);
+	}
 
 	if (bb == NULL) {
 		purple_debug_error("bonjour", "Got tooltip request for a buddy without protocol data.\n");
@@ -382,20 +388,35 @@
 
 	/* Only show first/last name if there is a nickname set (to avoid duplication) */
 	if (bb->nick != NULL && *bb->nick != '\0') {
-		if (bb->first != NULL && *bb->first != '\0')
-			purple_notify_user_info_add_pair(user_info, _("First name"), bb->first);
-		if (bb->last != NULL && *bb->last != '\0')
-			purple_notify_user_info_add_pair(user_info, _("Last name"), bb->last);
+		if (bb->first != NULL && *bb->first != '\0') {
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html(user_info, _("First name"), bb->first);
+		}
+		if (bb->last != NULL && *bb->last != '\0') {
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html(user_info, _("Last name"), bb->last);
+		}
 	}
 
-	if (bb->email != NULL && *bb->email != '\0')
-		purple_notify_user_info_add_pair(user_info, _("Email"), bb->email);
+	if (bb->email != NULL && *bb->email != '\0') {
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, _("Email"), bb->email);
+	}
 
-	if (bb->AIM != NULL && *bb->AIM != '\0')
-		purple_notify_user_info_add_pair(user_info, _("AIM Account"), bb->AIM);
+	if (bb->AIM != NULL && *bb->AIM != '\0') {
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, _("AIM Account"), bb->AIM);
+	}
 
-	if (bb->jid != NULL && *bb->jid != '\0')
-		purple_notify_user_info_add_pair(user_info, _("XMPP Account"), bb->jid);
+	if (bb->jid != NULL && *bb->jid != '\0') {
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, _("XMPP Account"), bb->jid);
+	}
 }
 
 static void
@@ -463,6 +484,7 @@
 
 static PurplePluginProtocolInfo prpl_info =
 {
+	sizeof(PurplePluginProtocolInfo),                        /* struct_size */
 	OPT_PROTO_NO_PASSWORD,
 	NULL,                                                    /* user_splits */
 	NULL,                                                    /* protocol_options */
@@ -528,15 +550,12 @@
 	NULL,                                                    /* unregister_user */
 	NULL,                                                    /* send_attention */
 	NULL,                                                    /* get_attention_types */
-	sizeof(PurplePluginProtocolInfo),                        /* struct_size */
 	NULL,                                                    /* get_account_text_table */
 	NULL,                                                    /* initiate_media */
 	NULL,                                                    /* get_media_caps */
 	NULL,                                                    /* get_moods */
 	NULL,                                                    /* set_public_alias */
-	NULL,                                                    /* get_public_alias */
-	NULL,                                                    /* add_buddy_with_invite */
-	NULL                                                     /* add_buddies_with_invite */
+	NULL                                                     /* get_public_alias */
 };
 
 static PurplePluginInfo info =
--- a/libpurple/protocols/bonjour/bonjour_ft.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/bonjour/bonjour_ft.c	Sun Sep 11 04:19:01 2011 +0000
@@ -90,12 +90,12 @@
 
 static void bonjour_xfer_request_denied(PurpleXfer *xfer)
 {
-	XepXfer *xf = xfer->data;
+	XepXfer *xf = purple_xfer_get_protocol_data(xfer);
 
 	purple_debug_info("bonjour", "Bonjour-xfer-request-denied.\n");
 
 	if(xf)
-		xep_ft_si_reject(xf->data, xf->sid, xfer->who, "403", "cancel");
+		xep_ft_si_reject(xf->data, xf->sid, purple_xfer_get_remote_user(xfer), "403", "cancel");
 
 	bonjour_free_xfer(xfer);
 }
@@ -162,11 +162,11 @@
 		xfer = xfers->data;
 		if(xfer == NULL)
 			break;
-		xf = xfer->data;
+		xf = purple_xfer_get_protocol_data(xfer);
 		if(xf == NULL)
 			break;
-		if(xf->sid && xfer->who && !strcmp(xf->sid, sid) &&
-				!strcmp(xfer->who, from))
+		if(xf->sid && purple_xfer_get_remote_user(xfer) && !strcmp(xf->sid, sid) &&
+				!strcmp(purple_xfer_get_remote_user(xfer), from))
 			return xfer;
 	}
 
@@ -180,7 +180,7 @@
 {
 	xmlnode *si_node, *feature, *field, *file, *x;
 	XepIq *iq;
-	XepXfer *xf = xfer->data;
+	XepXfer *xf = purple_xfer_get_protocol_data(xfer);
 	BonjourData *bd = NULL;
 	char buf[32];
 
@@ -210,8 +210,8 @@
 
 	file = xmlnode_new_child(si_node, "file");
 	xmlnode_set_namespace(file, "http://jabber.org/protocol/si/profile/file-transfer");
-	xmlnode_set_attrib(file, "name", xfer->filename);
-	g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, xfer->size);
+	xmlnode_set_attrib(file, "name", purple_xfer_get_filename(xfer));
+	g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, purple_xfer_get_size(xfer));
 	xmlnode_set_attrib(file, "size", buf);
 
 	feature = xmlnode_new_child(si_node, "feature");
@@ -240,7 +240,7 @@
 }
 
 static void
-xep_ft_si_result(PurpleXfer *xfer, char *to)
+xep_ft_si_result(PurpleXfer *xfer, const char *to)
 {
 	xmlnode *si_node, *feature, *field, *value, *x;
 	XepIq *iq;
@@ -249,7 +249,7 @@
 
 	if(!to || !xfer)
 		return;
-	xf = xfer->data;
+	xf = purple_xfer_get_protocol_data(xfer);
 	if(!xf)
 		return;
 
@@ -290,14 +290,14 @@
 		return;
 	}
 
-	purple_debug_info("bonjour", "bonjour-free-xfer-%p.\n", xfer);
+	purple_debug_misc("bonjour", "bonjour-free-xfer-%p.\n", xfer);
 
-	xf = (XepXfer*)xfer->data;
+	xf = purple_xfer_get_protocol_data(xfer);
 	if(xf != NULL) {
 		BonjourData *bd = (BonjourData*)xf->data;
 		if(bd != NULL) {
 			bd->xfer_lists = g_slist_remove(bd->xfer_lists, xfer);
-			purple_debug_info("bonjour", "B free xfer from lists(%p).\n", bd->xfer_lists);
+			purple_debug_misc("bonjour", "B free xfer from lists(%p).\n", bd->xfer_lists);
 		}
 		if (xf->proxy_connection != NULL)
 			purple_proxy_connect_cancel(xf->proxy_connection);
@@ -311,10 +311,10 @@
 		g_free(xf->buddy_ip);
 		g_free(xf->sid);
 		g_free(xf);
-		xfer->data = NULL;
+		purple_xfer_set_protocol_data(xfer, NULL);
 	}
 
-	purple_debug_info("bonjour", "Need close socket=%d.\n", xfer->fd);
+	purple_debug_misc("bonjour", "Need close socket.\n");
 }
 
 PurpleXfer *
@@ -328,13 +328,14 @@
 		return NULL;
 
 	purple_debug_info("bonjour", "Bonjour-new-xfer to %s.\n", who);
-	bd = (BonjourData*) gc->proto_data;
+	bd = purple_connection_get_protocol_data(gc);
 	if(bd == NULL)
 		return NULL;
 
 	/* Build the file transfer handle */
 	xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
-	xfer->data = xep_xfer = g_new0(XepXfer, 1);
+	xep_xfer = g_new0(XepXfer, 1);
+	purple_xfer_set_protocol_data(xfer, xep_xfer);
 	xep_xfer->data = bd;
 
 	purple_debug_info("bonjour", "Bonjour-new-xfer bd=%p data=%p.\n", bd, xep_xfer->data);
@@ -379,13 +380,13 @@
 	BonjourBuddy *bb;
 	XepXfer *xf;
 
-	xf = (XepXfer*)xfer->data;
+	xf = purple_xfer_get_protocol_data(xfer);
 	if(xf == NULL)
 		return;
 
 	purple_debug_info("bonjour", "Bonjour-xfer-init.\n");
 
-	buddy = purple_find_buddy(xfer->account, xfer->who);
+	buddy = purple_find_buddy(purple_xfer_get_account(xfer), purple_xfer_get_remote_user(xfer));
 	/* this buddy is offline. */
 	if (buddy == NULL || (bb = purple_buddy_get_protocol_data(buddy)) == NULL)
 		return;
@@ -396,10 +397,10 @@
 	if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
 		/* initiate file transfer, send SI offer. */
 		purple_debug_info("bonjour", "Bonjour xfer type is PURPLE_XFER_SEND.\n");
-		xep_ft_si_offer(xfer, xfer->who);
+		xep_ft_si_offer(xfer, purple_xfer_get_remote_user(xfer));
 	} else {
 		/* accept file transfer request, send SI result. */
-		xep_ft_si_result(xfer, xfer->who);
+		xep_ft_si_result(xfer, purple_xfer_get_remote_user(xfer));
 		purple_debug_info("bonjour", "Bonjour xfer type is PURPLE_XFER_RECEIVE.\n");
 	}
 }
@@ -416,7 +417,7 @@
 	g_return_if_fail(packet != NULL);
 	g_return_if_fail(pb != NULL);
 
-	bd = (BonjourData*) pc->proto_data;
+	bd = purple_connection_get_protocol_data(pc);
 	if(bd == NULL)
 		return;
 
@@ -502,7 +503,7 @@
 	g_return_if_fail(packet != NULL);
 	g_return_if_fail(pb != NULL);
 
-	bd = (BonjourData*) pc->proto_data;
+	bd = purple_connection_get_protocol_data(pc);
 	if(bd == NULL)
 		return;
 
@@ -530,7 +531,7 @@
 				int portnum;
 				XepXfer *xf = NULL;
 
-				xf = (XepXfer*)xfer->data;
+				xf = purple_xfer_get_protocol_data(xfer);
 				for(streamhost = xmlnode_get_child(query, "streamhost");
 						streamhost;
 						streamhost = xmlnode_get_next_twin(streamhost)) {
@@ -564,7 +565,7 @@
 				purple_debug_error("bonjour", "Didn't find an acceptable streamhost.\n");
 
 				if (iq_id && xfer != NULL)
-					xep_ft_si_reject(bd, iq_id, xfer->who, "404", "cancel");
+					xep_ft_si_reject(bd, iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel");
 			}
 
 		} else {
@@ -584,7 +585,7 @@
 	if(pc == NULL || id == NULL || from == NULL)
 		return;
 
-	bd = (BonjourData*) pc->proto_data;
+	bd = purple_connection_get_protocol_data(pc);
 	if(bd == NULL)
 		return;
 
@@ -592,7 +593,8 @@
 
 	/* Build the file transfer handle */
 	xfer = purple_xfer_new(pc->account, PURPLE_XFER_RECEIVE, from);
-	xfer->data = xf = g_new0(XepXfer, 1);
+	xf = g_new0(XepXfer, 1);
+	purple_xfer_set_protocol_data(xfer, xf);
 	xf->data = bd;
 	purple_xfer_set_filename(xfer, filename);
 	xf->iq_id = g_strdup(id);
@@ -614,7 +616,7 @@
 bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond)
 {
 	PurpleXfer *xfer = data;
-	XepXfer *xf = xfer->data;
+	XepXfer *xf = purple_xfer_get_protocol_data(xfer);
 	int acceptfd;
 	int len = 0;
 
@@ -632,8 +634,6 @@
 			/* This should cancel the ft */
 			purple_debug_error("bonjour", "Error accepting incoming SOCKS5 connection. (%d)\n", errno);
 
-			purple_input_remove(xfer->watcher);
-			xfer->watcher = 0;
 			close(source);
 			purple_xfer_cancel_remote(xfer);
 			return;
@@ -662,9 +662,6 @@
 		if(len < 0 && errno == EAGAIN)
 			return;
 		else if(len <= 0){
-			purple_input_remove(xfer->watcher);
-			xfer->watcher = 0;
-			close(source);
 			purple_xfer_cancel_remote(xfer);
 			return;
 		} else {
@@ -683,8 +680,6 @@
 		if (len < 0 && errno == EAGAIN)
 			return;
 		else if (len < 0) {
-			purple_input_remove(xfer->watcher);
-			xfer->watcher = 0;
 			close(source);
 			purple_xfer_cancel_remote(xfer);
 			return;
@@ -721,8 +716,6 @@
 		if (len < 0 && errno == EAGAIN) {
 			return;
 		} else if (len < 0) {
-			purple_input_remove(xfer->watcher);
-			xfer->watcher = 0;
 			close(source);
 			purple_xfer_cancel_remote(xfer);
 			return;
@@ -759,12 +752,12 @@
 
 	xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
 					 bonjour_sock5_request_cb, xfer);
-	xf = (XepXfer*)xfer->data;
+	xf = purple_xfer_get_protocol_data(xfer);
 	xf->listen_data = NULL;
 
 	bd = xf->data;
 
-	iq = xep_iq_new(bd, XEP_IQ_SET, xfer->who, bonjour_get_jid(bd->jabber_data->account), xf->sid);
+	iq = xep_iq_new(bd, XEP_IQ_SET, purple_xfer_get_remote_user(xfer), bonjour_get_jid(bd->jabber_data->account), xf->sid);
 
 	query = xmlnode_new_child(iq->node, "query");
 	xmlnode_set_namespace(query, "http://jabber.org/protocol/bytestreams");
@@ -775,7 +768,7 @@
 
 	local_ips = bonjour_jabber_get_local_ips(sock);
 
-	port = g_strdup_printf("%hu", xfer->local_port);
+	port = g_strdup_printf("%hu", purple_xfer_get_local_port(xfer));
 	while(local_ips) {
 		streamhost = xmlnode_new_child(query, "streamhost");
 		xmlnode_set_attrib(streamhost, "jid", xf->sid);
@@ -797,7 +790,7 @@
 		return;
 
 	purple_debug_info("bonjour", "Bonjour-bytestreams-init.\n");
-	xf = xfer->data;
+	xf = purple_xfer_get_protocol_data(xfer);
 
 	purple_network_listen_map_external(FALSE);
 	xf->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM,
@@ -813,7 +806,7 @@
 bonjour_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message)
 {
 	PurpleXfer *xfer = data;
-	XepXfer *xf = xfer->data;
+	XepXfer *xf = purple_xfer_get_protocol_data(xfer);
 	XepIq *iq;
 	xmlnode *q_node, *tmp_node;
 	BonjourData *bd;
@@ -823,7 +816,7 @@
 	if(source < 0) {
 		purple_debug_error("bonjour", "Error connecting via SOCKS5 - %s\n",
 			error_message ? error_message : "(null)");
-		xep_ft_si_reject(xf->data, xf->iq_id, xfer->who, "404", "cancel");
+		xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel");
 		/* Cancel the connection */
 		purple_xfer_cancel_local(xfer);
 		return;
@@ -836,7 +829,7 @@
 	/* Here, start the file transfer.*/
 
 	/* Notify Initiator of Connection */
-	iq = xep_iq_new(bd, XEP_IQ_RESULT, xfer->who, bonjour_get_jid(bd->jabber_data->account), xf->iq_id);
+	iq = xep_iq_new(bd, XEP_IQ_RESULT, purple_xfer_get_remote_user(xfer), bonjour_get_jid(bd->jabber_data->account), xf->iq_id);
 	q_node = xmlnode_new_child(iq->node, "query");
 	xmlnode_set_namespace(q_node, "http://jabber.org/protocol/bytestreams");
 	tmp_node = xmlnode_new_child(q_node, "streamhost-used");
@@ -862,7 +855,7 @@
 
 	purple_debug_info("bonjour", "bonjour-bytestreams-connect.\n");
 
-	xf = (XepXfer*)xfer->data;
+	xf = purple_xfer_get_protocol_data(xfer);
 	if(!xf)
 		return;
 
@@ -891,7 +884,7 @@
 							   bonjour_bytestreams_connect_cb, xfer);
 
 	if(xf->proxy_connection == NULL) {
-		xep_ft_si_reject(xf->data, xf->iq_id, xfer->who, "404", "cancel");
+		xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel");
 		/* Cancel the connection */
 		purple_xfer_cancel_local(xfer);
 	}
--- a/libpurple/protocols/bonjour/jabber.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/bonjour/jabber.c	Sun Sep 11 04:19:01 2011 +0000
@@ -929,7 +929,9 @@
 		while(tmp) {
 			ip = tmp->data;
 			if (ip != NULL && g_ascii_strcasecmp(ip, bconv->ip) == 0) {
-				BonjourJabber *jdata = ((BonjourData*) bconv->account->gc->proto_data)->jabber_data;
+				PurpleConnection *pc = purple_account_get_connection(bconv->account);
+				BonjourData *bd = purple_connection_get_protocol_data(pc);
+				BonjourJabber *jdata = bd->jabber_data;
 
 				purple_debug_info("bonjour", "Matched buddy %s to incoming conversation \"from\" attrib and IP (%s)\n",
 					purple_buddy_get_name(pb), bconv->ip);
@@ -962,7 +964,9 @@
 
 void
 bonjour_jabber_conv_match_by_ip(BonjourJabberConversation *bconv) {
-	BonjourJabber *jdata = ((BonjourData*) bconv->account->gc->proto_data)->jabber_data;
+	PurpleConnection *pc = purple_account_get_connection(bconv->account);
+	BonjourData *bd = purple_connection_get_protocol_data(pc);
+	BonjourJabber *jdata = bd->jabber_data;
 	struct _match_buddies_by_address_t *mbba;
 	GSList *buddies;
 
@@ -1122,7 +1126,9 @@
 
 void
 async_bonjour_jabber_close_conversation(BonjourJabberConversation *bconv) {
-	BonjourJabber *jdata = ((BonjourData*) bconv->account->gc->proto_data)->jabber_data;
+	PurpleConnection *pc = purple_account_get_connection(bconv->account);
+	BonjourData *bd = purple_connection_get_protocol_data(pc);
+	BonjourJabber *jdata = bd->jabber_data;
 
 	jdata->pending_conversations = g_slist_remove(jdata->pending_conversations, bconv);
 
@@ -1142,8 +1148,9 @@
 	if (bconv != NULL) {
 		BonjourData *bd = NULL;
 
-		if(PURPLE_CONNECTION_IS_VALID(bconv->account->gc)) {
-			bd = bconv->account->gc->proto_data;
+		PurpleConnection *pc = purple_account_get_connection(bconv->account);
+		if (PURPLE_CONNECTION_IS_VALID(pc)) {
+			bd = purple_connection_get_protocol_data(pc);
 			bd->jabber_data->pending_conversations = g_slist_remove(bd->jabber_data->pending_conversations, bconv);
 		}
 
@@ -1215,7 +1222,7 @@
 		purple_input_remove(jdata->watcher_id6);
 
 	/* Close all the conversation sockets and remove all the watchers after sending end streams */
-	if (jdata->account->gc != NULL) {
+	if (!purple_account_is_disconnected(jdata->account)) {
 		GSList *buddies, *l;
 
 		buddies = purple_find_buddies(jdata->account, NULL);
--- a/libpurple/protocols/bonjour/mdns_avahi.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/bonjour/mdns_avahi.c	Sun Sep 11 04:19:01 2011 +0000
@@ -615,7 +615,7 @@
 
 void _mdns_retrieve_buddy_icon(BonjourBuddy* buddy) {
 	PurpleConnection *conn = purple_account_get_connection(buddy->account);
-	BonjourData *bd = conn->proto_data;
+	BonjourData *bd = purple_connection_get_protocol_data(conn);
 	AvahiSessionImplData *session_idata = bd->dns_sd_data->mdns_impl_data;
 	AvahiBuddyImplData *idata = buddy->mdns_impl_data;
 	gchar *name;
--- a/libpurple/protocols/bonjour/mdns_common.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/bonjour/mdns_common.c	Sun Sep 11 04:19:01 2011 +0000
@@ -257,7 +257,7 @@
 bonjour_dns_sd_set_jid(PurpleAccount *account, const char *hostname)
 {
 	PurpleConnection *conn = purple_account_get_connection(account);
-	BonjourData *bd = conn->proto_data;
+	BonjourData *bd = purple_connection_get_protocol_data(conn);
 	const char *tmp, *account_name = purple_account_get_username(account);
 
 	/* Previously we allowed the hostname part of the jid to be set
--- a/libpurple/protocols/bonjour/mdns_types.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/bonjour/mdns_types.h	Sun Sep 11 04:19:01 2011 +0000
@@ -37,7 +37,7 @@
 	gchar *msg;
 } BonjourDnsSd;
 
-typedef enum _PublishType {
+typedef enum {
 	PUBLISH_START,
 	PUBLISH_UPDATE
 } PublishType;
--- a/libpurple/protocols/bonjour/mdns_win32.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/bonjour/mdns_win32.c	Sun Sep 11 04:19:01 2011 +0000
@@ -105,7 +105,7 @@
 		purple_debug_error("bonjour", "Error (%d) handling mDNS response.\n", errorCode);
 		/* This happens when the mDNSResponder goes down, I haven't seen it happen any other time (in my limited testing) */
 		if (errorCode == kDNSServiceErr_Unknown) {
-			purple_connection_error_reason(srh->account->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+			purple_connection_error(srh->account->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Error communicating with local mDNSResponder."));
 		}
 	}
@@ -177,7 +177,7 @@
 	args->resolver_query = NULL;
 
 	if ((pb = purple_find_buddy(args->account, args->res_data->name))) {
-		if (pb->proto_data != args->bb) {
+		if (purple_buddy_get_protocol_data(pb) != args->bb) {
 			purple_debug_error("bonjour", "Found purple buddy for %s not matching bonjour buddy record.",
 				args->res_data->name);
 			goto cleanup;
@@ -348,7 +348,7 @@
 
 				/* Is there an existing buddy? */
 				if ((pb = purple_find_buddy(account, serviceName)))
-					bb = pb->proto_data;
+					bb = purple_buddy_get_protocol_data(pb);
 				/* Is there a pending buddy? */
 				else {
 					while (tmp) {
@@ -368,7 +368,7 @@
 					if (pb == NULL)
 						pending_buddies = g_slist_prepend(pending_buddies, bb);
 					else
-						pb->proto_data = bb;
+						purple_buddy_set_protocol_data(pb, bb);
 				}
 
 				rd = g_new0(Win32SvcResolverData, 1);
@@ -408,7 +408,7 @@
 			GSList *l;
 			/* There may be multiple presences, we should only get rid of this one */
 			Win32SvcResolverData *rd_search;
-			BonjourBuddy *bb = pb->proto_data;
+			BonjourBuddy *bb = purple_buddy_get_protocol_data(pb);
 			Win32BuddyImplData *idata;
 
 			g_return_if_fail(bb != NULL);
--- a/libpurple/protocols/gg/buddylist.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/gg/buddylist.c	Sun Sep 11 04:19:01 2011 +0000
@@ -38,7 +38,7 @@
 /* void ggp_buddylist_send(PurpleConnection *gc) {{{ */
 void ggp_buddylist_send(PurpleConnection *gc)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	PurpleAccount *account = purple_connection_get_account(gc);
 	GSList *buddies;
 	uin_t *userlist;
@@ -90,7 +90,7 @@
 		gchar **data_tbl;
 		gchar *name, *show, *g;
 
-		if (strlen(users_tbl[i]) == 0)
+		if (!*users_tbl[i])
 			continue;
 
 		data_tbl = g_strsplit(users_tbl[i], ";", 8);
--- a/libpurple/protocols/gg/confer.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/gg/confer.c	Sun Sep 11 04:19:01 2011 +0000
@@ -42,7 +42,7 @@
 							 const uin_t uin)
 {
 	PurpleConversation *conv;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPChat *chat;
 	GList *l;
 	gchar *str_uin;
@@ -73,7 +73,7 @@
 void ggp_confer_participants_add(PurpleConnection *gc, const gchar *chat_name,
 				 const uin_t *recipients, int count)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GList *l;
 	gchar *str_uin;
 
@@ -111,7 +111,7 @@
 const char *ggp_confer_find_by_participants(PurpleConnection *gc,
 					    const uin_t *recipients, int count)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPChat *chat = NULL;
 	GList *l;
 	int matches;
@@ -149,7 +149,7 @@
 /* const char *ggp_confer_add_new(PurpleConnection *gc, const char *name) {{{ */
 const char *ggp_confer_add_new(PurpleConnection *gc, const char *name)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPChat *chat;
 
 	chat = g_new0(GGPChat, 1);
--- a/libpurple/protocols/gg/gg.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/gg/gg.c	Sun Sep 11 04:19:01 2011 +0000
@@ -97,7 +97,7 @@
 static void ggp_async_token_handler(gpointer _gc, gint fd, PurpleInputCondition cond)
 {
 	PurpleConnection *gc = _gc;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPToken *token = info->token;
 	GGPTokenCallback cb;
 
@@ -170,7 +170,7 @@
 	if (ggp_setup_proxy(account) == -1)
 		return;
 
-	info = gc->proto_data;
+	info = purple_connection_get_protocol_data(gc);
 
 	if ((req = gg_token(1)) == NULL) {
 		purple_notify_error(account,
@@ -199,7 +199,7 @@
 static void ggp_action_buddylist_get(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *)action->context;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 
 	purple_debug_info("gg", "Downloading...\n");
 
@@ -214,7 +214,7 @@
 static void ggp_action_buddylist_put(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *)action->context;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 
 	char *buddylist = ggp_buddylist_dump(purple_connection_get_account(gc));
 
@@ -235,7 +235,7 @@
 static void ggp_action_buddylist_delete(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *)action->context;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 
 	purple_debug_info("gg", "Deleting...\n");
 
@@ -334,7 +334,7 @@
 					     PurpleRequestFields *fields)
 {
 	PurpleAccount *account;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	struct gg_http *h = NULL;
 	struct gg_pubdir *s;
 	uin_t uin;
@@ -354,14 +354,14 @@
 
 	if (email == NULL || p1 == NULL || p2 == NULL || t == NULL ||
 	    *email == '\0' || *p1 == '\0' || *p2 == '\0' || *t == '\0') {
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 			_("You must fill in all registration fields"));
 		goto exit_err;
 	}
 
 	if (g_utf8_collate(p1, p2) != 0) {
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
 			_("Passwords do not match"));
 		goto exit_err;
@@ -371,7 +371,7 @@
 			token->id, t);
 	h = gg_register3(email, p1, token->id, t, 0);
 	if (h == NULL || !(s = h->data) || !s->success) {
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 			_("Unable to register new account.  An unknown error occurred."));
 		goto exit_err;
@@ -415,7 +415,7 @@
 static void ggp_callback_register_account_cancel(PurpleConnection *gc,
 						 PurpleRequestFields *fields)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPToken *token = info->token;
 
 	purple_account_disconnect(gc->account);
@@ -433,7 +433,7 @@
 	PurpleRequestFieldGroup *group;
 	PurpleRequestField *field;
 
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPToken *token = info->token;
 
 
@@ -483,7 +483,7 @@
 
 static void ggp_callback_show_next(PurpleConnection *gc, GList *row, gpointer user_data)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPSearchForm *form = user_data;
 	guint32 seq;
 
@@ -520,7 +520,7 @@
 
 static void ggp_callback_find_buddies(PurpleConnection *gc, PurpleRequestFields *fields)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPSearchForm *form;
 	guint32 seq;
 
@@ -621,7 +621,7 @@
 static void ggp_callback_change_passwd_ok(PurpleConnection *gc, PurpleRequestFields *fields)
 {
 	PurpleAccount *account;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	struct gg_http *h;
 	gchar *cur, *p1, *p2, *t;
 
@@ -696,7 +696,7 @@
 	PurpleRequestFieldGroup *group;
 	PurpleRequestField *field;
 
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPToken *token = info->token;
 
 	char *msg;
@@ -758,7 +758,7 @@
 
 static void ggp_action_change_status_broadcasting_ok(PurpleConnection *gc, PurpleRequestFields *fields)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	int selected_field;
 	PurpleAccount *account = purple_connection_get_account(gc);
 	PurpleStatus *status;
@@ -778,7 +778,7 @@
 static void ggp_action_change_status_broadcasting(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *)action->context;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	
 	PurpleRequestFields *fields;
 	PurpleRequestFieldGroup *group;
@@ -848,7 +848,7 @@
 
 	buddy = (PurpleBuddy *)node;
 	gc = purple_account_get_connection(purple_buddy_get_account(buddy));
-	info = gc->proto_data;
+	info = purple_connection_get_protocol_data(gc);
 
 	fields = purple_request_fields_new();
 	group = purple_request_field_group_new(NULL);
@@ -879,7 +879,7 @@
 
 static void ggp_add_deny(PurpleConnection *gc, const char *who)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	uin_t uin = ggp_str_to_uin(who);
 	
 	purple_debug_info("gg", "ggp_add_deny: %u\n", uin);
@@ -890,7 +890,7 @@
 
 static void ggp_rem_deny(PurpleConnection *gc, const char *who)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	uin_t uin = ggp_str_to_uin(who);
 	
 	purple_debug_info("gg", "ggp_rem_deny: %u\n", uin);
@@ -1024,7 +1024,7 @@
 
 				purple_debug_info("gg", "gg_get_avatar_url_cb: "
 					"requesting avatar for %s\n", uin);
-				url_data = purple_util_fetch_url_request_len_with_account(account,
+				url_data = purple_util_fetch_url_request_len(account,
 						bigavatar, TRUE, "Mozilla/4.0 (compatible; MSIE 5.0)",
 						FALSE, NULL, FALSE, -1, gg_fetch_avatar_cb, data);
 			}
@@ -1052,7 +1052,7 @@
 
 	avatarurl = g_strdup_printf("http://api.gadu-gadu.pl/avatars/%u/0.xml", uin);
 
-	url_data = purple_util_fetch_url_request_len_with_account(
+	url_data = purple_util_fetch_url_request_len(
 			purple_connection_get_account(gc), avatarurl, TRUE,
 			"Mozilla/4.0 (compatible; MSIE 5.5)", FALSE, NULL, FALSE, -1,
 			gg_get_avatar_url_cb, gc);
@@ -1194,27 +1194,37 @@
 
 	val = ggp_search_get_result(req, 0, GG_PUBDIR50_STATUS);
 	/* XXX: Use of ggp_str_to_uin() is an ugly hack! */
-	purple_notify_user_info_add_pair(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val)));
+	purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val)));
 	g_free(val);
 
 	who = ggp_search_get_result(req, 0, GG_PUBDIR50_UIN);
-	purple_notify_user_info_add_pair(user_info, _("UIN"), who);
+	/* TODO: Check whether it's correct to call add_pair_html,
+	         or if we should be using add_pair_plaintext */
+	purple_notify_user_info_add_pair_html(user_info, _("UIN"), who);
 
 	val = ggp_search_get_result(req, 0, GG_PUBDIR50_FIRSTNAME);
-	purple_notify_user_info_add_pair(user_info, _("First Name"), val);
+	/* TODO: Check whether it's correct to call add_pair_html,
+	         or if we should be using add_pair_plaintext */
+	purple_notify_user_info_add_pair_html(user_info, _("First Name"), val);
 	g_free(val);
 
 	val = ggp_search_get_result(req, 0, GG_PUBDIR50_NICKNAME);
-	purple_notify_user_info_add_pair(user_info, _("Nickname"), val);
+	/* TODO: Check whether it's correct to call add_pair_html,
+	         or if we should be using add_pair_plaintext */
+	purple_notify_user_info_add_pair_html(user_info, _("Nickname"), val);
 	g_free(val);
 
 	val = ggp_search_get_result(req, 0, GG_PUBDIR50_CITY);
-	purple_notify_user_info_add_pair(user_info, _("City"), val);
+	/* TODO: Check whether it's correct to call add_pair_html,
+	         or if we should be using add_pair_plaintext */
+	purple_notify_user_info_add_pair_html(user_info, _("City"), val);
 	g_free(val);
 
 	val = ggp_search_get_result(req, 0, GG_PUBDIR50_BIRTHYEAR);
 	if (strncmp(val, "0", 1)) {
-		purple_notify_user_info_add_pair(user_info, _("Birth Year"), val);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, _("Birth Year"), val);
 	}
 	g_free(val);
 
@@ -1225,15 +1235,12 @@
 	if (NULL != buddy) {
 		PurpleStatus *status;
 		const char *msg;
-		char *text;
 
 		status = purple_presence_get_active_status(purple_buddy_get_presence(buddy));
 		msg = purple_status_get_attr_string(status, "message");
 
 		if (msg != NULL) {
-			text = g_markup_escape_text(msg, -1);
-			purple_notify_user_info_add_pair(user_info, _("Message"), text);
-			g_free(text);
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Message"), msg);
 		}
 	}
 
@@ -1342,7 +1349,7 @@
 
 static void ggp_pubdir_reply_handler(PurpleConnection *gc, gg_pubdir50_t req)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPSearchForm *form;
 	int res_count;
 	guint32 seq;
@@ -1384,7 +1391,7 @@
 static void ggp_recv_image_handler(PurpleConnection *gc, const struct gg_event *ev)
 {
 	gint imgid = 0;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GList *entry = g_list_first(info->pending_richtext_messages);
 	gchar *handlerid = g_strdup_printf("IMGID_HANDLER-%i", ev->event.image_reply.crc32);
 
@@ -1432,7 +1439,7 @@
  */
 static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event *ev)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	PurpleConversation *conv;
 	gchar *from;
 	gchar *msg;
@@ -1601,7 +1608,7 @@
 
 static void ggp_send_image_handler(PurpleConnection *gc, const struct gg_event *ev)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	PurpleStoredImage *image;
 	gint imgid = GPOINTER_TO_INT(g_hash_table_lookup(info->pending_images, GINT_TO_POINTER(ev->event.image_request.crc32)));
 
@@ -1707,14 +1714,14 @@
 static void ggp_callback_recv(gpointer _gc, gint fd, PurpleInputCondition cond)
 {
 	PurpleConnection *gc = _gc;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	struct gg_event *ev;
 	int i;
 
 	if (!(ev = gg_watch_fd(info->session))) {
 		purple_debug_error("gg",
 			"ggp_callback_recv: gg_watch_fd failed -- CRITICAL!\n");
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to read from socket"));
 		return;
@@ -1842,7 +1849,7 @@
 
 	g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
 
-	info = gc->proto_data;
+	info = purple_connection_get_protocol_data(gc);
 
 	purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n",
 			info->session->check, info->session->state);
@@ -1880,7 +1887,7 @@
 
 	if (!(ev = gg_watch_fd(info->session))) {
 		purple_debug_error("gg", "login_handler: gg_watch_fd failed!\n");
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to read from socket"));
 		return;
@@ -1919,7 +1926,7 @@
 		case GG_EVENT_CONN_FAILED:
 			purple_input_remove(gc->inpa);
 			gc->inpa = 0;
-			purple_connection_error_reason (gc,
+			purple_connection_error (gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Connection failed"));
 			break;
@@ -1975,7 +1982,7 @@
 static void ggp_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full)
 {
 	PurpleStatus *status;
-	char *text, *tmp;
+	char *tmp;
 	const char *msg, *name, *alias;
 
 	g_return_if_fail(b != NULL);
@@ -1985,21 +1992,19 @@
 	name = purple_status_get_name(status);
 	alias = purple_buddy_get_alias(b);
 
-	purple_notify_user_info_add_pair (user_info, _("Alias"), alias);
+	purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), alias);
 
 	if (msg != NULL) {
-		text = g_markup_escape_text(msg, -1);
 		if (PURPLE_BUDDY_IS_ONLINE(b)) {
-			tmp = g_strdup_printf("%s: %s", name, text);
-			purple_notify_user_info_add_pair(user_info, _("Status"), tmp);
+			tmp = g_strdup_printf("%s: %s", name, msg);
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), tmp);
 			g_free(tmp);
 		} else {
-			purple_notify_user_info_add_pair(user_info, _("Message"), text);
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Message"), msg);
 		}
-		g_free(text);
 	/* We don't want to duplicate 'Status: Offline'. */
 	} else if (PURPLE_BUDDY_IS_ONLINE(b)) {
-		purple_notify_user_info_add_pair(user_info, _("Status"), name);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), name);
 	}
 }
 
@@ -2030,7 +2035,7 @@
 			NULL);
 	types = g_list_append(types, type);
 
- 	/*
+	/*
 	 * New statuses for GG 8.0 like PoGGadaj ze mna (not yet because
 	 * libpurple can't support Chatty status) and Nie przeszkadzac
 	 */
@@ -2062,13 +2067,15 @@
 	PurpleMenuAction *act;
 	GList *m = NULL;
 	PurpleAccount *account;
+	PurpleConnection *gc;
 	GGPInfo *info;
 
 	if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
 		return NULL;
 
 	account = purple_buddy_get_account((PurpleBuddy *) node);
-	info = purple_account_get_connection(account)->proto_data;
+	gc = purple_account_get_connection(account);
+	info = purple_connection_get_protocol_data(gc);
 	if (info->chats) {
 		act = purple_menu_action_new(_("Add to chat"),
 			PURPLE_CALLBACK(ggp_bmenu_add_to_chat),
@@ -2120,7 +2127,7 @@
 	info->pending_images = g_hash_table_new(g_direct_hash, g_direct_equal);
 	info->status_broadcasting = purple_account_get_bool(account, "status_broadcasting", TRUE);
 	
-	gc->proto_data = info;
+	purple_connection_set_protocol_data(gc, info);
 
 	glp->uin = ggp_get_uin(account);
 	glp->password = (char *)purple_account_get_password(account);
@@ -2157,7 +2164,7 @@
 		if (addr == NULL) {
 			gchar *tmp = g_strdup_printf(_("Unable to resolve hostname '%s': %s"),
 					address, g_strerror(errno));
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, /* should this be a settings error? */
 				tmp);
 			g_free(tmp);
@@ -2172,7 +2179,7 @@
 	info->session = gg_login(glp);
 	purple_connection_update_progress(gc, _("Connecting"), 0, 2);
 	if (info->session == NULL) {
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Connection failed"));
 		g_free(glp);
@@ -2184,18 +2191,19 @@
 
 static void ggp_close(PurpleConnection *gc)
 {
+	PurpleAccount *account;
+	GGPInfo *info;;
 
 	if (gc == NULL) {
 		purple_debug_info("gg", "gc == NULL\n");
 		return;
 	}
 
-	if (gc->proto_data) {
-		PurpleAccount *account = purple_connection_get_account(gc);
-		PurpleStatus *status;
-		GGPInfo *info = gc->proto_data;
-
-		status = purple_account_get_active_status(account);
+	account = purple_connection_get_account(gc);
+	info = purple_connection_get_protocol_data(gc);
+
+	if (info) {
+		PurpleStatus *status = purple_account_get_active_status(account);
 
 		if (info->session != NULL) {
 			ggp_set_status(account, status);
@@ -2214,7 +2222,7 @@
 		g_list_free(info->pending_richtext_messages);
 		g_hash_table_destroy(info->pending_images);
 		g_free(info);
-		gc->proto_data = NULL;
+		purple_connection_set_protocol_data(gc, NULL);
 	}
 
 	if (gc->inpa > 0)
@@ -2226,7 +2234,7 @@
 static int ggp_send_im(PurpleConnection *gc, const char *who, const char *msg,
 		       PurpleMessageFlags flags)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	char *tmp, *plain;
 	int ret = 1;
 	unsigned char format[1024];
@@ -2344,6 +2352,7 @@
 
 static unsigned int ggp_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state)
 {
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	int dummy_length; // we don't send real length of typed message
 	
 	if (state == PURPLE_TYPED) // not supported
@@ -2355,7 +2364,7 @@
 		dummy_length = 0;
 	
 	gg_typing_notification(
-		((GGPInfo*)gc->proto_data)->session,
+		info->session,
 		ggp_str_to_uin(name),
 		dummy_length); 
 	
@@ -2364,7 +2373,7 @@
 
 static void ggp_get_info(PurpleConnection *gc, const char *name)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPSearchForm *form;
 	guint32 seq;
 
@@ -2440,7 +2449,7 @@
 		return;
 
 	gc = purple_account_get_connection(account);
-	info = gc->proto_data;
+	info = purple_connection_get_protocol_data(gc);
 
 	new_status = ggp_to_gg_status(status, &new_msg);
 
@@ -2458,10 +2467,10 @@
 
 }
 
-static void ggp_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
+static void ggp_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
 {
 	PurpleAccount *account;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	const gchar *name = purple_buddy_get_name(buddy);
 
 	gg_add_notify(info->session, ggp_str_to_uin(name));
@@ -2475,14 +2484,14 @@
 static void ggp_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
 						 PurpleGroup *group)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 
 	gg_remove_notify(info->session, ggp_str_to_uin(purple_buddy_get_name(buddy)));
 }
 
 static void ggp_join_chat(PurpleConnection *gc, GHashTable *data)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPChat *chat;
 	char *chat_name;
 	GList *l;
@@ -2520,7 +2529,7 @@
 static int ggp_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags)
 {
 	PurpleConversation *conv;
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	GGPChat *chat = NULL;
 	GList *l;
 	/* char *msg, *plain; */
@@ -2575,14 +2584,14 @@
 
 static void ggp_keepalive(PurpleConnection *gc)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 
 	/* purple_debug_info("gg", "Keeping connection alive....\n"); */
 
 	if (gg_ping(info->session) < 0) {
 		purple_debug_info("gg", "Not connected to the server "
 				"or gg_session is not correct\n");
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Not connected to the server"));
 	}
@@ -2646,6 +2655,7 @@
 
 static PurplePluginProtocolInfo prpl_info =
 {
+	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	OPT_PROTO_REGISTER_NOSCREENNAME | OPT_PROTO_IM_IMAGE,
 	NULL,				/* user_splits */
 	NULL,				/* protocol_options */
@@ -2711,15 +2721,12 @@
 	NULL,				/* unregister_user */
 	NULL,				/* send_attention */
 	NULL,				/* get_attention_types */
-	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	NULL,                           /* get_account_text_table */
 	NULL,                           /* initiate_media */
 	NULL,                            /* can_do_media */
 	NULL,				/* get_moods */
 	NULL,				/* set_public_alias */
-	NULL,				/* get_public_alias */
-	NULL,				/* add_buddy_with_invite */
-	NULL				/* add_buddies_with_invite */
+	NULL				/* get_public_alias */
 };
 
 static PurplePluginInfo info = {
--- a/libpurple/protocols/gg/search.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/gg/search.c	Sun Sep 11 04:19:01 2011 +0000
@@ -135,7 +135,7 @@
 /* guint32 ggp_search_start(PurpleConnection *gc, GGPSearchForm *form) {{{ */
 guint32 ggp_search_start(PurpleConnection *gc, GGPSearchForm *form)
 {
-	GGPInfo *info = gc->proto_data;
+	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	gg_pubdir50_t req;
 	guint seq, offset;
 
--- a/libpurple/protocols/irc/dcc_send.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/irc/dcc_send.c	Sun Sep 11 04:19:01 2011 +0000
@@ -34,11 +34,12 @@
 
 struct irc_xfer_rx_data {
 	gchar *ip;
+	unsigned int remote_port;
 };
 
 static void irc_dccsend_recv_destroy(PurpleXfer *xfer)
 {
-	struct irc_xfer_rx_data *xd = xfer->data;
+	struct irc_xfer_rx_data *xd = purple_xfer_get_protocol_data(xfer);
 
 	g_free(xd->ip);
 	g_free(xd);
@@ -51,10 +52,10 @@
  */
 static void irc_dccsend_recv_ack(PurpleXfer *xfer, const guchar *data, size_t size) {
 	guint32 l;
-	size_t result;
+	gssize result;
 
-	l = htonl(xfer->bytes_sent);
-	result = write(xfer->fd, &l, sizeof(l));
+	l = htonl(purple_xfer_get_bytes_sent(xfer));
+	result = purple_xfer_write(xfer, (guchar *)&l, sizeof(l));
 	if (result != sizeof(l)) {
 		purple_debug_error("irc", "unable to send acknowledgement: %s\n", g_strerror(errno));
 		/* TODO: We should probably close the connection here or something. */
@@ -62,9 +63,9 @@
 }
 
 static void irc_dccsend_recv_init(PurpleXfer *xfer) {
-	struct irc_xfer_rx_data *xd = xfer->data;
+	struct irc_xfer_rx_data *xd = purple_xfer_get_protocol_data(xfer);
 
-	purple_xfer_start(xfer, -1, xd->ip, xfer->remote_port);
+	purple_xfer_start(xfer, -1, xd->ip, xd->remote_port);
 	g_free(xd->ip);
 	xd->ip = NULL;
 }
@@ -114,10 +115,10 @@
 	if (xfer)
 	{
 		xd = g_new0(struct irc_xfer_rx_data, 1);
-		xfer->data = xd;
+		purple_xfer_set_protocol_data(xfer, xd);
 
 		purple_xfer_set_filename(xfer, filename->str);
-		xfer->remote_port = atoi(token[i+1]);
+		xd->remote_port = atoi(token[i+1]);
 
 		nip = strtoul(token[i], NULL, 10);
 		if (nip) {
@@ -157,7 +158,7 @@
 
 static void irc_dccsend_send_destroy(PurpleXfer *xfer)
 {
-	struct irc_xfer_send_data *xd = xfer->data;
+	struct irc_xfer_send_data *xd = purple_xfer_get_protocol_data(xfer);
 
 	if (xd == NULL)
 		return;
@@ -178,7 +179,7 @@
 static void irc_dccsend_send_read(gpointer data, int source, PurpleInputCondition cond)
 {
 	PurpleXfer *xfer = data;
-	struct irc_xfer_send_data *xd = xfer->data;
+	struct irc_xfer_send_data *xd = purple_xfer_get_protocol_data(xfer);
 	char buffer[64];
 	int len;
 
@@ -228,13 +229,13 @@
 static gssize irc_dccsend_send_write(const guchar *buffer, size_t size, PurpleXfer *xfer)
 {
 	gssize s;
-	int ret;
+	gssize ret;
 
 	s = MIN(purple_xfer_get_bytes_remaining(xfer), size);
 	if (!s)
 		return 0;
 
-	ret = write(xfer->fd, buffer, s);
+	ret = purple_xfer_write(xfer, buffer, s);
 
 	if (ret < 0 && errno == EAGAIN)
 		ret = 0;
@@ -244,7 +245,7 @@
 
 static void irc_dccsend_send_connected(gpointer data, int source, PurpleInputCondition cond) {
 	PurpleXfer *xfer = (PurpleXfer *) data;
-	struct irc_xfer_send_data *xd = xfer->data;
+	struct irc_xfer_send_data *xd = purple_xfer_get_protocol_data(xfer);
 	int conn, flags;
 
 	conn = accept(xd->fd, NULL, 0);
@@ -285,7 +286,7 @@
 	struct in_addr addr;
 	unsigned short int port;
 
-	xd = xfer->data;
+	xd = purple_xfer_get_protocol_data(xfer);
 	xd->listen_data = NULL;
 
 	if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL
@@ -294,9 +295,9 @@
 		return;
 	}
 
-	xd = xfer->data;
+	xd = purple_xfer_get_protocol_data(xfer);
 	gc = purple_account_get_connection(purple_xfer_get_account(xfer));
-	irc = gc->proto_data;
+	irc = purple_connection_get_protocol_data(gc);
 
 	purple_xfer_unref(xfer);
 
@@ -316,13 +317,13 @@
 	                                 irc_dccsend_send_connected, xfer);
 
 	/* Send the intended recipient the DCC request */
-	arg[0] = xfer->who;
+	arg[0] = purple_xfer_get_remote_user(xfer);
 	inet_aton(purple_network_get_my_ip(irc->fd), &addr);
 	arg[1] = tmp = g_strdup_printf("\001DCC SEND \"%s\" %u %hu %" G_GSIZE_FORMAT "\001",
-	                               xfer->filename, ntohl(addr.s_addr),
-	                               port, xfer->size);
+	                               purple_xfer_get_filename(xfer), ntohl(addr.s_addr),
+	                               port, purple_xfer_get_size(xfer));
 
-	irc_cmd_privmsg(gc->proto_data, "msg", NULL, arg);
+	irc_cmd_privmsg(purple_connection_get_protocol_data(gc), "msg", NULL, arg);
 	g_free(tmp);
 }
 
@@ -331,9 +332,9 @@
  */
 static void irc_dccsend_send_init(PurpleXfer *xfer) {
 	PurpleConnection *gc = purple_account_get_connection(purple_xfer_get_account(xfer));
-	struct irc_xfer_send_data *xd = xfer->data;
+	struct irc_xfer_send_data *xd = purple_xfer_get_protocol_data(xfer);
 
-	xfer->filename = g_path_get_basename(xfer->local_filename);
+	purple_xfer_set_filename(xfer, g_path_get_basename(purple_xfer_get_local_filename(xfer)));
 
 	purple_xfer_ref(xfer);
 
@@ -359,7 +360,7 @@
 	{
 		xd = g_new0(struct irc_xfer_send_data, 1);
 		xd->fd = -1;
-		xfer->data = xd;
+		purple_xfer_set_protocol_data(xfer, xd);
 
 		/* Setup our I/O op functions */
 		purple_xfer_set_init_fnc(xfer, irc_dccsend_send_init);
--- a/libpurple/protocols/irc/irc.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/irc/irc.c	Sun Sep 11 04:19:01 2011 +0000
@@ -70,11 +70,11 @@
 	struct irc_conn *irc;
 	char *title;
 
-	if (gc == NULL || gc->proto_data == NULL) {
+	if (gc == NULL || purple_connection_get_protocol_data(gc) == NULL) {
 		purple_debug(PURPLE_DEBUG_ERROR, "irc", "got MOTD request for NULL gc\n");
 		return;
 	}
-	irc = gc->proto_data;
+	irc = purple_connection_get_protocol_data(gc);
 	if (irc->motd == NULL) {
 		purple_notify_error(gc, _("Error displaying MOTD"), _("No MOTD available"),
 				  _("There is no MOTD associated with this connection."));
@@ -100,7 +100,7 @@
 
 static int irc_send_raw(PurpleConnection *gc, const char *buf, int len)
 {
-	struct irc_conn *irc = (struct irc_conn*)gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	if (len == -1) {
 		len = strlen(buf);
 	}
@@ -130,7 +130,7 @@
 		PurpleConnection *gc = purple_account_get_connection(irc->account);
 		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
 			g_strerror(errno));
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
@@ -174,7 +174,7 @@
 		PurpleConnection *gc = purple_account_get_connection(irc->account);
 		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
 			g_strerror(errno));
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 	} else if (ret < buflen) {
@@ -359,13 +359,14 @@
 	gc->flags |= PURPLE_CONNECTION_NO_NEWLINES;
 
 	if (strpbrk(username, " \t\v\r\n") != NULL) {
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 			_("IRC nick and server may not contain whitespace"));
 		return;
 	}
 
-	gc->proto_data = irc = g_new0(struct irc_conn, 1);
+	irc = g_new0(struct irc_conn, 1);
+	purple_connection_set_protocol_data(gc, irc);
 	irc->fd = -1;
 	irc->account = account;
 	irc->outbuf = purple_circ_buffer_new(512);
@@ -390,7 +391,7 @@
 					purple_account_get_int(account, "port", IRC_DEFAULT_SSL_PORT),
 					irc_login_cb_ssl, irc_ssl_connect_failure, gc);
 		} else {
-			purple_connection_error_reason (gc,
+			purple_connection_error (gc,
 				PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 				_("SSL support unavailable"));
 			return;
@@ -403,7 +404,7 @@
 				 purple_account_get_int(account, "port", IRC_DEFAULT_PORT),
 				 irc_login_cb, gc) == NULL)
 		{
-			purple_connection_error_reason (gc,
+			purple_connection_error (gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Unable to connect"));
 			return;
@@ -415,7 +416,7 @@
 	char *buf, *tmp = NULL;
 	char *server;
 	const char *username, *realname;
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	const char *pass = purple_connection_get_password(gc);
 
 	if (pass && *pass) {
@@ -485,12 +486,12 @@
 static void irc_login_cb(gpointer data, gint source, const gchar *error_message)
 {
 	PurpleConnection *gc = data;
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 
 	if (source < 0) {
 		gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
 			error_message);
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
@@ -508,7 +509,7 @@
 		gpointer data)
 {
 	PurpleConnection *gc = data;
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 
 	irc->gsc = NULL;
 
@@ -517,7 +518,7 @@
 
 static void irc_close(PurpleConnection *gc)
 {
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 
 	if (irc == NULL)
 		return;
@@ -558,7 +559,7 @@
 
 static int irc_im_send(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags)
 {
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	char *plain;
 	const char *args[2];
 
@@ -574,7 +575,7 @@
 
 static void irc_get_info(PurpleConnection *gc, const char *who)
 {
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	const char *args[2];
 	args[0] = who;
 	args[1] = NULL;
@@ -589,7 +590,7 @@
 	const char *status_id = purple_status_get_id(status);
 
 	g_return_if_fail(gc != NULL);
-	irc = gc->proto_data;
+	irc = purple_connection_get_protocol_data(gc);
 
 	if (!purple_status_is_active(status))
 		return;
@@ -606,9 +607,9 @@
 	}
 }
 
-static void irc_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
+static void irc_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
 {
-	struct irc_conn *irc = (struct irc_conn *)gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	struct irc_buddy *ib;
 	const char *bname = purple_buddy_get_name(buddy);
 
@@ -633,7 +634,7 @@
 
 static void irc_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
 {
-	struct irc_conn *irc = (struct irc_conn *)gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	struct irc_buddy *ib;
 
 	ib = g_hash_table_lookup(irc->buddies, purple_buddy_get_name(buddy));
@@ -678,7 +679,7 @@
 {
 
 	PurpleConnection *gc = data;
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	int len;
 
 	if(!g_list_find(purple_connections_get_all(), gc)) {
@@ -699,12 +700,12 @@
 	} else if (len < 0) {
 		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
 				g_strerror(errno));
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	} else if (len == 0) {
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Server closed the connection"));
 		return;
@@ -716,7 +717,7 @@
 static void irc_input_cb(gpointer data, gint source, PurpleInputCondition cond)
 {
 	PurpleConnection *gc = data;
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	int len;
 
 	if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) {
@@ -730,12 +731,12 @@
 	} else if (len < 0) {
 		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
 				g_strerror(errno));
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	} else if (len == 0) {
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Server closed the connection"));
 		return;
@@ -746,7 +747,7 @@
 
 static void irc_chat_join (PurpleConnection *gc, GHashTable *data)
 {
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	const char *args[2];
 
 	args[0] = g_hash_table_lookup(data, "channel");
@@ -760,7 +761,7 @@
 
 static void irc_chat_invite(PurpleConnection *gc, int id, const char *message, const char *name)
 {
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	PurpleConversation *convo = purple_find_chat(gc, id);
 	const char *args[2];
 
@@ -776,7 +777,7 @@
 
 static void irc_chat_leave (PurpleConnection *gc, int id)
 {
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	PurpleConversation *convo = purple_find_chat(gc, id);
 	const char *args[2];
 
@@ -791,7 +792,7 @@
 
 static int irc_chat_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFlags flags)
 {
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	PurpleConversation *convo = purple_find_chat(gc, id);
 	const char *args[2];
 	char *tmp;
@@ -845,7 +846,7 @@
 	const char *name = NULL;
 	struct irc_conn *irc;
 
-	irc = gc->proto_data;
+	irc = purple_connection_get_protocol_data(gc);
 	name = purple_conversation_get_name(purple_find_chat(gc, id));
 
 	if (name == NULL)
@@ -863,7 +864,7 @@
 	PurpleRoomlistField *f;
 	char *buf;
 
-	irc = gc->proto_data;
+	irc = purple_connection_get_protocol_data(gc);
 
 	if (irc->roomlist)
 		purple_roomlist_unref(irc->roomlist);
@@ -890,13 +891,14 @@
 
 static void irc_roomlist_cancel(PurpleRoomlist *list)
 {
-	PurpleConnection *gc = purple_account_get_connection(list->account);
+	PurpleAccount *account = purple_roomlist_get_account(list);
+	PurpleConnection *gc = purple_account_get_connection(account);
 	struct irc_conn *irc;
 
 	if (gc == NULL)
 		return;
 
-	irc = gc->proto_data;
+	irc = purple_connection_get_protocol_data(gc);
 
 	purple_roomlist_set_in_progress(list, FALSE);
 
@@ -908,13 +910,14 @@
 
 static void irc_keepalive(PurpleConnection *gc)
 {
-	struct irc_conn *irc = gc->proto_data;
+	struct irc_conn *irc = purple_connection_get_protocol_data(gc);
 	if ((time(NULL) - irc->recv_time) > PING_TIMEOUT)
 		irc_cmd_ping(irc, NULL, NULL, NULL);
 }
 
 static PurplePluginProtocolInfo prpl_info =
 {
+	sizeof(PurplePluginProtocolInfo),    /* struct_size */
 	OPT_PROTO_CHAT_TOPIC | OPT_PROTO_PASSWORD_OPTIONAL |
 	OPT_PROTO_SLASH_COMMANDS_NATIVE,
 	NULL,					/* user_splits */
@@ -981,15 +984,12 @@
 	NULL,                   /* unregister_user */
 	NULL,                   /* send_attention */
 	NULL,                   /* get_attention_types */
-	sizeof(PurplePluginProtocolInfo),    /* struct_size */
 	NULL,                    /* get_account_text_table */
 	NULL,                    /* initiate_media */
 	NULL,					 /* get_media_caps */
 	NULL,					 /* get_moods */
 	NULL,					 /* set_public_alias */
-	NULL,					 /* get_public_alias */
-	NULL,					 /* add_buddy_with_invite */
-	NULL					 /* add_buddies_with_invite */
+	NULL					 /* get_public_alias */
 };
 
 static gboolean load_plugin (PurplePlugin *plugin) {
--- a/libpurple/protocols/irc/msgs.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/irc/msgs.c	Sun Sep 11 04:19:01 2011 +0000
@@ -352,44 +352,40 @@
 	tmp = g_strdup_printf("%s%s%s", tmp2,
 				(irc->whois.ircop ? _(" <i>(ircop)</i>") : ""),
 				(irc->whois.identified ? _(" <i>(identified)</i>") : ""));
-	purple_notify_user_info_add_pair(user_info, _("Nick"), tmp);
+	purple_notify_user_info_add_pair_html(user_info, _("Nick"), tmp);
 	g_free(tmp2);
 	g_free(tmp);
 
 	if (irc->whois.away) {
-		tmp = g_markup_escape_text(irc->whois.away, strlen(irc->whois.away));
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Away"), irc->whois.away);
 		g_free(irc->whois.away);
-		purple_notify_user_info_add_pair(user_info, _("Away"), tmp);
-		g_free(tmp);
 	}
 	if (irc->whois.userhost) {
-		tmp = g_markup_escape_text(irc->whois.name, strlen(irc->whois.name));
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), irc->whois.userhost);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Real name"), irc->whois.name);
+		g_free(irc->whois.userhost);
 		g_free(irc->whois.name);
-		purple_notify_user_info_add_pair(user_info, _("Username"), irc->whois.userhost);
-		purple_notify_user_info_add_pair(user_info, _("Real name"), tmp);
-		g_free(irc->whois.userhost);
-		g_free(tmp);
 	}
 	if (irc->whois.server) {
 		tmp = g_strdup_printf("%s (%s)", irc->whois.server, irc->whois.serverinfo);
-		purple_notify_user_info_add_pair(user_info, _("Server"), tmp);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Server"), tmp);
 		g_free(tmp);
 		g_free(irc->whois.server);
 		g_free(irc->whois.serverinfo);
 	}
 	if (irc->whois.channels) {
-		purple_notify_user_info_add_pair(user_info, _("Currently on"), irc->whois.channels->str);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Currently on"), irc->whois.channels->str);
 		g_string_free(irc->whois.channels, TRUE);
 	}
 	if (irc->whois.idle) {
 		gchar *timex = purple_str_seconds_to_string(irc->whois.idle);
-		purple_notify_user_info_add_pair(user_info, _("Idle for"), timex);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Idle for"), timex);
 		g_free(timex);
-		purple_notify_user_info_add_pair(user_info,
+		purple_notify_user_info_add_pair_plaintext(user_info,
 														_("Online since"), purple_date_format_full(localtime(&irc->whois.signon)));
 	}
-	if (!strcmp(irc->whois.nick, "Paco-Paco")) {
-		purple_notify_user_info_add_pair(user_info,
+	if (!strcmp(irc->whois.nick, "elb")) {
+		purple_notify_user_info_add_pair_plaintext(user_info,
 																   _("<b>Defining adjective:</b>"), _("Glorious"));
 	}
 
@@ -1075,7 +1071,7 @@
 				  _("Your selected nickname was rejected by the server.  It probably contains invalid characters."));
 
 	} else {
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 				  PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 				  _("Your selected account name was rejected by the server.  It probably contains invalid characters."));
 	}
--- a/libpurple/protocols/irc/parse.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/irc/parse.c	Sun Sep 11 04:19:01 2011 +0000
@@ -175,7 +175,7 @@
 	if (!gc)
 		return PURPLE_CMD_RET_FAILED;
 
-	irc = gc->proto_data;
+	irc = purple_connection_get_protocol_data(gc);
 
 	if ((cmdent = g_hash_table_lookup(irc->cmds, cmd)) == NULL)
 		return PURPLE_CMD_RET_FAILED;
@@ -670,11 +670,11 @@
 	} else if (!strncmp(input, "ERROR ", 6)) {
 		if (g_utf8_validate(input, -1, NULL)) {
 			char *tmp = g_strdup_printf("%s\n%s", _("Disconnected."), input);
-			purple_connection_error_reason (gc,
+			purple_connection_error (gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 			g_free(tmp);
 		} else
-			purple_connection_error_reason (gc,
+			purple_connection_error (gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Disconnected."));
 		return;
--- a/libpurple/protocols/jabber/adhoccommands.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/adhoccommands.c	Sun Sep 11 04:19:01 2011 +0000
@@ -228,7 +228,8 @@
 		JabberAdHocCommands *cmd = data;
 		PurpleBuddy *buddy = (PurpleBuddy *) node;
 		PurpleAccount *account = purple_buddy_get_account(buddy);
-		JabberStream *js = purple_account_get_connection(account)->proto_data;
+		PurpleConnection *gc = purple_account_get_connection(account);
+		JabberStream *js = purple_connection_get_protocol_data(gc);
 
 		jabber_adhoc_execute(js, cmd);
 	}
@@ -321,7 +322,7 @@
 	JabberAdHocCommands *cmd = action->user_data;
 	if(cmd) {
 		PurpleConnection *gc = (PurpleConnection *) action->context;
-		JabberStream *js = gc->proto_data;
+		JabberStream *js = purple_connection_get_protocol_data(gc);
 
 		jabber_adhoc_execute(js, cmd);
 	}
--- a/libpurple/protocols/jabber/auth.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/auth.c	Sun Sep 11 04:19:01 2011 +0000
@@ -77,7 +77,7 @@
 
 static void disallow_plaintext_auth(PurpleAccount *account)
 {
-	purple_connection_error_reason(purple_account_get_connection(account),
+	purple_connection_error(purple_account_get_connection(account),
 		PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
 		_("Server requires plaintext authentication over an unencrypted stream"));
 }
@@ -145,7 +145,7 @@
 
 	mechs = xmlnode_get_child(packet, "mechanisms");
 	if(!mechs) {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Invalid response from server"));
 		return;
@@ -186,7 +186,7 @@
 
 	if (js->auth_mech == NULL) {
 		/* Found no good mechanisms... */
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 				PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
 				_("Server does not use any supported authentication method"));
 		return;
@@ -194,7 +194,7 @@
 
 	state = js->auth_mech->start(js, mechs, &response, &msg);
 	if (state == JABBER_SASL_STATE_FAIL) {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 				PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
 				msg ? msg : _("Unknown Error"));
 	} else if (response) {
@@ -231,7 +231,7 @@
 				purple_account_set_password(account, NULL);
 		}
 
-		purple_connection_error_reason(js->gc, reason, msg);
+		purple_connection_error(js->gc, reason, msg);
 		g_free(msg);
 	}
 }
@@ -247,7 +247,7 @@
 	if (type == JABBER_IQ_ERROR) {
 		PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
 		char *msg = jabber_parse_error(js, packet, &reason);
-		purple_connection_error_reason(js->gc, reason, msg);
+		purple_connection_error(js->gc, reason, msg);
 		g_free(msg);
 	} else if (type == JABBER_IQ_RESULT) {
 		query = xmlnode_get_child(packet, "query");
@@ -321,7 +321,7 @@
 			}
 			finish_plaintext_authentication(js);
 		} else {
-			purple_connection_error_reason(js->gc,
+			purple_connection_error(js->gc,
 				PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
 				_("Server does not use any supported authentication method"));
 			return;
@@ -345,7 +345,7 @@
 	if (!jabber_stream_is_ssl(js) &&
 			g_str_equal("require_tls",
 				purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 			PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
 			_("You require encryption, but it is not available on this server."));
 		return;
@@ -394,7 +394,7 @@
 	const char *ns = xmlnode_get_namespace(packet);
 
 	if (!purple_strequal(ns, NS_XMPP_SASL)) {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Invalid response from server"));
 		return;
@@ -405,7 +405,7 @@
 		char *msg = NULL;
 		JabberSaslState state = js->auth_mech->handle_challenge(js, packet, &response, &msg);
 		if (state == JABBER_SASL_STATE_FAIL) {
-			purple_connection_error_reason(js->gc,
+			purple_connection_error(js->gc,
 					PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
 					msg ? msg : _("Invalid challenge from server"));
 		} else if (response) {
@@ -423,7 +423,7 @@
 	const char *ns = xmlnode_get_namespace(packet);
 
 	if (!purple_strequal(ns, NS_XMPP_SASL)) {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Invalid response from server"));
 		return;
@@ -434,12 +434,12 @@
 		JabberSaslState state = js->auth_mech->handle_success(js, packet, &msg);
 
 		if (state == JABBER_SASL_STATE_FAIL) {
-			purple_connection_error_reason(js->gc,
+			purple_connection_error(js->gc,
 					PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
 					msg ? msg : _("Invalid response from server"));
 			return;
 		} else if (state == JABBER_SASL_STATE_CONTINUE) {
-			purple_connection_error_reason(js->gc,
+			purple_connection_error(js->gc,
 					PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
 					msg ? msg : _("Server thinks authentication is complete, but client does not"));
 			return;
@@ -479,11 +479,11 @@
 		msg = jabber_parse_error(js, packet, &reason);
 
 	if (!msg) {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Invalid response from server"));
 	} else {
-		purple_connection_error_reason(js->gc, reason, msg);
+		purple_connection_error(js->gc, reason, msg);
 		g_free(msg);
 	}
 }
--- a/libpurple/protocols/jabber/auth_cyrus.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/auth_cyrus.c	Sun Sep 11 04:19:01 2011 +0000
@@ -34,7 +34,7 @@
 
 static void disallow_plaintext_auth(PurpleAccount *account)
 {
-	purple_connection_error_reason(purple_account_get_connection(account),
+	purple_connection_error(purple_account_get_connection(account),
 		PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
 		_("Server may require plaintext authentication over an unencrypted stream"));
 }
@@ -46,7 +46,7 @@
 	JabberSaslState state = jabber_auth_start_cyrus(js, &response, &error);
 
 	if (state == JABBER_SASL_STATE_FAIL) {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 				PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
 				error);
 		g_free(error);
--- a/libpurple/protocols/jabber/auth_plain.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/auth_plain.c	Sun Sep 11 04:19:01 2011 +0000
@@ -75,7 +75,7 @@
 
 static void disallow_plaintext_auth(PurpleAccount *account)
 {
-	purple_connection_error_reason(purple_account_get_connection(account),
+	purple_connection_error(purple_account_get_connection(account),
 		PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
 		_("Server requires plaintext authentication over an unencrypted stream"));
 }
--- a/libpurple/protocols/jabber/bosh.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/bosh.c	Sun Sep 11 04:19:01 2011 +0000
@@ -436,7 +436,7 @@
 
 	if (type != NULL && !strcmp(type, "terminate")) {
 		conn->state = BOSH_CONN_OFFLINE;
-		purple_connection_error_reason(conn->js->gc,
+		purple_connection_error(conn->js->gc,
 			PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 			_("The BOSH connection manager terminated your session."));
 		return TRUE;
@@ -539,7 +539,7 @@
 	if (sid) {
 		conn->sid = g_strdup(sid);
 	} else {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 		        PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		        _("No session ID given"));
 		return;
@@ -556,7 +556,7 @@
 			minor = atoi(dot + 1);
 
 		if (major != 1 || minor < 6) {
-			purple_connection_error_reason(js->gc,
+			purple_connection_error(js->gc,
 			        PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			        _("Unsupported version of BOSH protocol"));
 			return;
@@ -733,7 +733,7 @@
 		return;
 
 	if (++conn->bosh->failed_connections == MAX_FAILED_CONNECTIONS) {
-		purple_connection_error_reason(conn->bosh->js->gc,
+		purple_connection_error(conn->bosh->js->gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Unable to establish a connection with the server"));
 	} else {
@@ -939,7 +939,7 @@
 		gchar *tmp;
 		tmp = g_strdup_printf(_("Unable to establish a connection with the server: %s"),
 		        error);
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	}
@@ -965,18 +965,18 @@
 			                               ssl_connection_error_cb,
 			                               conn);
 			if (!conn->psc) {
-				purple_connection_error_reason(gc,
+				purple_connection_error(gc,
 					PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 					_("Unable to establish SSL connection"));
 			}
 		} else {
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 			    PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 			    _("SSL support unavailable"));
 		}
 	} else if (purple_proxy_connect(conn, account, bosh->host, bosh->port,
 	                                 connection_established_cb, conn) == NULL) {
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 		    PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		    _("Unable to connect"));
 	}
@@ -1023,7 +1023,7 @@
 		 */
 		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
 				g_strerror(errno));
-		purple_connection_error_reason(conn->bosh->js->gc,
+		purple_connection_error(conn->bosh->js->gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				tmp);
 		g_free(tmp);
@@ -1079,7 +1079,7 @@
 		 */
 		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
 				g_strerror(errno));
-		purple_connection_error_reason(conn->bosh->js->gc,
+		purple_connection_error(conn->bosh->js->gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				tmp);
 		g_free(tmp);
--- a/libpurple/protocols/jabber/buddy.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Sun Sep 11 04:19:01 2011 +0000
@@ -465,10 +465,22 @@
 	xmlnode *vc_node;
 	const struct tag_attr *tag_attr;
 
-	/* if we have't grabbed the remote vcard yet, we can't
+	/* if we haven't grabbed the remote vcard yet, we can't
 	 * assume that what we have here is correct */
-	if(!js->vcard_fetched)
+	if(!js->vcard_fetched) {
+		PurpleStoredImage *image;
+		g_free(js->initial_avatar_hash);
+		image = purple_buddy_icons_find_account_icon(purple_connection_get_account(gc));
+		if (image != NULL) {
+			js->initial_avatar_hash =
+					jabber_calculate_data_hash(purple_imgstore_get_data(image),
+					purple_imgstore_get_size(image), "sha1");
+			purple_imgstore_unref(image);
+		} else {
+			js->initial_avatar_hash = NULL;
+		}
 		return;
+	}
 
 	if (js->vcard_timer) {
 		purple_timeout_remove(js->vcard_timer);
@@ -545,7 +557,7 @@
 	PurpleAccount *account = purple_connection_get_account(gc);
 
 	/* Publish the avatar as specified in XEP-0084 */
-	jabber_avatar_set(gc->proto_data, img);
+	jabber_avatar_set(purple_connection_get_protocol_data(gc), img);
 	/* Set the image in our vCard */
 	jabber_set_info(gc, purple_account_get_user_info(account));
 
@@ -719,11 +731,16 @@
 			g_strdup_printf("%s%s%s", jbr->client.name,
 		                    (jbr->client.version ? " " : ""),
 		                    (jbr->client.version ? jbr->client.version : ""));
-		purple_notify_user_info_prepend_pair(user_info, _("Client"), tmp);
+		/* TODO: Check whether it's correct to call prepend_pair_html,
+		         or if we should be using prepend_pair_plaintext */
+		purple_notify_user_info_prepend_pair_html(user_info, _("Client"), tmp);
 		g_free(tmp);
 
-		if (jbr->client.os)
-			purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os);
+		if (jbr->client.os) {
+			/* TODO: Check whether it's correct to call prepend_pair_html,
+			         or if we should be using prepend_pair_plaintext */
+			purple_notify_user_info_prepend_pair_html(user_info, _("Operating System"), jbr->client.os);
+		}
 	}
 
 	if (jbr && jbr->tz_off != PURPLE_NO_TZ_OFF) {
@@ -739,13 +756,13 @@
 		                    jbr->tz_off < 0 ? '-' : '+',
 		                    abs(jbr->tz_off / (60*60)),
 		                    abs((jbr->tz_off % (60*60)) / 60));
-		purple_notify_user_info_prepend_pair(user_info, _("Local Time"), timestamp);
+		purple_notify_user_info_prepend_pair_plaintext(user_info, _("Local Time"), timestamp);
 		g_free(timestamp);
 	}
 
 	if (jbir && jbir->idle_seconds > 0) {
 		char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
-		purple_notify_user_info_prepend_pair(user_info, _("Idle"), idle);
+		purple_notify_user_info_prepend_pair_plaintext(user_info, _("Idle"), idle);
 		g_free(idle);
 	}
 
@@ -767,15 +784,15 @@
 		tmp = g_strdup_printf("%s%s%s", (status_name ? status_name : ""),
 						((status_name && purdy) ? ": " : ""),
 						(purdy ? purdy : ""));
-		purple_notify_user_info_prepend_pair(user_info, _("Status"), tmp);
+		purple_notify_user_info_prepend_pair_html(user_info, _("Status"), tmp);
 
 		g_snprintf(priority, sizeof(priority), "%d", jbr->priority);
-		purple_notify_user_info_prepend_pair(user_info, _("Priority"), priority);
+		purple_notify_user_info_prepend_pair_plaintext(user_info, _("Priority"), priority);
 
 		g_free(tmp);
 		g_free(purdy);
 	} else {
-		purple_notify_user_info_prepend_pair(user_info, _("Status"), _("Unknown"));
+		purple_notify_user_info_prepend_pair_plaintext(user_info, _("Status"), _("Unknown"));
 	}
 }
 
@@ -794,7 +811,7 @@
 	resource_name = jabber_get_resource(jbi->jid);
 
 	/* If we have one or more pairs from the vcard, put a section break above it */
-	if (purple_notify_user_info_get_entries(user_info))
+	if (g_queue_get_length(purple_notify_user_info_get_entries(user_info)))
 		purple_notify_user_info_prepend_section_break(user_info);
 
 	/* Add the information about the user's resource(s) */
@@ -815,8 +832,11 @@
 
 			add_jbr_info(jbi, jbr->name, jbr);
 
-			if (jbr->name)
-				purple_notify_user_info_prepend_pair(user_info, _("Resource"), jbr->name);
+			if (jbr->name) {
+				/* TODO: Check whether it's correct to call prepend_pair_html,
+				         or if we should be using prepend_pair_plaintext */
+				purple_notify_user_info_prepend_pair_html(user_info, _("Resource"), jbr->name);
+			}
 		}
 	}
 
@@ -836,7 +856,7 @@
 				title = _("Logged Off");
 				message = g_strdup_printf(_("%s ago"), last);
 			}
-			purple_notify_user_info_prepend_pair(user_info, title, message);
+			purple_notify_user_info_prepend_pair_plaintext(user_info, title, message);
 			g_free(last);
 			g_free(message);
 		}
@@ -846,7 +866,9 @@
 				g_strdup_printf("%s%s%s",	_("Offline"),
 				                jbi->last_message ? ": " : "",
 				                jbi->last_message ? jbi->last_message : "");
-			purple_notify_user_info_prepend_pair(user_info, _("Status"), status);
+			/* TODO: Check whether it's correct to call prepend_pair_html,
+			         or if we should be using prepend_pair_plaintext */
+			purple_notify_user_info_prepend_pair_html(user_info, _("Status"), status);
 			g_free(status);
 		}
 	}
@@ -1124,7 +1146,7 @@
 						char *mailto;
 						escaped = g_markup_escape_text(userid, -1);
 						mailto = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", escaped, escaped);
-						purple_notify_user_info_add_pair(user_info, _("Email"), mailto);
+						purple_notify_user_info_add_pair_html(user_info, _("Email"), mailto);
 
 						g_free(mailto);
 						g_free(escaped);
@@ -1137,7 +1159,7 @@
 
 					escaped = g_markup_escape_text(userid, -1);
 					mailto = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", escaped, escaped);
-					purple_notify_user_info_add_pair(user_info, _("Email"), mailto);
+					purple_notify_user_info_add_pair_html(user_info, _("Email"), mailto);
 
 					g_free(mailto);
 					g_free(escaped);
@@ -1184,7 +1206,7 @@
 						jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png")));
 						img_text = g_strdup_printf("<img id='%d'>", GPOINTER_TO_INT(jbi->vcard_imgids->data));
 
-						purple_notify_user_info_add_pair(user_info, (photo ? _("Photo") : _("Logo")), img_text);
+						purple_notify_user_info_add_pair_html(user_info, (photo ? _("Photo") : _("Logo")), img_text);
 
 						hash = jabber_calculate_data_hash(data, size, "sha1");
 						purple_buddy_icons_set_for_user(account, bare_jid, data, size, hash);
--- a/libpurple/protocols/jabber/caps.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/caps.c	Sun Sep 11 04:19:01 2011 +0000
@@ -958,7 +958,7 @@
 		const char *prpl_id = purple_account_get_protocol_id(account);
 		if (g_str_equal("prpl-jabber", prpl_id) && purple_account_is_connected(account)) {
 			PurpleConnection *gc = purple_account_get_connection(account);
-			jabber_presence_send(gc->proto_data, TRUE);
+			jabber_presence_send(purple_connection_get_protocol_data(gc), TRUE);
 		}
 	}
 
--- a/libpurple/protocols/jabber/chat.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/chat.c	Sun Sep 11 04:19:01 2011 +0000
@@ -70,7 +70,7 @@
 GHashTable *jabber_chat_info_defaults(PurpleConnection *gc, const char *chat_name)
 {
 	GHashTable *defaults;
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 
 	defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
 
@@ -146,7 +146,7 @@
 	int id;
 	if (!gc)
 		return NULL;
-	js = gc->proto_data;
+	js = purple_connection_get_protocol_data(gc);
 	id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
 	return jabber_chat_find_by_id(js, id);
 }
@@ -154,7 +154,7 @@
 void jabber_chat_invite(PurpleConnection *gc, int id, const char *msg,
 		const char *name)
 {
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	JabberChat *chat;
 	xmlnode *message, *body, *x, *invite;
 	char *room_jid;
@@ -360,7 +360,7 @@
 {
 	char *room, *server, *handle, *passwd;
 	JabberID *jid;
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	char *tmp;
 
 	room = g_hash_table_lookup(data, "room");
@@ -418,10 +418,9 @@
 
 void jabber_chat_leave(PurpleConnection *gc, int id)
 {
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	JabberChat *chat = jabber_chat_find_by_id(js, id);
 
-
 	if(!chat)
 		return;
 
@@ -459,7 +458,7 @@
 
 char *jabber_chat_buddy_real_name(PurpleConnection *gc, int id, const char *who)
 {
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	JabberChat *chat;
 	JabberChatMember *jcm;
 
@@ -887,13 +886,13 @@
 
 char *jabber_roomlist_room_serialize(PurpleRoomlistRoom *room)
 {
-
-	return g_strdup_printf("%s@%s", (char*)room->fields->data, (char*)room->fields->next->data);
+	GList *fields = purple_roomlist_room_get_fields(room);
+	return g_strdup_printf("%s@%s", (char*)fields->data, (char*)fields->next->data);
 }
 
 PurpleRoomlist *jabber_roomlist_get_list(PurpleConnection *gc)
 {
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	GList *fields = NULL;
 	PurpleRoomlistField *f;
 
@@ -928,11 +927,13 @@
 
 void jabber_roomlist_cancel(PurpleRoomlist *list)
 {
+	PurpleAccount *account;
 	PurpleConnection *gc;
 	JabberStream *js;
 
-	gc = purple_account_get_connection(list->account);
-	js = gc->proto_data;
+	account = purple_roomlist_get_account(list);
+	gc = purple_account_get_connection(account);
+	js = purple_connection_get_protocol_data(gc);
 
 	purple_roomlist_set_in_progress(list, FALSE);
 
--- a/libpurple/protocols/jabber/disco.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/disco.c	Sun Sep 11 04:19:01 2011 +0000
@@ -485,7 +485,7 @@
 			resp[0].hostname, resp[0].port);
 		account = purple_connection_get_account(js->gc);
 		js->stun_query =
-			purple_dnsquery_a_account(account, resp[0].hostname, resp[0].port,
+			purple_dnsquery_a(account, resp[0].hostname, resp[0].port,
 				jabber_disco_stun_lookup_cb, js);
 	}
 }
@@ -550,7 +550,7 @@
 		} else if (purple_network_get_stun_ip() == NULL ||
 		    purple_strequal(purple_network_get_stun_ip(), "")) {
 			js->srv_query_data =
-				purple_srv_resolve_account(
+				purple_srv_resolve(
 					purple_connection_get_account(js->gc), "stun", "udp",
 					js->user->domain,
 					jabber_disco_stun_srv_resolve_cb, js);
--- a/libpurple/protocols/jabber/google/jingleinfo.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/google/jingleinfo.c	Sun Sep 11 04:19:01 2011 +0000
@@ -117,7 +117,7 @@
 					purple_dnsquery_destroy(js->stun_query);
 
 				account = purple_connection_get_account(js->gc);
-				js->stun_query = purple_dnsquery_a_account(account, host, port,
+				js->stun_query = purple_dnsquery_a(account, host, port,
 					jabber_google_stun_lookup_cb, js);
 			}
 		}
--- a/libpurple/protocols/jabber/jabber.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Sun Sep 11 04:19:01 2011 +0000
@@ -119,7 +119,7 @@
 		if(js->unregistration)
 			jabber_unregister_account_cb(js);
 	} else {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			("Error initializing session"));
 	}
@@ -153,7 +153,7 @@
 
 			js->user = jabber_id_new(full_jid);
 			if (js->user == NULL) {
-				purple_connection_error_reason(js->gc,
+				purple_connection_error(js->gc,
 					PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 					_("Invalid response from server"));
 				g_free(full_jid);
@@ -170,7 +170,7 @@
 	} else {
 		PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
 		char *msg = jabber_parse_error(js, packet, &reason);
-		purple_connection_error_reason(js->gc, reason, msg);
+		purple_connection_error(js->gc, reason, msg);
 		g_free(msg);
 
 		return;
@@ -247,14 +247,14 @@
 
 	starttls = xmlnode_get_child(packet, "starttls");
 	if(xmlnode_get_child(starttls, "required")) {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 				PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 				_("Server requires TLS/SSL, but no TLS/SSL support was found."));
 		return TRUE;
 	}
 
 	if (g_str_equal("require_tls", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 				PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 				_("You require encryption, but no TLS/SSL support was found."));
 		return TRUE;
@@ -275,7 +275,7 @@
 			return;
 		}
 	} else if (g_str_equal(connection_security, "require_tls") && !jabber_stream_is_ssl(js)) {
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 			 PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
 			_("You require encryption, but it is not available on this server."));
 		return;
@@ -320,7 +320,7 @@
 	PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
 	char *msg = jabber_parse_error(js, packet, &reason);
 
-	purple_connection_error_reason(js->gc, reason, msg);
+	purple_connection_error(js->gc, reason, msg);
 
 	g_free(msg);
 }
@@ -407,7 +407,7 @@
 	else if (ret <= 0) {
 		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
 				g_strerror(errno));
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
@@ -443,7 +443,7 @@
 		if (!account->disconnecting) {
 			gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
 					g_strerror(errno));
-			purple_connection_error_reason(js->gc,
+			purple_connection_error(js->gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 			g_free(tmp);
 		}
@@ -544,7 +544,7 @@
 				purple_debug_error("jabber",
 					"sasl_encode error %d: %s\n", rc,
 					sasl_errdetail(js->sasl));
-				purple_connection_error_reason(gc,
+				purple_connection_error(gc,
 					PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 					error);
 				g_free(error);
@@ -616,8 +616,8 @@
 
 static gboolean jabber_keepalive_timeout(PurpleConnection *gc)
 {
-	JabberStream *js = gc->proto_data;
-	purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+	JabberStream *js = purple_connection_get_protocol_data(gc);
+	purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 					_("Ping timed out"));
 	js->keepalive_timeout = 0;
 	return FALSE;
@@ -642,7 +642,7 @@
 		PurpleInputCondition cond)
 {
 	PurpleConnection *gc = data;
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	int len;
 	static char buf[4096];
 
@@ -670,7 +670,7 @@
 		else
 			tmp = g_strdup_printf(_("Lost connection with server: %s"),
 					g_strerror(errno));
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 	}
@@ -702,7 +702,7 @@
 				purple_debug_error("jabber",
 					"sasl_decode_error %d: %s\n", rc,
 					sasl_errdetail(js->sasl));
-				purple_connection_error_reason(gc,
+				purple_connection_error(gc,
 					PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 					error);
 			} else if (olen > 0) {
@@ -728,7 +728,7 @@
 		else
 			tmp = g_strdup_printf(_("Lost connection with server: %s"),
 					g_strerror(errno));
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 	}
@@ -747,7 +747,7 @@
 		g_return_if_reached();
 	}
 
-	js = gc->proto_data;
+	js = purple_connection_get_protocol_data(gc);
 
 	if(js->state == JABBER_STREAM_CONNECTING)
 		jabber_send_raw(js, "<?xml version='1.0' ?>", -1);
@@ -789,7 +789,7 @@
 	if (!found) {
 		purple_debug_warning("jabber", "Unable to find alternative XMPP connection "
 				  "methods after failing to connect directly.\n");
-		purple_connection_error_reason(js->gc,
+		purple_connection_error(js->gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Unable to connect"));
 		return;
@@ -813,7 +813,7 @@
 			try_srv_connect(js);
 		} else {
 			purple_debug_info("jabber","Couldn't connect directly to %s.  Trying to find alternative connection methods, like BOSH.\n", js->user->domain);
-			js->srv_query_data = purple_txt_resolve_account(
+			js->srv_query_data = purple_txt_resolve(
 					purple_connection_get_account(gc), "_xmppconnect",
 					js->user->domain, txt_resolved_cb, js);
 		}
@@ -842,7 +842,7 @@
 	/* If the connection is already disconnected, we don't need to do anything else */
 	g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
 
-	js = gc->proto_data;
+	js = purple_connection_get_protocol_data(gc);
 	js->gsc = NULL;
 
 	purple_connection_ssl_error (gc, error);
@@ -874,7 +874,7 @@
 	if (purple_proxy_connect(js->gc, purple_connection_get_account(js->gc),
 			host, port, jabber_login_callback, js->gc) == NULL) {
 		if (fatal_failure) {
-			purple_connection_error_reason(js->gc,
+			purple_connection_error(js->gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Unable to connect"));
 		}
@@ -928,7 +928,8 @@
 	gchar *user;
 	gchar *slash;
 
-	js = gc->proto_data = g_new0(JabberStream, 1);
+	js = g_new0(JabberStream, 1);
+	purple_connection_set_protocol_data(gc, js);
 	js->gc = gc;
 	js->fd = -1;
 
@@ -940,7 +941,7 @@
 	js->user = jabber_id_new(user);
 
 	if (!js->user) {
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 			_("Invalid XMPP ID"));
 		g_free(user);
@@ -949,7 +950,7 @@
 	}
 
 	if (!js->user->node || *(js->user->node) == '\0') {
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 			_("Invalid XMPP ID. Username portion must be set."));
 		g_free(user);
@@ -958,7 +959,7 @@
 	}
 
 	if (!js->user->domain || *(js->user->domain) == '\0') {
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 			_("Invalid XMPP ID. Domain must be set."));
 		g_free(user);
@@ -978,7 +979,7 @@
 	g_free(user);
 	if (!js->user_jb) {
 		/* This basically *can't* fail, but for good measure... */
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 			_("Invalid XMPP ID"));
 		/* Destroying the connection will free the JabberStream */
@@ -1037,7 +1038,7 @@
 		if (js->bosh)
 			jabber_bosh_connection_connect(js->bosh);
 		else {
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 				_("Malformed BOSH URL"));
 		}
@@ -1054,12 +1055,12 @@
 					purple_account_get_int(account, "port", 5223),
 					jabber_login_callback_ssl, jabber_ssl_connect_failure, gc);
 			if (!js->gsc) {
-				purple_connection_error_reason(gc,
+				purple_connection_error(gc,
 					PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 					_("Unable to establish SSL connection"));
 			}
 		} else {
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 				_("SSL support unavailable"));
 		}
@@ -1073,7 +1074,7 @@
 		jabber_login_connect(js, js->user->domain, connect_server,
 				purple_account_get_int(account, "port", 5222), TRUE);
 	} else {
-		js->srv_query_data = purple_srv_resolve_account(account, "xmpp-client",
+		js->srv_query_data = purple_srv_resolve(account, "xmpp-client",
 				"tcp", js->user->domain, srv_resolved_cb, js);
 	}
 }
@@ -1559,14 +1560,14 @@
 	if(gc->state != PURPLE_CONNECTED) {
 		if(gc->state != PURPLE_CONNECTING)
 			jabber_login(account);
-		js = gc->proto_data;
+		js = purple_connection_get_protocol_data(gc);
 		js->unregistration = TRUE;
 		js->unregistration_cb = cb;
 		js->unregistration_user_data = user_data;
 		return;
 	}
 
-	js = gc->proto_data;
+	js = purple_connection_get_protocol_data(gc);
 
 	if (js->unregistration) {
 		purple_debug_error("jabber", "Unregistration in process; ignoring duplicate request.\n");
@@ -1598,7 +1599,7 @@
 		jabber_send_raw(js, "</stream:stream>", -1);
 
 	if (js->srv_query_data)
-		purple_srv_cancel(js->srv_query_data);
+		purple_srv_txt_query_destroy(js->srv_query_data);
 
 	if(js->gsc) {
 		purple_ssl_close(js->gsc);
@@ -1726,7 +1727,7 @@
 
 	g_free(js);
 
-	gc->proto_data = NULL;
+	purple_connection_set_protocol_data(gc, NULL);
 }
 
 void jabber_stream_set_state(JabberStream *js, JabberStreamState state)
@@ -1780,7 +1781,7 @@
 
 void jabber_idle_set(PurpleConnection *gc, int idle)
 {
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 
 	js->idle = idle ? time(NULL) - idle : idle;
 
@@ -2133,7 +2134,7 @@
 	if(!gc)
 		return NULL;
 
-	js = gc->proto_data;
+	js = purple_connection_get_protocol_data(gc);
 	if(js)
 		jb = jabber_buddy_find(js, purple_buddy_get_name(b), FALSE);
 
@@ -2174,8 +2175,8 @@
 	PurpleAccount *account = purple_buddy_get_account(b);
 	PurpleConnection *gc = purple_account_get_connection(account);
 
-	if (gc && gc->proto_data)
-		jb = jabber_buddy_find(gc->proto_data, purple_buddy_get_name(b), FALSE);
+	if (gc && purple_connection_get_protocol_data(gc))
+		jb = jabber_buddy_find(purple_connection_get_protocol_data(gc), purple_buddy_get_name(b), FALSE);
 
 	if(jb && !PURPLE_BUDDY_IS_ONLINE(b) && (jb->subscription & JABBER_SUB_PENDING || !(jb->subscription & JABBER_SUB_TO))) {
 		ret = g_strdup(_("Not Authorized"));
@@ -2225,7 +2226,7 @@
 	label = g_strdup_printf("%s%s", _("Status"), (res ? res : ""));
 	value = g_strdup_printf("%s%s%s", state, (text ? ": " : ""), (text ? text : ""));
 
-	purple_notify_user_info_add_pair(user_info, label, value);
+	purple_notify_user_info_add_pair_html(user_info, label, value);
 	g_free(label);
 	g_free(value);
 	g_free(text);
@@ -2238,7 +2239,7 @@
 		gchar *idle_str =
 			purple_str_seconds_to_string(time(NULL) - jbr->idle);
 		label = g_strdup_printf("%s%s", _("Idle"), (res ? res : ""));
-		purple_notify_user_info_add_pair(user_info, label, idle_str);
+		purple_notify_user_info_add_pair_plaintext(user_info, label, idle_str);
 		g_free(idle_str);
 		g_free(label);
 	}
@@ -2250,6 +2251,7 @@
 	JabberBuddy *jb;
 	PurpleAccount *account;
 	PurpleConnection *gc;
+	JabberStream *js;
 
 	g_return_if_fail(b != NULL);
 
@@ -2258,9 +2260,11 @@
 
 	gc = purple_account_get_connection(account);
 	g_return_if_fail(gc != NULL);
-	g_return_if_fail(gc->proto_data != NULL);
-
-	jb = jabber_buddy_find(gc->proto_data, purple_buddy_get_name(b), FALSE);
+
+	js = purple_connection_get_protocol_data(gc);
+	g_return_if_fail(js != NULL);
+
+	jb = jabber_buddy_find(js, purple_buddy_get_name(b), FALSE);
 
 	if(jb) {
 		JabberBuddyResource *jbr = NULL;
@@ -2310,10 +2314,10 @@
 					char *moodplustext =
 						g_strdup_printf("%s (%s)", description ? _(description) : mood, moodtext);
 
-					purple_notify_user_info_add_pair(user_info, _("Mood"), moodplustext);
+					purple_notify_user_info_add_pair_html(user_info, _("Mood"), moodplustext);
 					g_free(moodplustext);
 				} else
-					purple_notify_user_info_add_pair(user_info, _("Mood"),
+					purple_notify_user_info_add_pair_html(user_info, _("Mood"),
 					    description ? _(description) : mood);
 			}
 			if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) {
@@ -2323,7 +2327,7 @@
 				const char *album = purple_status_get_attr_string(tune, PURPLE_TUNE_ALBUM);
 				char *playing = purple_util_format_song_info(title, artist, album, NULL);
 				if (playing) {
-					purple_notify_user_info_add_pair(user_info, _("Now Listening"), playing);
+					purple_notify_user_info_add_pair_html(user_info, _("Now Listening"), playing);
 					g_free(playing);
 				}
 			}
@@ -2344,12 +2348,12 @@
 					sub = _("None");
 			}
 
-			purple_notify_user_info_add_pair(user_info, _("Subscription"), sub);
+			purple_notify_user_info_add_pair_html(user_info, _("Subscription"), sub);
 
 		}
 
 		if(!PURPLE_BUDDY_IS_ONLINE(b) && jb->error_msg) {
-			purple_notify_user_info_add_pair(user_info, _("Error"), jb->error_msg);
+			purple_notify_user_info_add_pair_html(user_info, _("Error"), jb->error_msg);
 		}
 	}
 }
@@ -2531,7 +2535,7 @@
 {
 
 	PurpleConnection *gc = (PurpleConnection *) action->context;
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	PurpleRequestFields *fields;
 	PurpleRequestFieldGroup *group;
 	PurpleRequestField *field;
@@ -2563,7 +2567,7 @@
 GList *jabber_actions(PurplePlugin *plugin, gpointer context)
 {
 	PurpleConnection *gc = (PurpleConnection *) context;
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	GList *m = NULL;
 	PurplePluginAction *act;
 
@@ -2634,7 +2638,7 @@
 
 void jabber_convo_closed(PurpleConnection *gc, const char *who)
 {
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	JabberID *jid;
 	JabberBuddy *jb;
 	JabberBuddyResource *jbr;
@@ -3159,7 +3163,7 @@
 static PurpleCmdRet jabber_cmd_buzz(PurpleConversation *conv,
 		const char *cmd, char **args, char **error, void *data)
 {
-	JabberStream *js = conv->account->gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(conv->account->gc);
 	const gchar *who;
 	gchar *description;
 	PurpleBuddy *buddy;
@@ -3206,7 +3210,7 @@
 
 gboolean jabber_send_attention(PurpleConnection *gc, const char *username, guint code)
 {
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	gchar *error = NULL;
 
 	if (!_jabber_send_buzz(js, username, &error)) {
@@ -3289,8 +3293,8 @@
 		      PurpleMediaSessionType type)
 {
 #ifdef USE_VV
-	JabberStream *js = (JabberStream *)
-			purple_account_get_connection(account)->proto_data;
+	PurpleConnection *gc = purple_account_get_connection(account);
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	JabberBuddy *jb;
 	JabberBuddyResource *jbr = NULL;
 	char *resource;
@@ -3301,7 +3305,6 @@
 		return FALSE;
 	}
 
-
 	if((resource = jabber_get_resource(who)) != NULL) {
 		/* they've specified a resource, no need to ask or
 		 * default or anything, just do it */
@@ -3432,8 +3435,8 @@
 PurpleMediaCaps jabber_get_media_caps(PurpleAccount *account, const char *who)
 {
 #ifdef USE_VV
-	JabberStream *js = (JabberStream *)
-			purple_account_get_connection(account)->proto_data;
+	PurpleConnection *gc = purple_account_get_connection(account);
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	JabberBuddy *jb;
 	JabberBuddyResource *jbr;
 	PurpleMediaCaps total = PURPLE_MEDIA_CAPS_NONE;
@@ -3521,7 +3524,7 @@
 
 gboolean jabber_can_receive_file(PurpleConnection *gc, const char *who)
 {
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 
 	if (js) {
 		JabberBuddy *jb = jabber_buddy_find(js, who, FALSE);
@@ -3571,7 +3574,7 @@
 jabber_cmd_mood(PurpleConversation *conv,
 		const char *cmd, char **args, char **error, void *data)
 {
-	JabberStream *js = conv->account->gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(conv->account->gc);
 
 	if (js->pep) {
 		/* if no argument was given, unset mood */
@@ -3755,7 +3758,7 @@
 
 	if (!purple_account_is_connected(account))
 		return FALSE;
-	js = gc->proto_data;
+	js = purple_connection_get_protocol_data(gc);
 
 	if (!(resource = jabber_get_resource(jid)) ||
 	    !(jb = jabber_buddy_find(js, jid, FALSE)) ||
--- a/libpurple/protocols/jabber/jutil.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/jutil.c	Sun Sep 11 04:19:01 2011 +0000
@@ -583,11 +583,16 @@
 
 const char *jabber_normalize(const PurpleAccount *account, const char *in)
 {
-	PurpleConnection *gc = account ? account->gc : NULL;
-	JabberStream *js = gc ? gc->proto_data : NULL;
+	PurpleConnection *gc = NULL;
+	JabberStream *js = NULL;
 	static char buf[3072]; /* maximum legal length of a jabber jid */
 	JabberID *jid;
 
+	if (account)
+		gc = purple_account_get_connection(account);
+	if (gc)
+		js = purple_connection_get_protocol_data(gc);
+
 	jid = jabber_id_new_internal(in, TRUE);
 	if(!jid)
 		return NULL;
--- a/libpurple/protocols/jabber/libxmpp.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/libxmpp.c	Sun Sep 11 04:19:01 2011 +0000
@@ -53,6 +53,7 @@
 
 static PurplePluginProtocolInfo prpl_info =
 {
+	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_MAIL_CHECK |
 #ifdef HAVE_CYRUS_SASL
 	OPT_PROTO_PASSWORD_OPTIONAL |
@@ -122,16 +123,12 @@
 	jabber_unregister_account,		/* unregister_user */
 	jabber_send_attention,			/* send_attention */
 	jabber_attention_types,			/* attention_types */
-
-	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	NULL, /* get_account_text_table */
 	jabber_initiate_media,          /* initiate_media */
 	jabber_get_media_caps,                  /* get_media_caps */
 	jabber_get_moods,  							/* get_moods */
 	NULL, /* set_public_alias */
-	NULL, /* get_public_alias */
-	NULL, /* add_buddy_with_invite */
-	NULL  /* add_buddies_with_invite */
+	NULL  /* get_public_alias */
 };
 
 static gboolean load_plugin(PurplePlugin *plugin)
--- a/libpurple/protocols/jabber/message.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/message.c	Sun Sep 11 04:19:01 2011 +0000
@@ -638,6 +638,8 @@
 					jabber_message_add_remote_smileys(js, to, packet);
 				}
 
+				xmlnode_strip_prefixes(child);
+
 				/* reformat xhtml so that img tags with a "cid:" src gets
 				  translated to the bare text of the emoticon (the "alt" attrib) */
 				/* this is done also when custom smiley retrieval is turned off,
@@ -1148,13 +1150,13 @@
 
 	resource = jabber_get_resource(who);
 
-	jb = jabber_buddy_find(gc->proto_data, who, TRUE);
+	jb = jabber_buddy_find(purple_connection_get_protocol_data(gc), who, TRUE);
 	jbr = jabber_buddy_find_resource(jb, resource);
 
 	g_free(resource);
 
 	jm = g_new0(JabberMessage, 1);
-	jm->js = gc->proto_data;
+	jm->js = purple_connection_get_protocol_data(gc);
 	jm->type = JABBER_MESSAGE_CHAT;
 	jm->chat_state = JM_STATE_ACTIVE;
 	jm->to = g_strdup(who);
@@ -1211,14 +1213,14 @@
 	if(!msg || !gc)
 		return 0;
 
-	js = gc->proto_data;
+	js = purple_connection_get_protocol_data(gc);
 	chat = jabber_chat_find_by_id(js, id);
 
 	if(!chat)
 		return 0;
 
 	jm = g_new0(JabberMessage, 1);
-	jm->js = gc->proto_data;
+	jm->js = purple_connection_get_protocol_data(gc);
 	jm->type = JABBER_MESSAGE_GROUPCHAT;
 	jm->to = g_strdup_printf("%s@%s", chat->room, chat->server);
 	jm->id = jabber_get_next_id(jm->js);
--- a/libpurple/protocols/jabber/oob.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/oob.c	Sun Sep 11 04:19:01 2011 +0000
@@ -48,13 +48,13 @@
 
 static void jabber_oob_xfer_init(PurpleXfer *xfer)
 {
-	JabberOOBXfer *jox = xfer->data;
+	JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
 	purple_xfer_start(xfer, -1, jox->address, jox->port);
 }
 
 static void jabber_oob_xfer_free(PurpleXfer *xfer)
 {
-	JabberOOBXfer *jox = xfer->data;
+	JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
 	jox->js->oob_file_transfers = g_list_remove(jox->js->oob_file_transfers,
 			xfer);
 
@@ -67,16 +67,16 @@
 		purple_input_remove(jox->writeh);
 	g_free(jox);
 
-	xfer->data = NULL;
+	purple_xfer_set_protocol_data(xfer, NULL);
 }
 
 static void jabber_oob_xfer_end(PurpleXfer *xfer)
 {
-	JabberOOBXfer *jox = xfer->data;
+	JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
 	JabberIq *iq;
 
 	iq = jabber_iq_new(jox->js, JABBER_IQ_RESULT);
-	xmlnode_set_attrib(iq->node, "to", xfer->who);
+	xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
 	jabber_iq_set_id(iq, jox->iq_id);
 
 	jabber_iq_send(iq);
@@ -86,10 +86,10 @@
 
 static void jabber_oob_xfer_request_send(gpointer data, gint source, PurpleInputCondition cond) {
 	PurpleXfer *xfer = data;
-	JabberOOBXfer *jox = xfer->data;
+	JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
 	int len, total_len = strlen(jox->write_buffer);
 
-	len = write(xfer->fd, jox->write_buffer + jox->written_len,
+	len = purple_xfer_write(xfer, (guchar*) jox->write_buffer + jox->written_len,
 		total_len - jox->written_len);
 
 	if(len < 0 && errno == EAGAIN)
@@ -110,7 +110,7 @@
 
 static void jabber_oob_xfer_start(PurpleXfer *xfer)
 {
-	JabberOOBXfer *jox = xfer->data;
+	JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
 
 	if(jox->write_buffer == NULL) {
 		jox->write_buffer = g_strdup_printf(
@@ -126,7 +126,7 @@
 }
 
 static gssize jabber_oob_xfer_read(guchar **buffer, PurpleXfer *xfer) {
-	JabberOOBXfer *jox = xfer->data;
+	JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
 	char test[2048];
 	char *tmp, *lenstr;
 	int len;
@@ -158,12 +158,12 @@
 }
 
 static void jabber_oob_xfer_recv_error(PurpleXfer *xfer, const char *code) {
-	JabberOOBXfer *jox = xfer->data;
+	JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
 	JabberIq *iq;
 	xmlnode *y, *z;
 
 	iq = jabber_iq_new(jox->js, JABBER_IQ_ERROR);
-	xmlnode_set_attrib(iq->node, "to", xfer->who);
+	xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
 	jabber_iq_set_id(iq, jox->iq_id);
 	y = xmlnode_new_child(iq->node, "error");
 	xmlnode_set_attrib(y, "code", code);
@@ -221,7 +221,7 @@
 	xfer = purple_xfer_new(js->gc->account, PURPLE_XFER_RECEIVE, from);
 	if (xfer)
 	{
-		xfer->data = jox;
+		purple_xfer_set_protocol_data(xfer, jox);
 
 		if(!(filename = g_strdup(g_strrstr(jox->page, "/"))))
 			filename = g_strdup(jox->page);
--- a/libpurple/protocols/jabber/parser.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/parser.c	Sun Sep 11 04:19:01 2011 +0000
@@ -52,7 +52,7 @@
 			 */
 			purple_debug_error("jabber", "Expecting stream header, got %s with "
 			                   "xmlns %s\n", element_name, namespace);
-			purple_connection_error_reason(js->gc,
+			purple_connection_error(js->gc,
 					PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
 					_("XMPP stream header missing"));
 			return;
@@ -73,7 +73,7 @@
 
 				if (js->protocol_version.major > 1) {
 					/* TODO: Send <unsupported-version/> error */
-					purple_connection_error_reason(js->gc,
+					purple_connection_error(js->gc,
 							PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
 							_("XMPP Version Mismatch"));
 					g_free(attrib);
@@ -98,7 +98,7 @@
 			/* This was underspecified in rfc3920 as only being a SHOULD, so
 			 * we cannot rely on it.  See #12331 and Oracle's server.
 			 */
-			purple_connection_error_reason(js->gc,
+			purple_connection_error(js->gc,
 					PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
 					_("XMPP stream missing ID"));
 #else
@@ -300,7 +300,7 @@
 				break;
 			case XML_ERR_FATAL:
 				purple_debug_error("jabber", "xmlParseChunk returned fatal %i\n", ret);
-				purple_connection_error_reason (js->gc,
+				purple_connection_error (js->gc,
 				                                PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				                                _("XML Parse error"));
 				break;
--- a/libpurple/protocols/jabber/presence.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/presence.c	Sun Sep 11 04:19:01 2011 +0000
@@ -393,7 +393,7 @@
 {
 	struct _jabber_add_permit *jap = data;
 	if(PURPLE_CONNECTION_IS_VALID(jap->gc))
-		jabber_presence_subscription_set(jap->gc->proto_data,
+		jabber_presence_subscription_set(purple_connection_get_protocol_data(jap->gc),
 			jap->who, "subscribed");
 	g_free(jap->who);
 	g_free(jap);
@@ -403,7 +403,7 @@
 {
 	struct _jabber_add_permit *jap = data;
 	if(PURPLE_CONNECTION_IS_VALID(jap->gc))
-		jabber_presence_subscription_set(jap->gc->proto_data,
+		jabber_presence_subscription_set(purple_connection_get_protocol_data(jap->gc),
 			jap->who, "unsubscribed");
 	g_free(jap->who);
 	g_free(jap);
--- a/libpurple/protocols/jabber/roster.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/roster.c	Sun Sep 11 04:19:01 2011 +0000
@@ -358,9 +358,9 @@
 }
 
 void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
-		PurpleGroup *group)
+		PurpleGroup *group, const char *message)
 {
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 	char *who;
 	JabberID *jid;
 	JabberBuddy *jb;
@@ -431,7 +431,7 @@
 		purple_debug_info("jabber", "jabber_roster_alias_change(): Aliased %s to %s\n",
 				name, alias ? alias : "(null)");
 
-		jabber_roster_update(gc->proto_data, name, NULL);
+		jabber_roster_update(purple_connection_get_protocol_data(gc), name, NULL);
 	}
 }
 
@@ -461,7 +461,7 @@
 	purple_debug_info("jabber", "jabber_roster_group_change(): Moving %s from %s to %s\n",
 	                  name, old_group, new_group);
 
-	jabber_roster_update(gc->proto_data, name, groups);
+	jabber_roster_update(purple_connection_get_protocol_data(gc), name, groups);
 }
 
 void jabber_roster_group_rename(PurpleConnection *gc, const char *old_name,
@@ -496,9 +496,9 @@
 		purple_debug_info("jabber", "jabber_roster_remove_buddy(): Removing %s from %s\n",
 		                  purple_buddy_get_name(buddy), purple_group_get_name(group));
 
-		jabber_roster_update(gc->proto_data, name, groups);
+		jabber_roster_update(purple_connection_get_protocol_data(gc), name, groups);
 	} else {
-		JabberIq *iq = jabber_iq_new_query(gc->proto_data, JABBER_IQ_SET,
+		JabberIq *iq = jabber_iq_new_query(purple_connection_get_protocol_data(gc), JABBER_IQ_SET,
 				"jabber:iq:roster");
 		xmlnode *query = xmlnode_get_child(iq->node, "query");
 		xmlnode *item = xmlnode_new_child(query, "item");
--- a/libpurple/protocols/jabber/roster.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/roster.h	Sun Sep 11 04:19:01 2011 +0000
@@ -32,7 +32,7 @@
                          JabberIqType type, const char *id, xmlnode *query);
 
 void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
-		PurpleGroup *group);
+		PurpleGroup *group, const char *message);
 void jabber_roster_alias_change(PurpleConnection *gc, const char *name,
 		const char *alias);
 void jabber_roster_group_change(PurpleConnection *gc, const char *name,
--- a/libpurple/protocols/jabber/si.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/si.c	Sun Sep 11 04:19:01 2011 +0000
@@ -87,9 +87,9 @@
 
 	for(xfers = js->file_transfers; xfers; xfers = xfers->next) {
 		PurpleXfer *xfer = xfers->data;
-		JabberSIXfer *jsx = xfer->data;
-		if(jsx->stream_id && xfer->who &&
-				!strcmp(jsx->stream_id, sid) && !strcmp(xfer->who, from))
+		JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
+		if(jsx->stream_id && purple_xfer_get_remote_user(xfer) &&
+				!strcmp(jsx->stream_id, sid) && !strcmp(purple_xfer_get_remote_user(xfer), from))
 			return xfer;
 	}
 
@@ -118,7 +118,7 @@
 jabber_si_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message)
 {
 	PurpleXfer *xfer = data;
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	JabberIq *iq;
 	xmlnode *query, *su;
 	JabberBytestreamsStreamhost *streamhost = jsx->streamhosts->data;
@@ -143,7 +143,7 @@
 	}
 
 	/* unknown file transfer type is assumed to be RECEIVE */
-	if(xfer->type == PURPLE_XFER_SEND)
+	if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND)
 	{
 		xmlnode *activate;
 		iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, NS_BYTESTREAMS);
@@ -151,14 +151,14 @@
 		query = xmlnode_get_child(iq->node, "query");
 		xmlnode_set_attrib(query, "sid", jsx->stream_id);
 		activate = xmlnode_new_child(query, "activate");
-		xmlnode_insert_data(activate, xfer->who, -1);
+		xmlnode_insert_data(activate, purple_xfer_get_remote_user(xfer), -1);
 
 		/* TODO: We need to wait for an activation result before starting */
 	}
 	else
 	{
 		iq = jabber_iq_new_query(jsx->js, JABBER_IQ_RESULT, NS_BYTESTREAMS);
-		xmlnode_set_attrib(iq->node, "to", xfer->who);
+		xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
 		jabber_iq_set_id(iq, jsx->iq_id);
 		query = xmlnode_get_child(iq->node, "query");
 		su = xmlnode_new_child(query, "streamhost-used");
@@ -174,7 +174,7 @@
 connect_timeout_cb(gpointer data)
 {
 	PurpleXfer *xfer = data;
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 
 	purple_debug_info("jabber", "Streamhost connection timeout of %d seconds exceeded.\n", STREAMHOST_CONNECT_TIMEOUT);
 
@@ -203,7 +203,7 @@
 jabber_si_bytestreams_ibb_timeout_cb(gpointer data)
 {
 	PurpleXfer *xfer = (PurpleXfer *) data;
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 
 	if (jsx && !jsx->ibb_session) {
 		purple_debug_info("jabber",
@@ -218,7 +218,7 @@
 
 static void jabber_si_bytestreams_attempt_connect(PurpleXfer *xfer)
 {
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	JabberBytestreamsStreamhost *streamhost;
 	JabberID *dstjid;
 
@@ -229,7 +229,7 @@
 		if(jsx->iq_id)
 			jabber_iq_set_id(iq, jsx->iq_id);
 
-		xmlnode_set_attrib(iq->node, "to", xfer->who);
+		xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
 		error = xmlnode_new_child(iq->node, "error");
 		xmlnode_set_attrib(error, "code", "404");
 		xmlnode_set_attrib(error, "type", "cancel");
@@ -271,7 +271,7 @@
 		purple_proxy_info_destroy(jsx->gpi);
 	jsx->gpi = NULL;
 
-	dstjid = jabber_id_new(xfer->who);
+	dstjid = jabber_id_new(purple_xfer_get_remote_user(xfer));
 
 	/* TODO: Deal with zeroconf */
 
@@ -284,7 +284,7 @@
 		purple_proxy_info_set_port(jsx->gpi, streamhost->port);
 
 		/* unknown file transfer type is assumed to be RECEIVE */
-		if(xfer->type == PURPLE_XFER_SEND)
+		if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND)
 			dstaddr = g_strdup_printf("%s%s@%s/%s%s@%s/%s", jsx->stream_id, jsx->js->user->node, jsx->js->user->domain,
 				jsx->js->user->resource, dstjid->node, dstjid->domain, dstjid->resource);
 		else
@@ -302,7 +302,7 @@
 		g_free(dstaddr);
 
 		/* When selecting a streamhost, timeout after STREAMHOST_CONNECT_TIMEOUT seconds, otherwise it takes forever */
-		if (xfer->type != PURPLE_XFER_SEND && jsx->connect_data != NULL)
+		if (purple_xfer_get_type(xfer) != PURPLE_XFER_SEND && jsx->connect_data != NULL)
 			jsx->connect_timeout = purple_timeout_add_seconds(
 				STREAMHOST_CONNECT_TIMEOUT, connect_timeout_cb, xfer);
 
@@ -337,7 +337,7 @@
 	if(!(xfer = jabber_si_xfer_find(js, sid, from)))
 		return;
 
-	jsx = xfer->data;
+	jsx = purple_xfer_get_protocol_data(xfer);
 
 	if(!jsx->accepted)
 		return;
@@ -375,15 +375,13 @@
 		PurpleInputCondition cond)
 {
 	PurpleXfer *xfer = data;
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	int len;
 
 	len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen);
 	if (len < 0 && errno == EAGAIN)
 		return;
 	else if (len < 0) {
-		purple_input_remove(xfer->watcher);
-		xfer->watcher = 0;
 		g_free(jsx->rxqueue);
 		jsx->rxqueue = NULL;
 		close(source);
@@ -412,7 +410,7 @@
 		PurpleInputCondition cond)
 {
 	PurpleXfer *xfer = data;
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	char buffer[42]; /* 40 for DST.ADDR + 2 bytes for port number*/
 	int len;
 	char *dstaddr, *hash;
@@ -426,8 +424,6 @@
 		if(len < 0 && errno == EAGAIN)
 			return;
 		else if(len <= 0) {
-			purple_input_remove(xfer->watcher);
-			xfer->watcher = 0;
 			close(source);
 			purple_xfer_cancel_remote(xfer);
 			return;
@@ -441,8 +437,6 @@
 		purple_debug_info("jabber", "Invalid socks5 conn req. header[0x%x,0x%x,0x%x,0x%x,0x%x]\n",
 				  jsx->rxqueue[0], jsx->rxqueue[1], jsx->rxqueue[2],
 				  jsx->rxqueue[3], jsx->rxqueue[4]);
-		purple_input_remove(xfer->watcher);
-		xfer->watcher = 0;
 		close(source);
 		purple_xfer_cancel_remote(xfer);
 		return;
@@ -455,8 +449,6 @@
 		if(len < 0 && errno == EAGAIN)
 			return;
 		else if(len <= 0) {
-			purple_input_remove(xfer->watcher);
-			xfer->watcher = 0;
 			close(source);
 			purple_xfer_cancel_remote(xfer);
 			return;
@@ -475,7 +467,7 @@
 
 	dstaddr = g_strdup_printf("%s%s@%s/%s%s", jsx->stream_id,
 			jsx->js->user->node, jsx->js->user->domain,
-			jsx->js->user->resource, xfer->who);
+			jsx->js->user->resource, purple_xfer_get_remote_user(xfer));
 
 	/* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */
 	hash = jabber_calculate_data_hash(dstaddr, strlen(dstaddr), "sha1");
@@ -527,15 +519,13 @@
 		PurpleInputCondition cond)
 {
 	PurpleXfer *xfer = data;
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	int len;
 
 	len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen);
 	if (len < 0 && errno == EAGAIN)
 		return;
 	else if (len < 0) {
-		purple_input_remove(xfer->watcher);
-		xfer->watcher = 0;
 		g_free(jsx->rxqueue);
 		jsx->rxqueue = NULL;
 		close(source);
@@ -547,11 +537,9 @@
 	if (jsx->rxlen < jsx->rxmaxlen)
 		return;
 
-	purple_input_remove(xfer->watcher);
-	xfer->watcher = 0;
-
 	/* If we sent a "Success", wait for a response, otherwise give up and cancel */
 	if (jsx->rxqueue[1] == 0x00) {
+		purple_input_remove(xfer->watcher);
 		xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ,
 			jabber_si_xfer_bytestreams_send_read_again_cb, xfer);
 		g_free(jsx->rxqueue);
@@ -568,7 +556,7 @@
 		PurpleInputCondition cond)
 {
 	PurpleXfer *xfer = data;
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	int i;
 	int len;
 	char buffer[256];
@@ -584,9 +572,6 @@
 		if(len < 0 && errno == EAGAIN)
 			return;
 		else if(len <= 0) {
-			purple_input_remove(xfer->watcher);
-			xfer->watcher = 0;
-			close(source);
 			purple_xfer_cancel_remote(xfer);
 			return;
 		}
@@ -603,9 +588,6 @@
 		if(len < 0 && errno == EAGAIN)
 			return;
 		else if(len <= 0) {
-			purple_input_remove(xfer->watcher);
-			xfer->watcher = 0;
-			close(source);
 			purple_xfer_cancel_remote(xfer);
 			return;
 		}
@@ -618,13 +600,9 @@
 	if(jsx->rxlen -2 < jsx->rxqueue[1])
 		return;
 
-	purple_input_remove(xfer->watcher);
-	xfer->watcher = 0;
-
 	purple_debug_info("jabber", "checking to make sure we're socks FIVE\n");
 
 	if(jsx->rxqueue[0] != 0x05) {
-		close(source);
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
@@ -641,6 +619,7 @@
 			jsx->rxqueue = g_malloc(jsx->rxmaxlen);
 			jsx->rxqueue[0] = 0x05;
 			jsx->rxqueue[1] = 0x00;
+			purple_input_remove(xfer->watcher);
 			xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
 				jabber_si_xfer_bytestreams_send_read_response_cb,
 				xfer);
@@ -658,6 +637,7 @@
 	jsx->rxqueue = g_malloc(jsx->rxmaxlen);
 	jsx->rxqueue[0] = 0x05;
 	jsx->rxqueue[1] = 0xFF;
+	purple_input_remove(xfer->watcher);
 	xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
 		jabber_si_xfer_bytestreams_send_read_response_cb, xfer);
 	jabber_si_xfer_bytestreams_send_read_response_cb(xfer,
@@ -680,7 +660,7 @@
 		PurpleInputCondition cond)
 {
 	PurpleXfer *xfer = data;
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	int acceptfd, flags;
 
 	purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_connected_cb\n");
@@ -727,12 +707,12 @@
 		return;
 	}
 
+	jsx = purple_xfer_get_protocol_data(xfer);
+
 	/* In the case of a direct file transfer, this is expected to return */
-	if(!xfer->data)
+	if(!jsx)
 		return;
 
-	jsx = xfer->data;
-
 	if(type != JABBER_IQ_RESULT) {
 		purple_debug_info("jabber",
 			    "jabber_si_xfer_connect_proxy_cb: type = error\n");
@@ -835,7 +815,7 @@
 	JabberBytestreamsStreamhost *sh, *sh2;
 	int streamhost_count = 0;
 
-	jsx = xfer->data;
+	jsx = purple_xfer_get_protocol_data(xfer);
 	jsx->listen_data = NULL;
 
 	/* I'm not sure under which conditions this can happen
@@ -848,7 +828,7 @@
 	purple_xfer_unref(xfer);
 
 	iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, NS_BYTESTREAMS);
-	xmlnode_set_attrib(iq->node, "to", xfer->who);
+	xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
 	query = xmlnode_get_child(iq->node, "query");
 
 	xmlnode_set_attrib(query, "sid", jsx->stream_id);
@@ -866,7 +846,7 @@
 		jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node,
 			jsx->js->user->domain, jsx->js->user->resource);
 		xfer->local_port = purple_network_get_port_from_fd(sock);
-		g_snprintf(port, sizeof(port), "%hu", xfer->local_port);
+		g_snprintf(port, sizeof(port), "%hu", purple_xfer_get_local_port(xfer));
 
 		public_ip = purple_network_get_my_ip(jsx->js->fd);
 
@@ -969,7 +949,7 @@
 
 	purple_xfer_ref(xfer);
 
-	jsx = xfer->data;
+	jsx = purple_xfer_get_protocol_data(xfer);
 
 	/* TODO: This should probably be done with an account option instead of
 	 *       piggy-backing on the TOR proxy type. */
@@ -1017,7 +997,7 @@
 	gsize size)
 {
 	PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
-	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 
 	if (size <= purple_xfer_get_bytes_remaining(xfer)) {
 		purple_debug_info("jabber", "about to write %" G_GSIZE_FORMAT " bytes from IBB stream\n",
@@ -1037,7 +1017,7 @@
 static gssize
 jabber_si_xfer_ibb_read(guchar **out_buffer, PurpleXfer *xfer)
 {
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	guchar *buffer;
 	gsize size;
 	gsize tmp;
@@ -1060,7 +1040,7 @@
 	const gchar *sid = xmlnode_get_attrib(open, "sid");
 	PurpleXfer *xfer = jabber_si_xfer_find(js, sid, who);
 	if (xfer) {
-		JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+		JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 		JabberIBBSession *sess =
 			jabber_ibb_session_create_from_xmlnode(js, who, id, open, xfer);
 
@@ -1105,7 +1085,7 @@
 static gssize
 jabber_si_xfer_ibb_write(const guchar *buffer, size_t len, PurpleXfer *xfer)
 {
-	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	JabberIBBSession *sess = jsx->ibb_session;
 	gsize packet_size = len < jabber_ibb_session_get_max_data_size(sess) ?
 		len : jabber_ibb_session_get_max_data_size(sess);
@@ -1149,7 +1129,7 @@
 static void
 jabber_si_xfer_ibb_send_init(JabberStream *js, PurpleXfer *xfer)
 {
-	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 
 	jsx->ibb_session = jabber_ibb_session_create(js, jsx->stream_id,
 		purple_xfer_get_remote_user(xfer), xfer);
@@ -1206,7 +1186,7 @@
 
 	for(field = xmlnode_get_child(x, "field"); field; field = xmlnode_get_next_twin(field)) {
 		const char *var = xmlnode_get_attrib(field, "var");
-		JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+		JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 
 		if(var && !strcmp(var, "stream-method")) {
 			if((value = xmlnode_get_child(field, "value"))) {
@@ -1237,7 +1217,7 @@
 
 static void jabber_si_xfer_send_request(PurpleXfer *xfer)
 {
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	JabberIq *iq;
 	xmlnode *si, *file, *feature, *x, *field, *option, *value;
 	char buf[32];
@@ -1247,10 +1227,10 @@
 
 	purple_xfer_prepare_thumbnail(xfer, "jpeg,png");
 #endif
-	xfer->filename = g_path_get_basename(xfer->local_filename);
+	purple_xfer_set_filename(xfer, g_path_get_basename(purple_xfer_get_local_filename(xfer)));
 
 	iq = jabber_iq_new(jsx->js, JABBER_IQ_SET);
-	xmlnode_set_attrib(iq->node, "to", xfer->who);
+	xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
 	si = xmlnode_new_child(iq->node, "si");
 	xmlnode_set_namespace(si, "http://jabber.org/protocol/si");
 	jsx->stream_id = jabber_get_next_id(jsx->js);
@@ -1259,8 +1239,8 @@
 
 	file = xmlnode_new_child(si, "file");
 	xmlnode_set_namespace(file, NS_SI_FILE_TRANSFER);
-	xmlnode_set_attrib(file, "name", xfer->filename);
-	g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, xfer->size);
+	xmlnode_set_attrib(file, "name", purple_xfer_get_filename(xfer));
+	g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, purple_xfer_get_size(xfer));
 	xmlnode_set_attrib(file, "size", buf);
 	/* maybe later we'll do hash and date attribs */
 
@@ -1309,7 +1289,7 @@
 
 static void jabber_si_xfer_free(PurpleXfer *xfer)
 {
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 
 	if (jsx) {
 		JabberStream *js = jsx->js;
@@ -1324,8 +1304,7 @@
 			jabber_iq_remove_callback_by_id(js, jsx->iq_id);
 		if (jsx->local_streamhost_fd >= 0)
 			close(jsx->local_streamhost_fd);
-		if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND &&
-			xfer->fd >= 0) {
+		if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && xfer->fd >= 0) {
 			purple_debug_info("jabber", "remove port mapping\n");
 			purple_network_remove_port_mapping(xfer->fd);
 		}
@@ -1356,7 +1335,7 @@
 		/* XXX: free other stuff */
 		g_free(jsx->rxqueue);
 		g_free(jsx);
-		xfer->data = NULL;
+		purple_xfer_set_protocol_data(xfer, NULL);
 	}
 }
 
@@ -1367,7 +1346,7 @@
  */
 static void jabber_si_xfer_cancel_send(PurpleXfer *xfer)
 {
-	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 
 	/* if there is an IBB session active, send close on that */
 	if (jsx->ibb_session) {
@@ -1380,7 +1359,7 @@
 
 static void jabber_si_xfer_request_denied(PurpleXfer *xfer)
 {
-	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	JabberStream *js = jsx->js;
 
 	/*
@@ -1391,7 +1370,7 @@
 		JabberIq *iq;
 		xmlnode *error, *child;
 		iq = jabber_iq_new(js, JABBER_IQ_ERROR);
-		xmlnode_set_attrib(iq->node, "to", xfer->who);
+		xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
 		jabber_iq_set_id(iq, jsx->iq_id);
 
 		error = xmlnode_new_child(iq->node, "error");
@@ -1412,7 +1391,7 @@
 
 static void jabber_si_xfer_cancel_recv(PurpleXfer *xfer)
 {
-	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	/* if there is an IBB session active, send close */
 	if (jsx->ibb_session) {
 		jabber_ibb_session_close(jsx->ibb_session);
@@ -1432,7 +1411,7 @@
 		JabberCapabilities capabilities, gpointer data)
 {
 	PurpleXfer *xfer = (PurpleXfer *) data;
-	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 
 	if (capabilities & JABBER_CAP_IBB) {
 		purple_debug_info("jabber",
@@ -1458,8 +1437,8 @@
 
 static void do_transfer_send(PurpleXfer *xfer, const char *resource)
 {
-	JabberSIXfer *jsx = xfer->data;
-	char **who_v = g_strsplit(xfer->who, "/", 2);
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
+	char **who_v = g_strsplit(purple_xfer_get_remote_user(xfer), "/", 2);
 	char *who;
 	JabberBuddy *jb;
 	JabberBuddyResource *jbr = NULL;
@@ -1508,7 +1487,7 @@
 
 static void jabber_si_xfer_init(PurpleXfer *xfer)
 {
-	JabberSIXfer *jsx = xfer->data;
+	JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
 	JabberIq *iq;
 	if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
 		JabberBuddy *jb;
@@ -1516,7 +1495,7 @@
 		char *resource;
 		GList *resources = NULL;
 
-		if(NULL != (resource = jabber_get_resource(xfer->who))) {
+		if(NULL != (resource = jabber_get_resource(purple_xfer_get_remote_user(xfer)))) {
 			/* they've specified a resource, no need to ask or
 			 * default or anything, just do it */
 
@@ -1525,7 +1504,7 @@
 			return;
 		}
 
-		jb = jabber_buddy_find(jsx->js, xfer->who, TRUE);
+		jb = jabber_buddy_find(jsx->js, purple_xfer_get_remote_user(xfer), TRUE);
 
 		if (jb) {
 			GList *l;
@@ -1549,11 +1528,11 @@
 			char *msg;
 
 			if(!jb) {
-				msg = g_strdup_printf(_("Unable to send file to %s, invalid JID"), xfer->who);
+				msg = g_strdup_printf(_("Unable to send file to %s, invalid JID"), purple_xfer_get_remote_user(xfer));
 			} else if(jb->subscription & JABBER_SUB_TO) {
-				msg = g_strdup_printf(_("Unable to send file to %s, user is not online"), xfer->who);
+				msg = g_strdup_printf(_("Unable to send file to %s, user is not online"), purple_xfer_get_remote_user(xfer));
 			} else {
-				msg = g_strdup_printf(_("Unable to send file to %s, not subscribed to user presence"), xfer->who);
+				msg = g_strdup_printf(_("Unable to send file to %s, not subscribed to user presence"), purple_xfer_get_remote_user(xfer));
 			}
 
 			purple_notify_error(jsx->js->gc, _("File Send Failed"), _("File Send Failed"), msg);
@@ -1566,7 +1545,7 @@
 		} else {
 			/* we've got multiple resources, we need to pick one to send to */
 			GList *l;
-			char *msg = g_strdup_printf(_("Please select the resource of %s to which you would like to send a file"), xfer->who);
+			char *msg = g_strdup_printf(_("Please select the resource of %s to which you would like to send a file"), purple_xfer_get_remote_user(xfer));
 			PurpleRequestFields *fields = purple_request_fields_new();
 			PurpleRequestField *field = purple_request_field_choice_new("resource", _("Resource"), 0);
 			PurpleRequestFieldGroup *group = purple_request_field_group_new(NULL);
@@ -1582,7 +1561,7 @@
 
 			purple_request_fields(jsx->js->gc, _("Select a Resource"), msg, NULL, fields,
 					_("Send File"), G_CALLBACK(resource_select_ok_cb), _("Cancel"), G_CALLBACK(resource_select_cancel_cb),
-					jsx->js->gc->account, xfer->who, NULL, xfer);
+					jsx->js->gc->account, purple_xfer_get_remote_user(xfer), NULL, xfer);
 
 			g_free(msg);
 		}
@@ -1592,7 +1571,7 @@
 		xmlnode *si, *feature, *x, *field, *value;
 
 		iq = jabber_iq_new(jsx->js, JABBER_IQ_RESULT);
-		xmlnode_set_attrib(iq->node, "to", xfer->who);
+		xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
 		if(jsx->iq_id)
 			jabber_iq_set_id(iq, jsx->iq_id);
 		else
@@ -1636,12 +1615,13 @@
 	PurpleXfer *xfer;
 	JabberSIXfer *jsx;
 
-	js = gc->proto_data;
+	js = purple_connection_get_protocol_data(gc);
 
 	xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
 	if (xfer)
 	{
-		xfer->data = jsx = g_new0(JabberSIXfer, 1);
+		jsx = g_new0(JabberSIXfer, 1);
+		purple_xfer_set_protocol_data(xfer, jsx);
 		jsx->js = js;
 		jsx->local_streamhost_fd = -1;
 
@@ -1777,7 +1757,7 @@
 	xfer = purple_xfer_new(js->gc->account, PURPLE_XFER_RECEIVE, from);
 	g_return_if_fail(xfer != NULL);
 
-	xfer->data = jsx;
+	purple_xfer_set_protocol_data(xfer, jsx);
 
 	purple_xfer_set_filename(xfer, filename);
 	if(filesize > 0)
--- a/libpurple/protocols/jabber/usertune.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/jabber/usertune.c	Sun Sep 11 04:19:01 2011 +0000
@@ -117,7 +117,7 @@
 
 void jabber_tune_set(PurpleConnection *gc, const PurpleJabberTuneInfo *tuneinfo) {
 	xmlnode *publish, *tunenode;
-	JabberStream *js = gc->proto_data;
+	JabberStream *js = purple_connection_get_protocol_data(gc);
 
 	publish = xmlnode_new("publish");
 	xmlnode_set_attrib(publish,"node","http://jabber.org/protocol/tune");
--- a/libpurple/protocols/msn/msg.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/msg.c	Sun Sep 11 04:19:01 2011 +0000
@@ -970,7 +970,7 @@
 			msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj);
 		}
 
-		msn_object_destroy(obj);
+		msn_object_destroy(obj, FALSE);
 		obj =   NULL;
 		who =   NULL;
 		sha1 = NULL;
@@ -1025,7 +1025,7 @@
 		slplink = msn_session_get_slplink(session, who);
 		msn_slplink_request_object(slplink, data, got_wink_cb, NULL, obj);
 
-		msn_object_destroy(obj);
+		msn_object_destroy(obj, FALSE);
 
 
 	} else if (!strcmp(id, "3")) {
@@ -1045,7 +1045,7 @@
 		slplink = msn_session_get_slplink(session, who);
 		msn_slplink_request_object(slplink, data, got_voiceclip_cb, NULL, obj);
 
-		msn_object_destroy(obj);
+		msn_object_destroy(obj, FALSE);
 
 	} else if (!strcmp(id, "4")) {
 		/* Action */
--- a/libpurple/protocols/msn/msn.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/msn.c	Sun Sep 11 04:19:01 2011 +0000
@@ -119,7 +119,7 @@
 	MsnSwitchBoard *swboard;
 
 	msg = msn_message_new_nudge();
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	swboard = msn_session_get_swboard(session, username, MSN_SB_FLAG_IM);
 
 	msn_switchboard_send_msg(swboard, msg, TRUE);
@@ -326,7 +326,7 @@
 	MsnSession *session;
 	MsnTransaction *trans;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	cmdproc = session->notification->cmdproc;
 
 	if (entry == NULL || *entry == '\0')
@@ -384,7 +384,7 @@
 	const char *mobile_number = NULL;
 	gsize payload_len;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	cmdproc = session->notification->cmdproc;
 
 	page = msn_page_new();
@@ -647,7 +647,7 @@
 	MsnSession *session;
 
 	gc = (PurpleConnection *) action->context;
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	purple_request_input(gc, NULL, _("Set your home phone number."), NULL,
 					   msn_user_get_home_phone(session->user), FALSE, FALSE, NULL,
@@ -664,7 +664,7 @@
 	MsnSession *session;
 
 	gc = (PurpleConnection *) action->context;
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	purple_request_input(gc, NULL, _("Set your work phone number."), NULL,
 					   msn_user_get_work_phone(session->user), FALSE, FALSE, NULL,
@@ -681,7 +681,7 @@
 	MsnSession *session;
 
 	gc = (PurpleConnection *) action->context;
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	purple_request_input(gc, NULL, _("Set your mobile phone number."), NULL,
 					   msn_user_get_mobile_phone(session->user), FALSE, FALSE, NULL,
@@ -719,7 +719,7 @@
 	MsnSession *session;
 	char *title;
 
-	session = pc->proto_data;
+	session = purple_connection_get_protocol_data(pc);
 
 	title = g_strdup_printf(_("Blocked Text for %s"), session->account->username);
 	if (session->blocked_text == NULL) {
@@ -743,7 +743,7 @@
 	MsnSession *session;
 
 	gc = (PurpleConnection *) action->context;
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	if (!session->passport_info.email_enabled) {
 		purple_notify_error(gc, NULL,
@@ -810,7 +810,7 @@
 	MsnTransaction *trans;
 
 	account = purple_connection_get_account(gc);
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	cmdproc = session->notification->cmdproc;
 
 	if (account->perm_deny == PURPLE_PRIVACY_ALLOW_ALL ||
@@ -840,7 +840,7 @@
 	account = purple_buddy_get_account(buddy);
 	gc = purple_account_get_connection(account);
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	swboard = msn_switchboard_new(session);
 	msn_switchboard_request(swboard);
@@ -869,7 +869,7 @@
 static void
 t_msn_xfer_cancel_send(PurpleXfer *xfer)
 {
-	MsnSlpLink *slplink = xfer->data;
+	MsnSlpLink *slplink = purple_xfer_get_protocol_data(xfer);
 	msn_slplink_unref(slplink);
 }
 
@@ -879,13 +879,13 @@
 	MsnSession *session;
 	PurpleXfer *xfer;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
 
 	g_return_val_if_fail(xfer != NULL, NULL);
 
-	xfer->data = msn_slplink_ref(msn_session_get_slplink(session, who));
+	purple_xfer_set_protocol_data(xfer, msn_slplink_ref(msn_session_get_slplink(session, who)));
 
 	purple_xfer_set_init_fnc(xfer, t_msn_xfer_init);
 	purple_xfer_set_cancel_send_fnc(xfer, t_msn_xfer_cancel_send);
@@ -918,7 +918,7 @@
 	g_free(normal);
 
 	if (ret) {
-		MsnSession *session = gc->proto_data;
+		MsnSession *session = purple_connection_get_protocol_data(gc);
 		if (session) {
 			MsnUser *user = msn_userlist_find_user(session->userlist, who);
 			if (user) {
@@ -1078,7 +1078,7 @@
 			if (psm != NULL && *psm) {
 				purple_notify_user_info_add_pair_plaintext(user_info, tmp2, psm);
 			} else {
-				purple_notify_user_info_add_pair(user_info, _("Status"), tmp2);
+				purple_notify_user_info_add_pair_html(user_info, _("Status"), tmp2);
 			}
 
 			g_free(tmp2);
@@ -1091,17 +1091,17 @@
 				}
 			} else {
 				if (purple_presence_is_idle(presence)) {
-					purple_notify_user_info_add_pair(user_info, _("Status"),
-						_("Idle"));
+					purple_notify_user_info_add_pair_plaintext(user_info,
+							_("Status"), _("Idle"));
 				} else {
-					purple_notify_user_info_add_pair(user_info, _("Status"),
-						purple_status_get_name(status));
+					purple_notify_user_info_add_pair_plaintext(user_info,
+							_("Status"), purple_status_get_name(status));
 				}
 			}
 		}
 
 		if (currentmedia) {
-			purple_notify_user_info_add_pair(user_info, mediatype, currentmedia);
+			purple_notify_user_info_add_pair_html(user_info, mediatype, currentmedia);
 			g_free(currentmedia);
 		}
 	}
@@ -1119,23 +1119,26 @@
 	{
 		const char *phone;
 
-		purple_notify_user_info_add_pair(user_info, _("Has you"),
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Has you"),
 									   ((user->list_op & (1 << MSN_LIST_RL)) ? _("Yes") : _("No")));
 
-		purple_notify_user_info_add_pair(user_info, _("Blocked"),
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Blocked"),
 									   ((user->list_op & (1 << MSN_LIST_BL)) ? _("Yes") : _("No")));
 
 		phone = msn_user_get_home_phone(user);
-		if (phone != NULL)
-			purple_notify_user_info_add_pair(user_info, _("Home Phone Number"), phone);
+		if (phone != NULL) {
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Home Phone Number"), phone);
+		}
 
 		phone = msn_user_get_work_phone(user);
-		if (phone != NULL)
-			purple_notify_user_info_add_pair(user_info, _("Work Phone Number"), phone);
+		if (phone != NULL) {
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Work Phone Number"), phone);
+		}
 
 		phone = msn_user_get_mobile_phone(user);
-		if (phone != NULL)
-			purple_notify_user_info_add_pair(user_info, _("Mobile Phone Number"), phone);
+		if (phone != NULL) {
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Mobile Phone Number"), phone);
+		}
 	}
 }
 
@@ -1213,7 +1216,7 @@
 	PurplePluginAction *act;
 
 	gc = (PurpleConnection *) context;
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	act = purple_plugin_action_new(_("Set Friendly Name..."),
 								 msn_show_set_friendly_name);
@@ -1333,7 +1336,7 @@
 
 	if (!purple_ssl_is_supported())
 	{
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 			_("SSL support is needed for MSN. Please install a supported "
 			  "SSL library."));
@@ -1350,7 +1353,7 @@
 
 	session = msn_session_new(account);
 
-	gc->proto_data = session;
+	purple_connection_set_protocol_data(gc, session);
 	gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_FORMATTING_WBFO | PURPLE_CONNECTION_NO_BGCOLOR |
 		PURPLE_CONNECTION_NO_FONTSIZE | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY;
 
@@ -1374,7 +1377,7 @@
 	}
 
 	if (!msn_session_connect(session, host, port, http_method))
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to connect"));
 }
@@ -1384,13 +1387,13 @@
 {
 	MsnSession *session;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	g_return_if_fail(session != NULL);
 
 	msn_session_destroy(session);
 
-	gc->proto_data = NULL;
+	purple_connection_set_protocol_data(gc, NULL);
 }
 
 static gboolean
@@ -1450,7 +1453,7 @@
 static void msn_emoticon_destroy(MsnEmoticon *emoticon)
 {
 	if (emoticon->obj)
-		msn_object_destroy(emoticon->obj);
+		msn_object_destroy(emoticon->obj, FALSE);
 	g_free(emoticon->smile);
 	g_free(emoticon);
 }
@@ -1536,7 +1539,7 @@
 	account = purple_connection_get_account(gc);
 	username = purple_account_get_username(account);
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	swboard = msn_session_find_swboard(session, who);
 
 	if (!strncmp("tel:+", who, 5)) {
@@ -1663,7 +1666,7 @@
 	MsnMessage *msg;
 
 	account = purple_connection_get_account(gc);
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	/*
 	 * TODO: I feel like this should be "if (state != PURPLE_TYPING)"
@@ -1712,7 +1715,7 @@
 
 	if (gc != NULL)
 	{
-		session = gc->proto_data;
+		session = purple_connection_get_protocol_data(gc);
 		msn_change_status(session);
 	}
 }
@@ -1722,7 +1725,7 @@
 {
 	MsnSession *session;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	msn_change_status(session);
 }
@@ -1852,7 +1855,7 @@
 	MsnSession *session;
 	MsnUserList *userlist;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	userlist = session->userlist;
 
 	if (!session->logged_in)
@@ -1869,7 +1872,7 @@
 	MsnUserList *userlist;
 	MsnUser *user;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	userlist = session->userlist;
 	user = msn_userlist_find_user(userlist, who);
 
@@ -1897,7 +1900,7 @@
 	MsnUserList *userlist;
 	MsnUser *user;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	userlist = session->userlist;
 	user = msn_userlist_find_user(userlist, who);
 
@@ -1924,7 +1927,7 @@
 	MsnUserList *userlist;
 	MsnUser *user;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	userlist = session->userlist;
 
 	if (!session->logged_in)
@@ -1947,7 +1950,7 @@
 	MsnUserList *userlist;
 	MsnUser *user;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	userlist = session->userlist;
 
 	if (!session->logged_in)
@@ -1976,7 +1979,7 @@
 	MsnSession *session;
 	MsnSwitchBoard *swboard;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	swboard = msn_session_find_swboard_with_id(session, id);
 
@@ -2001,7 +2004,7 @@
 	MsnSwitchBoard *swboard;
 	PurpleConversation *conv;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	swboard = msn_session_find_swboard_with_id(session, id);
 
@@ -2038,7 +2041,7 @@
 	GString *emoticons = NULL;
 
 	account = purple_connection_get_account(gc);
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	username = purple_account_get_username(account);
 	swboard = msn_session_find_swboard_with_id(session, id);
 
@@ -2104,7 +2107,7 @@
 	MsnSession *session;
 	MsnTransaction *trans;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	if (!session->http_method)
 	{
@@ -2122,7 +2125,7 @@
 {
 	MsnSession *session;
 
-	session = pc->proto_data;
+	session = purple_connection_get_protocol_data(pc);
 
 	msn_update_contact(session, name, MSN_UPDATE_ALIAS, alias);
 }
@@ -2134,7 +2137,7 @@
 	MsnSession *session;
 	MsnUserList *userlist;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	userlist = session->userlist;
 
 	msn_userlist_move_buddy(userlist, who, old_group_name, new_group_name);
@@ -2147,7 +2150,7 @@
 	MsnSession *session;
 	const char *gname;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	g_return_if_fail(session != NULL);
 	g_return_if_fail(session->userlist != NULL);
@@ -2171,7 +2174,7 @@
 	MsnSwitchBoard *swboard;
 	PurpleConversation *conv;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	swboard = msn_session_find_swboard(session, who);
 
@@ -2207,7 +2210,7 @@
 	MsnSession *session;
 	MsnUser *user;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	user = session->user;
 
 	msn_user_set_buddy_icon(user, img);
@@ -2221,7 +2224,7 @@
 	MsnSession *session;
 	const char *gname;
 
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	gname = purple_group_get_name(group);
 
 	purple_debug_info("msn", "Remove group %s\n", gname);
@@ -2262,7 +2265,7 @@
 		{
 			char *nicktext = g_markup_escape_text(alias, -1);
 			tmp = g_strdup_printf("<font sml=\"msn\">%s</font>", nicktext);
-			purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp);
+			purple_notify_user_info_add_pair_html(user_info, _("Nickname"), tmp);
 			g_free(tmp);
 			g_free(nicktext);
 		}
@@ -2361,7 +2364,7 @@
 
 	if (error_message != NULL || url_text == NULL || strcmp(url_text, "") == 0)
 	{
-		purple_notify_user_info_add_pair(user_info,
+		purple_notify_user_info_add_pair_html(user_info,
 				_("Error retrieving profile"), NULL);
 
 		purple_notify_userinfo(info_data->gc, info_data->name, user_info, NULL, NULL);
@@ -2680,7 +2683,7 @@
 	if (user_url != NULL)
 	{
 		tmp = g_strdup_printf("<a href=\"%s\">%s</a>", user_url, user_url);
-		purple_notify_user_info_add_pair(user_info, _("Homepage"), tmp);
+		purple_notify_user_info_add_pair_html(user_info, _("Homepage"), tmp);
 		g_free(tmp);
 		g_free(user_url);
 
@@ -2703,9 +2706,9 @@
 		char *p = strstr(url_buffer, "<form id=\"profile_form\" name=\"profile_form\" action=\"http&#58;&#47;&#47;spaces.live.com&#47;profile.aspx&#63;cid&#61;0\"");
 		PurpleBuddy *b = purple_find_buddy
 				(purple_connection_get_account(info_data->gc), info_data->name);
-		purple_notify_user_info_add_pair(user_info,
+		purple_notify_user_info_add_pair_html(user_info,
 				_("Error retrieving profile"), NULL);
-		purple_notify_user_info_add_pair(user_info, NULL,
+		purple_notify_user_info_add_pair_plaintext(user_info, NULL,
 				((p && b) ? _("The user has not created a public profile.") :
 					(p ? _("MSN reported not being able to find the user's profile. "
 							"This either means that the user does not exist, "
@@ -2720,7 +2723,7 @@
 	purple_notify_user_info_add_section_break(user_info);
 	tmp = g_strdup_printf("<a href=\"%s%s\">%s</a>",
 			PROFILE_URL, info_data->name, _("View web profile"));
-	purple_notify_user_info_add_pair(user_info, NULL, tmp);
+	purple_notify_user_info_add_pair_html(user_info, NULL, tmp);
 	g_free(tmp);
 
 #if PHOTO_SUPPORT
@@ -2801,7 +2804,7 @@
 			purple_debug_info("msn", "%s is %" G_GSIZE_FORMAT " bytes\n", photo_url_text, len);
 			id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL);
 			g_snprintf(buf, sizeof(buf), "<img id=\"%d\"><br>", id);
-			purple_notify_user_info_prepend_pair(user_info, NULL, buf);
+			purple_notify_user_info_prepend_pair_html(user_info, NULL, buf);
 		}
 	}
 
@@ -2927,6 +2930,7 @@
 
 static PurplePluginProtocolInfo prpl_info =
 {
+	sizeof(PurplePluginProtocolInfo),	/* struct_size */
 	OPT_PROTO_MAIL_CHECK|OPT_PROTO_INVITE_MESSAGE,
 	NULL,                               /* user_splits */
 	NULL,                               /* protocol_options */
@@ -2948,7 +2952,7 @@
 	msn_set_status,                     /* set_away */
 	msn_set_idle,                       /* set_idle */
 	NULL,                               /* change_passwd */
-	NULL,                               /* add_buddy */
+	msn_add_buddy,                      /* add_buddy */
 	NULL,                               /* add_buddies */
 	msn_rem_buddy,                      /* remove_buddy */
 	NULL,                               /* remove_buddies */
@@ -2992,15 +2996,12 @@
 	NULL,                               /* unregister_user */
 	msn_send_attention,                 /* send_attention */
 	msn_attention_types,                /* attention_types */
-	sizeof(PurplePluginProtocolInfo),	/* struct_size */
 	msn_get_account_text_table,         /* get_account_text_table */
 	NULL,                               /* initiate_media */
 	NULL,                               /* get_media_caps */
 	NULL,                               /* get_moods */
 	msn_set_public_alias,               /* set_public_alias */
-	msn_get_public_alias,               /* get_public_alias */
-	msn_add_buddy,                      /* add_buddy_with_invite */
-	NULL                                /* add_buddies_with_invite */
+	msn_get_public_alias                /* get_public_alias */
 };
 
 static PurplePluginInfo info =
--- a/libpurple/protocols/msn/object.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/object.c	Sun Sep 11 04:19:01 2011 +0000
@@ -103,7 +103,7 @@
 	if (obj->creator == NULL || obj->size == 0 || obj->type == 0
 	 || obj->sha1d == NULL) {
 		purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
-		msn_object_destroy(obj);
+		msn_object_destroy(obj, FALSE);
 		return NULL;
 	}
 
@@ -111,12 +111,12 @@
 		/* Location/friendly are required for non-buddyicon objects */
 		if (obj->type != MSN_OBJECT_USERTILE) {
 			purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
-			msn_object_destroy(obj);
+			msn_object_destroy(obj, FALSE);
 			return NULL;
 		/* Buddy icon object can contain Url/Url1 instead */
 		} else if (obj->url == NULL || obj->url1 == NULL) {
 			purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
-			msn_object_destroy(obj);
+			msn_object_destroy(obj, FALSE);
 			return NULL;
 		}
 	}
@@ -193,10 +193,13 @@
 }
 
 void
-msn_object_destroy(MsnObject *obj)
+msn_object_destroy(MsnObject *obj, gboolean only_remote)
 {
 	g_return_if_fail(obj != NULL);
 
+	if (only_remote && obj->local)
+		return;
+
 	g_free(obj->creator);
 	g_free(obj->location);
 	g_free(obj->friendly);
--- a/libpurple/protocols/msn/object.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/object.h	Sun Sep 11 04:19:01 2011 +0000
@@ -86,9 +86,10 @@
 /**
  * Destroys an MsnObject structure.
  *
- * @param obj The object structure.
+ * @param obj         The object structure.
+ * @param only_remote Only destroy non-local objects.
  */
-void msn_object_destroy(MsnObject *obj);
+void msn_object_destroy(MsnObject *obj, gboolean only_remote);
 
 /**
  * Outputs a string representation of an MsnObject.
--- a/libpurple/protocols/msn/sbconn.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/sbconn.c	Sun Sep 11 04:19:01 2011 +0000
@@ -121,6 +121,8 @@
 			}
 #endif
 		}
+	} else {
+		msn_transaction_set_saveable(trans, FALSE);
 	}
 
 	trans->payload = payload;
--- a/libpurple/protocols/msn/session.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/session.c	Sun Sep 11 04:19:01 2011 +0000
@@ -420,7 +420,7 @@
 
 	msn_session_disconnect(session);
 
-	purple_connection_error_reason(gc, reason, msg);
+	purple_connection_error(gc, reason, msg);
 
 	g_free(msg);
 }
--- a/libpurple/protocols/msn/slp.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/slp.c	Sun Sep 11 04:19:01 2011 +0000
@@ -364,7 +364,7 @@
 	fn = purple_xfer_get_filename(xfer);
 	fp = purple_xfer_get_local_filename(xfer);
 
-	slplink = xfer->data;
+	slplink = purple_xfer_get_protocol_data(xfer);
 
 	g_return_if_fail(slplink != NULL);
 	g_return_if_fail(fp != NULL);
@@ -384,7 +384,7 @@
 	purple_xfer_set_read_fnc(xfer, msn_xfer_read);
 	purple_xfer_set_write_fnc(xfer, msn_xfer_write);
 
-	xfer->data = slpcall;
+	purple_xfer_set_protocol_data(xfer, slpcall);
 
 	context = gen_context(xfer, fn, fp);
 
--- a/libpurple/protocols/msn/slpcall.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/slpcall.c	Sun Sep 11 04:19:01 2011 +0000
@@ -113,7 +113,7 @@
 	if (slpcall->xfer != NULL) {
 		if (purple_xfer_get_type(slpcall->xfer) == PURPLE_XFER_RECEIVE)
 			g_byte_array_free(slpcall->u.incoming_data, TRUE);
-		slpcall->xfer->data = NULL;
+		purple_xfer_set_protocol_data(slpcall->xfer, NULL);
 		purple_xfer_unref(slpcall->xfer);
 	}
 
@@ -485,7 +485,7 @@
 			if (img)
 				purple_imgstore_ref(img);
 		}
-		msn_object_destroy(obj);
+		msn_object_destroy(obj, FALSE);
 
 		if (img != NULL) {
 			/* DATA PREP */
@@ -550,7 +550,7 @@
 			slpcall->xfer = xfer;
 			purple_xfer_ref(slpcall->xfer);
 
-			xfer->data = slpcall;
+			purple_xfer_set_protocol_data(xfer, slpcall);
 
 			if (file_context->preview) {
 				purple_xfer_set_thumbnail(xfer, file_context->preview,
--- a/libpurple/protocols/msn/slplink.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/slplink.c	Sun Sep 11 04:19:01 2011 +0000
@@ -465,7 +465,7 @@
 					purple_xfer_ref(xfer);
 					purple_xfer_start(xfer,	-1, NULL, 0);
 
-					if (xfer->data == NULL) {
+					if (purple_xfer_get_protocol_data(xfer) == NULL) {
 						purple_xfer_unref(xfer);
 						msn_slpmsg_destroy(slpmsg);
 						g_return_val_if_reached(NULL);
--- a/libpurple/protocols/msn/user.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/user.c	Sun Sep 11 04:19:01 2011 +0000
@@ -76,7 +76,7 @@
 	}
 
 	if (user->msnobj != NULL)
-		msn_object_destroy(user->msnobj);
+		msn_object_destroy(user->msnobj, FALSE);
 
 	g_free(user->passport);
 	g_free(user->friendly_name);
@@ -406,7 +406,7 @@
 
 	gc = purple_account_get_connection(account);
 	if (gc != NULL)
-		session = gc->proto_data;
+		session = purple_connection_get_protocol_data(gc);
 
 	if ((session != NULL) && (user = msn_userlist_find_user(session->userlist, name)) != NULL)
 	{
@@ -588,8 +588,8 @@
 {
 	g_return_if_fail(user != NULL);
 
-	if (user->msnobj != NULL && !msn_object_find_local(msn_object_get_sha1(obj)))
-		msn_object_destroy(user->msnobj);
+	if (user->msnobj != NULL)
+		msn_object_destroy(user->msnobj, TRUE);
 
 	user->msnobj = obj;
 
--- a/libpurple/protocols/msn/userlist.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/userlist.c	Sun Sep 11 04:19:01 2011 +0000
@@ -54,7 +54,7 @@
 
 	if (PURPLE_CONNECTION_IS_VALID(pa->gc))
 	{
-		MsnSession *session = pa->gc->proto_data;
+		MsnSession *session = purple_connection_get_protocol_data(pa->gc);
 		MsnUserList *userlist = session->userlist;
 		PurpleAccount *account = purple_connection_get_account(pa->gc);
 
@@ -79,7 +79,7 @@
 
 	if (PURPLE_CONNECTION_IS_VALID(pa->gc))
 	{
-		MsnSession *session = pa->gc->proto_data;
+		MsnSession *session = purple_connection_get_protocol_data(pa->gc);
 		MsnUserList *userlist = session->userlist;
 		MsnCallbackState *state = msn_callback_state_new(session);
 
--- a/libpurple/protocols/msn/xfer.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/msn/xfer.c	Sun Sep 11 04:19:01 2011 +0000
@@ -42,7 +42,7 @@
 
 	purple_debug_info("msn", "xfer_init\n");
 
-	slpcall = xfer->data;
+	slpcall = purple_xfer_get_protocol_data(xfer);
 
 	/* Send Ok */
 	content = g_strdup_printf("SessionID: %lu\r\n\r\n",
@@ -62,9 +62,9 @@
 	char *content;
 
 	g_return_if_fail(xfer != NULL);
-	g_return_if_fail(xfer->data != NULL);
 
-	slpcall = xfer->data;
+	slpcall = purple_xfer_get_protocol_data(xfer);
+	g_return_if_fail(slpcall != NULL);
 
 	if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL)
 	{
@@ -102,7 +102,7 @@
 
 	g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND, -1);
 
-	slpcall = xfer->data;
+	slpcall = purple_xfer_get_protocol_data(xfer);
 	/* Not sure I trust it'll be there */
 	g_return_val_if_fail(slpcall != NULL, -1);
 
@@ -126,7 +126,7 @@
 
 	g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE, -1);
 
-	slpcall = xfer->data;
+	slpcall = purple_xfer_get_protocol_data(xfer);
 	/* Not sure I trust it'll be there */
 	g_return_val_if_fail(slpcall != NULL, -1);
 
--- a/libpurple/protocols/mxit/actions.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/actions.c	Sun Sep 11 04:19:01 2011 +0000
@@ -43,7 +43,7 @@
  */
 static void mxit_profile_cb( PurpleConnection* gc, PurpleRequestFields* fields )
 {
-	struct MXitSession*		session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*		session	= purple_connection_get_protocol_data( gc ) ;
 	PurpleRequestField*		field	= NULL;
 	const char*				name	= NULL;
 	const char*				bday	= NULL;
@@ -84,13 +84,6 @@
 		g_string_append( attributes, attrib );
 		acount++;
 
-		/* force hidden if disabled */
-		if ( profile->hidden == FALSE ) {
-			g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_HIDENUMBER, CP_PROFILE_TYPE_BOOL, "1" );
-			g_string_append( attributes, attrib );
-			acount++;
-		}
-
 		/* update birthday */
 		g_strlcpy( profile->birthday, bday, sizeof( profile->birthday ) );
 		g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_BIRTHDATE, CP_PROFILE_TYPE_UTF8, profile->birthday );
@@ -165,7 +158,7 @@
 
 		/* update where am i */
 		name = purple_request_fields_get_string( fields, "whereami" );
-		if ( !name)
+		if ( !name )
 			profile->whereami[0] = '\0';
 		else
 			g_strlcpy( profile->whereami, name, sizeof( profile->whereami ) );
@@ -207,7 +200,7 @@
 static void mxit_profile_action( PurplePluginAction* action )
 {
 	PurpleConnection*			gc		= (PurpleConnection*) action->context;
-	struct MXitSession*			session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*			session	= purple_connection_get_protocol_data( gc );
 	struct MXitProfile*			profile	= session->profile;
 
 	PurpleRequestFields*		fields	= NULL;
@@ -304,7 +297,7 @@
  */
 static void mxit_change_pin_cb( PurpleConnection* gc, PurpleRequestFields* fields )
 {
-	struct MXitSession*		session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*		session	= purple_connection_get_protocol_data( gc );
 	const char*				pin		= NULL;
 	const char*				pin2	= NULL;
 	const char*				err		= NULL;
@@ -366,7 +359,7 @@
 static void mxit_change_pin_action( PurplePluginAction* action )
 {
 	PurpleConnection*			gc		= (PurpleConnection*) action->context;
-	struct MXitSession*			session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*			session	= purple_connection_get_protocol_data( gc );
 
 	PurpleRequestFields*		fields	= NULL;
 	PurpleRequestFieldGroup*	group	= NULL;
@@ -375,8 +368,8 @@
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_change_pin_action\n" );
 
 	fields = purple_request_fields_new();
-	group = purple_request_field_group_new(NULL);
-	purple_request_fields_add_group(fields, group);
+	group = purple_request_field_group_new( NULL );
+	purple_request_fields_add_group( fields, group );
 
 	/* pin */
 	field = purple_request_field_string_new( "pin", _( "PIN" ), session->acc->password, FALSE );
@@ -402,7 +395,7 @@
 static void mxit_splash_action( PurplePluginAction* action )
 {
 	PurpleConnection*		gc		= (PurpleConnection*) action->context;
-	struct MXitSession*		session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*		session	= purple_connection_get_protocol_data( gc );
 
 	if ( splash_current( session ) != NULL )
 		splash_display( session );
@@ -439,7 +432,7 @@
 static void mxit_suggested_friends_action( PurplePluginAction* action )
 {
 	PurpleConnection*		gc				= (PurpleConnection*) action->context;
-	struct MXitSession*		session			= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*		session			= purple_connection_get_protocol_data( gc );
 	const char*				profilelist[]	= {
 				CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME, CP_PROFILE_FIRSTNAME,
 				CP_PROFILE_LASTNAME, CP_PROFILE_REGCOUNTRY, CP_PROFILE_STATUS, CP_PROFILE_AVATAR,
@@ -456,7 +449,7 @@
  */
 static void mxit_user_search_cb( PurpleConnection *gc, const char *input )
 {
-	struct MXitSession*		session			= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*		session			= purple_connection_get_protocol_data( gc );
 	const char*				profilelist[]	= {
 				CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME, CP_PROFILE_FIRSTNAME,
 				CP_PROFILE_LASTNAME, CP_PROFILE_REGCOUNTRY, CP_PROFILE_STATUS, CP_PROFILE_AVATAR,
@@ -479,10 +472,10 @@
 		_( "Search for a MXit contact" ),
 		_( "Type search information" ),
 		NULL, FALSE, FALSE, NULL,
-		_("_Search"), G_CALLBACK( mxit_user_search_cb ),
-		_("_Cancel"), NULL,
+		_( "_Search" ), G_CALLBACK( mxit_user_search_cb ),
+		_( "_Cancel" ), NULL,
 		purple_connection_get_account( gc ), NULL, NULL,
-		gc);
+		gc );
 }
 
 
--- a/libpurple/protocols/mxit/cipher.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/cipher.c	Sun Sep 11 04:19:01 2011 +0000
@@ -1,7 +1,7 @@
 /*
  *					MXit Protocol libPurple Plugin
  *
- *					-- user password encryption --
+ *						-- encryption --
  *
  *				Pieter Loubser	<libpurple@mxit.com>
  *
@@ -31,30 +31,69 @@
 #include	"aes.h"
 
 
-/* password encryption */
+/* encryption */
 #define		INITIAL_KEY		"6170383452343567"
 #define		SECRET_HEADER	"<mxit/>"
+#define		ENCRYPT_HEADER	"<mxitencrypted ver=\"5.2\"/>"
+
+
+/*------------------------------------------------------------------------
+ * Add ISO10126 Padding to the data.
+ *
+ *  @param data		The data to pad.
+ */
+static void padding_add( GString* data )
+{
+	unsigned int blocks = ( data->len / 16 ) + 1;
+	unsigned int padding = ( blocks * 16 ) - data->len;
+
+	g_string_set_size( data, blocks * 16 );
+	data->str[data->len - 1] = padding;
+}
 
 
 /*------------------------------------------------------------------------
- * Pad the secret data using ISO10126 Padding.
+ * Remove ISO10126 Padding from the data.
  *
- *  @param secret	The data to pad (caller must ensure buffer has enough space for padding)
- *  @return			The total number of 128-bit blocks used
+ *  @param data		The data from which to remove padding.
  */
-static int pad_secret_data( char* secret )
+static void padding_remove( GString* data )
 {
-	int		blocks	= 0;
-	int		passlen;
-	int		padding;
+	unsigned int padding;
+
+	if ( data->len == 0 )
+		return;
+
+	padding = data->str[data->len - 1];
+	g_string_truncate( data, data->len - padding );
+}
+
 
-	passlen = strlen( secret );
-	blocks = ( passlen / 16 ) + 1;
-	padding = ( blocks * 16 ) - passlen;
-	secret[passlen] = 0x50;
-	secret[(blocks * 16) - 1] = padding;
+/*------------------------------------------------------------------------
+ * Generate the Transport-Layer crypto key.
+ *  (Note: this function is not-thread safe)
+ *
+ *  @param session	The MXit Session object
+ *	@return			The transport-layer crypto key.
+ */
+static char* transport_layer_key( struct MXitSession* session )
+{
+	static char	key[16 + 1];
+	int			passlen			= strlen( session->acc->password );
 
-	return blocks;
+	/* initialize with initial key */
+	g_strlcpy( key, INITIAL_KEY, sizeof( key ) );
+
+	/* client key (8 bytes) */
+	memcpy( key, session->clientkey, strlen( session->clientkey ) );
+
+	/* add last 8 characters of the PIN (no padding if less characters) */
+	if ( passlen <= 8 )
+		memcpy( key + 8, session->acc->password, passlen );
+	else
+		memcpy( key + 8, session->acc->password + ( passlen - 8 ), 8 );
+
+	return key;
 }
 
 
@@ -67,42 +106,131 @@
  */
 char* mxit_encrypt_password( struct MXitSession* session )
 {
-	char		key[64];
+	char		key[16 + 1];
 	char		exkey[512];
-	char		pass[64];
+	GString*	pass			= NULL;
 	char		encrypted[64];
 	char*		base64;
-	int			blocks;
-	int			size;
 	int			i;
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_encrypt_password\n" );
 
 	memset( encrypted, 0x00, sizeof( encrypted ) );
-	memset( exkey, 0x00, sizeof( exkey ) );
-	memset( pass, 0x58, sizeof( pass ) );
-	pass[sizeof( pass ) - 1] = '\0';
 
-	/* build the custom AES encryption key */
+	/* build the AES encryption key */
 	g_strlcpy( key, INITIAL_KEY, sizeof( key ) );
 	memcpy( key, session->clientkey, strlen( session->clientkey ) );
 	ExpandKey( (unsigned char*) key, (unsigned char*) exkey );
 
-	/* build the custom data to be encrypted */
-	g_strlcpy( pass, SECRET_HEADER, sizeof( pass ) );
-	strcat( pass, session->acc->password );
+	/* build the secret data to be encrypted: SECRET_HEADER + password */
+	pass = g_string_new( SECRET_HEADER );
+	g_string_append( pass, session->acc->password );
+	padding_add( pass );		/* add ISO10126 padding */
 
-	/* pad the secret data */
-	blocks = pad_secret_data( pass );
-	size = blocks * 16;
-
-	/* now encrypt the password. we encrypt each block separately (ECB mode) */
-	for ( i = 0; i < size; i += 16 )
-		Encrypt( (unsigned char*) pass + i, (unsigned char*) exkey, (unsigned char*) encrypted + i );
+	/* now encrypt the secret. we encrypt each block separately (ECB mode) */
+	for ( i = 0; i < pass->len; i += 16 )
+		Encrypt( (unsigned char*) pass->str + i, (unsigned char*) exkey, (unsigned char*) encrypted + i );
 
 	/* now base64 encode the encrypted password */
-	base64 = purple_base64_encode( (unsigned char*) encrypted, size );
+	base64 = purple_base64_encode( (unsigned char*) encrypted, pass->len );
+
+	g_string_free( pass, TRUE );
 
 	return base64;
 }
 
+
+/*------------------------------------------------------------------------
+ * Decrypt a message using transport-layer encryption.
+ *
+ *  @param session	The MXit session object
+ *	@param message	The encrypted message data (is base64-encoded).
+ *  @return			The decrypted message.  Must be g_free'd when no longer needed.
+ */
+char* mxit_decrypt_message( struct MXitSession* session, char* message )
+{
+	guchar*		raw_message;
+	gsize		raw_len;
+	char		exkey[512];
+	GString*	decoded		= NULL;
+	int			i;
+
+	/* remove optional header: <mxitencrypted ver="5.2"/> */
+	if ( strncmp( message, ENCRYPT_HEADER, strlen( ENCRYPT_HEADER ) ) == 0 )
+		message += strlen( ENCRYPT_HEADER );
+
+	/* base64 decode the message */
+	raw_message = purple_base64_decode( message, &raw_len );
+
+	/* build the AES key */
+	ExpandKey( (unsigned char*) transport_layer_key( session ), (unsigned char*) exkey );
+
+	/* AES decrypt each block */
+	decoded = g_string_sized_new( raw_len );
+	for ( i = 0; i < raw_len; i += 16 ) {
+		char	block[16];
+
+		Decrypt( (unsigned char*) raw_message + i, (unsigned char*) exkey, (unsigned char*) block );
+		g_string_append_len( decoded, block, 16 );
+	}
+	g_free( raw_message );
+
+	/* check that the decrypted message starts with header: <mxit/> */
+	if ( strncmp( decoded->str, SECRET_HEADER, strlen( SECRET_HEADER ) != 0 ) ) {
+		g_string_free( decoded, TRUE );
+		return NULL;			/* message could not be decrypted */
+	}
+
+	/* remove ISO10126 padding */
+	padding_remove( decoded );
+
+	/* remove encryption header */
+	g_string_erase( decoded, 0, strlen( SECRET_HEADER ) );
+
+	return g_string_free( decoded, FALSE );
+}
+
+
+/*------------------------------------------------------------------------
+ * Encrypt a message using transport-layer encryption.
+ *
+ *  @param session	The MXit session object
+ *	@param message	The message data.
+ *  @return			The encrypted message.  Must be g_free'd when no longer needed.
+ */
+char* mxit_encrypt_message( struct MXitSession* session, char* message )
+{
+	GString*	raw_message	= NULL;
+	char		exkey[512];
+	GString*	encoded		= NULL;
+	gchar*		base64;
+	int			i;
+
+	purple_debug_info( MXIT_PLUGIN_ID, "encrypt message: '%s'\n", message );
+
+	/* append encryption header to message data */
+	raw_message = g_string_new( SECRET_HEADER );
+	g_string_append( raw_message, message );
+	padding_add( raw_message );		/* add ISO10126 padding */
+
+	/* build the AES key */
+	ExpandKey( (unsigned char*) transport_layer_key( session ), (unsigned char*) exkey );
+
+	/* AES encrypt each block */
+	encoded = g_string_sized_new( raw_message->len );
+	for ( i = 0; i < raw_message->len; i += 16 ) {
+		char	block[16];
+
+		Encrypt( (unsigned char*) raw_message->str + i, (unsigned char*) exkey, (unsigned char*) block );
+		g_string_append_len( encoded, block, 16 );
+	}
+	g_string_free( raw_message, TRUE );
+
+	/* base64 encode the encrypted message */
+	base64 = purple_base64_encode( (unsigned char *) encoded->str, encoded->len );
+	g_string_free( encoded, TRUE );
+
+	purple_debug_info( MXIT_PLUGIN_ID, "encrypted message: '%s'\n", base64 );
+
+	return base64;
+}
--- a/libpurple/protocols/mxit/cipher.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/cipher.h	Sun Sep 11 04:19:01 2011 +0000
@@ -1,7 +1,7 @@
 /*
  *					MXit Protocol libPurple Plugin
  *
- *					-- user password encryption --
+ *						-- encryption --
  *
  *				Pieter Loubser	<libpurple@mxit.com>
  *
@@ -32,5 +32,7 @@
 
 char* mxit_encrypt_password( struct MXitSession* session );
 
+char* mxit_decrypt_message( struct MXitSession* session, char* message );
+char* mxit_encrypt_message( struct MXitSession* session, char* message );
 
 #endif		/* _MXIT_CIPHER_H_ */
--- a/libpurple/protocols/mxit/filexfer.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/filexfer.c	Sun Sep 11 04:19:01 2011 +0000
@@ -97,11 +97,11 @@
  */
 static void mxit_xfer_free( PurpleXfer* xfer )
 {
-	struct mxitxfer*	mx		= (struct mxitxfer*) xfer->data;;
+	struct mxitxfer*	mx	= purple_xfer_get_protocol_data( xfer );
 
 	if ( mx ) {
+		purple_xfer_set_protocol_data( xfer, NULL );
 		g_free( mx );
-		xfer->data = NULL;
 	}
 }
 
@@ -117,7 +117,7 @@
  */
 static void mxit_xfer_init( PurpleXfer* xfer )
 {
-	struct mxitxfer*	mx	= (struct mxitxfer*) xfer->data;
+	struct mxitxfer*	mx	= purple_xfer_get_protocol_data( xfer );
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_xfer_init\n" );
 
@@ -126,7 +126,7 @@
 
 		if ( purple_xfer_get_size( xfer ) > CP_MAX_FILESIZE ) {
 			/* the file is too big */
-			purple_xfer_error( xfer->type, xfer->account, xfer->who, _( "The file you are trying to send is too large!" ) );
+			purple_xfer_error( purple_xfer_get_type( xfer ), purple_xfer_get_account( xfer ), purple_xfer_get_remote_user( xfer ), _( "The file you are trying to send is too large!" ) );
 			purple_xfer_cancel_local( xfer );
 			return;
 		}
@@ -151,6 +151,7 @@
  */
 static void mxit_xfer_start( PurpleXfer* xfer )
 {
+	size_t			filesize;
 	unsigned char*	buffer;
 	int				size;
 	int				wrote;
@@ -163,10 +164,12 @@
 		 * a buffer and copy the file data into memory and then we can send it to
 		 * the contact. we will send the whole file with one go.
 		 */
-		buffer = g_malloc( xfer->bytes_remaining );
-		size = fread( buffer, xfer->bytes_remaining, 1, xfer->dest_fp );
+		filesize = purple_xfer_get_bytes_remaining( xfer );
+		buffer = g_malloc( filesize );
+		size = fread( buffer, filesize, 1, xfer->dest_fp );
+		// TODO: If (size != 1) -> file read error
 
-		wrote = purple_xfer_write( xfer, buffer, xfer->bytes_remaining );
+		wrote = purple_xfer_write( xfer, buffer, filesize );
 		if ( wrote > 0 )
 			purple_xfer_set_bytes_sent( xfer, wrote );
 
@@ -215,7 +218,7 @@
  */
 static gssize mxit_xfer_write( const guchar* buffer, size_t size, PurpleXfer* xfer )
 {
-	struct mxitxfer*	mx	= (struct mxitxfer*) xfer->data;
+	struct mxitxfer*	mx	= purple_xfer_get_protocol_data( xfer );
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_xfer_write\n" );
 
@@ -245,7 +248,7 @@
  */
 static void mxit_xfer_request_denied( PurpleXfer* xfer )
 {
-	struct mxitxfer*	mx		= (struct mxitxfer*) xfer->data;
+	struct mxitxfer*	mx		= purple_xfer_get_protocol_data( xfer );
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_xfer_request_denied\n" );
 
@@ -295,7 +298,7 @@
  */
 PurpleXfer* mxit_xfer_new( PurpleConnection* gc, const char* who )
 {
-	struct MXitSession*	session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*	session	= purple_connection_get_protocol_data( gc );
 	PurpleXfer*			xfer	= NULL;
 	struct mxitxfer*	mx		= NULL;
 
@@ -305,7 +308,7 @@
 	/* create file info and attach it to the file transfer */
 	mx = g_new0( struct mxitxfer, 1 );
 	mx->session = session;
-	xfer->data = mx;
+	purple_xfer_set_protocol_data( xfer, mx );
 
 	/* configure callbacks (reference: "libpurple/ft.h") */
 	purple_xfer_set_init_fnc( xfer, mxit_xfer_init );
@@ -362,7 +365,7 @@
 		mx = g_new0( struct mxitxfer, 1 );
 		mx->session = session;
 		memcpy( mx->fileid, fileid, MXIT_CHUNK_FILEID_LEN );
-		xfer->data = mx;
+		purple_xfer_set_protocol_data( xfer, mx );
 
 		purple_xfer_set_filename( xfer, filename );
 		if( filesize > 0 )
@@ -395,9 +398,9 @@
 	while ( item ) {
 		xfer = item->data;
 
-		if ( xfer->account == session->acc ) {
+		if ( purple_xfer_get_account( xfer ) == session->acc ) {
 			/* transfer is associated with this MXit account */
-			struct mxitxfer* mx	= xfer->data;
+			struct mxitxfer* mx	= purple_xfer_get_protocol_data( xfer );
 
 			/* does the fileid match? */
 			if ( ( mx ) && ( memcmp( mx->fileid, fileid, MXIT_CHUNK_FILEID_LEN ) == 0 ) )
@@ -431,12 +434,13 @@
 	/* find the file-transfer object */
 	xfer = find_mxit_xfer( session, fileid );
 	if ( xfer ) {
-		mx = xfer->data;
+		mx = purple_xfer_get_protocol_data( xfer );
 
 		/* this is the transfer we have been looking for */
 		purple_xfer_ref( xfer );
 		purple_xfer_start( xfer, -1, NULL, 0 );
 		fwrite( data, datalen, 1, xfer->dest_fp );
+		// TODO: Handle error from fwrite()
 		purple_xfer_unref( xfer );
 		purple_xfer_set_completed( xfer, TRUE );
 		purple_xfer_end( xfer );
--- a/libpurple/protocols/mxit/formcmds.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/formcmds.c	Sun Sep 11 04:19:01 2011 +0000
@@ -86,7 +86,6 @@
 static void mxit_cb_ii_returned(PurpleUtilFetchUrlData* url_data, gpointer user_data, const gchar* url_text, gsize len, const gchar* error_message)
 {
 	struct ii_url_request*	iireq		= (struct ii_url_request*) user_data;
-	char*					ii_data;
 	int*					intptr		= NULL;
 	int						id;
 
@@ -106,12 +105,8 @@
 		goto done;
 	}
 
-	/* make a copy of the data */
-	ii_data = g_malloc(len);
-	memcpy(ii_data, (const char*) url_text, len);
-
-	/* we now have the inline image, store it in the imagestore */
-	id = purple_imgstore_add_with_id(ii_data, len, NULL);
+	/* we now have the inline image, store a copy in the imagestore */
+	id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL);
 
 	/* map the inline image id to purple image id */
 	intptr = g_malloc(sizeof(int));
@@ -253,8 +248,8 @@
 
 /*------------------------------------------------------------------------
  * Process a Reply MXit command.
- *  [::op=cmd|type=reply|replymsg=back|selmsg=b) Back|id=12345:]
- *  [::op=cmd|nm=rep|type=reply|replymsg=back|selmsg=b) Back|id=12345:]
+ *  [::op=cmd|type=reply|replymsg=back|selmsg=b) Back|displaymsg=Processing|id=12345:]
+ *  [::op=cmd|nm=rep|type=reply|replymsg=back|selmsg=b) Back|displaymsg=Processing|id=12345:]
  *
  *  @param mx			The received message data object
  *  @param hash			The MXit command <key,value> map
@@ -265,22 +260,26 @@
 	char* selmsg;
 	char* nm;
 
-	selmsg = g_hash_table_lookup(hash, "selmsg");			/* find the selection message */
-	replymsg = g_hash_table_lookup(hash, "replymsg");		/* find the reply message */
+	selmsg = g_hash_table_lookup(hash, "selmsg");			/* selection message */
+	replymsg = g_hash_table_lookup(hash, "replymsg");		/* reply message */
 	nm = g_hash_table_lookup(hash, "nm");					/* name parameter */
-	if ((selmsg) && (replymsg) && (nm)) {
+
+	if ((selmsg == NULL) || (replymsg == NULL))
+		return;		/* these parameters are required */
+
+	if (nm) {		/* indicates response must be a structured response */
 		gchar*	seltext = g_markup_escape_text(purple_url_decode(selmsg), -1);
-		gchar*	replycmd = g_strdup_printf("::type=reply|nm=%s|res=%s|err=0:", nm, replymsg);
+		gchar*	replycmd = g_strdup_printf("type=reply|nm=%s|res=%s|err=0", nm, replymsg);
 
-		mxit_add_html_link( mx, replycmd, seltext );
+		mxit_add_html_link( mx, replycmd, TRUE, seltext );
 
 		g_free(seltext);
 		g_free(replycmd);
 	}
-	else if ((selmsg) && (replymsg)) {
+	else {
 		gchar*	seltext = g_markup_escape_text(purple_url_decode(selmsg), -1);
 
-		mxit_add_html_link( mx, purple_url_decode(replymsg), seltext );
+		mxit_add_html_link( mx, purple_url_decode(replymsg), FALSE, seltext );
 
 		g_free(seltext);
 	}
@@ -317,6 +316,7 @@
 
 /*------------------------------------------------------------------------
  * Process an inline image MXit command.
+ *  [::op=img|dat=ASDF23408asdflkj2309flkjsadf%3d%3d|algn=1|w=120|h=12|t=100|replymsg=text:]
  *
  *  @param mx			The received message data object
  *  @param hash			The MXit command <key,value> map
@@ -372,7 +372,7 @@
 	reply = g_hash_table_lookup(hash, "replymsg");
 	if (reply) {
 		g_string_append_printf(msg, "\n");
-		mxit_add_html_link(mx, reply, _( "click here" ));
+		mxit_add_html_link(mx, reply, FALSE, _( "click here" ));
 	}
 }
 
--- a/libpurple/protocols/mxit/http.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/http.c	Sun Sep 11 04:19:01 2011 +0000
@@ -273,7 +273,7 @@
 	/* source is the file descriptor of the new connection */
 	if ( source < 0 ) {
 		purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_http_connect failed: %s\n", error_message );
-		purple_connection_error( req->session->con, _( "Unable to connect to the MXit HTTP server. Please check your server settings." ) );
+		purple_connection_error( req->session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Unable to connect to the MXit HTTP server. Please check your server settings." ) );
 		return;
 	}
 
--- a/libpurple/protocols/mxit/login.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/login.c	Sun Sep 11 04:19:01 2011 +0000
@@ -49,29 +49,27 @@
  */
 static struct MXitSession* mxit_create_object( PurpleAccount* account )
 {
+	PurpleConnection*	con			= purple_account_get_connection( account );
 	struct MXitSession*	session		= NULL;
-	PurpleConnection*	con			= NULL;
 
 	/* currently the wapsite does not handle a '+' in front of the username (mxitid) so we just strip it */
-	if ( account->username[0] == '+' ) {
-		char*		fixed;
+	{
+		const char* username	= purple_account_get_username( account );
 
-		/* cut off the '+' */
-		fixed = g_strdup( &account->username[1] );
-		purple_account_set_username( account, fixed );
-		g_free( fixed );
+		if ( username[0] == '+' ) {
+			char* fixed	= g_strdup( &username[1] );
+			purple_account_set_username( account, fixed );
+			g_free( fixed );
+		}
 	}
 
 	session = g_new0( struct MXitSession, 1 );
+	session->con = con;
+	session->acc = account;
 
 	/* configure the connection (reference: "libpurple/connection.h") */
-	con = purple_account_get_connection( account );
-	con->proto_data = session;
+	purple_connection_set_protocol_data( con, session );
 	con->flags |= PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_SUPPORT_MOODS;
-	session->con = con;
-
-	/* add account */
-	session->acc = account;
 
 	/* configure the session (reference: "libpurple/account.h") */
 	g_strlcpy( session->server, purple_account_get_string( account, MXIT_CONFIG_SERVER_ADDR, DEFAULT_SERVER ), sizeof( session->server ) );
@@ -165,7 +163,7 @@
 	/* source is the file descriptor of the new connection */
 	if ( source < 0 ) {
 		purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_connect failed: %s\n", error_message );
-		purple_connection_error( session->con, _( "Unable to connect to the MXit server. Please check your server settings." ) );
+		purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Unable to connect to the MXit server. Please check your server settings." ) );
 		return;
 	}
 
@@ -202,7 +200,7 @@
 		/* socket connection */
 		data = purple_proxy_connect( session->con, session->acc, session->server, session->port, mxit_cb_connect, session );
 		if ( !data ) {
-			purple_connection_error( session->con, _( "Unable to connect to the MXit server. Please check your server settings." ) );
+			purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Unable to connect to the MXit server. Please check your server settings." ) );
 			return;
 		}
 	}
@@ -221,7 +219,7 @@
  */
 static void mxit_cb_register_ok( PurpleConnection *gc, PurpleRequestFields *fields )
 {
-	struct MXitSession*		session		= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*		session		= purple_connection_get_protocol_data( gc );
 	struct MXitProfile*		profile		= session->profile;
 	const char*				str;
 	const char*				pin;
@@ -303,7 +301,7 @@
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_register_cancel\n" );
 
 	/* disconnect */
-	purple_account_disconnect( gc->account );
+	purple_account_disconnect( purple_connection_get_account( gc ) );
 }
 
 
@@ -391,7 +389,7 @@
 
 	if ( !url_text ) {
 		/* no reply from the WAP site */
-		purple_connection_error( session->con, _( "Error contacting the MXit WAP site. Please try again later." ) );
+		purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Error contacting the MXit WAP site. Please try again later." ) );
 		return;
 	}
 
@@ -400,7 +398,7 @@
 
 	if ( !parts ) {
 		/* wapserver error */
-		purple_connection_error( session->con, _( "MXit is currently unable to process the request. Please try again later." ) );
+		purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "MXit is currently unable to process the request. Please try again later." ) );
 		return;
 	}
 
@@ -410,26 +408,26 @@
 				/* valid reply! */
 				break;
 			case '1' :
-				purple_connection_error( session->con, _( "Wrong security code entered. Please try again later." ) );
+				purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Wrong security code entered. Please try again later." ) );
 				return;
 			case '2' :
-				purple_connection_error( session->con, _( "Your session has expired. Please try again later." ) );
+				purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Your session has expired. Please try again later." ) );
 				return;
 			case '5' :
-				purple_connection_error( session->con, _( "Invalid country selected. Please try again." ) );
+				purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Invalid country selected. Please try again." ) );
 				return;
 			case '6' :
-				purple_connection_error( session->con, _( "The MXit ID you entered is not registered. Please register first." ) );
+				purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "The MXit ID you entered is not registered. Please register first." ) );
 				return;
 			case '7' :
-				purple_connection_error( session->con, _( "The MXit ID you entered is already registered. Please choose another." ) );
+				purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "The MXit ID you entered is already registered. Please choose another." ) );
 				/* this user's account already exists, so we need to change the registration login flag to be login */
 				purple_account_set_int( session->acc, MXIT_CONFIG_STATE, MXIT_STATE_LOGIN );
 				return;
 			case '3' :
 			case '4' :
 			default :
-				purple_connection_error( session->con, _( "Internal error. Please try again later." ) );
+				purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Internal error. Please try again later." ) );
 				return;
 	}
 
@@ -507,7 +505,7 @@
  */
 static void mxit_cb_captcha_ok( PurpleConnection* gc, PurpleRequestFields* fields )
 {
-	struct MXitSession*		session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*		session	= purple_connection_get_protocol_data( gc );
 	PurpleUtilFetchUrlData*	url_data;
 	PurpleRequestField*		field;
 	const char*				captcha_resp;
@@ -571,7 +569,7 @@
  */
 static void mxit_cb_captcha_cancel( PurpleConnection* gc, PurpleRequestFields* fields )
 {
-	struct MXitSession*		session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*		session	= purple_connection_get_protocol_data( gc );
 
 	/* free up the login resources */
 	free_logindata( session->logindata );
@@ -611,7 +609,7 @@
 
 	if ( !url_text ) {
 		/* no reply from the WAP site */
-		purple_connection_error( session->con, _( "Error contacting the MXit WAP site. Please try again later." ) );
+		purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Error contacting the MXit WAP site. Please try again later." ) );
 		return;
 	}
 
@@ -620,7 +618,7 @@
 
 	if ( ( !parts ) || ( parts[0][0] != '0' ) ) {
 		/* server could not find the user */
-		purple_connection_error( session->con, _( "MXit is currently unable to process the request. Please try again later." ) );
+		purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "MXit is currently unable to process the request. Please try again later." ) );
 		return;
 	}
 
@@ -743,7 +741,7 @@
 	 * if we don't have any info saved from a previous login, we need to get it from the MXit WAP site.
 	 * we do cache it, so this step is only done on the very first login for each account.
 	 */
-	if ( ( session->distcode == NULL ) || ( strlen( session->distcode ) == 0 ) ) {
+	if ( ( session->distcode == NULL ) || ( !*session->distcode ) ) {
 		/* this must be the very first login, so we need to retrieve the user information */
 		get_clientinfo( session );
 	}
--- a/libpurple/protocols/mxit/markup.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/markup.c	Sun Sep 11 04:19:01 2011 +0000
@@ -124,10 +124,11 @@
  * Adds a link to a message
  *
  *  @param mx				The Markup message object
- *	@param linkname			This is the what will be returned when the link gets clicked
- *	@param displayname		This is the name for the link which will be displayed in the UI
+ *	@param replydata		This is the what will be returned when the link gets clicked
+ *	@param isStructured		Indicates that the reply is a structured reply
+ *	@param displaytext		This is the text for the link which will be displayed in the UI
  */
-void mxit_add_html_link( struct RXMsgData* mx, const char* linkname, const char* displayname )
+void mxit_add_html_link( struct RXMsgData* mx, const char* replydata, gboolean isStructured, const char* displaytext )
 {
 #ifdef	MXIT_LINK_CLICK
 	char	retstr[256];
@@ -135,15 +136,24 @@
 	char	link[256];
 	int		len;
 
-	len = g_snprintf( retstr, sizeof( retstr ), "%s|%s|%s|%s|%s", MXIT_LINK_KEY, purple_account_get_username( mx->session->acc ),
-											purple_account_get_protocol_id( mx->session->acc ), mx->from, linkname );
+	/*
+	 * The link content is encoded as follows:
+	 *  MXIT_LINK_KEY | ACCOUNT_USER | ACCOUNT_PROTO | REPLY_TO | REPLY_FORMAT | REPLY_DATA
+	 */
+	len = g_snprintf( retstr, sizeof( retstr ), "%s|%s|%s|%s|%i|%s",
+			MXIT_LINK_KEY,
+			purple_account_get_username( mx->session->acc ),
+			purple_account_get_protocol_id( mx->session->acc ),
+			mx->from,
+			isStructured ? 1 : 0,
+			replydata );
 	retstr64 = purple_base64_encode( (const unsigned char*) retstr, len );
 	g_snprintf( link, sizeof( link ), "%s%s", MXIT_LINK_PREFIX, retstr64 );
 	g_free( retstr64 );
 
-	g_string_append_printf( mx->msg, "<a href=\"%s\">%s</a>", link, displayname );
+	g_string_append_printf( mx->msg, "<a href=\"%s\">%s</a>", link, displaytext );
 #else
-	g_string_append_printf( mx->msg, "<b>%s</b>", linkname );
+	g_string_append_printf( mx->msg, "<b>%s</b>", replydata );
 #endif
 }
 
@@ -735,6 +745,7 @@
 	gboolean	tag_bold	= FALSE;
 	gboolean	tag_under	= FALSE;
 	gboolean	tag_italic	= FALSE;
+	int			font_size	= 0;
 
 #ifdef MXIT_DEBUG_MARKUP
 	purple_debug_info( MXIT_PLUGIN_ID, "Markup RX (original): '%s'\n", message );
@@ -823,7 +834,7 @@
 					if ( ch ) {
 						/* end found */
 						*ch = '\0';
-						mxit_add_html_link( mx, &message[i + 1], &message[i + 1] );
+						mxit_add_html_link( mx, &message[i + 1], FALSE, &message[i + 1] );
 						*ch = '$';
 						i += ( ch - &message[i + 1] ) + 1;
 					}
@@ -862,59 +873,54 @@
 					}
 					break;
 			case '.' :
-					if ( !( msgflags & CP_MSG_EMOTICON ) ) {
-						g_string_append_c( mx->msg, message[i] );
-						break;
-					}
-					else if ( i + 1 >= len ) {
+					if ( i + 1 >= len ) {
 						/* message too short */
 						g_string_append_c( mx->msg, '.' );
 						break;
 					}
 
-					switch ( message[i+1] ) {
-						case '+' :
-								/* increment text size */
-								g_string_append( mx->msg, "<font size=\"+1\">" );
-								i++;
-								break;
-						case '-' :
-								/* decrement text size */
-								g_string_append( mx->msg, "<font size=\"-1\">" );
-								i++;
-								break;
-						case '{' :
-								/* custom emoticon */
-								if ( i + 2 >= len ) {
-									/* message too short */
-									g_string_append_c( mx->msg, '.' );
-									break;
-								}
+					if ( ( msgflags & CP_MSG_EMOTICON ) && ( message[i+1] == '{' ) ) {
+						/* custom emoticon */
+						if ( i + 2 >= len ) {
+							/* message too short */
+							g_string_append_c( mx->msg, '.' );
+							break;
+						}
+
+						parse_emoticon_str( &message[i+2], tmpstr1 );
+						if ( tmpstr1[0] != '\0' ) {
+							mx->got_img = TRUE;
+
+							if ( g_hash_table_lookup( mx->session->iimages, tmpstr1 ) ) {
+								/* emoticon found in the cache, so we do not have to request it from the WAPsite */
+							}
+							else {
+								/* request emoticon from the WAPsite */
+								mx->img_count++;
+								emoticon_request( mx, tmpstr1 );
+							}
 
-								parse_emoticon_str( &message[i+2], tmpstr1 );
-								if ( tmpstr1[0] != '\0' ) {
-									mx->got_img = TRUE;
+							g_string_append_printf( mx->msg, MXIT_II_TAG"%s>", tmpstr1 );
+							i += strlen( tmpstr1 ) + 2;
+						}
+						else
+							g_string_append_c( mx->msg, '.' );
+					}
+					else if ( ( msgflags & CP_MSG_MARKUP ) && ( message[i+1] == '+' ) ) {
+						/* increment text size */
+						font_size++;
+						g_string_append_printf( mx->msg, "<font size=\"%+i\">", font_size );
+						i++;
+					}
+					else if ( ( msgflags & CP_MSG_MARKUP ) && ( message[i+1] == '-' ) ) {
+						/* decrement text size */
+						font_size--;
+						g_string_append_printf( mx->msg, "<font size=\"%+i\">", font_size );
+						i++;
+					}
+					else
+						g_string_append_c( mx->msg, '.' );
 
-									if ( g_hash_table_lookup( mx->session->iimages, tmpstr1 ) ) {
-										/* emoticon found in the cache, so we do not have to request it from the WAPsite */
-									}
-									else {
-										/* request emoticon from the WAPsite */
-										mx->img_count++;
-										emoticon_request( mx, tmpstr1 );
-									}
-
-									g_string_append_printf( mx->msg, MXIT_II_TAG"%s>", tmpstr1 );
-									i += strlen( tmpstr1 ) + 2;
-								}
-								else
-									g_string_append_c( mx->msg, '.' );
-
-								break;
-						default :
-								g_string_append_c( mx->msg, '.' );
-								break;
-					}
 					break;
 			case '\\' :
 					if ( i + 1 >= len ) {
--- a/libpurple/protocols/mxit/markup.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/markup.h	Sun Sep 11 04:19:01 2011 +0000
@@ -31,7 +31,7 @@
 
 void mxit_parse_markup( struct RXMsgData* mx, char* message, int len, short msgtype, int msgflags );
 char* mxit_convert_markup_tx( const char* message, int* msgtype );
-void mxit_add_html_link( struct RXMsgData* mx, const char* linkname, const char* displayname );
+void mxit_add_html_link( struct RXMsgData* mx, const char* replydata, gboolean isStructured, const char* displaytext );
 void mxit_show_message( struct RXMsgData* mx );
 
 void mxit_free_emoticon_cache( struct MXitSession* session );
--- a/libpurple/protocols/mxit/multimx.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/multimx.c	Sun Sep 11 04:19:01 2011 +0000
@@ -277,7 +277,11 @@
 	GHashTable *components;
 	struct multimx* multimx = NULL;
 
-	purple_debug_info(MXIT_PLUGIN_ID, "Groupchat invite to '%s' by '%s'\n", contact->alias, creator);
+	purple_debug_info(MXIT_PLUGIN_ID, "Groupchat invite to '%s' (roomid='%s') by '%s'\n", contact->alias, contact->username, creator);
+
+	/* Check if the room already exists (ie, already joined or invite pending) */
+	if (find_room_by_username(session, contact->username) != NULL)
+		return;
 
 	/* Create a new room */
 	multimx = room_create(session, contact->username, contact->alias, STATE_INVITED);
@@ -307,7 +311,7 @@
 	multimx = find_room_by_username(session, contact->username);
 	if (multimx == NULL) {
 		multimx = room_create(session, contact->username, contact->alias, TRUE);
-		}
+	}
 	else if (multimx->state == STATE_INVITED) {
 		/* After successfully accepting an invitation */
 		multimx->state = STATE_JOINED;
@@ -454,7 +458,7 @@
  */
 void mxit_chat_join(PurpleConnection *gc, GHashTable *components)
 {
-	struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+	struct MXitSession* session = purple_connection_get_protocol_data(gc);
 	const char* roomname = NULL;
 	struct multimx* multimx = NULL;
 
@@ -496,7 +500,7 @@
  */
 void mxit_chat_reject(PurpleConnection *gc, GHashTable* components)
 {
-	struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+	struct MXitSession* session = purple_connection_get_protocol_data(gc);
 	const char* roomname = NULL;
 	struct multimx* multimx = NULL;
 
@@ -539,7 +543,7 @@
  */
 void mxit_chat_invite(PurpleConnection *gc, int id, const char *msg, const char *username)
 {
-	struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+	struct MXitSession* session = purple_connection_get_protocol_data(gc);
 	struct multimx* multimx = NULL;
 	PurpleBuddy* buddy;
 	PurpleConversation *convo;
@@ -585,7 +589,7 @@
  */
 void mxit_chat_leave(PurpleConnection *gc, int id)
 {
-	struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+	struct MXitSession* session = purple_connection_get_protocol_data(gc);
 	struct multimx* multimx = NULL;
 
 	purple_debug_info(MXIT_PLUGIN_ID, "Groupchat %i leave\n", id);
@@ -616,7 +620,7 @@
  */
 int mxit_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags)
 {
-	struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+	struct MXitSession* session = purple_connection_get_protocol_data(gc);
 	struct multimx* multimx = NULL;
 	const char* nickname;
 
--- a/libpurple/protocols/mxit/mxit.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/mxit.c	Sun Sep 11 04:19:01 2011 +0000
@@ -58,7 +58,7 @@
 static void* mxit_link_click( const char* link64 )
 {
 	PurpleAccount*		account;
-	PurpleConnection*	con;
+	PurpleConnection*	gc;
 	gchar**				parts		= NULL;
 	gchar*				link		= NULL;
 	gsize				len;
@@ -75,10 +75,10 @@
 	link = (gchar*) purple_base64_decode( link64 + strlen( MXIT_LINK_PREFIX ), &len );
 	purple_debug_info( MXIT_PLUGIN_ID, "Clicked Link: '%s'\n", link );
 
-	parts = g_strsplit( link, "|", 5 );
+	parts = g_strsplit( link, "|", 6 );
 
 	/* check if this is a valid mxit link */
-	if ( ( !parts ) || ( !parts[0] ) || ( !parts[1] ) || ( !parts[2] ) || ( !parts[3] ) || ( !parts[4] ) ) {
+	if ( ( !parts ) || ( !parts[0] ) || ( !parts[1] ) || ( !parts[2] ) || ( !parts[3] ) || ( !parts[4] ) || ( !parts[5] ) ) {
 		/* this is not for us */
 		goto skip;
 	}
@@ -91,15 +91,15 @@
 	account = purple_accounts_find( parts[1], parts[2] );
 	if ( !account )
 		goto skip;
-	con = purple_account_get_connection( account );
-	if ( !con )
+	gc = purple_account_get_connection( account );
+	if ( !gc )
 		goto skip;
 
 	/* determine if it's a command-response to send */
-	is_command = g_str_has_prefix( parts[4], "::type=reply|" );
+	is_command = ( atoi( parts[4] ) == 1 );
 
 	/* send click message back to MXit */
-	mxit_send_message( con->proto_data, parts[3], parts[4], FALSE, is_command );
+	mxit_send_message( purple_connection_get_protocol_data( gc ), parts[3], parts[5], FALSE, is_command );
 
 	g_free( link );
 	link = NULL;
@@ -129,7 +129,7 @@
 /*------------------------------------------------------------------------
  * Register MXit to receive URI click notifications from the UI
  */
-void mxit_register_uri_handler(void)
+void mxit_register_uri_handler( void )
 {
 	not_link_ref_count++;
 	if ( not_link_ref_count == 1 ) {
@@ -198,7 +198,7 @@
 	if ( !buddy )
 		return;
 
-	contact = purple_buddy_get_protocol_data(buddy);
+	contact = purple_buddy_get_protocol_data( buddy );
 	if ( !contact )
 		return;
 
@@ -214,7 +214,7 @@
 		case MXIT_TYPE_INFO :
 				tmp = g_strdup_printf("<font color=\"#999999\">%s</font>\n", _( "Loading menu..." ));
 				serv_got_im( session->con, who, tmp, PURPLE_MESSAGE_NOTIFY, time( NULL ) );
-				g_free(tmp);
+				g_free( tmp );
 				mxit_send_message( session, who, " ", FALSE, FALSE );
 		default :
 				break;
@@ -268,7 +268,7 @@
  */
 static const char* mxit_list_emblem( PurpleBuddy* buddy )
 {
-	struct contact*	contact = purple_buddy_get_protocol_data(buddy);
+	struct contact*	contact = purple_buddy_get_protocol_data( buddy );
 
 	if ( !contact )
 		return NULL;
@@ -309,19 +309,18 @@
  */
 char* mxit_status_text( PurpleBuddy* buddy )
 {
-	struct contact*	contact = purple_buddy_get_protocol_data(buddy);
+	char* text = NULL;
+	struct contact*	contact = purple_buddy_get_protocol_data( buddy );
 
 	if ( !contact )
 		return NULL;
 
-	if ( contact->statusMsg ) {
-		/* status message */
-		return g_strdup( contact-> statusMsg );
-	}
-	else {
-		/* mood */
-		return g_strdup( mxit_convert_mood_to_name( contact->mood ) );
-	}
+	if ( contact->statusMsg )							/* status message */
+		text = g_strdup( contact-> statusMsg );
+	else if ( contact->mood != MXIT_MOOD_NONE )			/* mood */
+		text = g_strdup( mxit_convert_mood_to_name( contact->mood ) );
+
+	return text;
 }
 
 
@@ -334,34 +333,33 @@
  */
 static void mxit_tooltip( PurpleBuddy* buddy, PurpleNotifyUserInfo* info, gboolean full )
 {
-	struct contact*	contact = purple_buddy_get_protocol_data(buddy);
+	struct contact*	contact = purple_buddy_get_protocol_data( buddy );
 
 	if ( !contact )
 		return;
 
 	/* status (reference: "libpurple/notify.h") */
 	if ( contact->presence != MXIT_PRESENCE_OFFLINE )
-		purple_notify_user_info_add_pair( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) );
+		purple_notify_user_info_add_pair_plaintext( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) );
 
 	/* status message */
-	if ( contact->statusMsg )
-		purple_notify_user_info_add_pair( info, _( "Status Message" ), contact->statusMsg );
+	if ( contact->statusMsg ) {
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html( info, _( "Status Message" ), contact->statusMsg );
+	}
 
 	/* mood */
 	if ( contact->mood != MXIT_MOOD_NONE )
-		purple_notify_user_info_add_pair( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) );
+		purple_notify_user_info_add_pair_plaintext( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) );
 
 	/* subscription type */
 	if ( contact->subtype != 0 )
-		purple_notify_user_info_add_pair( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) );
+		purple_notify_user_info_add_pair_plaintext( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) );
 
 	/* rejection message */
 	if ( ( contact->subtype == MXIT_SUBTYPE_REJECTED ) && ( contact->msg != NULL ) )
-		purple_notify_user_info_add_pair( info, _( "Rejection Message" ), contact->msg );
-
-	/* hidden number */
-	if ( contact->flags & MXIT_CFLAG_HIDDEN )
-		purple_notify_user_info_add_pair( info, _( "Hidden Number" ), _( "Yes" ) );
+		purple_notify_user_info_add_pair_plaintext( info, _( "Rejection Message" ), contact->msg );
 }
 
 
@@ -372,7 +370,7 @@
  */
 static void mxit_close( PurpleConnection* gc )
 {
-	struct MXitSession*	session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*	session	= purple_connection_get_protocol_data( gc );
 
 	/* disable signals */
 	mxit_disable_signals( session );
@@ -408,7 +406,7 @@
 {
 	purple_debug_info( MXIT_PLUGIN_ID, "Sending message '%s' to buddy '%s'\n", message, who );
 
-	mxit_send_message( gc->proto_data, who, message, TRUE, FALSE );
+	mxit_send_message( purple_connection_get_protocol_data( gc ), who, message, TRUE, FALSE );
 
 	return 1;		/* echo to conversation window */
 }
@@ -422,14 +420,14 @@
  */
 static void mxit_set_status( PurpleAccount* account, PurpleStatus* status )
 {
-	struct MXitSession*		session =	purple_account_get_connection( account )->proto_data;
+	struct MXitSession*		session =	purple_connection_get_protocol_data( purple_account_get_connection( account ) );
 	const char*				statusid;
 	int						presence;
 	char*					statusmsg1;
 	char*					statusmsg2;
 
 	/* Handle mood changes */
-	if (purple_status_type_get_primitive(purple_status_get_type(status)) == PURPLE_STATUS_MOOD) {
+	if ( purple_status_type_get_primitive(purple_status_get_type( status ) ) == PURPLE_STATUS_MOOD ) {
 		const char* moodid = purple_status_get_attr_string( status, PURPLE_MOOD_NAME );
 		int mood;
 
@@ -492,7 +490,7 @@
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_free_buddy\n" );
 
-	contact = purple_buddy_get_protocol_data(buddy);
+	contact = purple_buddy_get_protocol_data( buddy );
 	if ( contact ) {
 		if ( contact->statusMsg )
 			g_free( contact->statusMsg );
@@ -503,7 +501,7 @@
 		g_free( contact );
 	}
 
-	purple_buddy_set_protocol_data(buddy, NULL);
+	purple_buddy_set_protocol_data( buddy, NULL );
 }
 
 
@@ -515,7 +513,7 @@
  */
 static void mxit_keepalive( PurpleConnection *gc )
 {
-	struct MXitSession*	session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*	session	= purple_connection_get_protocol_data( gc );
 
 	/* if not logged in, there is nothing to do */
 	if ( !( session->flags & MXIT_FLAG_LOGGEDIN ) )
@@ -543,7 +541,7 @@
  */
 static void mxit_set_buddy_icon( PurpleConnection *gc, PurpleStoredImage *img )
 {
-	struct MXitSession*	session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*	session	= purple_connection_get_protocol_data( gc );
 
 	if ( img == NULL )
 		mxit_set_avatar( session, NULL, 0 );
@@ -562,7 +560,7 @@
 {
 	PurpleBuddy*			buddy;
 	struct contact*			contact;
-	struct MXitSession*		session			= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*		session			= purple_connection_get_protocol_data( gc );
 	const char*				profilelist[]	= { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME,
 												CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_REGCOUNTRY, CP_PROFILE_LASTSEEN,
 												CP_PROFILE_STATUS, CP_PROFILE_AVATAR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME };
@@ -612,14 +610,10 @@
  */
 static void mxit_reinvite( PurpleBlistNode *node, gpointer ignored )
 {
-	PurpleBuddy*		buddy;
+	PurpleBuddy*		buddy		= (PurpleBuddy *) node;
+	PurpleConnection*	gc			= purple_account_get_connection( purple_buddy_get_account( buddy ) );
+	struct MXitSession*	session		= purple_connection_get_protocol_data( gc );
 	struct contact*		contact;
-	PurpleConnection*	gc;
-	struct MXitSession*	session;
-
-	buddy = (PurpleBuddy *)node;
-	gc = purple_account_get_connection( purple_buddy_get_account( buddy ) );
-	session = gc->proto_data;
 
 	contact = purple_buddy_get_protocol_data( (PurpleBuddy*) node );
 	if ( !contact )
@@ -653,15 +647,28 @@
 	if ( ( contact->subtype == MXIT_SUBTYPE_DELETED ) || ( contact->subtype == MXIT_SUBTYPE_REJECTED ) || ( contact->subtype == MXIT_SUBTYPE_NONE ) ) {
 		/* contact is in Deleted, Rejected or None state */
 		act = purple_menu_action_new( _( "Re-Invite" ), PURPLE_CALLBACK( mxit_reinvite ), NULL, NULL );
-		m = g_list_append(m, act);
+		m = g_list_append( m, act );
 	}
 
 	return m;
 }
 
+
+/*------------------------------------------------------------------------
+ * Return Chat-room default settings.
+ *
+ *  @return		Chat defaults list
+ */
+static GHashTable *mxit_chat_info_defaults( PurpleConnection *gc, const char *chat_name )
+{
+    return g_hash_table_new_full( g_str_hash, g_str_equal, NULL, g_free );
+}
+
+
 /*========================================================================================================================*/
 
 static PurplePluginProtocolInfo proto_info = {
+	sizeof( PurplePluginProtocolInfo ),		/* struct_size */
 	OPT_PROTO_REGISTER_NOSCREENNAME | OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE,			/* options */
 	NULL,					/* user_splits */
 	NULL,					/* protocol_options */
@@ -680,7 +687,7 @@
 	mxit_status_types,		/* status types				[roster.c] */
 	mxit_blist_menu,		/* blist_node_menu */
 	mxit_chat_info,			/* chat_info				[multimx.c] */
-	NULL,					/* chat_info_defaults */
+	mxit_chat_info_defaults,/* chat_info_defaults */
 	mxit_login,				/* login					[login.c] */
 	mxit_close,				/* close */
 	mxit_send_im,			/* send_im */
@@ -690,7 +697,7 @@
 	mxit_set_status,		/* set_status */
 	NULL,					/* set_idle */
 	NULL,					/* change_passwd */
-	NULL,					/* add_buddy				[roster.c] */
+	mxit_add_buddy,			/* add_buddy				[roster.c] */
 	NULL,					/* add_buddies */
 	mxit_remove_buddy,		/* remove_buddy				[roster.c] */
 	NULL,					/* remove_buddies */
@@ -734,15 +741,12 @@
 	NULL,					/* unregister_user */
 	NULL,					/* send_attention */
 	NULL,					/* attention_types */
-	sizeof( PurplePluginProtocolInfo ),		/* struct_size */
 	mxit_get_text_table,	/* get_account_text_table */
 	mxit_media_initiate,	/* initiate_media */
 	mxit_media_caps,		/* get_media_caps */
 	mxit_get_moods,			/* get_moods */
 	NULL,					/* set_public_alias */
-	NULL,					/* get_public_alias */
-	mxit_add_buddy,			/* add_buddy_with_invite */
-	NULL					/* add_buddies_with_invite */
+	NULL					/* get_public_alias */
 };
 
 
--- a/libpurple/protocols/mxit/mxit.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/mxit.h	Sun Sep 11 04:19:01 2011 +0000
@@ -191,7 +191,7 @@
 void mxit_enable_signals( struct MXitSession* session );
 
 #ifdef	MXIT_LINK_CLICK
-void mxit_register_uri_handler(void);
+void mxit_register_uri_handler( void );
 #endif
 
 
--- a/libpurple/protocols/mxit/profile.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/profile.c	Sun Sep 11 04:19:01 2011 +0000
@@ -115,16 +115,16 @@
 	struct tm now, bdate;
 	int age;
 
-	if ( ( !date ) || ( strlen( date ) == 0 ) )
+	if ( ( !date ) || ( !*date ) )
 		return 0;
 
 	/* current time */
-	t = time(NULL);
+	t = time( NULL );
 	localtime_r( &t, &now );
 
 	/* decode hdate */
 	memset( &bdate, 0, sizeof( struct tm ) );
-	purple_str_to_time(date, FALSE, &bdate, NULL, NULL);
+	purple_str_to_time( date, FALSE, &bdate, NULL, NULL );
 
 	/* calculate difference */
 	age = now.tm_year - bdate.tm_year;
@@ -170,54 +170,56 @@
 
 	buddy = purple_find_buddy( session->acc, username );
 	if ( buddy ) {
-		purple_notify_user_info_add_pair( info, _( "Alias" ), purple_buddy_get_alias( buddy ) );
+		purple_notify_user_info_add_pair_plaintext( info, _( "Alias" ), purple_buddy_get_alias( buddy ) );
 		purple_notify_user_info_add_section_break( info );
-		contact = purple_buddy_get_protocol_data(buddy);
+		contact = purple_buddy_get_protocol_data( buddy );
 	}
 
-	purple_notify_user_info_add_pair( info, _( "Display Name" ), profile->nickname );
+	purple_notify_user_info_add_pair_plaintext( info, _( "Display Name" ), profile->nickname );
 
 	tmp = g_strdup_printf("%s (%i)", profile->birthday, calculateAge( profile->birthday ) );
-	purple_notify_user_info_add_pair( info, _( "Birthday" ), tmp );
+	purple_notify_user_info_add_pair_plaintext( info, _( "Birthday" ), tmp );
 	g_free( tmp );
 
-	purple_notify_user_info_add_pair( info, _( "Gender" ), profile->male ? _( "Male" ) : _( "Female" ) );
+	purple_notify_user_info_add_pair_plaintext( info, _( "Gender" ), profile->male ? _( "Male" ) : _( "Female" ) );
 
 	/* optional information */
-	purple_notify_user_info_add_pair( info, _( "First Name" ), profile->firstname );
-	purple_notify_user_info_add_pair( info, _( "Last Name" ), profile->lastname );
-	purple_notify_user_info_add_pair( info, _( "Country" ), profile->regcountry );
+	purple_notify_user_info_add_pair_plaintext( info, _( "First Name" ), profile->firstname );
+	purple_notify_user_info_add_pair_plaintext( info, _( "Last Name" ), profile->lastname );
+
+	purple_notify_user_info_add_pair_plaintext( info, _( "Country" ), profile->regcountry );
 
-	if ( strlen( profile->aboutme ) > 0 )
-		purple_notify_user_info_add_pair( info, _( "About Me" ), profile->aboutme );
-	if ( strlen( profile->whereami ) > 0 )
-		purple_notify_user_info_add_pair( info, _( "Where I Live" ), profile->whereami );
+	if ( *profile->aboutme )
+		purple_notify_user_info_add_pair_plaintext( info, _( "About Me" ), profile->aboutme );
+
+	if ( *profile->whereami )
+		purple_notify_user_info_add_pair_plaintext( info, _( "Where I Live" ), profile->whereami );
 
 	purple_notify_user_info_add_section_break( info );
 
 	if ( contact ) {
 		/* presence */
-		purple_notify_user_info_add_pair( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) );
+		purple_notify_user_info_add_pair_plaintext( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) );
 
 		/* last online */
 		if ( contact->presence == MXIT_PRESENCE_OFFLINE )
-			purple_notify_user_info_add_pair( info, _( "Last Online" ), ( profile->lastonline == 0 ) ? _( "Unknown" ) : datetime( profile->lastonline ) );
+			purple_notify_user_info_add_pair_plaintext( info, _( "Last Online" ), ( profile->lastonline == 0 ) ? _( "Unknown" ) : datetime( profile->lastonline ) );
 
 		/* mood */
 		if ( contact->mood != MXIT_MOOD_NONE )
-			purple_notify_user_info_add_pair( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) );
+			purple_notify_user_info_add_pair_plaintext( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) );
 		else
-			purple_notify_user_info_add_pair( info, _( "Mood" ), _( "None" ) );
+			purple_notify_user_info_add_pair_plaintext( info, _( "Mood" ), _( "None" ) );
 
 		/* status message */
-		if ( contact->statusMsg )
-			purple_notify_user_info_add_pair( info, _( "Status Message" ), contact->statusMsg );
+		if ( contact->statusMsg ) {
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html( info, _( "Status Message" ), contact->statusMsg );
+		}
 
 		/* subscription type */
-		purple_notify_user_info_add_pair( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) );
-
-		/* hidden number */
-		purple_notify_user_info_add_pair( info, _( "Hidden Number" ), ( contact->flags & MXIT_CFLAG_HIDDEN ) ? _( "Yes" ) : _( "No" ) );
+		purple_notify_user_info_add_pair_plaintext( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) );
 	}
 	else {
 		/* this is an invite */
@@ -226,17 +228,21 @@
 			/* invite found */
 
 			if ( contact->msg )
-				purple_notify_user_info_add_pair( info, _( "Invite Message" ), contact->msg );
+				purple_notify_user_info_add_pair_plaintext( info, _( "Invite Message" ), contact->msg );
 
 			if ( contact->imgid ) {
 				/* this invite has a avatar */
 				char* img_text;
 				img_text = g_strdup_printf( "<img id='%d'>", contact->imgid );
-				purple_notify_user_info_add_pair( info, _( "Photo" ), img_text );
+				purple_notify_user_info_add_pair_html( info, _( "Photo" ), img_text );
+				g_free(img_text);
 			}
 
-			if ( contact->statusMsg )
-				purple_notify_user_info_add_pair( info, _( "Status Message" ), contact->statusMsg );
+			if ( contact->statusMsg ) {
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html( info, _( "Status Message" ), contact->statusMsg );
+			}
 		}
 	}
 
@@ -284,6 +290,7 @@
 
 	/* define columns */
 	column = purple_notify_searchresults_column_new( _( "UserId" ) );
+	purple_notify_searchresult_column_set_visible( column, FALSE );
 	purple_notify_searchresults_column_add( results, column );
 	column = purple_notify_searchresults_column_new( _( "Display Name" ) );
 	purple_notify_searchresults_column_add( results, column );
@@ -298,7 +305,7 @@
 	column = purple_notify_searchresults_column_new( _( "Where I live" ) );
 	purple_notify_searchresults_column_add( results, column );
 
-	while (entries != NULL) {
+	while ( entries != NULL ) {
 		struct MXitProfile* profile	= ( struct MXitProfile *) entries->data;
 		GList*	row;
 		gchar* tmp = purple_base64_encode( (unsigned char *) profile->userid, strlen( profile->userid ) );
@@ -328,5 +335,5 @@
 
 	purple_notify_searchresults( session->con, NULL, text, NULL, results, NULL, NULL );
 
-	g_free( text);
+	g_free( text );
 }
--- a/libpurple/protocols/mxit/profile.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/profile.h	Sun Sep 11 04:19:01 2011 +0000
@@ -50,7 +50,6 @@
 
 	int			flags;								/* user's profile flags */
 	gint64		lastonline;							/* user's last-online timestamp */
-	gboolean	hidden;								/* set if the user's mxitid should remain hidden */
 };
 
 struct MXitSession;
--- a/libpurple/protocols/mxit/protocol.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/protocol.c	Sun Sep 11 04:19:01 2011 +0000
@@ -86,7 +86,7 @@
 void mxit_strip_domain( char* username )
 {
 	if ( g_str_has_suffix( username, "@m" ) )
-		username[ strlen(username) - 2 ] = '\0';
+		username[ strlen( username ) - 2 ] = '\0';
 }
 
 
@@ -408,7 +408,7 @@
 		res = mxit_write_sock_packet( session->fd, data, datalen );
 		if ( res < 0 ) {
 			/* we must have lost the connection, so terminate it so that we can reconnect */
-			purple_connection_error( session->con, _( "We have lost the connection to MXit. Please reconnect." ) );
+			purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "We have lost the connection to MXit. Please reconnect." ) );
 		}
 	}
 	else {
@@ -530,7 +530,7 @@
 		if ( session->last_tx <= mxit_now_milli() - ( MXIT_ACK_TIMEOUT * 1000 ) ) {
 			/* ack timeout! so we close the connection here */
 			purple_debug_info( MXIT_PLUGIN_ID, "mxit_manage_queue: Timeout awaiting ACK for command '%i'\n", session->outack );
-			purple_connection_error( session->con, _( "Timeout while waiting for a response from the MXit server." ) );
+			purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Timeout while waiting for a response from the MXit server." ) );
 		}
 		return;
 	}
@@ -704,9 +704,9 @@
 	locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE );
 
 	/* Voice and Video supported */
-	if (mxit_audio_enabled() && mxit_video_enabled())
-		features |= (MXIT_CF_VOICE | MXIT_CF_VIDEO);
-	else if (mxit_audio_enabled())
+	if ( mxit_audio_enabled() && mxit_video_enabled() )
+		features |= ( MXIT_CF_VOICE | MXIT_CF_VIDEO );
+	else if ( mxit_audio_enabled() )
 		features |= MXIT_CF_VOICE;
 
 	/* generate client version string (eg, P-2.7.10-Y-PURPLE) */
@@ -748,9 +748,9 @@
 	locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE );
 
 	/* Voice and Video supported */
-	if (mxit_audio_enabled() && mxit_video_enabled())
-		features |= (MXIT_CF_VOICE | MXIT_CF_VIDEO);
-	else if (mxit_audio_enabled())
+	if ( mxit_audio_enabled() && mxit_video_enabled() )
+		features |= ( MXIT_CF_VOICE | MXIT_CF_VIDEO );
+	else if ( mxit_audio_enabled() )
 		features |= MXIT_CF_VOICE;
 
 	/* generate client version string (eg, P-2.7.10-Y-PURPLE) */
@@ -835,7 +835,7 @@
 
 	/* add attributes */
 	for ( i = 0; i < nr_attrib; i++ )
-		datalen += sprintf(	data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
+		datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
 
 	/* queue packet for transmission */
 	mxit_queue_packet( session, data, datalen, CP_CMD_EXTPROFILE_GET );
@@ -868,7 +868,7 @@
 
 	/* add attributes */
 	for ( i = 1; i < nr_attrib * 3; i+=3 )
-		datalen += sprintf(	data + datalen, "%c%s%c%s%c%s",		/* \1name\1type\1value  */
+		datalen += sprintf( data + datalen, "%c%s%c%s%c%s",		/* \1name\1type\1value  */
 								CP_FLD_TERM, parts[i], CP_FLD_TERM, parts[i + 1], CP_FLD_TERM, parts[i + 2] );
 
 	/* queue packet for transmission */
@@ -900,7 +900,7 @@
 
 	/* add attributes */
 	for ( i = 0; i < nr_attrib; i++ )
-		datalen += sprintf(	data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
+		datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
 
 	/* queue packet for transmission */
 	mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS );
@@ -929,7 +929,7 @@
 
 	/* add attributes */
 	for ( i = 0; i < nr_attrib; i++ )
-		datalen += sprintf(	data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
+		datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
 
 	/* queue packet for transmission */
 	mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS );
@@ -1175,7 +1175,7 @@
 
 	/* add usernames */
 	for ( i = 0; i < nr_usernames; i++ )
-		datalen += sprintf(	data + datalen, "%c%s", CP_FLD_TERM, usernames[i] );
+		datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] );
 
 	/* queue packet for transmission */
 	mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_CREATE );
@@ -1204,7 +1204,7 @@
 
 	/* add usernames */
 	for ( i = 0; i < nr_usernames; i++ )
-		datalen += sprintf(	data + datalen, "%c%s", CP_FLD_TERM, usernames[i] );
+		datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] );
 
 	/* queue packet for transmission */
 	mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_INVITE );
@@ -1448,7 +1448,7 @@
 	PurpleStatus*	status;
 	int				presence;
 	const char*		statusmsg;
-	const char*		profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_HIDENUMBER, CP_PROFILE_FULLNAME,
+	const char*		profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME,
 									CP_PROFILE_TITLE, CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_EMAIL,
 									CP_PROFILE_MOBILENR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME, CP_PROFILE_FLAGS };
 
@@ -1516,6 +1516,7 @@
 {
 	struct RXMsgData*	mx			= NULL;
 	char*				message		= NULL;
+	char*				sender		= NULL;
 	int					msglen		= 0;
 	int					msgflags	= 0;
 	int					msgtype		= 0;
@@ -1529,10 +1530,11 @@
 	msglen = strlen( message );
 
 	/* strip off dummy domain */
-	mxit_strip_domain( records[0]->fields[0]->data );
+	sender = records[0]->fields[0]->data;
+	mxit_strip_domain( sender );
 
 #ifdef	DEBUG_PROTOCOL
-	purple_debug_info( MXIT_PLUGIN_ID, "Message received from '%s'\n", records[0]->fields[0]->data );
+	purple_debug_info( MXIT_PLUGIN_ID, "Message received from '%s'\n", sender );
 #endif
 
 	/* decode message flags (if any) */
@@ -1540,33 +1542,42 @@
 		msgflags = atoi( records[0]->fields[4]->data );
 	msgtype = atoi( records[0]->fields[2]->data );
 
-	if ( msgflags & CP_MSG_ENCRYPTED ) {
-		/* this is an encrypted message. we do not currently support those so ignore it */
+	if ( msgflags & CP_MSG_PWD_ENCRYPTED ) {
+		/* this is a password encrypted message. we do not currently support those so ignore it */
 		PurpleBuddy*	buddy;
 		const char*		name;
 		char			msg[128];
 
-		buddy = purple_find_buddy( session->acc, records[0]->fields[0]->data );
+		buddy = purple_find_buddy( session->acc, sender );
 		if ( buddy )
 			name = purple_buddy_get_alias( buddy );
 		else
-			name = records[0]->fields[0]->data;
+			name = sender;
 		g_snprintf( msg, sizeof( msg ), _( "%s sent you an encrypted message, but it is not supported on this client." ), name );
 		mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Message Error" ), msg );
 		return;
 	}
+	else if ( msgflags & CP_MSG_TL_ENCRYPTED ) {
+		/* this is a transport-layer encrypted message. */
+		message = mxit_decrypt_message( session, message );
+		if ( !message ) {
+			/* could not be decrypted */
+			serv_got_im( session->con, sender, _( "An encrypted message was received which could not be decrypted." ), PURPLE_MESSAGE_ERROR, time( NULL ) );
+			return;
+		}
+	}
 
 	if ( msgflags & CP_MSG_NOTIFY_DELIVERY ) {
 		/* delivery notification is requested */
 		if ( records[0]->fcount >= 4 )
-			mxit_send_msgevent( session, records[0]->fields[0]->data, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED );
+			mxit_send_msgevent( session, sender, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED );
 	}
 
 	/* create and initialise new markup struct */
 	mx = g_new0( struct RXMsgData, 1 );
 	mx->msg = g_string_sized_new( msglen );
 	mx->session = session;
-	mx->from = g_strdup( records[0]->fields[0]->data );
+	mx->from = g_strdup( sender );
 	mx->timestamp = atoi( records[0]->fields[1]->data );
 	mx->got_img = FALSE;
 	mx->chatid = -1;
@@ -1597,6 +1608,10 @@
 		 * so the image received callback function will eventually display
 		 * the message. */
 	}
+
+	/* cleanup */
+	if ( msgflags & CP_MSG_TL_ENCRYPTED )
+		g_free( message );
 }
 
 
@@ -1633,7 +1648,7 @@
 
 		if ( rec->fcount >= 5 ) {
 			/* there is a personal invite message attached */
-			if ( ( rec->fields[4]->data ) && ( strlen( rec->fields[4]->data ) > 0 ) )
+			if ( ( rec->fields[4]->data ) && ( *rec->fields[4]->data ) )
 				contact->msg = strdup( rec->fields[4]->data );
 		}
 
@@ -1810,10 +1825,6 @@
 			/* gender */
 			profile->male = ( fvalue[0] == '1' );
 		}
-		else if ( strcmp( CP_PROFILE_HIDENUMBER, fname ) == 0 ) {
-			/* hide number */
-			profile->hidden = ( fvalue[0] == '1' );
-		}
 		else if ( strcmp( CP_PROFILE_FULLNAME, fname ) == 0 ) {
 			/* nickname */
 			g_strlcpy( profile->nickname, fvalue, sizeof( profile->nickname ) );
@@ -1879,7 +1890,7 @@
 		contact = get_mxit_invite_contact( session, mxitId );
 		if ( contact ) {
 			/* this is an invite, so update its profile info */
-			if ( ( statusMsg ) && ( strlen( statusMsg ) > 0 ) ) {
+			if ( ( statusMsg ) && ( *statusMsg ) ) {
 				/* update the status message */
 				if ( contact->statusMsg )
 					g_free( contact->statusMsg );
@@ -1890,7 +1901,7 @@
 			if ( contact->profile )
 				g_free( contact->profile );
 			contact->profile = profile;
-			if ( ( avatarId ) && ( strlen( avatarId ) > 0 ) ) {
+			if ( ( avatarId ) && ( *avatarId ) ) {
 				/* avatar must be requested for this invite before we can display it */
 				mxit_get_avatar( session, mxitId, avatarId );
 				if ( contact->avatarId )
@@ -1908,7 +1919,7 @@
 			if ( avatarId )
 				mxit_update_buddy_avatar( session, mxitId, avatarId );
 
-			if ( ( statusMsg ) && ( strlen( statusMsg ) > 0 ) ) {
+			if ( ( statusMsg ) && ( *statusMsg ) ) {
 				/* update the status message */
 				PurpleBuddy*		buddy	= NULL;
 
@@ -2125,13 +2136,13 @@
 					contact = get_mxit_invite_contact( session, chunk.mxitid );
 					if ( contact ) {
 						/* this is an invite (add image to the internal image store) */
-						contact->imgid = purple_imgstore_add_with_id( chunk.data, chunk.length, NULL );
+						contact->imgid = purple_imgstore_add_with_id( g_memdup( chunk.data, chunk.length ), chunk.length, NULL );
 						/* show the profile */
 						mxit_show_profile( session, chunk.mxitid, contact->profile );
 					}
 					else {
 						/* this is a contact's avatar, so update it */
-						purple_buddy_icons_set_for_user( session->acc, chunk.mxitid, g_memdup( chunk.data, chunk.length), chunk.length, chunk.avatarid );
+						purple_buddy_icons_set_for_user( session->acc, chunk.mxitid, g_memdup( chunk.data, chunk.length ), chunk.length, chunk.avatarid );
 					}
 				}
 			}
@@ -2192,7 +2203,7 @@
 		session->port = atoi( host[2] );
 	}
 	else {
-		purple_connection_error( session->con, _( "Cannot perform redirect using the specified protocol" ) );
+		purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Cannot perform redirect using the specified protocol" ) );
 		goto redirect_fail;
 	}
 
@@ -2270,7 +2281,7 @@
 
 		case CP_CMD_PRESENCE :
 				/* presence update */
-				mxit_parse_cmd_presence(session, &packet->records[2], packet->rcount - 3 );
+				mxit_parse_cmd_presence( session, &packet->records[2], packet->rcount - 3 );
 				break;
 
 		case CP_CMD_RX_MSG :
@@ -2361,7 +2372,7 @@
 
 	if ( packet->errcode == MXIT_ERRCODE_LOGGEDOUT ) {
 		/* we are not currently logged in, so we need to reconnect */
-		purple_connection_error( session->con, _( errdesc ) );
+		purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( errdesc ) );
 	}
 
 	/* packet command */
@@ -2375,12 +2386,12 @@
 				}
 				else {
 					snprintf( errmsg, sizeof( errmsg ), _( "Login error: %s (%i)" ), errdesc, packet->errcode );
-					purple_connection_error( session->con, errmsg );
+					purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, errmsg );
 					return -1;
 				}
 		case CP_CMD_LOGOUT :
 				snprintf( errmsg, sizeof( errmsg ), _( "Logout error: %s (%i)" ), errdesc, packet->errcode );
-				purple_connection_error_reason( session->con, PURPLE_CONNECTION_ERROR_NAME_IN_USE, _( errmsg ) );
+				purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NAME_IN_USE, _( errmsg ) );
 				return -1;
 		case CP_CMD_CONTACT :
 				mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Contact Error" ), _( errdesc ) );
@@ -2643,7 +2654,7 @@
 
 		if ( packet.rcount < 2 ) {
 			/* bad packet */
-			purple_connection_error( session->con, _( "Invalid packet received from MXit." ) );
+			purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Invalid packet received from MXit." ) );
 			free_rx_packet( &packet );
 			continue;
 		}
@@ -2708,12 +2719,12 @@
 		len = read( session->fd, &ch, 1 );
 		if ( len < 0 ) {
 			/* connection error */
-			purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x01)" ) );
+			purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x01)" ) );
 			return;
 		}
 		else if ( len == 0 ) {
 			/* connection closed */
-			purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x02)" ) );
+			purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x02)" ) );
 			return;
 		}
 		else {
@@ -2723,7 +2734,7 @@
 				session->rx_lbuf[session->rx_i] = '\0';
 				session->rx_res = atoi( &session->rx_lbuf[3] );
 				if ( session->rx_res > CP_MAX_PACKET ) {
-					purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x03)" ) );
+					purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x03)" ) );
 				}
 				session->rx_state = RX_STATE_DATA;
 				session->rx_i = 0;
@@ -2734,7 +2745,7 @@
 				session->rx_i++;
 				if ( session->rx_i >= sizeof( session->rx_lbuf ) ) {
 					/* malformed packet length record (too long) */
-					purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x04)" ) );
+					purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x04)" ) );
 					return;
 				}
 			}
@@ -2745,12 +2756,12 @@
 		len = read( session->fd, &session->rx_dbuf[session->rx_i], session->rx_res );
 		if ( len < 0 ) {
 			/* connection error */
-			purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x05)" ) );
+			purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x05)" ) );
 			return;
 		}
 		else if ( len == 0 ) {
 			/* connection closed */
-			purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x06)" ) );
+			purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x06)" ) );
 			return;
 		}
 		else {
--- a/libpurple/protocols/mxit/protocol.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/protocol.h	Sun Sep 11 04:19:01 2011 +0000
@@ -155,7 +155,10 @@
 /* message flags */
 #define		CP_MSG_NOTIFY_DELIVERY	0x0002					/* request delivery notification */
 #define		CP_MSG_NOTIFY_READ		0x0004					/* request read notification */
-#define		CP_MSG_ENCRYPTED		0x0010					/* message is encrypted */
+#define		CP_MSG_PWD_ENCRYPTED	0x0010					/* message is password encrypted */
+#define		CP_MSG_TL_ENCRYPTED		0x0020					/* message is transport encrypted */
+#define		CP_MSG_RPLY_PWD_ENCRYPT	0x0040					/* reply should be password encrypted */
+#define		CP_MSG_RPLY_TL_ENCRYPT	0x0080					/* reply should be transport encrypted */
 #define		CP_MSG_MARKUP			0x0200					/* message may contain markup */
 #define		CP_MSG_EMOTICON			0x0400					/* message may contain custom emoticons */
 
@@ -179,7 +182,7 @@
 /* extended profile attribute fields */
 #define		CP_PROFILE_BIRTHDATE	"birthdate"				/* Birthdate (String - ISO 8601 format) */
 #define		CP_PROFILE_GENDER		"gender"				/* Gender (Boolean - 0=female, 1=male) */
-#define		CP_PROFILE_HIDENUMBER	"hidenumber"			/* Hide Number (Boolean - 0=false, 1=true) */
+// #define		CP_PROFILE_HIDENUMBER	"hidenumber"			/* Hide Number (Boolean - 0=false, 1=true) (DEPRECATED) */
 #define		CP_PROFILE_FULLNAME		"fullname"				/* Fullname (UTF8 String) */
 #define		CP_PROFILE_STATUS		"statusmsg"				/* Status Message (UTF8 String) */
 #define		CP_PROFILE_PREVSTATUS	"prevstatusmsgs"		/* Previous Status Messages (UTF8 String) */
--- a/libpurple/protocols/mxit/roster.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/roster.c	Sun Sep 11 04:19:01 2011 +0000
@@ -82,9 +82,9 @@
 	}
 
 	/* add Mood option */
-	type = purple_status_type_new_with_attrs(PURPLE_STATUS_MOOD, "mood", NULL, FALSE, TRUE, TRUE,
+	type = purple_status_type_new_with_attrs( PURPLE_STATUS_MOOD, "mood", NULL, FALSE, TRUE, TRUE,
 		PURPLE_MOOD_NAME, _("Mood Name"), purple_value_new( PURPLE_TYPE_STRING ),
-		NULL);
+		NULL );
 	statuslist = g_list_append( statuslist, type );
 
 	return statuslist;
@@ -135,21 +135,21 @@
 
 /* moods (reference: libpurple/status.h) */
 static PurpleMood mxit_moods[] = {
-	{"angry",		N_("Angry"),		NULL},
-	{"excited",		N_("Excited"),		NULL},
-	{"grumpy",		N_("Grumpy"),		NULL},
-	{"happy",		N_("Happy"),		NULL},
-	{"in_love",		N_("In love"),		NULL},
-	{"invincible",	N_("Invincible"),	NULL},
-	{"sad",			N_("Sad"),			NULL},
-	{"hot",			N_("Hot"),			NULL},
-	{"sick",		N_("Sick"),			NULL},
-	{"sleepy",		N_("Sleepy"),		NULL},
-	{"bored",		N_("Bored"),		NULL},
-	{"cold",		N_("Cold"),			NULL},
-	{"confused",	N_("Confused"),		NULL},
-	{"hungry",		N_("Hungry"),		NULL},
-	{"stressed",	N_("Stressed"),		NULL},
+	{ "angry",		N_( "Angry" ),		NULL },
+	{ "excited",	N_( "Excited" ),	NULL },
+	{ "grumpy",		N_( "Grumpy" ),		NULL },
+	{ "happy",		N_( "Happy" ),		NULL },
+	{ "in_love",	N_( "In love" ),	NULL },
+	{ "invincible",	N_( "Invincible" ),	NULL },
+	{ "sad",		N_( "Sad" ),		NULL },
+	{ "hot",		N_( "Hot" ),		NULL },
+	{ "sick",		N_( "Sick" ),		NULL },
+	{ "sleepy",		N_( "Sleepy" ),		NULL },
+	{ "bored",		N_( "Bored" ),		NULL },
+	{ "cold",		N_( "Cold" ),		NULL },
+	{ "confused",	N_( "Confused" ),	NULL },
+	{ "hungry",		N_( "Hungry" ),		NULL },
+	{ "stressed",	N_( "Stressed" ),	NULL },
 	/* Mark the last record. */
 	{ NULL, NULL, NULL }
 };
@@ -293,14 +293,15 @@
  */
 static PurpleBuddy* mxit_update_buddy_group( struct MXitSession* session, PurpleBuddy* buddy, PurpleGroup* group )
 {
-	struct contact*		contact			= NULL;
 	PurpleGroup*		current_group	= purple_buddy_get_group( buddy );
-	PurpleBuddy*		newbuddy		= NULL;
 
 	/* make sure the groups actually differs */
 	if ( strcmp( current_group->name, group->name ) != 0 ) {
 		/* groupnames does not match, so we need to make the update */
 
+		struct contact*		contact		= purple_buddy_get_protocol_data( buddy );
+		PurpleBuddy*		newbuddy	= NULL;
+
 		purple_debug_info( MXIT_PLUGIN_ID, "Moving '%s' from group '%s' to '%s'\n", buddy->alias, current_group->name, group->name );
 
 		/*
@@ -310,10 +311,10 @@
 		 * again. This is really not ideal and very irritating, but how else then?
 		 */
 
-		/* create new buddy */
+		/* create new buddy, and transfer 'contact' data */
 		newbuddy = purple_buddy_new( session->acc, buddy->name, buddy->alias );
-		newbuddy->proto_data = buddy->proto_data;
-		buddy->proto_data = NULL;
+		purple_buddy_set_protocol_data( newbuddy, contact );
+		purple_buddy_set_protocol_data( buddy, NULL );
 
 		/* remove the buddy */
 		purple_blist_remove_buddy( buddy );
@@ -322,7 +323,6 @@
 		purple_blist_add_buddy( newbuddy, NULL, group, NULL );
 
 		/* now re-instate his presence again */
-		contact = newbuddy->proto_data;
 		if ( contact ) {
 
 			/* update the buddy's status (reference: "libpurple/prpl.h") */
@@ -396,7 +396,7 @@
 
 		/* create new buddy */
 		buddy = purple_buddy_new( session->acc, contact->username, contact->alias );
-		purple_buddy_set_protocol_data(buddy, contact);
+		purple_buddy_set_protocol_data( buddy, contact );
 
 		/* add new buddy to list */
 		purple_blist_add_buddy( buddy, NULL, group, NULL );
@@ -728,7 +728,7 @@
  */
 void mxit_add_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group, const char* message )
 {
-	struct MXitSession*	session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*	session	= purple_connection_get_protocol_data( gc );
 	GSList*				list	= NULL;
 	PurpleBuddy*		mxbuddy	= NULL;
 	unsigned int		i;
@@ -804,7 +804,7 @@
  */
 void mxit_remove_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group )
 {
-	struct MXitSession*	session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*	session	= purple_connection_get_protocol_data( gc );
 	const gchar *		buddy_name = purple_buddy_get_name( buddy );
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_remove_buddy '%s'\n", buddy_name );
@@ -822,7 +822,7 @@
  */
 void mxit_buddy_alias( PurpleConnection* gc, const char* who, const char* alias )
 {
-	struct MXitSession*	session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*	session	= purple_connection_get_protocol_data( gc );
 	PurpleBuddy*		buddy	= NULL;
 	PurpleGroup*		group	= NULL;
 
@@ -856,7 +856,7 @@
  */
 void mxit_buddy_group( PurpleConnection* gc, const char* who, const char* old_group, const char* new_group )
 {
-	struct MXitSession*	session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*	session	= purple_connection_get_protocol_data( gc );
 	PurpleBuddy*		buddy	= NULL;
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_buddy_group from '%s' to '%s'\n", old_group, new_group );
@@ -883,7 +883,7 @@
  */
 void mxit_rename_group( PurpleConnection* gc, const char* old_name, PurpleGroup* group, GList* moved_buddies )
 {
-	struct MXitSession*	session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*	session	= purple_connection_get_protocol_data( gc );
 	PurpleBuddy*		buddy	= NULL;
 	GList*				item	= NULL;
 
--- a/libpurple/protocols/mxit/roster.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/roster.h	Sun Sep 11 04:19:01 2011 +0000
@@ -74,7 +74,7 @@
 
 
 /* MXit contact flags */
-#define		MXIT_CFLAG_HIDDEN			0x02
+//#define		MXIT_CFLAG_HIDDEN			0x02		/* (DEPRECATED) */
 #define		MXIT_CFLAG_GATEWAY			0x04
 #define		MXIT_CFLAG_FOCUS_SEND_BLANK	0x20000
 
@@ -96,7 +96,7 @@
 /* client protocol constants */
 #define		MXIT_CP_MAX_JID_LEN			64
 #define		MXIT_CP_MAX_GROUP_LEN		32
-#define		MXIT_CP_MAX_ALIAS_LEN		48
+#define		MXIT_CP_MAX_ALIAS_LEN		100
 
 #define		MXIT_DEFAULT_GROUP			"MXit"
 
@@ -106,8 +106,8 @@
  */
 struct contact {
 	char		username[MXIT_CP_MAX_JID_LEN+1];	/* unique contact name (with domain) */
-	char		alias[MXIT_CP_MAX_GROUP_LEN+1];		/* contact alias (what will be seen) */
-	char		groupname[MXIT_CP_MAX_ALIAS_LEN+1];	/* contact group name */
+	char		alias[MXIT_CP_MAX_ALIAS_LEN+1];		/* contact alias (what will be seen) */
+	char		groupname[MXIT_CP_MAX_GROUP_LEN+1];	/* contact group name */
 
 	short		type;								/* contact type */
 	short		mood;								/* contact current mood */
--- a/libpurple/protocols/mxit/splashscreen.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/splashscreen.c	Sun Sep 11 04:19:01 2011 +0000
@@ -144,7 +144,7 @@
  */
 static void splash_click_ok(PurpleConnection* gc, PurpleRequestFields* fields)
 {
-	struct MXitSession*	session	= (struct MXitSession*) gc->proto_data;
+	struct MXitSession*	session	= purple_connection_get_protocol_data(gc);
 	const char* splashId;
 
 	/* Get current splash ID */
--- a/libpurple/protocols/mxit/voicevideo.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/mxit/voicevideo.c	Sun Sep 11 04:19:01 2011 +0000
@@ -63,7 +63,7 @@
  */
 PurpleMediaCaps mxit_media_caps(PurpleAccount *account, const char *who)
 {
-	struct MXitSession*	session	= purple_account_get_connection(account)->proto_data;
+	struct MXitSession*	session	= purple_connection_get_protocol_data(purple_account_get_connection(account));
 	PurpleBuddy*		buddy;
 	struct contact*		contact;
 	PurpleMediaCaps		capa	= PURPLE_MEDIA_CAPS_NONE;
@@ -71,7 +71,7 @@
 	purple_debug_info(MXIT_PLUGIN_ID, "mxit_media_caps: buddy '%s'\n", who);
 
 	/* We need to have a voice/video server */
-	if (strlen(session->voip_server) == 0)
+	if (!*session->voip_server)
 		return PURPLE_MEDIA_CAPS_NONE;
 
 	/* find the buddy information for this contact (reference: "libpurple/blist.h") */
@@ -95,7 +95,7 @@
 
 	/* and only when they're online */
 	if (contact->presence == MXIT_PRESENCE_OFFLINE)
-		return MXIT_PRESENCE_OFFLINE;
+		return PURPLE_MEDIA_CAPS_NONE;
 
 	/* they support voice-only */
 	if (contact->capabilities & MXIT_PFLAG_VOICE)
--- a/libpurple/protocols/myspace/myspace.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/myspace/myspace.c	Sun Sep 11 04:19:01 2011 +0000
@@ -429,11 +429,9 @@
 	user = msim_get_user_from_buddy(buddy, TRUE);
 
 	if (PURPLE_BUDDY_IS_ONLINE(buddy)) {
-		MsimSession *session;
 		PurpleAccount *account = purple_buddy_get_account(buddy);
 		PurpleConnection *gc = purple_account_get_connection(account);
-
-		session = (MsimSession *)gc->proto_data;
+		MsimSession *session = purple_connection_get_protocol_data(gc);
 
 		/* TODO: if (full), do something different? */
 
@@ -698,7 +696,7 @@
 	if (nc_len != MSIM_AUTH_CHALLENGE_LENGTH) {
 		purple_debug_info("msim", "bad nc length: %" G_GSIZE_MODIFIER
 				"x != 0x%x\n", nc_len, MSIM_AUTH_CHALLENGE_LENGTH);
-		purple_connection_error_reason (session->gc,
+		purple_connection_error (session->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unexpected challenge length from server"));
 		return FALSE;
@@ -835,7 +833,7 @@
 		purple_debug_info("msim",
 				"msim_check_alive: %zu > interval of %d, presumed dead\n",
 				delta, MSIM_KEEPALIVE_INTERVAL);
-		purple_connection_error_reason(session->gc,
+		purple_connection_error(session->gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Lost connection with server"));
 
@@ -1866,7 +1864,7 @@
 					purple_account_set_password(session->account, NULL);
 				break;
 		}
-		purple_connection_error_reason(session->gc, reason, full_errmsg);
+		purple_connection_error(session->gc, reason, full_errmsg);
 	} else {
 		purple_notify_error(session->account, _("MySpaceIM Error"), full_errmsg, NULL);
 	}
@@ -2022,12 +2020,12 @@
 	g_return_if_fail(source >= 0);  /* Note: 0 is a valid fd */
 
 	gc = (PurpleConnection *)(gc_uncasted);
-	session = gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	/* libpurple/eventloop.h only defines these two */
 	if (cond != PURPLE_INPUT_READ && cond != PURPLE_INPUT_WRITE) {
 		purple_debug_info("msim_input_cb", "unknown condition=%d\n", cond);
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Invalid input condition"));
 		return;
@@ -2069,12 +2067,12 @@
 
 		tmp = g_strdup_printf(_("Lost connection with server: %s"),
 				g_strerror(errno));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	} else if (n == 0) {
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Server closed the connection"));
 		return;
@@ -2092,7 +2090,7 @@
 		purple_debug_info("msim", "msim_input_cb: strlen=%d, but read %d bytes"
 				"--null byte encountered?\n",
 				strlen(session->rxbuf + session->rxoff), n);
-		/*purple_connection_error_reason (gc,
+		/*purple_connection_error (gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				"Invalid message - null byte on input"); */
 		return;
@@ -2117,7 +2115,7 @@
 		msg = msim_parse(session->rxbuf);
 		if (!msg) {
 			purple_debug_info("msim", "msim_input_cb: couldn't parse rxbuf\n");
-			purple_connection_error_reason (gc,
+			purple_connection_error (gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Unable to parse message"));
 			break;
@@ -2157,12 +2155,12 @@
 	g_return_if_fail(data != NULL);
 
 	gc = (PurpleConnection *)data;
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	if (source < 0) {
 		gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
 				error_message);
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 			g_free(tmp);
 		return;
@@ -2191,7 +2189,7 @@
 	purple_debug_info("msim", "logging in %s\n", acct->username);
 
 	gc = purple_account_get_connection(acct);
-	gc->proto_data = msim_session_new(acct);
+	purple_connection_set_protocol_data(gc, msim_session_new(acct));
 	gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_URLDESC;
 
 	/*
@@ -2219,7 +2217,7 @@
 	if (!purple_proxy_connect(gc, acct, host, port, msim_connect_cb, gc)) {
 		/* TODO: try other ports if in auto mode, then save
 		 * working port and try that first next time. */
-		purple_connection_error_reason (gc,
+		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to connect"));
 		return;
@@ -2259,11 +2257,11 @@
 		buddies = g_slist_delete_link(buddies, buddies);
 	}
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	if (session == NULL)
 		return;
 
-	gc->proto_data = NULL;
+	purple_connection_set_protocol_data(gc, NULL);
 
 	if (session->gc->inpa) {
 		purple_input_remove(session->gc->inpa);
@@ -2304,7 +2302,7 @@
 
 	/* 'flags' has many options, not used here. */
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	message_msim = html_to_msim_markup(session, message);
 
@@ -2344,7 +2342,7 @@
 	g_return_val_if_fail(gc != NULL, 0);
 	g_return_val_if_fail(name != NULL, 0);
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	switch (state) {
 		case PURPLE_TYPING:
@@ -2430,7 +2428,7 @@
 	g_return_if_fail(gc != NULL);
 	g_return_if_fail(username != NULL);
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	/* Obtain uid of buddy. */
 	user = msim_find_user(session, username);
@@ -2487,6 +2485,7 @@
 static void
 msim_set_status(PurpleAccount *account, PurpleStatus *status)
 {
+	PurpleConnection *gc = purple_account_get_connection(account);
 	PurpleStatusType *type;
 	PurplePresence *pres;
 	MsimSession *session;
@@ -2495,7 +2494,7 @@
 	gchar *stripped;
 	gchar *unrecognized_msg;
 
-	session = (MsimSession *)account->gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	type = purple_status_get_type(status);
 	pres = purple_status_get_presence(status);
@@ -2558,7 +2557,7 @@
 
 	g_return_if_fail(gc != NULL);
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	status = purple_account_get_active_status(session->account);
 
@@ -2628,7 +2627,7 @@
  * Add a buddy to user's buddy list.
  */
 static void
-msim_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
+msim_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
 {
 	MsimSession *session;
 	MsimMessage *msg;
@@ -2636,7 +2635,7 @@
 	MsimMessage *body;
 	const char *name, *gname;
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	name = purple_buddy_get_name(buddy);
 	gname = group ? purple_group_get_name(group) : NULL;
 
@@ -2709,7 +2708,7 @@
 	MsimMessage *persist_msg;
 	const char *name;
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 	name = purple_buddy_get_name(buddy);
 
 	delbuddy_msg = msim_msg_new(
@@ -2766,7 +2765,7 @@
 	MsimSession *session;
 	MsimMessage *msg, *body;
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	/* Remove from buddy list */
 	msg = msim_msg_new(
@@ -2818,7 +2817,7 @@
 	MsimSession *session;
 	MsimMessage *msg, *body;
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	/*
 	 * Remove from our list of blocked contacts, so we know they
@@ -2948,7 +2947,7 @@
 	g_return_val_if_fail(buf != NULL, -1);
 	g_return_val_if_fail(total_bytes >= 0, -1);
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	/* Loop until all data is sent, or a failure occurs. */
 	total_bytes_sent = 0;
@@ -3008,6 +3007,7 @@
  * Callbacks called by Purple, to access this plugin.
  */
 static PurplePluginProtocolInfo prpl_info = {
+	sizeof(PurplePluginProtocolInfo), /* struct_size */
 	/* options */
 	  OPT_PROTO_USE_POINTSIZE        /* specify font size in sane point size */
 	| OPT_PROTO_MAIL_CHECK,
@@ -3077,15 +3077,12 @@
 	NULL,                  /* unregister_user */
 	msim_send_attention,   /* send_attention */
 	msim_attention_types,  /* attention_types */
-	sizeof(PurplePluginProtocolInfo), /* struct_size */
 	msim_get_account_text_table,              /* get_account_text_table */
 	NULL,                   /* initiate_media */
 	NULL,                   /* get_media_caps */
 	NULL,                   /* get_moods */
 	NULL,                   /* set_public_alias */
-	NULL,                   /* get_public_alias */
-	NULL,                   /* add_buddy_with_invite */
-	NULL                    /* add_buddies_with_invite */
+	NULL                    /* get_public_alias */
 };
 
 /**
@@ -3151,7 +3148,7 @@
 	gchar *group_name;
 
 	gc = (PurpleConnection *)action->context;
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	group_name = "MySpace Friends";
 
@@ -3530,6 +3527,7 @@
 msim_uri_handler(const gchar *proto, const gchar *cmd, GHashTable *params)
 {
 	PurpleAccount *account;
+	PurpleConnection *gc;
 	MsimSession *session;
 	GList *l;
 	gchar *uid_str, *cid_str;
@@ -3578,7 +3576,8 @@
 		return FALSE;
 	}
 
-	session = (MsimSession *)account->gc->proto_data;
+	gc = purple_account_get_connection(account);
+	session = purple_connection_get_protocol_data(gc);
 	g_return_val_if_fail(session != NULL, FALSE);
 
 	/* Lookup userid to username. TODO: push this down, to IM sending/contact
--- a/libpurple/protocols/myspace/user.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/myspace/user.c	Sun Sep 11 04:19:01 2011 +0000
@@ -117,27 +117,33 @@
 	/* Useful to identify the account the tooltip refers to.
 	 *  Other prpls show this. */
 	if (user->username) {
-		purple_notify_user_info_add_pair(user_info, _("User"), user->username);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("User"), user->username);
 	}
 
 	/* a/s/l...the vitals */
 	if (user->age) {
 		char age[16];
 		g_snprintf(age, sizeof(age), "%d", user->age);
-		purple_notify_user_info_add_pair(user_info, _("Age"), age);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Age"), age);
 	}
 
 	if (user->gender && *user->gender) {
-		purple_notify_user_info_add_pair(user_info, _("Gender"), user->gender);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Gender"), user->gender);
 	}
 
 	if (user->location && *user->location) {
-		purple_notify_user_info_add_pair(user_info, _("Location"), user->location);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Location"), user->location);
 	}
 
 	/* Other information */
 	if (user->headline && *user->headline) {
-		purple_notify_user_info_add_pair(user_info, _("Headline"), user->headline);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Headline"), user->headline);
 	}
 
 	if (user->buddy != NULL) {
@@ -153,7 +159,9 @@
 
 			str = msim_format_now_playing(artist, title);
 			if (str && *str) {
-				purple_notify_user_info_add_pair(user_info, _("Song"), str);
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_plaintext(user_info, _("Song"), str);
 			}
 			g_free(str);
 		}
@@ -163,7 +171,7 @@
 	if (user->total_friends) {
 		char friends[16];
 		g_snprintf(friends, sizeof(friends), "%d", user->total_friends);
-		purple_notify_user_info_add_pair(user_info, _("Total Friends"), friends);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Total Friends"), friends);
 	}
 
 	if (full) {
@@ -180,8 +188,11 @@
 		} else if (cv) {
 			client = g_strdup_printf("Build %d", cv);
 		}
-		if (client && *client)
-			purple_notify_user_info_add_pair(user_info, _("Client Version"), client);
+		if (client && *client) {
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Client Version"), client);
+		}
 		g_free(client);
 	}
 
@@ -195,7 +206,7 @@
 		else
 			profile = g_strdup_printf("<a href=\"http://myspace.com/%d\">%s</a>",
 					user->id, _("View web profile"));
-		purple_notify_user_info_add_pair(user_info, NULL, profile);
+		purple_notify_user_info_add_pair_html(user_info, NULL, profile);
 		g_free(profile);
 	}
 }
@@ -401,7 +412,7 @@
  *
  * @param session
  * @param msg The user information reply, with any amount of information.
- * @param user The structure to save to, or NULL to save in PurpleBuddy->proto_data.
+ * @param user The structure to save to, or NULL to save in PurpleBuddy's protocol_data.
  *
  * Variable information is saved to the passed MsimUser structure. Permanent
  * information (UserID) is stored in the blist node of the buddy list (and
@@ -636,7 +647,7 @@
 	if (!body) {
 		purple_debug_info("msim_username_is_set_cb", "No body");
 		/* Error: No body! */
-		purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
+		purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
 	}
 	username = msim_msg_get_string(body, "UserName");
 	code = msim_msg_get_integer(body,"Code");
@@ -678,13 +689,13 @@
 					NULL)) {
 			/* Error! */
 			/* Can't set... Disconnect */
-			purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
+			purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
 		}
 
 	} else {
 		/* Error! */
 		purple_debug_info("msim","username_is_set Error: Invalid cmd/dsn/lid combination");
-		purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
+		purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
 	}
 }
 
@@ -747,7 +758,7 @@
 
 	g_return_if_fail(gc != NULL);
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	user_msg = msim_msg_new(
 			"user", MSIM_TYPE_STRING, g_strdup(msim_username_to_set),
@@ -782,7 +793,7 @@
 
 	if (!body) {
 		purple_debug_info("msim_username_is_available_cb", "No body for %s?!\n", username);
-		purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+		purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 				_("An error occurred while trying to set the username.  "
 				"Please try again, or visit http://editprofile.myspace.com/index.cfm?"
 				"fuseaction=profile.username to set your username."));
@@ -840,7 +851,7 @@
 
 	g_return_if_fail(gc != NULL);
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	purple_debug_info("msim_check_username_availability_cb", "Checking username: %s\n", username_to_check);
 
@@ -867,7 +878,7 @@
 	purple_debug_info("msim", "Don't set username");
 
 	/* Protocol won't log in now without a username set.. Disconnect */
-	purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("No username set"));
+	purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("No username set"));
 }
 
 /**
--- a/libpurple/protocols/myspace/zap.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/myspace/zap.c	Sun Sep 11 04:19:01 2011 +0000
@@ -132,7 +132,7 @@
 	PurpleAttentionType *attn;
 	PurpleBuddy *buddy;
 
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	/* Look for this attention type, by the code index given. */
 	types = msim_attention_types(gc->account);
@@ -175,7 +175,7 @@
 	/* Find the session */
 	account = purple_buddy_get_account(buddy);
 	gc = purple_account_get_connection(account);
-	session = (MsimSession *)gc->proto_data;
+	session = purple_connection_get_protocol_data(gc);
 
 	zap = GPOINTER_TO_INT(zap_num_ptr);
 
--- a/libpurple/protocols/novell/novell.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/novell/novell.c	Sun Sep 11 04:19:01 2011 +0000
@@ -140,7 +140,7 @@
 				reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
 		}
 
-		purple_connection_error_reason(gc, reason, err);
+		purple_connection_error(gc, reason, err);
 		g_free(err);
 	}
 }
@@ -1126,7 +1126,7 @@
 
 	if (_is_disconnect_error(err)) {
 
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Error communicating with server. Closing connection."));
 		return TRUE;
@@ -1515,20 +1515,27 @@
 	tag = _("User ID");
 	value = nm_user_record_get_userid(user_record);
 	if (value) {
-		purple_notify_user_info_add_pair(user_info, tag, value);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, tag, value);
 	}
 
-/*	tag = _("DN");
+#if 0
+	tag = _("DN");
 	value = nm_user_record_get_dn(user_record);
 	if (value) {
-		purple_notify_user_info_add_pair(user_info, tag, value);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, tag, value);
 	}
-*/
+#endif /* if 0 */
 
 	tag = _("Full name");
 	value = nm_user_record_get_full_name(user_record);
 	if (value) {
-		purple_notify_user_info_add_pair(user_info, tag, value);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, tag, value);
 	}
 
 	count = nm_user_record_get_property_count(user_record);
@@ -1538,7 +1545,9 @@
 			tag = _map_property_tag(nm_property_get_tag(property));
 			value = nm_property_get_value(property);
 			if (tag && value) {
-				purple_notify_user_info_add_pair(user_info, tag, value);
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, tag, value);
 			}
 			nm_release_property(property);
 		}
@@ -1620,7 +1629,7 @@
 	buddy = (PurpleBuddy *) node;
 	gc = purple_account_get_connection(purple_buddy_get_account(buddy));
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -1676,7 +1685,7 @@
 	NMUser *user;
 
 	gc = data;
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	user->conn->ssl_conn->data = NULL;
 
 	purple_connection_ssl_error (gc, error);
@@ -1693,7 +1702,7 @@
 	if (gc == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -1702,7 +1711,7 @@
 
 		if (_is_disconnect_error(rc)) {
 
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Error communicating with server. Closing connection."));
 		} else {
@@ -1727,7 +1736,7 @@
 	if (gc == NULL || gsc == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if ((user == NULL) || (conn = user->conn) == NULL)
 		return;
 
@@ -1743,7 +1752,7 @@
 		conn->connected = TRUE;
 		purple_ssl_input_add(gsc, novell_ssl_recv_cb, gc);
 	} else {
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to connect"));
 	}
@@ -2028,7 +2037,7 @@
 	{
 		if (!purple_account_get_remember_password(account))
 			purple_account_set_password(account, NULL);
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_NAME_IN_USE,
 			_("You have signed on from another location"));
 	}
@@ -2184,7 +2193,7 @@
 		 */
 
 		/* ...but for now just error out with a nice message. */
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 			_("Unable to connect to server. Please enter the "
 			  "address of the server to which you wish to connect."));
@@ -2197,7 +2206,7 @@
 	user = nm_initialize_user(name, server, port, account, _event_callback);
 	if (user && user->conn) {
 		/* save user */
-		gc->proto_data = user;
+		purple_connection_set_protocol_data(gc, user);
 
 		/* connect to the server */
 		purple_connection_update_progress(gc, _("Connecting"),
@@ -2213,7 +2222,7 @@
 													  user->conn->addr, user->conn->port,
 													  novell_ssl_connected_cb, novell_ssl_connect_error, gc);
 		if (user->conn->ssl_conn->data == NULL) {
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 				_("SSL support unavailable"));
 		}
@@ -2229,7 +2238,7 @@
 	if (gc == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user) {
 		conn = user->conn;
 		if (conn && conn->ssl_conn) {
@@ -2237,7 +2246,7 @@
 		}
 		nm_deinitialize_user(user);
 	}
-	gc->proto_data = NULL;
+	purple_connection_set_protocol_data(gc, NULL);
 }
 
 static int
@@ -2257,7 +2266,7 @@
 		message_body == NULL || *message_body == '\0')
 		return 0;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return 0;
 
@@ -2343,7 +2352,7 @@
 	if (gc == NULL || name == NULL)
 		return 0;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return 0;
 
@@ -2377,7 +2386,7 @@
 	if (gc == NULL || who == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user && (dn = nm_lookup_dn(user, who))) {
 		conf = nm_find_conversation(user, dn);
 		if (conf) {
@@ -2399,7 +2408,7 @@
 	if (gc == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -2431,7 +2440,7 @@
 	if (gc == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -2470,7 +2479,7 @@
 	if (gc == NULL || text == NULL)
 		return -1;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return -1;
 
@@ -2536,7 +2545,7 @@
 }
 
 static void
-novell_add_buddy(PurpleConnection * gc, PurpleBuddy *buddy, PurpleGroup * group)
+novell_add_buddy(PurpleConnection * gc, PurpleBuddy *buddy, PurpleGroup * group, const char *message)
 {
 	NMFolder *folder = NULL;
 	NMContact *contact;
@@ -2610,7 +2619,7 @@
 	if (gc == NULL || buddy == NULL || group == NULL)
 		return;
 
-	user = (NMUser *) gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user && (dn = nm_lookup_dn(user, purple_buddy_get_name(buddy)))) {
 		gname = purple_group_get_name(group);
 		if (strcmp(gname, NM_ROOT_FOLDER_NAME) == 0) {
@@ -2642,7 +2651,7 @@
 	if (gc == NULL || group == NULL)
 		return;
 
-	user = (NMUser *) gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user) {
 		NMFolder *folder = nm_find_folder(user, purple_group_get_name(group));
 
@@ -2667,7 +2676,7 @@
 	if (gc == NULL || name == NULL || alias == NULL)
 		return;
 
-	user = (NMUser *) gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user && (dn = nm_lookup_dn(user, name))) {
 
 		/* Alias all of instances of the contact */
@@ -2726,7 +2735,7 @@
 		old_group_name == NULL || new_group_name == NULL)
 		return;
 
-	user = (NMUser *) gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user && (dn = nm_lookup_dn(user, name))) {
 
 		/* Find the old folder */
@@ -2784,7 +2793,7 @@
 		return;
 	}
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user) {
 		const char *gname = purple_group_get_name(group);
 		/* Does new folder exist already? */
@@ -2830,7 +2839,7 @@
 		return;
 
 	gc = purple_account_get_connection(purple_buddy_get_account(buddy));
-	if (gc == NULL || (user = gc->proto_data) == NULL)
+	if (gc == NULL || (user = purple_connection_get_protocol_data(gc)) == NULL)
 		return;
 
 	if (PURPLE_BUDDY_IS_ONLINE(buddy)) {
@@ -2860,10 +2869,13 @@
 					break;
 			}
 
-			purple_notify_user_info_add_pair(user_info, _("Status"), status_str);
-
-			if (text)
-				purple_notify_user_info_add_pair(user_info, _("Message"), text);
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status_str);
+
+			if (text) {
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, _("Message"), text);
+			}
 		}
 	}
 }
@@ -2879,7 +2891,7 @@
 	if (gc == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -2908,7 +2920,7 @@
 	if (gc == NULL || name == NULL)
 		return;
 
-	user = (NMUser *) gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user) {
 
 		user_record = nm_find_user_record(user, name);
@@ -2937,17 +2949,19 @@
 	if (buddy && account) {
 		PurpleConnection *gc = purple_account_get_connection(account);
 
-		if (gc && gc->proto_data) {
-			NMUser *user = gc->proto_data;
-
-			dn = nm_lookup_dn(user, purple_buddy_get_name(buddy));
-			if (dn) {
-				NMUserRecord *user_record = nm_find_user_record(user, dn);
-
-				if (user_record) {
-					text = nm_user_record_get_status_text(user_record);
-					if (text)
-						return g_strdup(text);
+		if (gc) {
+			NMUser *user = purple_connection_get_protocol_data(gc);
+
+			if (user) {
+				dn = nm_lookup_dn(user, purple_buddy_get_name(buddy));
+				if (dn) {
+					NMUserRecord *user_record = nm_find_user_record(user, dn);
+
+					if (user_record) {
+						text = nm_user_record_get_status_text(user_record);
+						if (text)
+							return g_strdup(text);
+					}
 				}
 			}
 		}
@@ -3023,7 +3037,7 @@
 		return;
 
 	gc = purple_account_get_connection(account);
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -3070,7 +3084,7 @@
 	if (gc == NULL || who == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -3114,7 +3128,7 @@
 	if (gc == NULL || who == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -3158,7 +3172,7 @@
 	if (gc == NULL || who == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -3188,7 +3202,7 @@
 	if (gc == NULL || who == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -3223,7 +3237,7 @@
 	if (gc == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -3451,7 +3465,7 @@
 	if (gc == NULL)
 		return;
 
-	user = gc->proto_data;
+	user = purple_connection_get_protocol_data(gc);
 	if (user == NULL)
 		return;
 
@@ -3460,6 +3474,7 @@
 }
 
 static PurplePluginProtocolInfo prpl_info = {
+	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	0,
 	NULL,						/* user_splits */
 	NULL,						/* protocol_options */
@@ -3525,15 +3540,12 @@
 	NULL,						/* unregister_user */
 	NULL,						/* send_attention */
 	NULL,						/* get_attention_types */
-	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	NULL,						/* get_account_text_table */
 	NULL,						/* initiate_media */
 	NULL,						/* get_media_caps */
 	NULL,						/* get_moods */
 	NULL,						/* set_public_alias */
-	NULL,						/* get_public_alias */
-	NULL,						/* add_buddy_with_invite */
-	NULL						/* add_buddies_with_invite */
+	NULL						/* get_public_alias */
 };
 
 static PurplePluginInfo info = {
--- a/libpurple/protocols/null/nullprpl.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/null/nullprpl.c	Sun Sep 11 04:19:01 2011 +0000
@@ -234,7 +234,7 @@
     const char *message = purple_status_get_attr_string(status, "message");
 
     char *text;
-    if (message && strlen(message) > 0)
+    if (message && *message)
       text = g_strdup_printf("%s: %s", name, message);
     else
       text = g_strdup(name);
@@ -258,19 +258,23 @@
     PurplePresence *presence = purple_buddy_get_presence(buddy);
     PurpleStatus *status = purple_presence_get_active_status(presence);
     char *msg = nullprpl_status_text(buddy);
-    purple_notify_user_info_add_pair(info, purple_status_get_name(status),
+	/* TODO: Check whether it's correct to call add_pair_html,
+	         or if we should be using add_pair_plaintext */
+    purple_notify_user_info_add_pair_html(info, purple_status_get_name(status),
                                      msg);
     g_free(msg);
 
     if (full) {
       const char *user_info = purple_account_get_user_info(gc->account);
       if (user_info)
-        purple_notify_user_info_add_pair(info, _("User info"), user_info);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+        purple_notify_user_info_add_pair_html(info, _("User info"), user_info);
     }
 
   } else {
     /* they're not logged in */
-    purple_notify_user_info_add_pair(info, _("User info"), _("not logged in"));
+    purple_notify_user_info_add_pair_plaintext(info, _("User info"), _("not logged in"));
   }
 
   purple_debug_info("nullprpl", "showing %s tooltip for %s\n",
@@ -510,7 +514,9 @@
     body = purple_account_get_user_info(acct);
   else
     body = _("No user info.");
-  purple_notify_user_info_add_pair(info, "Info", body);
+  /* TODO: Check whether it's correct to call add_pair_html,
+           or if we should be using add_pair_plaintext */
+  purple_notify_user_info_add_pair_html(info, "Info", body);
 
   /* show a buddy's user info in a nice dialog box */
   purple_notify_userinfo(gc,        /* connection the buddy info came through */
@@ -542,7 +548,7 @@
 }
 
 static void nullprpl_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
-                               PurpleGroup *group)
+                               PurpleGroup *group, const char *message)
 {
   const char *username = gc->account->username;
   PurpleConnection *buddy_gc = get_nullprpl_gc(buddy->name);
@@ -565,20 +571,20 @@
                                  username,
                                  NULL,   /* local account id (rarely used) */
                                  NULL,   /* alias */
-                                 NULL);  /* message */
+                                 message);  /* message */
     }
   }
 }
 
 static void nullprpl_add_buddies(PurpleConnection *gc, GList *buddies,
-                                 GList *groups) {
+                                 GList *groups, const char *message) {
   GList *buddy = buddies;
   GList *group = groups;
 
   purple_debug_info("nullprpl", "adding multiple buddies\n");
 
   while (buddy && group) {
-    nullprpl_add_buddy(gc, (PurpleBuddy *)buddy->data, (PurpleGroup *)group->data);
+    nullprpl_add_buddy(gc, (PurpleBuddy *)buddy->data, (PurpleGroup *)group->data, message);
     buddy = g_list_next(buddy);
     group = g_list_next(group);
   }
@@ -775,10 +781,10 @@
   to_username = args[0];
   message = args[1];
 
-  if (!to_username || strlen(to_username) == 0) {
+  if (!to_username || !*to_username) {
     *error = g_strdup(_("Whisper is missing recipient."));
     return PURPLE_CMD_RET_FAILED;
-  } else if (!message || strlen(message) == 0) {
+  } else if (!message || !*message) {
     *error = g_strdup(_("Whisper is missing message."));
     return PURPLE_CMD_RET_FAILED;
   }
@@ -927,7 +933,7 @@
 
   purple_conv_chat_set_topic(to, username, topic);
 
-  if (topic && strlen(topic) > 0)
+  if (topic && *topic)
     msg = g_strdup_printf(_("%s sets topic to: %s"), username, topic);
   else
     msg = g_strdup_printf(_("%s clears topic"), username);
@@ -1013,14 +1019,17 @@
 }
 
 static void nullprpl_roomlist_cancel(PurpleRoomlist *list) {
+ PurpleAccount *account = purple_roomlist_get_account(list);
  purple_debug_info("nullprpl", "%s asked to cancel room list request\n",
-                   list->account->username);
+                   purple_account_get_username(account));
 }
 
 static void nullprpl_roomlist_expand_category(PurpleRoomlist *list,
                                               PurpleRoomlistRoom *category) {
+ PurpleAccount *account = purple_roomlist_get_account(list);
  purple_debug_info("nullprpl", "%s asked to expand room list category %s\n",
-                   list->account->username, category->name);
+                   purple_account_get_username(account),
+                   purple_roomlist_room_get_name(category));
 }
 
 /* nullprpl doesn't support file transfer...yet... */
@@ -1043,6 +1052,7 @@
 
 static PurplePluginProtocolInfo prpl_info =
 {
+  sizeof(PurplePluginProtocolInfo),    /* struct_size */
   OPT_PROTO_NO_PASSWORD | OPT_PROTO_CHAT_TOPIC,  /* options */
   NULL,               /* user_splits, initialized in nullprpl_init() */
   NULL,               /* protocol_options, initialized in nullprpl_init() */
@@ -1116,15 +1126,12 @@
   NULL,                                /* unregister_user */
   NULL,                                /* send_attention */
   NULL,                                /* get_attention_types */
-  sizeof(PurplePluginProtocolInfo),    /* struct_size */
   NULL,                                /* get_account_text_table */
   NULL,                                /* initiate_media */
   NULL,                                /* get_media_caps */
   NULL,                                /* get_moods */
   NULL,                                /* set_public_alias */
-  NULL,                                /* get_public_alias */
-  NULL,                                /* add_buddy_with_invite */
-  NULL                                 /* add_buddies_with_invite */
+  NULL                                 /* get_public_alias */
 };
 
 static void nullprpl_init(PurplePlugin *plugin)
--- a/libpurple/protocols/oscar/authorization.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/authorization.c	Sun Sep 11 04:19:01 2011 +0000
@@ -49,7 +49,7 @@
 		purple_debug_info("oscar", "ssi: adding buddy %s to group %s\n",
 				   bname, gname);
 		aim_ssi_sendauthrequest(od, bname, msg ? msg : _("Please authorize me so I can add you to my buddy list."));
-		if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY))
+		if (!aim_ssi_itemlist_finditem(&od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY))
 		{
 			aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, TRUE);
 
--- a/libpurple/protocols/oscar/clientlogin.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/clientlogin.c	Sun Sep 11 04:19:01 2011 +0000
@@ -182,7 +182,7 @@
 		/* Note to translators: %s in this string is a URL */
 		msg = generate_error_message(response_node,
 				get_start_oscar_session_url(od));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
 		g_free(msg);
 		return FALSE;
@@ -204,7 +204,7 @@
 				"missing statusCode: %s\n", response);
 		msg = generate_error_message(response_node,
 				get_start_oscar_session_url(od));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
 		g_free(msg);
 		xmlnode_free(response_node);
@@ -232,7 +232,7 @@
 				"was %s: %s\n", tmp, response);
 
 		if ((code == 401 && status_detail != 1014) || code == 607)
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 					PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 					_("You have been connecting and disconnecting too "
 					  "frequently. Wait ten minutes and try again. If "
@@ -242,7 +242,7 @@
 			char *msg;
 			msg = generate_error_message(response_node,
 					get_start_oscar_session_url(od));
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 					PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg);
 			g_free(msg);
 		}
@@ -261,7 +261,7 @@
 				"something: %s\n", response);
 		msg = generate_error_message(response_node,
 				get_start_oscar_session_url(od));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
 		g_free(msg);
 		xmlnode_free(response_node);
@@ -277,7 +277,7 @@
 				purple_debug_warning("oscar", "We haven't received a tlsCertName to use. We will not do SSL to BOS.\n");
 			} else {
 				purple_debug_error("oscar", "startOSCARSession was missing tlsCertName: %s\n", response);
-				purple_connection_error_reason(
+				purple_connection_error(
 					gc,
 					PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 					_("You required encryption in your account settings, but one of the servers doesn't support it."));
@@ -299,7 +299,7 @@
 				"something: %s\n", response);
 		msg = generate_error_message(response_node,
 				get_start_oscar_session_url(od));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
 		g_free(msg);
 		g_free(*host);
@@ -337,7 +337,7 @@
 		tmp = g_strdup_printf(_("Error requesting %s: %s"),
 				get_start_oscar_session_url(od), error_message ?
 				error_message : _("The server returned an empty response"));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
@@ -384,7 +384,7 @@
 	g_free(signature);
 
 	/* Make the request */
-	od->url_data = purple_util_fetch_url_request_len_with_account(account,
+	od->url_data = purple_util_fetch_url_request_len(account,
 			url, TRUE, NULL, FALSE, NULL, FALSE, -1,
 			start_oscar_session_cb, od);
 	g_free(url);
@@ -395,7 +395,7 @@
  * and extracts the useful information.
  *
  * @param gc           The PurpleConnection.  If the response data does
- *                     not indicate then purple_connection_error_reason()
+ *                     not indicate then purple_connection_error()
  *                     will be called to close this connection.
  * @param response     The response data from the clientLogin request.
  * @param response_len The length of the above response, or -1 if
@@ -431,7 +431,7 @@
 				"response as XML: %s\n", response);
 		msg = generate_error_message(response_node,
 				get_client_login_url(od));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
 		g_free(msg);
 		return FALSE;
@@ -455,7 +455,7 @@
 				"missing statusCode: %s\n", response);
 		msg = generate_error_message(response_node,
 				get_client_login_url(od));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
 		g_free(msg);
 		xmlnode_free(response_node);
@@ -482,23 +482,23 @@
 			PurpleAccount *account = purple_connection_get_account(gc);
 			if (!purple_account_get_remember_password(account))
 				purple_account_set_password(account, NULL);
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 					PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
 					_("Incorrect password"));
 		} else if (status_code == 330 && status_detail_code == 3015) {
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 					PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
 					_("Server requested that you fill out a CAPTCHA in order to "
 					"sign in, but this client does not currently support CAPTCHAs."));
 		} else if (status_code == 401 && status_detail_code == 3019) {
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 					PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 					_("AOL does not allow your screen name to authenticate here"));
 		} else {
 			char *msg;
 			msg = generate_error_message(response_node,
 					get_client_login_url(od));
-			purple_connection_error_reason(gc,
+			purple_connection_error(gc,
 					PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg);
 			g_free(msg);
 		}
@@ -517,7 +517,7 @@
 				"something: %s\n", response);
 		msg = generate_error_message(response_node,
 				get_client_login_url(od));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
 		g_free(msg);
 		xmlnode_free(response_node);
@@ -535,7 +535,7 @@
 				"something: %s\n", response);
 		msg = generate_error_message(response_node,
 				get_client_login_url(od));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
 		g_free(msg);
 		g_free(*token);
@@ -572,7 +572,7 @@
 		tmp = g_strdup_printf(_("Error requesting %s: %s"),
 				get_client_login_url(od), error_message ?
 				error_message : _("The server returned an empty response"));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
@@ -646,7 +646,7 @@
 	g_string_free(body, TRUE);
 
 	/* Send the POST request  */
-	od->url_data = purple_util_fetch_url_request_len_with_account(
+	od->url_data = purple_util_fetch_url_request_len(
 			purple_connection_get_account(gc), get_client_login_url(od),
 			TRUE, NULL, FALSE, request->str, FALSE, -1,
 			client_login_cb, od);
--- a/libpurple/protocols/oscar/family_feedbag.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/family_feedbag.c	Sun Sep 11 04:19:01 2011 +0000
@@ -21,9 +21,9 @@
 /*
  * Family 0x0013 - Server-Side/Stored Information.
  *
- * Relatively new facility that allows certain types of information, such as
- * a user's buddy list, permit/deny list, and permit/deny preferences, to be
- * stored on the server, so that they can be accessed from any client.
+ * Deals with storing certain types of information, such as a user's buddy
+ * list, permit/deny list, and permit/deny preferences, on the server, so
+ * that they can be accessed from any client.
  *
  * We keep 2 copies of SSI data:
  * 1) An exact copy of what is stored on the AIM servers.
@@ -40,14 +40,41 @@
  *
  * This is entirely too complicated.
  * You don't know the half of it.
- *
  */
 
 #include "oscar.h"
+#include "oscarcommon.h"
 #include "debug.h"
 
 static int aim_ssi_addmoddel(OscarData *od);
 
+static void aim_ssi_item_free(struct aim_ssi_item *item)
+{
+	g_free(item->name);
+	aim_tlvlist_free(item->data);
+	g_free(item);
+}
+
+static void aim_ssi_item_set_name(struct aim_ssi_itemlist *list, struct aim_ssi_item *item, const char *name)
+{
+	gchar key[3000];
+
+	if (item->name) {
+		/* Remove old name from hash table */
+		snprintf(key, sizeof(key), "%hx%s", item->type, oscar_normalize(NULL, item->name));
+		g_hash_table_remove(list->idx_all_named_items, key);
+	}
+
+	g_free(item->name);
+	item->name = g_strdup(name);
+
+	if (name) {
+		/* Add new name to hash table */
+		snprintf(key, sizeof(key), "%hx%s", item->type, oscar_normalize(NULL, item->name));
+		g_hash_table_insert(list->idx_all_named_items, g_strdup(key), item);
+	}
+}
+
 /**
  * List types based on http://dev.aol.com/aim/oscar/#FEEDBAG (archive.org)
  * and http://iserverd.khstu.ru/oscar/ssi_item.html
@@ -113,7 +140,7 @@
  * @return Return a pointer to the modified item.
  */
 static void
-aim_ssi_itemlist_rebuildgroup(struct aim_ssi_item *list, const char *name)
+aim_ssi_itemlist_rebuildgroup(struct aim_ssi_itemlist *list, const char *name)
 {
 	int newlen;
 	struct aim_ssi_item *cur, *group;
@@ -125,11 +152,11 @@
 	/* Find the length for the new additional data */
 	newlen = 0;
 	if (group->gid == 0x0000) {
-		for (cur=list; cur; cur=cur->next)
+		for (cur=list->data; cur; cur=cur->next)
 			if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000))
 				newlen += 2;
 	} else {
-		for (cur=list; cur; cur=cur->next)
+		for (cur=list->data; cur; cur=cur->next)
 			if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY))
 				newlen += 2;
 	}
@@ -138,14 +165,14 @@
 	if (newlen > 0) {
 		guint8 *newdata;
 
-		newdata = (guint8 *)g_malloc((newlen)*sizeof(guint8));
+		newdata = g_new(guint8, newlen);
 		newlen = 0;
 		if (group->gid == 0x0000) {
-			for (cur=list; cur; cur=cur->next)
+			for (cur=list->data; cur; cur=cur->next)
 				if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000))
 						newlen += aimutil_put16(newdata+newlen, cur->gid);
 		} else {
-			for (cur=list; cur; cur=cur->next)
+			for (cur=list->data; cur; cur=cur->next)
 				if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY))
 						newlen += aimutil_put16(newdata+newlen, cur->bid);
 		}
@@ -167,15 +194,12 @@
  * @param data The additional data for the new item.
  * @return A pointer to the newly created item.
  */
-static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, const char *name, guint16 gid, guint16 bid, guint16 type, GSList *data)
+static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_itemlist *list, const char *name, guint16 gid, guint16 bid, guint16 type, GSList *data)
 {
 	gboolean exists;
 	struct aim_ssi_item *cur, *new;
 
-	new = g_new(struct aim_ssi_item, 1);
-
-	/* Set the name */
-	new->name = g_strdup(name);
+	new = g_new0(struct aim_ssi_item, 1);
 
 	/* Set the group ID# and buddy ID# */
 	new->gid = gid;
@@ -185,7 +209,7 @@
 			do {
 				new->gid += 0x0001;
 				exists = FALSE;
-				for (cur = *list; cur != NULL; cur = cur->next)
+				for (cur = list->data; cur != NULL; cur = cur->next)
 					if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid == new->gid)) {
 						exists = TRUE;
 						break;
@@ -202,7 +226,7 @@
 			do {
 				new->bid += 0x0001;
 				exists = FALSE;
-				for (cur = *list; cur != NULL; cur = cur->next)
+				for (cur = list->data; cur != NULL; cur = cur->next)
 					if (cur->bid == new->bid || cur->gid == new->bid) {
 						exists = TRUE;
 						break;
@@ -214,7 +238,7 @@
 			do {
 				new->bid += 0x0001;
 				exists = FALSE;
-				for (cur = *list; cur != NULL; cur = cur->next)
+				for (cur = list->data; cur != NULL; cur = cur->next)
 					if (cur->bid == new->bid && cur->gid == new->gid) {
 						exists = TRUE;
 						break;
@@ -226,23 +250,29 @@
 	/* Set the type */
 	new->type = type;
 
+	/* Add it to the gid+bid hashtable */
+	g_hash_table_insert(list->idx_gid_bid, GINT_TO_POINTER((new->gid << 16) + new->bid), new);
+
+	/* Set the name - do this *AFTER* setting the type because type is used for the key */
+	aim_ssi_item_set_name(list, new, name);
+
 	/* Set the TLV list */
 	new->data = aim_tlvlist_copy(data);
 
 	/* Add the item to the list in the correct numerical position.  Fancy, eh? */
-	if (*list) {
-		if ((new->gid < (*list)->gid) || ((new->gid == (*list)->gid) && (new->bid < (*list)->bid))) {
-			new->next = *list;
-			*list = new;
+	if (list->data) {
+		if ((new->gid < list->data->gid) || ((new->gid == list->data->gid) && (new->bid < list->data->bid))) {
+			new->next = list->data;
+			list->data = new;
 		} else {
 			struct aim_ssi_item *prev;
-			for ((prev=*list, cur=(*list)->next); (cur && ((new->gid > cur->gid) || ((new->gid == cur->gid) && (new->bid > cur->bid)))); prev=cur, cur=cur->next);
+			for ((prev=list->data, cur=list->data->next); (cur && ((new->gid > cur->gid) || ((new->gid == cur->gid) && (new->bid > cur->bid)))); prev=cur, cur=cur->next);
 			new->next = prev->next;
 			prev->next = new;
 		}
 	} else {
-		new->next = *list;
-		*list = new;
+		new->next = list->data;
+		list->data = new;
 	}
 
 	return new;
@@ -255,25 +285,31 @@
  * @param del A pointer to the item you want to remove from the list.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-static int aim_ssi_itemlist_del(struct aim_ssi_item **list, struct aim_ssi_item *del)
+static int aim_ssi_itemlist_del(struct aim_ssi_itemlist *list, struct aim_ssi_item *del)
 {
-	if (!(*list) || !del)
+	gchar key[3000];
+
+	if (!(list->data) || !del)
 		return -EINVAL;
 
 	/* Remove the item from the list */
-	if (*list == del) {
-		*list = (*list)->next;
+	if (list->data == del) {
+		list->data = list->data->next;
 	} else {
 		struct aim_ssi_item *cur;
-		for (cur=*list; (cur->next && (cur->next!=del)); cur=cur->next);
+		for (cur=list->data; (cur->next && (cur->next!=del)); cur=cur->next);
 		if (cur->next)
 			cur->next = del->next;
 	}
 
+	/* Remove from the hashtables */
+	g_hash_table_remove(list->idx_gid_bid, GINT_TO_POINTER((del->gid << 16) + del->bid));
+
+	snprintf(key, sizeof(key), "%hx%s", del->type, oscar_normalize(NULL, del->name));
+	g_hash_table_remove(list->idx_all_named_items, key);
+
 	/* Free the removed item */
-	g_free(del->name);
-	aim_tlvlist_free(del->data);
-	g_free(del);
+	aim_ssi_item_free(del);
 
 	return 0;
 }
@@ -320,10 +356,10 @@
 	return 0;
 }
 
-static gboolean aim_ssi_itemlist_valid(struct aim_ssi_item *list, struct aim_ssi_item *item)
+static gboolean aim_ssi_itemlist_valid(struct aim_ssi_itemlist *list, struct aim_ssi_item *item)
 {
 	struct aim_ssi_item *cur;
-	for (cur=list; cur; cur=cur->next)
+	for (cur=list->data; cur; cur=cur->next)
 		if (cur == item)
 			return TRUE;
 	return FALSE;
@@ -337,13 +373,10 @@
  * @param bid The buddy ID# of the desired item.
  * @return Return a pointer to the item if found, else return NULL;
  */
-struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, guint16 gid, guint16 bid)
+struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_itemlist *list, guint16 gid, guint16 bid)
 {
-	struct aim_ssi_item *cur;
-	for (cur=list; cur; cur=cur->next)
-		if ((cur->gid == gid) && (cur->bid == bid))
-			return cur;
-	return NULL;
+	guint32 id_key = (gid << 16) + bid;
+	return g_hash_table_lookup(list->idx_gid_bid, GINT_TO_POINTER(id_key));
 }
 
 /**
@@ -356,37 +389,30 @@
  * @param type The type of the desired item.
  * @return Return a pointer to the item if found, else return NULL.
  */
-struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *bn, guint16 type)
+struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_itemlist *list, const char *gn, const char *bn, guint16 type)
 {
 	struct aim_ssi_item *cur;
-	if (!list)
+	gchar key[3000];
+
+	if (!list->data)
 		return NULL;
 
 	if (gn && bn) { /* For finding buddies in groups */
-		for (cur=list; cur; cur=cur->next)
+		g_return_val_if_fail(type == AIM_SSI_TYPE_BUDDY, NULL);
+		for (cur=list->data; cur; cur=cur->next)
 			if ((cur->type == type) && (cur->name) && !(oscar_util_name_compare(cur->name, bn))) {
 				struct aim_ssi_item *curg;
-				for (curg=list; curg; curg=curg->next)
+				for (curg=list->data; curg; curg=curg->next)
 					if ((curg->type == AIM_SSI_TYPE_GROUP) && (curg->gid == cur->gid) && (curg->name) && !(oscar_util_name_compare(curg->name, gn)))
 						return cur;
 			}
 
-	} else if (gn) { /* For finding groups */
-		for (cur=list; cur; cur=cur->next) {
-			if ((cur->type == type) && (cur->bid == 0x0000) && (cur->name) && !(oscar_util_name_compare(cur->name, gn))) {
-				return cur;
-			}
-		}
-
-	} else if (bn) { /* For finding permits, denies, and ignores */
-		for (cur=list; cur; cur=cur->next) {
-			if ((cur->type == type) && (cur->name) && !(oscar_util_name_compare(cur->name, bn))) {
-				return cur;
-			}
-		}
+	} else if (gn || bn) { /* For finding groups, permits, denies and ignores */
+		snprintf(key, sizeof(key), "%hx%s", type, oscar_normalize(NULL, gn ? gn : bn));
+		return g_hash_table_lookup(list->idx_all_named_items, key);
 
 	/* For stuff without names--permit deny setting, visibility mask, etc. */
-	} else for (cur=list; cur; cur=cur->next) {
+	} else for (cur=list->data; cur; cur=cur->next) {
 		if ((cur->type == type) && (!cur->name))
 			return cur;
 	}
@@ -401,7 +427,7 @@
  * @param bn The group name of the desired item.
  * @return Return a pointer to the name of the item if found, else return NULL;
  */
-struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *bn)
+struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_itemlist *list, const char *bn)
 {
 	if (!bn)
 		return NULL;
@@ -415,10 +441,10 @@
  * @param bn The buddy name of the desired item.
  * @return Return a pointer to the name of the item if found, else return NULL;
  */
-char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *bn)
+char *aim_ssi_itemlist_findparentname(struct aim_ssi_itemlist *list, const char *bn)
 {
 	struct aim_ssi_item *cur, *curg;
-	if (!list || !bn)
+	if (!list->data || !bn)
 		return NULL;
 	if (!(cur = aim_ssi_itemlist_exists(list, bn)))
 		return NULL;
@@ -433,7 +459,7 @@
  * @param list A pointer to the current list of items.
  * @return Return the current SSI permit deny setting, or 0 if no setting was found.
  */
-int aim_ssi_getpermdeny(struct aim_ssi_item *list)
+int aim_ssi_getpermdeny(struct aim_ssi_itemlist *list)
 {
 	struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PDINFO);
 	if (cur) {
@@ -451,7 +477,7 @@
  * @param list A pointer to the current list of items.
  * @return Return the current set of preferences.
  */
-guint32 aim_ssi_getpresence(struct aim_ssi_item *list)
+guint32 aim_ssi_getpresence(struct aim_ssi_itemlist *list)
 {
 	struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS);
 	if (cur) {
@@ -472,17 +498,23 @@
  *         alias, or NULL if the buddy has no alias.  You should free
  *         this returned value!
  */
-char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *bn)
+char *aim_ssi_getalias(struct aim_ssi_itemlist *list, const char *gn, const char *bn)
 {
-	struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY);
-	if (cur) {
-		aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x0131, 1);
-		if (tlv && tlv->length)
-			return g_strndup((const gchar *)tlv->value, tlv->length);
+	struct aim_ssi_item *item = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY);
+	if (item) {
+		return aim_ssi_getalias_from_item(item);
 	}
 	return NULL;
 }
 
+char *aim_ssi_getalias_from_item(struct aim_ssi_item *item)
+{
+	aim_tlv_t *tlv = aim_tlv_gettlv(item->data, 0x0131, 1);
+	if (tlv && tlv->length)
+		return g_strndup((const gchar *)tlv->value, tlv->length);
+	return NULL;
+}
+
 /**
  * Locally find the comment of the given buddy.
  *
@@ -493,7 +525,7 @@
  *         comment, or NULL if the buddy has no comment.  You should free
  *         this returned value!
  */
-char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *bn)
+char *aim_ssi_getcomment(struct aim_ssi_itemlist *list, const char *gn, const char *bn)
 {
 	struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY);
 	if (cur) {
@@ -513,7 +545,7 @@
  * @param bn The name of the buddy.
  * @return 1 if you are waiting for authorization; 0 if you are not
  */
-gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *bn)
+gboolean aim_ssi_waitingforauth(struct aim_ssi_itemlist *list, const char *gn, const char *bn)
 {
 	struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY);
 	if (cur) {
@@ -561,8 +593,8 @@
 
 	/* Deletions */
 	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.official.data; cur1 && (n < 15); cur1=cur1->next) {
+			if (!aim_ssi_itemlist_find(&od->ssi.local, cur1->gid, cur1->bid)) {
 				n++;
 				new = g_new(struct aim_ssi_tmp, 1);
 				new->action = SNAC_SUBTYPE_FEEDBAG_DEL;
@@ -575,15 +607,15 @@
 					cur->next = new;
 				} else
 					od->ssi.pending = new;
-			       	aim_ssi_item_debug_append(debugstr, "Deleting item ", cur1);
+					aim_ssi_item_debug_append(debugstr, "Deleting item ", cur1);
 			}
 		}
 	}
 
 	/* Additions */
 	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.local.data; cur1 && (n < 15); cur1=cur1->next) {
+			if (!aim_ssi_itemlist_find(&od->ssi.official, cur1->gid, cur1->bid)) {
 				n++;
 				new = g_new(struct aim_ssi_tmp, 1);
 				new->action = SNAC_SUBTYPE_FEEDBAG_ADD;
@@ -596,15 +628,15 @@
 					cur->next = new;
 				} else
 					od->ssi.pending = new;
-			       	aim_ssi_item_debug_append(debugstr, "Adding item ", cur1);
+					aim_ssi_item_debug_append(debugstr, "Adding item ", cur1);
 			}
 		}
 	}
 
 	/* Modifications */
 	if (!od->ssi.pending) {
-		for (cur1=od->ssi.local; cur1 && (n < 15); cur1=cur1->next) {
-			cur2 = aim_ssi_itemlist_find(od->ssi.official, cur1->gid, cur1->bid);
+		for (cur1=od->ssi.local.data; cur1 && (n < 15); cur1=cur1->next) {
+			cur2 = aim_ssi_itemlist_find(&od->ssi.official, cur1->gid, cur1->bid);
 			if (cur2 && (aim_ssi_itemlist_cmp(cur1, cur2))) {
 				n++;
 				new = g_new(struct aim_ssi_tmp, 1);
@@ -618,15 +650,15 @@
 					cur->next = new;
 				} else
 					od->ssi.pending = new;
-			       	aim_ssi_item_debug_append(debugstr, "Modifying item ", cur1);
+					aim_ssi_item_debug_append(debugstr, "Modifying item ", cur1);
 			}
 		}
 	}
 	if (debugstr->len > 0) {
 		purple_debug_info("oscar", "%s", debugstr->str);
 		if (purple_debug_is_verbose()) {
-	    		g_string_truncate(debugstr, 0);
-			for (cur1 = od->ssi.local; cur1; cur1 = cur1->next) 
+			g_string_truncate(debugstr, 0);
+			for (cur1 = od->ssi.local.data; cur1; cur1 = cur1->next)
 				aim_ssi_item_debug_append(debugstr, "\t", cur1);
 			purple_debug_misc("oscar", "Dumping item list of account %s:\n%s",
 				purple_connection_get_account(od->gc)->username, debugstr->str);
@@ -673,22 +705,18 @@
 	struct aim_ssi_item *cur, *del;
 	struct aim_ssi_tmp *curtmp, *deltmp;
 
-	cur = od->ssi.official;
+	cur = od->ssi.official.data;
 	while (cur) {
 		del = cur;
 		cur = cur->next;
-		g_free(del->name);
-		aim_tlvlist_free(del->data);
-		g_free(del);
+		aim_ssi_item_free(del);
 	}
 
-	cur = od->ssi.local;
+	cur = od->ssi.local.data;
 	while (cur) {
 		del = cur;
 		cur = cur->next;
-		g_free(del->name);
-		aim_tlvlist_free(del->data);
-		g_free(del);
+		aim_ssi_item_free(del);
 	}
 
 	curtmp = od->ssi.pending;
@@ -699,8 +727,8 @@
 	}
 
 	od->ssi.numitems = 0;
-	od->ssi.official = NULL;
-	od->ssi.local = NULL;
+	od->ssi.official.data = NULL;
+	od->ssi.local.data = NULL;
 	od->ssi.pending = NULL;
 	od->ssi.timestamp = (time_t)0;
 }
@@ -726,7 +754,7 @@
 	/* DESTROY any buddies that are directly in the master group. */
 	/* Do the same for buddies that are in a non-existant group. */
 	/* This will kind of mess up if you hit the item limit, but this function isn't too critical */
-	cur = od->ssi.local;
+	cur = od->ssi.local.data;
 	while (cur) {
 		next = cur->next;
 		if (!cur->name) {
@@ -734,8 +762,8 @@
 				aim_ssi_delbuddy(od, NULL, NULL);
 			else if (cur->type == AIM_SSI_TYPE_PERMIT || cur->type == AIM_SSI_TYPE_DENY || cur->type == AIM_SSI_TYPE_ICQDENY)
 				aim_ssi_del_from_private_list(od, NULL, cur->type);
-		} else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(od->ssi.local, cur->gid, 0x0000)))) {
-			char *alias = aim_ssi_getalias(od->ssi.local, NULL, cur->name);
+		} else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(&od->ssi.local, cur->gid, 0x0000)))) {
+			char *alias = aim_ssi_getalias(&od->ssi.local, NULL, cur->name);
 			aim_ssi_addbuddy(od, cur->name, "orphans", NULL, alias, NULL, NULL, FALSE);
 			aim_ssi_delbuddy(od, cur->name, NULL);
 			g_free(alias);
@@ -744,7 +772,7 @@
 	}
 
 	/* Make sure there aren't any duplicate buddies in a group, or duplicate permits or denies */
-	cur = od->ssi.local;
+	cur = od->ssi.local.data;
 	while (cur) {
 		if ((cur->type == AIM_SSI_TYPE_BUDDY) || (cur->type == AIM_SSI_TYPE_PERMIT) || (cur->type == AIM_SSI_TYPE_DENY))
 		{
@@ -785,16 +813,16 @@
 		return -EINVAL;
 
 	/* Find the parent */
-	if (!(parent = aim_ssi_itemlist_finditem(od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) {
+	if (!(parent = aim_ssi_itemlist_finditem(&od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) {
 		/* Find the parent's parent (the master group) */
-		if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
+		if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL)
 			aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
 
 		/* Add the parent */
 		parent = aim_ssi_itemlist_add(&od->ssi.local, group, 0xFFFF, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
 
 		/* Modify the parent's parent (the master group) */
-		aim_ssi_itemlist_rebuildgroup(od->ssi.local, NULL);
+		aim_ssi_itemlist_rebuildgroup(&od->ssi.local, NULL);
 	}
 
 	/* Create a TLV list for the new buddy */
@@ -812,7 +840,7 @@
 	aim_tlvlist_free(data);
 
 	/* Modify the parent group */
-	aim_ssi_itemlist_rebuildgroup(od->ssi.local, group);
+	aim_ssi_itemlist_rebuildgroup(&od->ssi.local, group);
 
 	/* Sync our local list with the server list */
 	return aim_ssi_sync(od);
@@ -824,7 +852,7 @@
 	if (!od || !name || !od->ssi.received_data)
 		return -EINVAL;
 
-	if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
+	if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL)
 		aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
 
 	aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, list_type, NULL);
@@ -839,7 +867,7 @@
 	if (!od)
 		return -EINVAL;
 
-	if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, NULL, name, list_type)))
+	if (!(del = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, name, list_type)))
 		return -EINVAL;
 
 	aim_ssi_itemlist_del(&od->ssi.local, del);
@@ -862,14 +890,14 @@
 		return -EINVAL;
 
 	/* Find the buddy */
-	if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, group, name, AIM_SSI_TYPE_BUDDY)))
+	if (!(del = aim_ssi_itemlist_finditem(&od->ssi.local, group, name, AIM_SSI_TYPE_BUDDY)))
 		return -EINVAL;
 
 	/* Remove the item from the list */
 	aim_ssi_itemlist_del(&od->ssi.local, del);
 
 	/* Modify the parent group */
-	aim_ssi_itemlist_rebuildgroup(od->ssi.local, group);
+	aim_ssi_itemlist_rebuildgroup(&od->ssi.local, group);
 
 	/* Sync our local list with the server list */
 	return aim_ssi_sync(od);
@@ -891,7 +919,7 @@
 		return -EINVAL;
 
 	/* Find the group */
-	if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP)))
+	if (!(del = aim_ssi_itemlist_finditem(&od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP)))
 		return -EINVAL;
 
 	/* Don't delete the group if it's not empty */
@@ -903,7 +931,7 @@
 	aim_ssi_itemlist_del(&od->ssi.local, del);
 
 	/* Modify the parent group */
-	aim_ssi_itemlist_rebuildgroup(od->ssi.local, group);
+	aim_ssi_itemlist_rebuildgroup(&od->ssi.local, group);
 
 	/* Sync our local list with the server list */
 	return aim_ssi_sync(od);
@@ -925,7 +953,7 @@
 	GSList *data;
 
 	/* Find the buddy */
-	buddy = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, bn, AIM_SSI_TYPE_BUDDY);
+	buddy = aim_ssi_itemlist_finditem(&od->ssi.local, oldgn, bn, AIM_SSI_TYPE_BUDDY);
 	if (buddy == NULL)
 		return -EINVAL;
 
@@ -958,11 +986,11 @@
 	if (!od || !gn || !bn)
 		return -EINVAL;
 
-	if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY)))
+	if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY)))
 		return -EINVAL;
 
 	/* Either add or remove the 0x0131 TLV from the TLV chain */
-	if ((alias != NULL) && (strlen(alias) > 0))
+	if (alias && *alias)
 		aim_tlvlist_replace_str(&tmp->data, 0x0131, alias);
 	else
 		aim_tlvlist_remove(&tmp->data, 0x0131);
@@ -988,11 +1016,11 @@
 	if (!od || !gn || !bn)
 		return -EINVAL;
 
-	if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY)))
+	if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY)))
 		return -EINVAL;
 
 	/* Either add or remove the 0x0131 TLV from the TLV chain */
-	if ((comment != NULL) && (strlen(comment) > 0))
+	if (comment && *comment)
 		aim_tlvlist_replace_str(&tmp->data, 0x013c, comment);
 	else
 		aim_tlvlist_remove(&tmp->data, 0x013c);
@@ -1016,11 +1044,10 @@
 	if (!od || !oldgn || !newgn)
 		return -EINVAL;
 
-	if (!(group = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP)))
+	if (!(group = aim_ssi_itemlist_finditem(&od->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP)))
 		return -EINVAL;
 
-	g_free(group->name);
-	group->name = g_strdup(newgn);
+	aim_ssi_item_set_name(&od->ssi.local, group, newgn);
 
 	/* Sync our local list with the server list */
 	return aim_ssi_sync(od);
@@ -1047,9 +1074,9 @@
 		return -EINVAL;
 
 	/* Find the PDINFO item, or add it if it does not exist */
-	if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PDINFO))) {
+	if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PDINFO))) {
 		/* Make sure the master group exists */
-		if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
+		if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL)
 			aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
 
 		tmp = aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PDINFO, NULL);
@@ -1079,9 +1106,9 @@
 		return -EINVAL;
 
 	/* Find the ICONINFO item, or add it if it does not exist */
-	if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) {
+	if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) {
 		/* Make sure the master group exists */
-		if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
+		if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL)
 			aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
 
 		tmp = aim_ssi_itemlist_add(&od->ssi.local, "1", 0x0000, 0xFFFF, AIM_SSI_TYPE_ICONINFO, NULL);
@@ -1139,9 +1166,9 @@
 		return -EINVAL;
 
 	/* Find the PRESENCEPREFS item, or add it if it does not exist */
-	if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS))) {
+	if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS))) {
 		/* Make sure the master group exists */
-		if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
+		if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL)
 			aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
 
 		tmp = aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PRESENCEPREFS, NULL);
@@ -1266,7 +1293,7 @@
 	if (!(snac->flags & 0x0001)) {
 		/* Make a copy of the list */
 		struct aim_ssi_item *cur;
-		for (cur=od->ssi.official; cur; cur=cur->next)
+		for (cur=od->ssi.official.data; cur; cur=cur->next)
 			aim_ssi_itemlist_add(&od->ssi.local, cur->name, cur->gid, cur->bid, cur->type, cur->data);
 
 		od->ssi.received_data = TRUE;
@@ -1416,18 +1443,16 @@
 			data = NULL;
 
 		/* Replace the 2 local items with the given one */
-		if ((item = aim_ssi_itemlist_find(od->ssi.local, gid, bid))) {
+		if ((item = aim_ssi_itemlist_find(&od->ssi.local, gid, bid))) {
 			item->type = type;
-			g_free(item->name);
-			item->name = g_strdup(name);
+			aim_ssi_item_set_name(&od->ssi.local, item, name);
 			aim_tlvlist_free(item->data);
 			item->data = aim_tlvlist_copy(data);
 		}
 
-		if ((item = aim_ssi_itemlist_find(od->ssi.official, gid, bid))) {
+		if ((item = aim_ssi_itemlist_find(&od->ssi.official, gid, bid))) {
 			item->type = type;
-			g_free(item->name);
-			item->name = g_strdup(name);
+			aim_ssi_item_set_name(&od->ssi.official, item, name);
 			aim_tlvlist_free(item->data);
 			item->data = aim_tlvlist_copy(data);
 		}
@@ -1461,9 +1486,9 @@
 		byte_stream_get16(bs);
 		byte_stream_advance(bs, byte_stream_get16(bs));
 
-		if ((del = aim_ssi_itemlist_find(od->ssi.local, gid, bid)))
+		if ((del = aim_ssi_itemlist_find(&od->ssi.local, gid, bid)))
 			aim_ssi_itemlist_del(&od->ssi.local, del);
-		if ((del = aim_ssi_itemlist_find(od->ssi.official, gid, bid)))
+		if ((del = aim_ssi_itemlist_find(&od->ssi.official, gid, bid)))
 			aim_ssi_itemlist_del(&od->ssi.official, del);
 
 		if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
@@ -1504,7 +1529,8 @@
 			if (cur->action == SNAC_SUBTYPE_FEEDBAG_ADD) {
 				/* Remove the item from the local list */
 				/* Make sure cur->item is still valid memory */
-				if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) {
+				/* TODO: "Still valid memory"?  That's bad form. */
+				if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) {
 					cur->name = g_strdup(cur->item->name);
 					aim_ssi_itemlist_del(&od->ssi.local, cur->item);
 				}
@@ -1512,11 +1538,10 @@
 
 			} else if (cur->action == SNAC_SUBTYPE_FEEDBAG_MOD) {
 				/* Replace the local item with the item from the official list */
-				if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) {
+				if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) {
 					struct aim_ssi_item *cur1;
-					if ((cur1 = aim_ssi_itemlist_find(od->ssi.official, cur->item->gid, cur->item->bid))) {
-						g_free(cur->item->name);
-						cur->item->name = g_strdup(cur1->name);
+					if ((cur1 = aim_ssi_itemlist_find(&od->ssi.official, cur->item->gid, cur->item->bid))) {
+						aim_ssi_item_set_name(&od->ssi.official, cur->item, cur1->name);
 						aim_tlvlist_free(cur->item->data);
 						cur->item->data = aim_tlvlist_copy(cur1->data);
 					}
@@ -1525,7 +1550,7 @@
 
 			} else if (cur->action == SNAC_SUBTYPE_FEEDBAG_DEL) {
 				/* Add the item back into the local list */
-				if (aim_ssi_itemlist_valid(od->ssi.official, cur->item)) {
+				if (aim_ssi_itemlist_valid(&od->ssi.official, cur->item)) {
 					aim_ssi_itemlist_add(&od->ssi.local, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data);
 				} else
 					cur->item = NULL;
@@ -1535,18 +1560,17 @@
 			/* Do the exact opposite */
 			if (cur->action == SNAC_SUBTYPE_FEEDBAG_ADD) {
 			/* Add the local item to the official list */
-				if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) {
+				if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) {
 					aim_ssi_itemlist_add(&od->ssi.official, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data);
 				} else
 					cur->item = NULL;
 
 			} else if (cur->action == SNAC_SUBTYPE_FEEDBAG_MOD) {
 				/* Replace the official item with the item from the local list */
-				if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) {
+				if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) {
 					struct aim_ssi_item *cur1;
-					if ((cur1 = aim_ssi_itemlist_find(od->ssi.official, cur->item->gid, cur->item->bid))) {
-						g_free(cur1->name);
-						cur1->name = g_strdup(cur->item->name);
+					if ((cur1 = aim_ssi_itemlist_find(&od->ssi.official, cur->item->gid, cur->item->bid))) {
+						aim_ssi_item_set_name(&od->ssi.official, cur1, cur->item->name);
 						aim_tlvlist_free(cur1->data);
 						cur1->data = aim_tlvlist_copy(cur->item->data);
 					}
@@ -1555,7 +1579,7 @@
 
 			} else if (cur->action == SNAC_SUBTYPE_FEEDBAG_DEL) {
 				/* Remove the item from the official list */
-				if (aim_ssi_itemlist_valid(od->ssi.official, cur->item))
+				if (aim_ssi_itemlist_valid(&od->ssi.official, cur->item))
 					aim_ssi_itemlist_del(&od->ssi.official, cur->item);
 				cur->item = NULL;
 			}
--- a/libpurple/protocols/oscar/flap_connection.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/flap_connection.c	Sun Sep 11 04:19:01 2011 +0000
@@ -487,7 +487,7 @@
 
 		if (tmp != NULL)
 		{
-			purple_connection_error_reason(od->gc, reason, tmp);
+			purple_connection_error(od->gc, reason, tmp);
 			g_free(tmp);
 		}
 	}
--- a/libpurple/protocols/oscar/libaim.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/libaim.c	Sun Sep 11 04:19:01 2011 +0000
@@ -29,6 +29,7 @@
 
 static PurplePluginProtocolInfo prpl_info =
 {
+	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE,
 	NULL,					/* user_splits */
 	NULL,					/* protocol_options */
@@ -50,7 +51,7 @@
 	oscar_set_status,		/* set_status */
 	oscar_set_idle,			/* set_idle */
 	oscar_change_passwd,	/* change_passwd */
-	NULL,					/* add_buddy */
+	oscar_add_buddy,		/* add_buddy */
 	NULL,					/* add_buddies */
 	oscar_remove_buddy,		/* remove_buddy */
 	NULL,					/* remove_buddies */
@@ -94,15 +95,12 @@
 	NULL,					/* unregister_user */
 	NULL,					/* send_attention */
 	NULL,					/* get_attention_types */
-	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	NULL,					/* get_account_text_table */
 	NULL,					/* initiate_media */
 	NULL,					/* get_media_caps */
 	NULL,					/* get_moods */
 	NULL,					/* set_public_alias */
-	NULL,					/* get_public_alias */
-	oscar_add_buddy,		/* add_buddy_with_invite */
-	NULL					/* add_buddies_with_invite */
+	NULL					/* get_public_alias */
 };
 
 static PurplePluginInfo info =
--- a/libpurple/protocols/oscar/libicq.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/libicq.c	Sun Sep 11 04:19:01 2011 +0000
@@ -38,6 +38,7 @@
 
 static PurplePluginProtocolInfo prpl_info =
 {
+	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE,
 	NULL,					/* user_splits */
 	NULL,					/* protocol_options */
@@ -59,7 +60,7 @@
 	oscar_set_status,		/* set_status */
 	oscar_set_idle,			/* set_idle */
 	oscar_change_passwd,	/* change_passwd */
-	NULL,					/* add_buddy */
+	oscar_add_buddy,		/* add_buddy */
 	NULL,					/* add_buddies */
 	oscar_remove_buddy,		/* remove_buddy */
 	NULL,					/* remove_buddies */
@@ -103,16 +104,12 @@
 	NULL,					/* unregister_user */
 	NULL,					/* send_attention */
 	NULL,					/* get_attention_types */
-
-	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	icq_get_account_text_table, /* get_account_text_table */
 	NULL,					/* initiate_media */
 	NULL,					/* can_do_media */
 	oscar_get_purple_moods, /* get_moods */
 	NULL,					/* set_public_alias */
-	NULL,					/* get_public_alias */
-	oscar_add_buddy,		/* add_buddy_with_invite */
-	NULL					/* add_buddies_with_invite */
+	NULL					/* get_public_alias */
 };
 
 static PurplePluginInfo info =
--- a/libpurple/protocols/oscar/oft.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/oft.c	Sun Sep 11 04:19:01 2011 +0000
@@ -362,10 +362,10 @@
 
 	if (purple_circ_buffer_get_max_read(conn->buffer_outgoing) == 0)
 	{
+		int fd = conn->fd;
 		conn->sending_data_timer = 0;
-		conn->xfer->fd = conn->fd;
 		conn->fd = -1;
-		purple_xfer_start(conn->xfer, conn->xfer->fd, NULL, 0);
+		purple_xfer_start(conn->xfer, fd, NULL, 0);
 		return FALSE;
 	}
 
@@ -589,7 +589,7 @@
 {
 	PeerConnection *conn;
 
-	conn = xfer->data;
+	conn = purple_xfer_get_protocol_data(xfer);
 	conn->flags |= PEER_CONNECTION_FLAG_APPROVED;
 	peer_connection_trynext(conn);
 }
@@ -599,7 +599,7 @@
 {
 	PeerConnection *conn;
 
-	conn = xfer->data;
+	conn = purple_xfer_get_protocol_data(xfer);
 
 	/* Tell the other person that we've received everything */
 	conn->fd = conn->xfer->fd;
@@ -617,7 +617,7 @@
 	PeerConnection *conn;
 
 	/* Update our rolling checksum.  Like Walmart, yo. */
-	conn = xfer->data;
+	conn = purple_xfer_get_protocol_data(xfer);
 	conn->xferdata.recvcsum = peer_oft_checksum_chunk(buffer,
 			size, conn->xferdata.recvcsum, purple_xfer_get_bytes_sent(xfer) & 1);
 }
@@ -653,7 +653,7 @@
 	PeerConnection *conn;
 	size_t size;
 
-	conn = xfer->data;
+	conn = purple_xfer_get_protocol_data(xfer);
 	conn->flags |= PEER_CONNECTION_FLAG_APPROVED;
 
 	/* Make sure the file size can be represented in 32 bits */
@@ -665,9 +665,9 @@
 		size2 = purple_str_size_to_units(G_MAXUINT32);
 		tmp = g_strdup_printf(_("File %s is %s, which is larger than "
 				"the maximum size of %s."),
-				xfer->local_filename, size1, size2);
+				purple_xfer_get_local_filename(xfer), size1, size2);
 		purple_xfer_error(purple_xfer_get_type(xfer),
-				purple_xfer_get_account(xfer), xfer->who, tmp);
+				purple_xfer_get_account(xfer), purple_xfer_get_remote_user(xfer), tmp);
 		g_free(size1);
 		g_free(size2);
 		g_free(tmp);
@@ -689,9 +689,9 @@
 	strncpy((gchar *)conn->xferdata.idstring, "Cool FileXfer", 31);
 	conn->xferdata.modtime = 0;
 	conn->xferdata.cretime = 0;
-	xfer->filename = g_path_get_basename(xfer->local_filename);
-	conn->xferdata.name_length = MAX(64, strlen(xfer->filename) + 1);
-	conn->xferdata.name = (guchar *)g_strndup(xfer->filename, conn->xferdata.name_length - 1);
+	purple_xfer_set_filename(xfer, g_path_get_basename(purple_xfer_get_local_filename(xfer)));
+	conn->xferdata.name_length = MAX(64, strlen(purple_xfer_get_filename(xfer)) + 1);
+	conn->xferdata.name = (guchar *)g_strndup(purple_xfer_get_filename(xfer), conn->xferdata.name_length - 1);
 
 	peer_oft_checksum_file(conn, xfer,
 			peer_oft_checksum_calculated_cb, G_MAXUINT32);
@@ -713,7 +713,7 @@
 {
 	PeerConnection *conn;
 
-	conn = xfer->data;
+	conn = purple_xfer_get_protocol_data(xfer);
 
 	/*
 	 * If we're done sending, intercept the socket from the core ft code
@@ -742,7 +742,7 @@
 {
 	PeerConnection *conn;
 
-	conn = xfer->data;
+	conn = purple_xfer_get_protocol_data(xfer);
 
 	if (conn == NULL)
 		return;
--- a/libpurple/protocols/oscar/oscar.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Sun Sep 11 04:19:01 2011 +0000
@@ -308,7 +308,7 @@
 		gchar *msg;
 		msg = g_strdup_printf(_("Unable to connect to authentication server: %s"),
 				error_message);
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
 		g_free(msg);
 	}
 	else if (conn->type == SNAC_FAMILY_LOCATE)
@@ -316,7 +316,7 @@
 		gchar *msg;
 		msg = g_strdup_printf(_("Unable to connect to BOS server: %s"),
 				error_message);
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
 		g_free(msg);
 	}
 	else
@@ -578,7 +578,7 @@
 	gc = data;
 	od = purple_connection_get_protocol_data(gc);
 	report_idle = strcmp((const char *)value, "none") != 0;
-	presence = aim_ssi_getpresence(od->ssi.local);
+	presence = aim_ssi_getpresence(&od->ssi.local);
 
 	if (report_idle)
 		aim_ssi_setpresence(od, presence | AIM_SSI_PRESENCE_FLAG_SHOWIDLE);
@@ -600,7 +600,7 @@
 
 	gc = data;
 	od = purple_connection_get_protocol_data(gc);
-	presence = aim_ssi_getpresence(od->ssi.local);
+	presence = aim_ssi_getpresence(&od->ssi.local);
 
 	if (value)
 		aim_ssi_setpresence(od, presence & ~AIM_SSI_PRESENCE_FLAG_NORECENTBUDDIES);
@@ -735,13 +735,13 @@
 	if (!oscar_util_valid_name(purple_account_get_username(account))) {
 		gchar *buf;
 		buf = g_strdup_printf(_("Unable to sign on as %s because the username is invalid.  Usernames must be a valid email address, or start with a letter and contain only letters, numbers and spaces, or contain only numbers."), purple_account_get_username(account));
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, buf);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, buf);
 		g_free(buf);
 		return;
 	}
 
 	gc->flags |= PURPLE_CONNECTION_HTML;
-	if (oscar_util_valid_name_icq((purple_account_get_username(account)))) {
+	if (g_str_equal(purple_account_get_protocol_id(account), "prpl-icq")) {
 		od->icq = TRUE;
 	} else {
 		gc->flags |= PURPLE_CONNECTION_AUTO_RESP;
@@ -756,7 +756,7 @@
 
 	encryption_type = purple_account_get_string(account, "encryption", OSCAR_DEFAULT_ENCRYPTION);
 	if (!purple_ssl_is_supported() && strcmp(encryption_type, OSCAR_REQUIRE_ENCRYPTION) == 0) {
-		purple_connection_error_reason(
+		purple_connection_error(
 			gc,
 			PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 			_("You required encryption in your account settings, but encryption is not supported by your system."));
@@ -825,7 +825,7 @@
 		}
 
 		if (newconn->gsc == NULL && newconn->connect_data == NULL) {
-			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+			purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 					_("Unable to connect"));
 			return;
 		}
@@ -1048,7 +1048,7 @@
 
 	if (conn->gsc == NULL && conn->connect_data == NULL)
 	{
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
 		return 0;
 	}
 
@@ -1087,41 +1087,41 @@
 		switch (info->errorcode) {
 		case 0x01:
 			/* Unregistered username */
-			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_INVALID_USERNAME, _("Username does not exist"));
+			purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_USERNAME, _("Username does not exist"));
 			break;
 		case 0x05:
 			/* Incorrect password */
 			if (!purple_account_get_remember_password(account))
 				purple_account_set_password(account, NULL);
-			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect password"));
+			purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect password"));
 			break;
 		case 0x11:
 			/* Suspended account */
-			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Your account is currently suspended"));
+			purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Your account is currently suspended"));
 			break;
 		case 0x02:
 		case 0x14:
 			/* service temporarily unavailable */
-			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("The AOL Instant Messenger service is temporarily unavailable."));
+			purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("The AOL Instant Messenger service is temporarily unavailable."));
 			break;
 		case 0x18:
 			/* username connecting too frequently */
-			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your username has been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer."));
+			purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your username has been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer."));
 			break;
 		case 0x1c:
 		{
 			/* client too old */
 			g_snprintf(buf, sizeof(buf), _("The client version you are using is too old. Please upgrade at %s"),
 					oscar_get_ui_info_string("website", PURPLE_WEBSITE));
-			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, buf);
+			purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, buf);
 			break;
 		}
 		case 0x1d:
 			/* IP address connecting too frequently */
-			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your IP address has been connecting and disconnecting too frequently. Wait a minute and try again. If you continue to try, you will need to wait even longer."));
+			purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your IP address has been connecting and disconnecting too frequently. Wait a minute and try again. If you continue to try, you will need to wait even longer."));
 			break;
 		default:
-			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Unknown reason"));
+			purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Unknown reason"));
 			break;
 		}
 		purple_debug_info("oscar", "Login Error Code 0x%04hx\n", info->errorcode);
@@ -1169,7 +1169,7 @@
 	g_free(host);
 	if (newconn->gsc == NULL && newconn->connect_data == NULL)
 	{
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
 		return 0;
 	}
 
@@ -1199,7 +1199,7 @@
 	PurpleConnection *gc = user_data;
 
 	/* Disconnect */
-	purple_connection_error_reason(gc,
+	purple_connection_error(gc,
 		PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
 		_("The SecurID key entered is invalid"));
 }
@@ -1292,7 +1292,7 @@
 			purple_debug_warning("oscar", "We won't use SSL for FLAP type 0x%04hx.\n", redir->group);
 		} else if (strcmp(encryption_type, OSCAR_REQUIRE_ENCRYPTION) == 0) {
 			purple_debug_error("oscar", "FLAP server %s:%d of type 0x%04hx doesn't support encryption.", host, port, redir->group);
-			purple_connection_error_reason(
+			purple_connection_error(
 				gc,
 				PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
 				_("You required encryption in your account settings, but one of the servers doesn't support it."));
@@ -2278,7 +2278,7 @@
 	return 0;
 }
 
-static int purple_parse_clientauto_ch4(OscarData *od, char *who, guint16 reason, guint32 state, char *msg) {
+static int purple_parse_clientauto_ch4(OscarData *od, const char *who, guint16 reason, guint32 state, char *msg) {
 	PurpleConnection *gc = od->gc;
 
 	switch(reason) {
@@ -2286,16 +2286,20 @@
 			char *statusmsg, **splitmsg;
 			PurpleNotifyUserInfo *user_info;
 
+			statusmsg = oscar_icqstatus(state);
+
 			/* Split at (carriage return/newline)'s, then rejoin later with BRs between. */
-			statusmsg = oscar_icqstatus(state);
+			/* TODO: Don't we need to escape each piece? */
 			splitmsg = g_strsplit(msg, "\r\n", 0);
 
 			user_info = purple_notify_user_info_new();
 
-			purple_notify_user_info_add_pair(user_info, _("UIN"), who);
-			purple_notify_user_info_add_pair(user_info, _("Status"), statusmsg);
+			purple_notify_user_info_add_pair_plaintext(user_info, _("UIN"), who);
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html(user_info, _("Status"), statusmsg);
 			purple_notify_user_info_add_section_break(user_info);
-			purple_notify_user_info_add_pair(user_info, NULL, g_strjoinv("<BR>", splitmsg));
+			purple_notify_user_info_add_pair_html(user_info, NULL, g_strjoinv("<BR>", splitmsg));
 
 			g_free(statusmsg);
 			g_strfreev(splitmsg);
@@ -2309,16 +2313,20 @@
 			char *statusmsg, **splitmsg;
 			PurpleNotifyUserInfo *user_info;
 
+			statusmsg = oscar_icqstatus(state);
+
 			/* Split at (carriage return/newline)'s, then rejoin later with BRs between. */
-			statusmsg = oscar_icqstatus(state);
+			/* TODO: Don't we need to escape each piece? */
 			splitmsg = g_strsplit(msg, "\r\n", 0);
 
 			user_info = purple_notify_user_info_new();
 
-			purple_notify_user_info_add_pair(user_info, _("UIN"), who);
-			purple_notify_user_info_add_pair(user_info, _("Status"), statusmsg);
+			purple_notify_user_info_add_pair_plaintext(user_info, _("UIN"), who);
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html(user_info, _("Status"), statusmsg);
 			purple_notify_user_info_add_section_break(user_info);
-			purple_notify_user_info_add_pair(user_info, NULL, g_strjoinv("<BR>", splitmsg));
+			purple_notify_user_info_add_pair_html(user_info, NULL, g_strjoinv("<BR>", splitmsg));
 
 			g_free(statusmsg);
 			g_strfreev(splitmsg);
@@ -3716,7 +3724,7 @@
 	}
 
 	if (od->ssi.received_data) {
-		if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY)) {
+		if (!aim_ssi_itemlist_finditem(&od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY)) {
 			purple_debug_info("oscar",
 					   "ssi: adding buddy %s to group %s\n", bname, gname);
 			aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, 0);
@@ -3728,8 +3736,8 @@
 				purple_prpl_got_user_status(account, bname,
 						OSCAR_STATUS_ID_MOBILE, NULL);
 			}
-		} else if (aim_ssi_waitingforauth(od->ssi.local,
-		                                  aim_ssi_itemlist_findparentname(od->ssi.local, bname),
+		} else if (aim_ssi_waitingforauth(&od->ssi.local,
+		                                  aim_ssi_itemlist_findparentname(&od->ssi.local, bname),
 		                                  bname)) {
 			/* Not authorized -- Re-request authorization */
 			oscar_auth_sendrequest(gc, bname, msg);
@@ -3767,7 +3775,7 @@
 	OscarData *od = purple_connection_get_protocol_data(gc);
 
 	if (od->ssi.received_data) {
-		char *gname = aim_ssi_itemlist_findparentname(od->ssi.local, name);
+		char *gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name);
 		if (gname) {
 			purple_debug_info("oscar",
 					   "ssi: changing the alias for buddy %s to %s\n", name, alias ? alias : "(none)");
@@ -3784,7 +3792,7 @@
 
 	if (od->ssi.received_data) {
 		const char *gname = purple_group_get_name(group);
-		if (aim_ssi_itemlist_finditem(od->ssi.local, gname, NULL, AIM_SSI_TYPE_GROUP)) {
+		if (aim_ssi_itemlist_finditem(&od->ssi.local, gname, NULL, AIM_SSI_TYPE_GROUP)) {
 			GList *cur, *groups = NULL;
 			PurpleAccount *account = purple_connection_get_account(gc);
 
@@ -3798,7 +3806,7 @@
 			}
 
 			purple_account_remove_buddies(account, moved_buddies, groups);
-			purple_account_add_buddies(account, moved_buddies);
+			purple_account_add_buddies(account, moved_buddies, NULL);
 			g_list_free(groups);
 			purple_debug_info("oscar",
 					   "ssi: moved all buddies from group %s to %s\n", old_name, gname);
@@ -3935,7 +3943,7 @@
 		gname = purple_group_get_name(g);
 		bname = purple_buddy_get_name(b);
 
-		if (aim_ssi_itemlist_exists(od->ssi.local, bname)) {
+		if (aim_ssi_itemlist_exists(&od->ssi.local, bname)) {
 			/* If the buddy is an ICQ user then load his nickname */
 			const char *servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick");
 			char *alias;
@@ -3944,7 +3952,7 @@
 				serv_got_alias(gc, bname, servernick);
 
 			/* Store local alias on server */
-			alias = aim_ssi_getalias(od->ssi.local, gname, bname);
+			alias = aim_ssi_getalias(&od->ssi.local, gname, bname);
 			balias = purple_buddy_get_local_buddy_alias(b);
 			if (!alias && balias && *balias)
 				aim_ssi_aliasbuddy(od, gname, bname, balias);
@@ -3967,7 +3975,7 @@
 		while (next != NULL) {
 			cur = next;
 			next = next->next;
-			if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) {
+			if (!aim_ssi_itemlist_finditem(&od->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) {
 				purple_debug_info("oscar",
 						"ssi: removing permit %s from local list\n", (const char *)cur->data);
 				purple_privacy_permit_remove(account, cur->data, TRUE);
@@ -3980,7 +3988,7 @@
 	while (next != NULL) {
 		cur = next;
 		next = next->next;
-		if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, deny_entry_type)) {
+		if (!aim_ssi_itemlist_finditem(&od->ssi.local, NULL, cur->data, deny_entry_type)) {
 			purple_debug_info("oscar",
 					"ssi: removing deny %s from local list\n", (const char *)cur->data);
 			purple_privacy_deny_remove(account, cur->data, TRUE);
@@ -3988,7 +3996,7 @@
 	}
 
 	/* Presence settings (idle time visibility) */
-	tmp = aim_ssi_getpresence(od->ssi.local);
+	tmp = aim_ssi_getpresence(&od->ssi.local);
 	if (tmp != 0xFFFFFFFF) {
 		const char *idle_reporting_pref;
 		gboolean report_idle;
@@ -4006,7 +4014,7 @@
 
 	/*** Begin code for adding from server list to local list ***/
 
-	for (curitem=od->ssi.local; curitem; curitem=curitem->next) {
+	for (curitem=od->ssi.local.data; curitem; curitem=curitem->next) {
 		if (curitem->name && !g_utf8_validate(curitem->name, -1, NULL)) {
 			/* Got node with invalid UTF-8 in the name.  Skip it. */
 			purple_debug_warning("oscar", "ssi: server list contains item of "
@@ -4020,7 +4028,7 @@
 					struct aim_ssi_item *groupitem;
 					char *gname, *gname_utf8, *alias, *alias_utf8;
 
-					groupitem = aim_ssi_itemlist_find(od->ssi.local, curitem->gid, 0x0000);
+					groupitem = aim_ssi_itemlist_find(&od->ssi.local, curitem->gid, 0x0000);
 					gname = groupitem ? groupitem->name : NULL;
 					gname_utf8 = oscar_utf8_try_convert(account, od, gname);
 
@@ -4030,7 +4038,7 @@
 						purple_blist_add_group(g, NULL);
 					}
 
-					alias = aim_ssi_getalias(od->ssi.local, gname, curitem->name);
+					alias = aim_ssi_getalias_from_item(curitem);
 					alias_utf8 = oscar_utf8_try_convert(account, od, alias);
 
 					b = purple_find_buddy_in_group(account, curitem->name, g);
@@ -4099,7 +4107,7 @@
 				 * a part of your status and not really related to blocking.
 				 */
 				if (!od->icq && curitem->data) {
-					guint8 perm_deny = aim_ssi_getpermdeny(od->ssi.local);
+					guint8 perm_deny = aim_ssi_getpermdeny(&od->ssi.local);
 					if (perm_deny != 0 && perm_deny != account->perm_deny)
 					{
 						purple_debug_info("oscar",
@@ -4228,10 +4236,10 @@
 	if ((type != 0x0000) || (name == NULL))
 		return 1;
 
-	gname = aim_ssi_itemlist_findparentname(od->ssi.local, name);
+	gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name);
 	gname_utf8 = gname ? oscar_utf8_try_convert(account, od, gname) : NULL;
 
-	alias = aim_ssi_getalias(od->ssi.local, gname, name);
+	alias = aim_ssi_getalias(&od->ssi.local, gname, name);
 	alias_utf8 = oscar_utf8_try_convert(account, od, alias);
 	g_free(alias);
 
@@ -4269,7 +4277,7 @@
 
 	}
 
-	ssi_item = aim_ssi_itemlist_finditem(od->ssi.local,
+	ssi_item = aim_ssi_itemlist_finditem(&od->ssi.local,
 			gname, name, AIM_SSI_TYPE_BUDDY);
 	if (ssi_item == NULL)
 	{
@@ -4586,32 +4594,18 @@
 const char *oscar_list_icon_icq(PurpleAccount *a, PurpleBuddy *b)
 {
 	const char *name = b ? purple_buddy_get_name(b) : NULL;
-	if ((b == NULL) || (name == NULL) || oscar_util_valid_name_sms(name))
-	{
-		if (a == NULL || oscar_util_valid_name_icq(purple_account_get_username(a)))
-			return "icq";
-		else
-			return "aim";
-	}
-
-	if (oscar_util_valid_name_icq(name))
+	if (name && !oscar_util_valid_name_sms(name) && oscar_util_valid_name_icq(name))
 		return "icq";
-	return "aim";
+
+	return "icq";
 }
 
 const char *oscar_list_icon_aim(PurpleAccount *a, PurpleBuddy *b)
 {
 	const char *name = b ? purple_buddy_get_name(b) : NULL;
-	if ((b == NULL) || (name == NULL) || oscar_util_valid_name_sms(name))
-	{
-		if (a != NULL && oscar_util_valid_name_icq(purple_account_get_username(a)))
-			return "icq";
-		else
-			return "aim";
-	}
-
-	if (oscar_util_valid_name_icq(name))
+	if (name && !oscar_util_valid_name_sms(name) && oscar_util_valid_name_icq(name))
 		return "icq";
+
 	return "aim";
 }
 
@@ -4642,8 +4636,8 @@
 	if (purple_presence_is_online(presence) == FALSE) {
 		char *gname;
 		if ((name) && (od) && (od->ssi.received_data) &&
-			(gname = aim_ssi_itemlist_findparentname(od->ssi.local, name)) &&
-			(aim_ssi_waitingforauth(od->ssi.local, gname, name))) {
+			(gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name)) &&
+			(aim_ssi_waitingforauth(&od->ssi.local, gname, name))) {
 			return "not-authorized";
 		}
 	}
@@ -4710,8 +4704,8 @@
 	if ((od != NULL) && !purple_presence_is_online(presence))
 	{
 		const char *name = purple_buddy_get_name(b);
-		char *gname = aim_ssi_itemlist_findparentname(od->ssi.local, name);
-		if (aim_ssi_waitingforauth(od->ssi.local, gname, name))
+		char *gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name);
+		if (aim_ssi_waitingforauth(&od->ssi.local, gname, name))
 			ret = g_strdup(_("Not Authorized"));
 		else
 			ret = g_strdup(_("Offline"));
@@ -4954,7 +4948,7 @@
 
 	data = g_new(struct name_data, 1);
 
-	comment = aim_ssi_getcomment(od->ssi.local, purple_group_get_name(g), name);
+	comment = aim_ssi_getcomment(&od->ssi.local, purple_group_get_name(g), name);
 	comment_utf8 = comment ? oscar_utf8_try_convert(account, od, comment) : NULL;
 
 	data->gc = gc;
@@ -5046,7 +5040,7 @@
 	name = purple_buddy_get_name(buddy);
 	account = purple_buddy_get_account(buddy);
 	gc = purple_account_get_connection(account);
-	od = gc->proto_data;
+	od = purple_connection_get_protocol_data(gc);
 	conn = peer_connection_find_by_type(od, name, OSCAR_CAPABILITY_DIRECTIM);
 
 	if (conn != NULL)
@@ -5175,8 +5169,8 @@
 		 * waiting for authorization.
 		 */
 		char *gname;
-		gname = aim_ssi_itemlist_findparentname(od->ssi.local, bname);
-		if (gname && aim_ssi_waitingforauth(od->ssi.local, gname, bname))
+		gname = aim_ssi_itemlist_findparentname(&od->ssi.local, bname);
+		if (gname && aim_ssi_waitingforauth(&od->ssi.local, gname, bname))
 		{
 			act = purple_menu_action_new(_("Re-request Authorization"),
 			                           PURPLE_CALLBACK(oscar_auth_sendrequest_menu),
@@ -5327,7 +5321,7 @@
 		buddy = cur->data;
 		bname = purple_buddy_get_name(buddy);
 		gname = purple_group_get_name(purple_buddy_get_group(buddy));
-		if (aim_ssi_waitingforauth(od->ssi.local, gname, bname)) {
+		if (aim_ssi_waitingforauth(&od->ssi.local, gname, bname)) {
 			filtered_buddies = g_slist_prepend(filtered_buddies, buddy);
 		}
 	}
@@ -5482,7 +5476,7 @@
 		conn->flags |= PEER_CONNECTION_FLAG_APPROVED;
 		aim_icbm_makecookie(conn->cookie);
 		conn->xfer = xfer;
-		xfer->data = conn;
+		purple_xfer_set_protocol_data(xfer, conn);
 	}
 
 	return xfer;
--- a/libpurple/protocols/oscar/oscar.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Sun Sep 11 04:19:01 2011 +0000
@@ -308,9 +308,14 @@
 
 #include "peer.h"
 
-/*
- * AIM Session: The main client-data interface.
- *
+struct aim_ssi_itemlist {
+	struct aim_ssi_item *data;
+	GHashTable *idx_gid_bid;
+	GHashTable *idx_all_named_items;
+};
+
+/**
+ * The main client-data interface.
  */
 struct _OscarData
 {
@@ -387,8 +392,8 @@
 	struct {
 		gboolean received_data;
 		guint16 numitems;
-		struct aim_ssi_item *official;
-		struct aim_ssi_item *local;
+		struct aim_ssi_itemlist official;
+		struct aim_ssi_itemlist local;
 		struct aim_ssi_tmp *pending;
 		time_t timestamp;
 		gboolean waiting_for_ack;
@@ -916,15 +921,16 @@
 /* 0x001a */ int aim_ssi_sendauthreply(OscarData *od, const char *bn, guint8 reply, const char *msg);
 
 /* Client functions for retrieving SSI data */
-struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, guint16 gid, guint16 bid);
-struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *bn, guint16 type);
-struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *bn);
-char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *bn);
-int aim_ssi_getpermdeny(struct aim_ssi_item *list);
-guint32 aim_ssi_getpresence(struct aim_ssi_item *list);
-char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *bn);
-char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *bn);
-gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *bn);
+struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_itemlist *list, guint16 gid, guint16 bid);
+struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_itemlist *list, const char *gn, const char *bn, guint16 type);
+struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_itemlist *list, const char *bn);
+char *aim_ssi_itemlist_findparentname(struct aim_ssi_itemlist *list, const char *bn);
+int aim_ssi_getpermdeny(struct aim_ssi_itemlist *list);
+guint32 aim_ssi_getpresence(struct aim_ssi_itemlist *list);
+char *aim_ssi_getalias(struct aim_ssi_itemlist *list, const char *gn, const char *bn);
+char *aim_ssi_getalias_from_item(struct aim_ssi_item *item);
+char *aim_ssi_getcomment(struct aim_ssi_itemlist *list, const char *gn, const char *bn);
+gboolean aim_ssi_waitingforauth(struct aim_ssi_itemlist *list, const char *gn, const char *bn);
 
 /* Client functions for changing SSI data */
 int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, GSList *tlvlist, const char *alias, const char *comment, const char *smsnum, gboolean needauth);
--- a/libpurple/protocols/oscar/oscar_data.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/oscar_data.c	Sun Sep 11 04:19:01 2011 +0000
@@ -47,6 +47,12 @@
 	od->buddyinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 	od->handlerlist = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
 
+	od->ssi.local.idx_gid_bid = g_hash_table_new(g_direct_hash, g_direct_equal);
+	od->ssi.local.idx_all_named_items = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+
+	od->ssi.official.idx_gid_bid = g_hash_table_new(g_direct_hash, g_direct_equal);
+	od->ssi.official.idx_all_named_items = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+
 	/*
 	 * Register all the modules for this session...
 	 */
@@ -126,6 +132,12 @@
 	g_hash_table_destroy(od->buddyinfo);
 	g_hash_table_destroy(od->handlerlist);
 
+	g_hash_table_destroy(od->ssi.local.idx_gid_bid);
+	g_hash_table_destroy(od->ssi.local.idx_all_named_items);
+
+	g_hash_table_destroy(od->ssi.official.idx_gid_bid);
+	g_hash_table_destroy(od->ssi.official.idx_all_named_items);
+
 	g_free(od);
 }
 
--- a/libpurple/protocols/oscar/peer.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/peer.c	Sun Sep 11 04:19:01 2011 +0000
@@ -212,7 +212,7 @@
 	if (conn->xfer != NULL)
 	{
 		PurpleXferStatusType status;
-		conn->xfer->data = NULL;
+		purple_xfer_set_protocol_data(conn->xfer, NULL);
 		status = purple_xfer_get_status(conn->xfer);
 		if ((status != PURPLE_XFER_STATUS_DONE) &&
 			(status != PURPLE_XFER_STATUS_CANCEL_LOCAL) &&
@@ -1072,7 +1072,7 @@
 		conn->xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE, bn);
 		if (conn->xfer)
 		{
-			conn->xfer->data = conn;
+			purple_xfer_set_protocol_data(conn->xfer, conn);
 			purple_xfer_ref(conn->xfer);
 			purple_xfer_set_size(conn->xfer, args->info.sendfile.totsize);
 
--- a/libpurple/protocols/oscar/userinfo.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/userinfo.c	Sun Sep 11 04:19:01 2011 +0000
@@ -131,21 +131,16 @@
 }
 
 static void
-oscar_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *name, const char *value)
-{
-	if (value && value[0]) {
-		purple_notify_user_info_add_pair(user_info, name, value);
-	}
-}
-
-static void
 oscar_user_info_convert_and_add(PurpleAccount *account, OscarData *od, PurpleNotifyUserInfo *user_info,
 					const char *name, const char *value)
 {
 	gchar *utf8;
 
 	if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) {
-		purple_notify_user_info_add_pair(user_info, name, utf8);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext.  Will
+		         need to check callers of this function. */
+		purple_notify_user_info_add_pair_html(user_info, name, utf8);
 		g_free(utf8);
 	}
 }
@@ -158,7 +153,10 @@
 
 	if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) {
 		gchar *tmp = g_strdup_printf("<a href=\"%s%s\">%s</a>", url_prefix, utf8, utf8);
-		purple_notify_user_info_add_pair(user_info, name, tmp);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext.  Will
+		         need to check callers of this function. */
+		purple_notify_user_info_add_pair_html(user_info, name, tmp);
 		g_free(utf8);
 		g_free(tmp);
 	}
@@ -263,8 +261,8 @@
 				message = tmp;
 			}
 
-		} else if (aim_ssi_waitingforauth(od->ssi.local,
-			aim_ssi_itemlist_findparentname(od->ssi.local, purple_buddy_get_name(b)),
+		} else if (aim_ssi_waitingforauth(&od->ssi.local,
+			aim_ssi_itemlist_findparentname(&od->ssi.local, purple_buddy_get_name(b)),
 			purple_buddy_get_name(b)))
 		{
 			/* Note if an offline buddy is not authorized */
@@ -295,12 +293,12 @@
 			} else {
 				description = g_strdup(_(mood));
 			}
-			purple_notify_user_info_add_pair(user_info, _("Mood"), description);
+			purple_notify_user_info_add_pair_html(user_info, _("Mood"), description);
 			g_free(description);
 		}
 	}
 
-	purple_notify_user_info_add_pair(user_info, _("Status"), message);
+	purple_notify_user_info_add_pair_html(user_info, _("Status"), message);
 	g_free(message);
 }
 
@@ -340,23 +338,23 @@
 		bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->bn));
 
 	if ((bi != NULL) && (bi->ipaddr != 0)) {
-		tmp =  g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
-						(bi->ipaddr & 0xff000000) >> 24,
-						(bi->ipaddr & 0x00ff0000) >> 16,
-						(bi->ipaddr & 0x0000ff00) >> 8,
-						(bi->ipaddr & 0x000000ff));
-		oscar_user_info_add_pair(user_info, _("IP Address"), tmp);
-		g_free(tmp);
+		char tmp2[40];
+		sprintf(tmp2, "%hhu.%hhu.%hhu.%hhu",
+				(bi->ipaddr & 0xff000000) >> 24,
+				(bi->ipaddr & 0x00ff0000) >> 16,
+				(bi->ipaddr & 0x0000ff00) >> 8,
+				(bi->ipaddr & 0x000000ff));
+		purple_notify_user_info_add_pair_plaintext(user_info, _("IP Address"), tmp2);
 	}
 
 	if ((userinfo != NULL) && (userinfo->warnlevel != 0)) {
-		tmp = g_strdup_printf("%d", (int)(userinfo->warnlevel/10.0 + .5));
-		oscar_user_info_add_pair(user_info, _("Warning Level"), tmp);
-		g_free(tmp);
+		char tmp2[12];
+		sprintf(tmp2, "%d", (int)(userinfo->warnlevel/10.0 + .5));
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Warning Level"), tmp2);
 	}
 
 	if ((b != NULL) && (bname != NULL) && (g != NULL) && (gname != NULL)) {
-		tmp = aim_ssi_getcomment(od->ssi.local, gname, bname);
+		tmp = aim_ssi_getcomment(&od->ssi.local, gname, bname);
 		if (tmp != NULL) {
 			char *tmp2 = g_markup_escape_text(tmp, strlen(tmp));
 			g_free(tmp);
@@ -372,7 +370,7 @@
 {
 	PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
 	gchar *buf = g_strdup_printf(_("User information not available: %s"), oscar_get_msgerr_reason(error_reason));
-	purple_notify_user_info_add_pair(user_info, NULL, buf);
+	purple_notify_user_info_add_pair_plaintext(user_info, NULL, buf);
 	purple_notify_userinfo(od->gc, buddy, user_info, NULL, NULL);
 	purple_notify_user_info_destroy(user_info);
 	purple_conv_present_error(buddy, purple_connection_get_account(od->gc), buf);
@@ -402,16 +400,16 @@
 	else
 		bi = NULL;
 
-	purple_notify_user_info_add_pair(user_info, _("UIN"), who);
+	purple_notify_user_info_add_pair_plaintext(user_info, _("UIN"), who);
 	oscar_user_info_convert_and_add(account, od, user_info, _("Nick"), info->nick);
 	if ((bi != NULL) && (bi->ipaddr != 0)) {
-		char *tstr =  g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
-						(bi->ipaddr & 0xff000000) >> 24,
-						(bi->ipaddr & 0x00ff0000) >> 16,
-						(bi->ipaddr & 0x0000ff00) >> 8,
-						(bi->ipaddr & 0x000000ff));
-		purple_notify_user_info_add_pair(user_info, _("IP Address"), tstr);
-		g_free(tstr);
+		char tstr[40];
+		sprintf(tstr, "%hhu.%hhu.%hhu.%hhu",
+				(bi->ipaddr & 0xff000000) >> 24,
+				(bi->ipaddr & 0x00ff0000) >> 16,
+				(bi->ipaddr & 0x0000ff00) >> 8,
+				(bi->ipaddr & 0x000000ff));
+		purple_notify_user_info_add_pair_plaintext(user_info, _("IP Address"), tstr);
 	}
 	oscar_user_info_convert_and_add(account, od, user_info, _("First Name"), info->first);
 	oscar_user_info_convert_and_add(account, od, user_info, _("Last Name"), info->last);
@@ -425,7 +423,7 @@
 	oscar_user_info_convert_and_add(account, od, user_info, _("Mobile Phone"), info->mobile);
 
 	if (info->gender != 0)
-		purple_notify_user_info_add_pair(user_info, _("Gender"), (info->gender == 1 ? _("Female") : _("Male")));
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Gender"), (info->gender == 1 ? _("Female") : _("Male")));
 
 	if ((info->birthyear > 1900) && (info->birthmonth > 0) && (info->birthday > 0)) {
 		/* Initialize the struct properly or strftime() will crash
@@ -437,7 +435,7 @@
 		tm->tm_mon  = (int)info->birthmonth - 1;
 		tm->tm_year = (int)info->birthyear - 1900;
 
-		/* Ignore dst setting of today to avoid timezone shift between 
+		/* Ignore dst setting of today to avoid timezone shift between
 		 * dates in summer and winter time. */
 		tm->tm_isdst = -1;
 
@@ -451,8 +449,9 @@
 	if ((info->age > 0) && (info->age < 255)) {
 		char age[5];
 		snprintf(age, sizeof(age), "%hhd", info->age);
-		purple_notify_user_info_add_pair(user_info, _("Age"), age);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Age"), age);
 	}
+	/* TODO: Is it correct to pass info->email here...? */
 	oscar_user_info_convert_and_add_hyperlink(account, od, user_info, _("Personal Web Page"), info->email, "");
 	if (buddy != NULL)
 		oscar_user_info_append_status(gc, user_info, buddy, /* aim_userinfo_t */ NULL, /* use_html_status */ TRUE);
@@ -482,6 +481,7 @@
 		oscar_user_info_convert_and_add(account, od, user_info, _("Company"), info->workcompany);
 		oscar_user_info_convert_and_add(account, od, user_info, _("Division"), info->workdivision);
 		oscar_user_info_convert_and_add(account, od, user_info, _("Position"), info->workposition);
+		/* TODO: Is it correct to pass info->email here...? */
 		oscar_user_info_convert_and_add_hyperlink(account, od, user_info, _("Web Page"), info->email, "");
 	}
 
@@ -505,7 +505,7 @@
 
 	if ((userinfo->present & AIM_USERINFO_PRESENT_IDLE) && userinfo->idletime != 0) {
 		tmp = purple_str_seconds_to_string(userinfo->idletime*60);
-		oscar_user_info_add_pair(user_info, _("Idle"), tmp);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), tmp);
 		g_free(tmp);
 	}
 
@@ -514,17 +514,18 @@
 	if ((userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) && !oscar_util_valid_name_sms(userinfo->bn)) {
 		/* An SMS contact is always online; its Online Since value is not useful */
 		time_t t = userinfo->onlinesince;
-		oscar_user_info_add_pair(user_info, _("Online Since"), purple_date_format_full(localtime(&t)));
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Online Since"), purple_date_format_full(localtime(&t)));
 	}
 
 	if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) {
 		time_t t = userinfo->membersince;
-		oscar_user_info_add_pair(user_info, _("Member Since"), purple_date_format_full(localtime(&t)));
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Member Since"), purple_date_format_full(localtime(&t)));
 	}
 
 	if (userinfo->capabilities != 0) {
 		tmp = oscar_caps_to_string(userinfo->capabilities);
-		oscar_user_info_add_pair(user_info, _("Capabilities"), tmp);
+		if (tmp && *tmp)
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Capabilities"), tmp);
 		g_free(tmp);
 	}
 
@@ -533,7 +534,11 @@
 		info_utf8 = oscar_encoding_to_utf8(userinfo->info_encoding, userinfo->info, userinfo->info_len);
 		tmp = oscar_util_format_string(info_utf8, purple_account_get_username(account));
 		purple_notify_user_info_add_section_break(user_info);
-		oscar_user_info_add_pair(user_info, _("Profile"), tmp);
+		if (tmp && *tmp) {
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html(user_info, _("Profile"), tmp);
+		}
 		g_free(tmp);
 		g_free(info_utf8);
 	}
@@ -542,9 +547,9 @@
 	base_profile_url = oscar_util_valid_name_icq(userinfo->bn) ? "http://www.icq.com/people" : "http://profiles.aim.com";
 	tmp = g_strdup_printf("<a href=\"%s/%s\">%s</a>",
 			base_profile_url, purple_normalize(account, userinfo->bn), _("View web profile"));
-	purple_notify_user_info_add_pair(user_info, NULL, tmp);
+	purple_notify_user_info_add_pair_html(user_info, NULL, tmp);
 	g_free(tmp);
 
 	purple_notify_userinfo(gc, userinfo->bn, user_info, NULL, NULL);
 	purple_notify_user_info_destroy(user_info);
-}
\ No newline at end of file
+}
--- a/libpurple/protocols/oscar/visibility.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/oscar/visibility.c	Sun Sep 11 04:19:01 2011 +0000
@@ -51,7 +51,7 @@
 static gboolean
 is_buddy_on_list(OscarData *od, const char *bname)
 {
-	return aim_ssi_itemlist_finditem(od->ssi.local, NULL, bname, get_buddy_list_type(od)) != NULL;
+	return aim_ssi_itemlist_finditem(&od->ssi.local, NULL, bname, get_buddy_list_type(od)) != NULL;
 }
 
 static void
@@ -102,7 +102,7 @@
 
 		buddy = cur->data;
 		bname = purple_buddy_get_name(buddy);
-		if (aim_ssi_itemlist_finditem(od->ssi.local, NULL, bname, list_type)) {
+		if (aim_ssi_itemlist_finditem(&od->ssi.local, NULL, bname, list_type)) {
 			filtered_buddies = g_slist_prepend(filtered_buddies, buddy);
 		}
 	}
--- a/libpurple/protocols/sametime/sametime.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/sametime/sametime.c	Sun Sep 11 04:19:01 2011 +0000
@@ -197,7 +197,7 @@
 
 
 /** the purple plugin data.
-    available as gc->proto_data and mwSession_getClientData */
+    available as purple_connection_get_protocol_data(gc) and mwSession_getClientData */
 struct mwPurplePluginData {
   struct mwSession *session;
 
@@ -320,7 +320,7 @@
 
   g_return_val_if_fail(gc != NULL, NULL);
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   g_return_val_if_fail(pd != NULL, NULL);
 
   return pd->session;
@@ -413,7 +413,7 @@
 			g_strerror(errno));
     DEBUG_ERROR("write returned %" G_GSSIZE_FORMAT ", %" G_GSIZE_FORMAT
 			" bytes left unwritten\n", ret, len);
-    purple_connection_error_reason(pd->gc,
+    purple_connection_error(pd->gc,
                                    PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
                                    tmp);
 	g_free(tmp);
@@ -499,7 +499,7 @@
   gc = mwAwareList_getClientData(list);
   acct = purple_connection_get_account(gc);
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   idle = aware->status.time;
   stat = aware->status.status;
   id = aware->id.user;
@@ -851,7 +851,7 @@
 static PurpleBuddy *buddy_ensure(PurpleConnection *gc, PurpleGroup *group,
 			       struct mwSametimeUser *stuser) {
 
-  struct mwPurplePluginData *pd = gc->proto_data;
+  struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
   PurpleBuddy *buddy;
   PurpleAccount *acct = purple_connection_get_account(gc);
 
@@ -861,7 +861,7 @@
   enum mwSametimeUserType type = mwSametimeUser_getType(stuser);
 
   g_return_val_if_fail(id != NULL, NULL);
-  g_return_val_if_fail(strlen(id) > 0, NULL);
+  g_return_val_if_fail(*id, NULL);
 
   buddy = purple_find_buddy_in_group(acct, id, group);
   if(! buddy) {
@@ -968,7 +968,7 @@
 
   if(type == mwSametimeGroup_DYNAMIC) {
     purple_blist_node_set_string(gn, GROUP_KEY_OWNER, owner);
-    group_add(gc->proto_data, group);
+    group_add(purple_connection_get_protocol_data(gc), group);
   }
 
   return group;
@@ -1398,7 +1398,7 @@
   }
 
   if(add_buds) {
-    purple_account_add_buddies(acct, add_buds);
+    purple_account_add_buddies(acct, add_buds, NULL);
     g_list_free(add_buds);
   }
 }
@@ -1613,7 +1613,7 @@
       default:
         reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
       }
-      purple_connection_error_reason(gc, reason, err);
+      purple_connection_error(gc, reason, err);
       g_free(err);
     }
     break;
@@ -1762,7 +1762,7 @@
 
   if(! ret) {
     DEBUG_INFO("connection reset\n");
-    purple_connection_error_reason(pd->gc,
+    purple_connection_error(pd->gc,
                                    PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
                                    _("Server closed the connection"));
 
@@ -1773,7 +1773,7 @@
     DEBUG_INFO("error in read callback: %s\n", err_str);
 
     msg = g_strdup_printf(_("Lost connection with server: %s"), err_str);
-    purple_connection_error_reason(pd->gc,
+    purple_connection_error(pd->gc,
                                    PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
                                    msg);
     g_free(msg);
@@ -1799,7 +1799,7 @@
       /* this is a regular connect, error out */
       gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
           error_message);
-      purple_connection_error_reason(pd->gc,
+      purple_connection_error(pd->gc,
                                      PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
                                      tmp);
       g_free(tmp);
@@ -2139,7 +2139,7 @@
 
 static void ft_incoming_cancel(PurpleXfer *xfer) {
   /* incoming transfer rejected or cancelled in-progress */
-  struct mwFileTransfer *ft = xfer->data;
+  struct mwFileTransfer *ft = purple_xfer_get_protocol_data(xfer);
   if(ft) mwFileTransfer_reject(ft);
 }
 
@@ -2155,9 +2155,9 @@
   struct mwFileTransfer *ft;
   FILE *fp;
 
-  ft = xfer->data;
-
-  fp = g_fopen(xfer->local_filename, "wb");
+  ft = purple_xfer_get_protocol_data(xfer);
+
+  fp = g_fopen(purple_xfer_get_local_filename(xfer), "wb");
   if(! fp) {
     mwFileTransfer_cancel(ft);
     return;
@@ -2202,7 +2202,7 @@
   {
 	purple_xfer_ref(xfer);
 	mwFileTransfer_setClientData(ft, xfer, (GDestroyNotify) purple_xfer_unref);
-	xfer->data = ft;
+	purple_xfer_set_protocol_data(xfer, ft);
 
 	purple_xfer_set_init_fnc(xfer, ft_incoming_init);
 	purple_xfer_set_cancel_recv_fnc(xfer, ft_incoming_cancel);
@@ -2231,8 +2231,7 @@
   if(fread(buf, (size_t) o.len, 1, fp)) {
 
     /* calculate progress and display it */
-    xfer->bytes_sent += o.len;
-    xfer->bytes_remaining -= o.len;
+    purple_xfer_set_bytes_sent(xfer, purple_xfer_get_bytes_sent(xfer) + o.len);
     purple_xfer_update_progress(xfer);
 
     mwFileTransfer_send(ft, &o);
@@ -2264,7 +2263,7 @@
   }
 
   if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
-    xfer->dest_fp = g_fopen(xfer->local_filename, "rb");
+    xfer->dest_fp = g_fopen(purple_xfer_get_local_filename(xfer), "rb");
     ft_send(ft, xfer->dest_fp);
   }
 }
@@ -2281,7 +2280,7 @@
 
   xfer = mwFileTransfer_getClientData(ft);
   if(xfer) {
-    xfer->data = NULL;
+    purple_xfer_set_protocol_data(xfer, NULL);
 
     if(! mwFileTransfer_getRemaining(ft)) {
       purple_xfer_set_completed(xfer, TRUE);
@@ -2334,8 +2333,7 @@
   }
 
   /* update the progress */
-  xfer->bytes_sent += data->len;
-  xfer->bytes_remaining -= data->len;
+  purple_xfer_set_bytes_sent(xfer, purple_xfer_get_bytes_sent(xfer) + data->len);
   purple_xfer_update_progress(xfer);
 
   /* let the other side know we got it, and to send some more */
@@ -3194,7 +3192,7 @@
   mwSession_addCipher(pd->session, mwCipher_new_RC2_128(pd->session));
 
   mwSession_setClientData(pd->session, pd, NULL);
-  gc->proto_data = pd;
+  purple_connection_set_protocol_data(gc, pd);
 
   return pd;
 }
@@ -3203,7 +3201,7 @@
 static void mwPurplePluginData_free(struct mwPurplePluginData *pd) {
   g_return_if_fail(pd != NULL);
 
-  pd->gc->proto_data = NULL;
+  purple_connection_set_protocol_data(pd->gc, NULL);
 
   mwSession_removeService(pd->session, mwService_AWARE);
   mwSession_removeService(pd->session, mwService_CONFERENCE);
@@ -3265,7 +3263,7 @@
   const char *ret = NULL;
 
   if ((gc = purple_account_get_connection(purple_buddy_get_account(b)))
-      && (pd = gc->proto_data))
+      && (pd = purple_connection_get_protocol_data(gc)))
     ret = mwServiceAware_getText(pd->srvc_aware, &t);
 
   return (ret && g_utf8_validate(ret, -1, NULL)) ? g_markup_escape_text(ret, -1): NULL;
@@ -3328,29 +3326,27 @@
   char *tmp;
 
   if ((gc = purple_account_get_connection(purple_buddy_get_account(b)))
-      && (pd = gc->proto_data))
+      && (pd = purple_connection_get_protocol_data(gc)))
      message = mwServiceAware_getText(pd->srvc_aware, &idb);
 
   status = status_text(b);
 
   if(message != NULL && g_utf8_validate(message, -1, NULL) && purple_utf8_strcasecmp(status, message)) {
-    tmp = g_markup_escape_text(message, -1);
-	purple_notify_user_info_add_pair(user_info, status, tmp);
-    g_free(tmp);
+	purple_notify_user_info_add_pair_plaintext(user_info, status, message);
 
   } else {
-	purple_notify_user_info_add_pair(user_info, _("Status"), status);
+	purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status);
   }
 
   if(full && pd != NULL) {
     tmp = user_supports_text(pd->srvc_aware, purple_buddy_get_name(b));
     if(tmp) {
-	  purple_notify_user_info_add_pair(user_info, _("Supports"), tmp);
+	  purple_notify_user_info_add_pair_plaintext(user_info, _("Supports"), tmp);
       g_free(tmp);
     }
 
     if(buddy_is_external(b)) {
-	  purple_notify_user_info_add_pair(user_info, NULL, _("External User"));
+	  purple_notify_user_info_add_pair_plaintext(user_info, NULL, _("External User"));
     }
   }
 }
@@ -3407,7 +3403,7 @@
 
   acct = purple_buddy_get_account(buddy);
   gc = purple_account_get_connection(acct);
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   srvc = pd->srvc_conf;
 
   f = purple_request_fields_get_field(fields, CHAT_KEY_TOPIC);
@@ -3573,7 +3569,7 @@
   gc = purple_account_get_connection(acct);
   g_return_if_fail(gc != NULL);
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   g_return_if_fail(pd != NULL);
 
   /*
@@ -3612,7 +3608,7 @@
   gc = purple_account_get_connection(acct);
   g_return_if_fail(gc != NULL);
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   g_return_if_fail(pd != NULL);
 
   rcpt_name = g_strdup_printf("@U %s", buddy->name);
@@ -3691,7 +3687,7 @@
 
 static void prompt_host_cancel_cb(PurpleConnection *gc) {
   const char *msg = _("No Sametime Community Server specified");
-  purple_connection_error_reason(gc,
+  purple_connection_error(gc,
                                  PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
                                  msg);
 }
@@ -3806,7 +3802,7 @@
   purple_connection_update_progress(gc, _("Connecting"), 1, MW_CONNECT_STEPS);
 
   if (purple_proxy_connect(gc, account, host, port, connect_cb, pd) == NULL) {
-    purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+    purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
                                    _("Unable to connect"));
   }
 }
@@ -3817,7 +3813,7 @@
 
   g_return_if_fail(gc != NULL);
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   g_return_if_fail(pd != NULL);
 
   /* get rid of the blist save timeout */
@@ -3831,7 +3827,7 @@
   mwSession_stop(pd->session, 0x00);
 
   /* no longer necessary */
-  gc->proto_data = NULL;
+  purple_connection_set_protocol_data(gc, NULL);
 
   /* stop watching the socket */
   if(gc->inpa) {
@@ -4022,7 +4018,7 @@
   struct mwConversation *conv;
 
   g_return_val_if_fail(gc != NULL, 0);
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
 
   g_return_val_if_fail(pd != NULL, 0);
 
@@ -4097,7 +4093,7 @@
   gpointer t = GINT_TO_POINTER(!! state);
 
   g_return_val_if_fail(gc != NULL, 0);
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
 
   g_return_val_if_fail(pd != NULL, 0);
 
@@ -4193,53 +4189,54 @@
   g_return_if_fail(who != NULL);
   g_return_if_fail(*who != '\0');
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
 
   acct = purple_connection_get_account(gc);
   b = purple_find_buddy(acct, who);
   user_info = purple_notify_user_info_new();
 
   if(purple_str_has_prefix(who, "@E ")) {
-	purple_notify_user_info_add_pair(user_info, _("External User"), NULL);
+	purple_notify_user_info_add_pair_html(user_info, _("External User"), NULL);
   }
 
-  purple_notify_user_info_add_pair(user_info, _("User ID"), who);
+  purple_notify_user_info_add_pair_plaintext(user_info, _("User ID"), who);
 
   if(b) {
     guint32 type;
 
     if(purple_buddy_get_server_alias(b)) {
-		purple_notify_user_info_add_pair(user_info, _("Full Name"), purple_buddy_get_server_alias(b));
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, _("Full Name"), purple_buddy_get_server_alias(b));
     }
 
     type = purple_blist_node_get_int((PurpleBlistNode *) b, BUDDY_KEY_CLIENT);
     if(type) {
-	  tmp = g_strdup(mw_client_name(type));
-	  if (!tmp)
+	  tmp2 = mw_client_name(type);
+	  if (tmp2) {
+		purple_notify_user_info_add_pair_plaintext(user_info, _("Last Known Client"), tmp2);
+	  } else {
 		tmp = g_strdup_printf(_("Unknown (0x%04x)<br>"), type);
-
-	  purple_notify_user_info_add_pair(user_info, _("Last Known Client"), tmp);
-
-	  g_free(tmp);
+		purple_notify_user_info_add_pair_html(user_info, _("Last Known Client"), tmp);
+	    g_free(tmp);
+	  }
     }
   }
 
   tmp = user_supports_text(pd->srvc_aware, who);
   if(tmp) {
-	purple_notify_user_info_add_pair(user_info, _("Supports"), tmp);
+	purple_notify_user_info_add_pair_plaintext(user_info, _("Supports"), tmp);
 	g_free(tmp);
   }
 
   if(b) {
-	purple_notify_user_info_add_pair(user_info, _("Status"), status_text(b));
+	purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status_text(b));
 
 	/* XXX Is this adding a status message in its own section rather than with the "Status" label? */
     tmp2 = mwServiceAware_getText(pd->srvc_aware, &idb);
     if(tmp2 && g_utf8_validate(tmp2, -1, NULL)) {
-      tmp = g_markup_escape_text(tmp2, -1);
 	  purple_notify_user_info_add_section_break(user_info);
-	  purple_notify_user_info_add_pair(user_info, NULL, tmp);
-      g_free(tmp);
+	  purple_notify_user_info_add_pair_plaintext(user_info, NULL, tmp2);
     }
   }
 
@@ -4437,7 +4434,7 @@
   buddy = data->buddy;
 
   gc = purple_account_get_connection(purple_buddy_get_account(buddy));
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
 
   if(results)
     res = results->data;
@@ -4516,9 +4513,10 @@
 
 static void mw_prpl_add_buddy(PurpleConnection *gc,
 			      PurpleBuddy *buddy,
-			      PurpleGroup *group) {
-
-  struct mwPurplePluginData *pd = gc->proto_data;
+			      PurpleGroup *group,
+			      const char *message) {
+
+  struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
   struct mwServiceResolve *srvc;
   GList *query;
   enum mwResolveFlag flags;
@@ -4563,13 +4561,14 @@
 
 static void mw_prpl_add_buddies(PurpleConnection *gc,
 				GList *buddies,
-				GList *groups) {
+				GList *groups,
+				const char *message) {
 
   struct mwPurplePluginData *pd;
   GHashTable *group_sets;
   struct mwAwareIdBlock *idbs, *idb;
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
 
   /* map PurpleGroup:GList of mwAwareIdBlock */
   group_sets = g_hash_table_new(g_direct_hash, g_direct_equal);
@@ -4620,7 +4619,7 @@
 
   GList *rem = g_list_prepend(NULL, &idb);
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   group = purple_buddy_get_group(buddy);
   list = list_ensure(pd, group);
 
@@ -4667,7 +4666,7 @@
   acct = purple_connection_get_account(gc);
   g_return_if_fail(acct != NULL);
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   g_return_if_fail(pd != NULL);
 
   session = pd->session;
@@ -4751,7 +4750,7 @@
   struct mwPurplePluginData *pd;
   char *c, *t;
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
 
   c = g_hash_table_lookup(components, CHAT_KEY_NAME);
   t = g_hash_table_lookup(components, CHAT_KEY_TOPIC);
@@ -4793,7 +4792,7 @@
   struct mwServiceConference *srvc;
   char *c;
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   srvc = pd->srvc_conf;
 
   if(g_hash_table_lookup(components, CHAT_KEY_IS_PLACE)) {
@@ -4825,7 +4824,7 @@
   struct mwPlace *place;
   struct mwIdBlock idb = { (char *) who, NULL };
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   g_return_if_fail(pd != NULL);
 
   conf = ID_TO_CONF(pd, id);
@@ -4849,7 +4848,7 @@
   struct mwPurplePluginData *pd;
   struct mwConference *conf;
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
 
   g_return_if_fail(pd != NULL);
   conf = ID_TO_CONF(pd, id);
@@ -4885,7 +4884,7 @@
   char *msg;
   int ret;
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
 
   g_return_val_if_fail(pd != NULL, 0);
   conf = ID_TO_CONF(pd, id);
@@ -4923,7 +4922,7 @@
 				const char *who,
 				const char *alias) {
 
-  struct mwPurplePluginData *pd = gc->proto_data;
+  struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
   g_return_if_fail(pd != NULL);
 
   /* it's a change to the buddy list, so we've gotta reflect that in
@@ -4941,7 +4940,7 @@
   struct mwAwareIdBlock idb = { mwAware_USER, (char *) who, NULL };
   GList *gl = g_list_prepend(NULL, &idb);
 
-  struct mwPurplePluginData *pd = gc->proto_data;
+  struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
   PurpleGroup *group;
   struct mwAwareList *list;
 
@@ -4967,7 +4966,7 @@
 				 PurpleGroup *group,
 				 GList *buddies) {
 
-  struct mwPurplePluginData *pd = gc->proto_data;
+  struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
   g_return_if_fail(pd != NULL);
 
   /* it's a change in the buddy list, so we've gotta reflect that in
@@ -4987,7 +4986,7 @@
 
 
 static void mw_prpl_convo_closed(PurpleConnection *gc, const char *who) {
-  struct mwPurplePluginData *pd = gc->proto_data;
+  struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
   struct mwServiceIm *srvc;
   struct mwConversation *conv;
   struct mwIdBlock idb = { (char *) who, NULL };
@@ -5022,7 +5021,7 @@
   struct mwPurplePluginData *pd;
   struct mwAwareList *list;
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   g_return_if_fail(pd != NULL);
   g_return_if_fail(pd->group_list_map != NULL);
 
@@ -5046,7 +5045,7 @@
 
   g_return_val_if_fail(gc != NULL, FALSE);
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   g_return_val_if_fail(pd != NULL, FALSE);
 
   srvc = pd->srvc_aware;
@@ -5078,12 +5077,12 @@
 
   acct = purple_xfer_get_account(xfer);
   gc = purple_account_get_connection(acct);
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   srvc = pd->srvc_ft;
 
   filename = purple_xfer_get_local_filename(xfer);
   filesize = purple_xfer_get_size(xfer);
-  idb.user = xfer->who;
+  idb.user = purple_xfer_get_remote_user(xfer);
 
   purple_xfer_update_progress(xfer);
 
@@ -5092,7 +5091,7 @@
   if(! fp) {
     char *msg = g_strdup_printf(_("Error reading file %s: \n%s\n"),
 				filename, g_strerror(errno));
-    purple_xfer_error(purple_xfer_get_type(xfer), acct, xfer->who, msg);
+    purple_xfer_error(purple_xfer_get_type(xfer), acct, purple_xfer_get_remote_user(xfer), msg);
     g_free(msg);
     return;
   }
@@ -5107,14 +5106,14 @@
 
   purple_xfer_ref(xfer);
   mwFileTransfer_setClientData(ft, xfer, (GDestroyNotify) purple_xfer_unref);
-  xfer->data = ft;
+  purple_xfer_set_protocol_data(xfer, ft);
 
   mwFileTransfer_offer(ft);
 }
 
 
 static void ft_outgoing_cancel(PurpleXfer *xfer) {
-  struct mwFileTransfer *ft = xfer->data;
+  struct mwFileTransfer *ft = purple_xfer_get_protocol_data(xfer);
 
   DEBUG_INFO("ft_outgoing_cancel called\n");
 
@@ -5155,6 +5154,7 @@
 
 
 static PurplePluginProtocolInfo mw_prpl_info = {
+  .struct_size               = sizeof(PurplePluginProtocolInfo),
   .options                   = OPT_PROTO_IM_IMAGE,
   .user_splits               = NULL, /*< set in mw_plugin_init */
   .protocol_options          = NULL, /*< set in mw_plugin_init */
@@ -5214,8 +5214,7 @@
   .new_xfer                  = mw_prpl_new_xfer,
   .offline_message           = NULL,
   .whiteboard_prpl_ops       = NULL,
-  .send_raw                  = NULL,
-  .struct_size               = sizeof(PurplePluginProtocolInfo)
+  .send_raw                  = NULL
 };
 
 
@@ -5537,7 +5536,7 @@
   enum mwResolveFlag flags;
   guint32 req;
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   srvc = pd->srvc_resolve;
 
   query = g_list_prepend(NULL, (char *) name);
@@ -5662,7 +5661,7 @@
   enum mwResolveFlag flags;
   guint32 req;
 
-  pd = gc->proto_data;
+  pd = purple_connection_get_protocol_data(gc);
   srvc = pd->srvc_resolve;
 
   query = g_list_prepend(NULL, (char *) name);
--- a/libpurple/protocols/silc/buddy.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/silc/buddy.c	Sun Sep 11 04:19:01 2011 +0000
@@ -72,7 +72,7 @@
 			   void *context)
 {
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 
 	if (!sg->conn)
 		return;
@@ -146,7 +146,7 @@
 silcpurple_buddy_keyagr_do(PurpleConnection *gc, const char *name,
 			   gboolean force_local)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcDList clients;
 	SilcClientEntry client_entry;
 	SilcClientConnectionParams params;
@@ -346,7 +346,7 @@
 
 	b = (PurpleBuddy *) node;
 	gc = purple_account_get_connection(purple_buddy_get_account(b));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	/* Find client entry */
 	clients = silc_client_get_clients_local(sg->client, sg->conn,
@@ -426,7 +426,7 @@
 static void
 silcpurple_buddy_privkey(PurpleConnection *gc, const char *name)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcPurplePrivkey p;
 	SilcDList clients;
 	SilcClientEntry client_entry;
@@ -554,7 +554,7 @@
 static void
 silcpurple_buddy_getkey(PurpleConnection *gc, const char *name)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcClientEntry client_entry;
@@ -618,7 +618,7 @@
 
 	b = (PurpleBuddy *) node;
 	gc = purple_account_get_connection(purple_buddy_get_account(b));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	pkfile = purple_blist_node_get_string(node, "public-key");
 	if (!silc_pkcs_load_public_key(pkfile, &public_key)) {
@@ -669,7 +669,7 @@
 
 void silcpurple_get_info(PurpleConnection *gc, const char *who)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcClientEntry client_entry;
@@ -1338,7 +1338,7 @@
 static void
 silcpurple_add_buddy_i(PurpleConnection *gc, PurpleBuddy *b, gboolean init)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcPurpleBuddyRes r;
@@ -1396,7 +1396,7 @@
 	silc_buffer_free(attrs);
 }
 
-void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
+void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
 {
 	/* Don't add if the buddy is already on the list.
 	 *
@@ -1437,7 +1437,7 @@
 	const char *server;
 	int port;
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 	if (sg == NULL)
 		return;
 
@@ -1467,7 +1467,7 @@
 {
 	PurpleAccount *account = purple_buddy_get_account(b);
 	PurpleConnection *gc = purple_account_get_connection(account);
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcClientID *client_id = purple_buddy_get_protocol_data(b);
@@ -1533,7 +1533,7 @@
 {
 	PurpleAccount *account = purple_buddy_get_account(b);
 	PurpleConnection *gc = purple_account_get_connection(account);
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcClientID *client_id = purple_buddy_get_protocol_data(b);
@@ -1547,54 +1547,72 @@
 		return;
 
 	if (client_entry->nickname)
-		purple_notify_user_info_add_pair(user_info, _("Nickname"),
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, _("Nickname"),
 					       client_entry->nickname);
 	if (client_entry->username && client_entry->hostname) {
 		g_snprintf(tmp, sizeof(tmp), "%s@%s", client_entry->username, client_entry->hostname);
-		purple_notify_user_info_add_pair(user_info, _("Username"), tmp);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, _("Username"), tmp);
 	}
 	if (client_entry->mode) {
 		memset(tmp, 0, sizeof(tmp));
 		silcpurple_get_umode_string(client_entry->mode,
 					  tmp, sizeof(tmp) - strlen(tmp));
-		purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp);
+		purple_notify_user_info_add_pair_plaintext(user_info, _("User Modes"), tmp);
 	}
 
 	silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr);
 
 	if (statusstr) {
-		purple_notify_user_info_add_pair(user_info, _("Message"), statusstr);
+		/* TODO: Check whether it's correct to call add_pair_html,
+		         or if we should be using add_pair_plaintext */
+		purple_notify_user_info_add_pair_html(user_info, _("Message"), statusstr);
 		g_free(statusstr);
 	}
 
 	if (full) {
 		if (moodstr) {
-			purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr);
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html(user_info, _("Mood"), moodstr);
 			g_free(moodstr);
 		}
 
 		if (contactstr) {
-			purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr);
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html(user_info, _("Preferred Contact"), contactstr);
 			g_free(contactstr);
 		}
 
 		if (langstr) {
-			purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr);
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html(user_info, _("Preferred Language"), langstr);
 			g_free(langstr);
 		}
 
 		if (devicestr) {
-			purple_notify_user_info_add_pair(user_info, _("Device"), devicestr);
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html(user_info, _("Device"), devicestr);
 			g_free(devicestr);
 		}
 
 		if (tzstr) {
-			purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr);
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html(user_info, _("Timezone"), tzstr);
 			g_free(tzstr);
 		}
 
 		if (geostr) {
-			purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr);
+			/* TODO: Check whether it's correct to call add_pair_html,
+			         or if we should be using add_pair_plaintext */
+			purple_notify_user_info_add_pair_html(user_info, _("Geolocation"), geostr);
 			g_free(geostr);
 		}
 	}
@@ -1611,7 +1629,7 @@
 
 	b = (PurpleBuddy *) node;
 	gc = purple_account_get_connection(purple_buddy_get_account(b));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	/* Call KILL */
 	silc_client_command_call(sg->client, sg->conn, NULL, "KILL",
@@ -1635,7 +1653,7 @@
 {
 	PurpleAccount *account = purple_buddy_get_account(buddy);
 	PurpleConnection *gc = purple_account_get_connection(account);
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClientConnection conn = sg->conn;
 	const char *pkfile = NULL;
 	SilcClientEntry client_entry = NULL;
@@ -1701,7 +1719,7 @@
 
 void silcpurple_buddy_set_icon(PurpleConnection *gc, PurpleStoredImage *img)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcMime mime;
--- a/libpurple/protocols/silc/chat.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/silc/chat.c	Sun Sep 11 04:19:01 2011 +0000
@@ -91,7 +91,7 @@
 static void
 silcpurple_chat_getinfo(PurpleConnection *gc, GHashTable *components)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	const char *chname;
 	char tmp[256], *tmp2;
 	GString *s;
@@ -500,7 +500,7 @@
 
 	chat = (PurpleChat *) node;
 	gc = purple_account_get_connection(purple_chat_get_account(chat));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
 				 g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -587,7 +587,7 @@
 
 	chat = (PurpleChat *) node;
 	gc = purple_account_get_connection(purple_chat_get_account(chat));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	p = silc_calloc(1, sizeof(*p));
 	if (!p)
@@ -637,7 +637,7 @@
 
 	chat = (PurpleChat *) node;
 	gc = purple_account_get_connection(purple_chat_get_account(chat));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
 				 g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -656,7 +656,7 @@
 
 	chat = (PurpleChat *) node;
 	gc = purple_account_get_connection(purple_chat_get_account(chat));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	if (!sg->conn)
 		return;
@@ -733,7 +733,7 @@
 
 	chat = (PurpleChat *) node;
 	gc = purple_account_get_connection(purple_chat_get_account(chat));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	if (!sg->conn)
 		return;
@@ -768,7 +768,7 @@
 
 	chat = (PurpleChat *) node;
 	gc = purple_account_get_connection(purple_chat_get_account(chat));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
 				 g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -786,7 +786,7 @@
 
 	chat = (PurpleChat *) node;
 	gc = purple_account_get_connection(purple_chat_get_account(chat));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
 				 g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -804,7 +804,7 @@
 
 	chat = (PurpleChat *) node;
 	gc = purple_account_get_connection(purple_chat_get_account(chat));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
 				 g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -822,7 +822,7 @@
 
 	chat = (PurpleChat *) node;
 	gc = purple_account_get_connection(purple_chat_get_account(chat));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
 				 g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -840,7 +840,7 @@
 
 	chat = (PurpleChat *) node;
 	gc = purple_account_get_connection(purple_chat_get_account(chat));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
 				 g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -858,7 +858,7 @@
 
 	chat = (PurpleChat *) node;
 	gc = purple_account_get_connection(purple_chat_get_account(chat));
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
 				 g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -882,7 +882,7 @@
 {
 	GHashTable *components = purple_chat_get_components(chat);
 	PurpleConnection *gc = purple_account_get_connection(purple_chat_get_account(chat));
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClientConnection conn = sg->conn;
 	const char *chname = NULL;
 	SilcChannelEntry channel = NULL;
@@ -1020,7 +1020,7 @@
 
 void silcpurple_chat_join(PurpleConnection *gc, GHashTable *data)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	const char *channel, *passphrase, *parentch;
@@ -1103,7 +1103,7 @@
 void silcpurple_chat_invite(PurpleConnection *gc, int id, const char *msg,
 			    const char *name)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcHashTableList htl;
@@ -1148,7 +1148,7 @@
 
 void silcpurple_chat_leave(PurpleConnection *gc, int id)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcHashTableList htl;
@@ -1218,7 +1218,7 @@
 int silcpurple_chat_send(PurpleConnection *gc, int id, const char *msg,
 			 PurpleMessageFlags msgflags)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcHashTableList htl;
@@ -1340,7 +1340,7 @@
 
 void silcpurple_chat_set_topic(PurpleConnection *gc, int id, const char *topic)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcHashTableList htl;
@@ -1384,7 +1384,7 @@
 
 PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	GList *fields = NULL;
@@ -1419,12 +1419,13 @@
 
 void silcpurple_roomlist_cancel(PurpleRoomlist *list)
 {
-	PurpleConnection *gc = purple_account_get_connection(list->account);
+	PurpleAccount *account = purple_roomlist_get_account(list);
+	PurpleConnection *gc = purple_account_get_connection(account);
 	SilcPurple sg;
 
 	if (!gc)
 		return;
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	purple_roomlist_set_in_progress(list, FALSE);
 	if (sg->roomlist == list) {
--- a/libpurple/protocols/silc/ft.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/silc/ft.c	Sun Sep 11 04:19:01 2011 +0000
@@ -76,7 +76,7 @@
 
 	if (status == SILC_CLIENT_FILE_MONITOR_CLOSED) {
 		/* All started sessions terminate here */
-		xfer->xfer->data = NULL;
+		purple_xfer_set_protocol_data(xfer->xfer, NULL);
 		purple_xfer_unref(xfer->xfer);
 		silc_free(xfer);
 		return;
@@ -132,8 +132,7 @@
 	if (!offset && filesize)
 		purple_xfer_set_size(xfer->xfer, filesize);
 	if (offset && filesize) {
-		xfer->xfer->bytes_sent = offset;
-		xfer->xfer->bytes_remaining = filesize - offset;
+		purple_xfer_set_bytes_sent(xfer->xfer, offset);
 	}
 	purple_xfer_update_progress(xfer->xfer);
 
@@ -150,7 +149,7 @@
 static void
 silcpurple_ftp_cancel(PurpleXfer *x)
 {
-	SilcPurpleXfer xfer = x->data;
+	SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
 
 	if (!xfer)
 		return;
@@ -163,7 +162,7 @@
 static void
 silcpurple_ftp_ask_name_cancel(PurpleXfer *x)
 {
-	SilcPurpleXfer xfer = x->data;
+	SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
 
 	if (!xfer)
 		return;
@@ -176,7 +175,7 @@
 static void
 silcpurple_ftp_ask_name_ok(PurpleXfer *x)
 {
-	SilcPurpleXfer xfer = x->data;
+	SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
 	const char *name;
 
 	if (!xfer)
@@ -212,7 +211,7 @@
 static void
 silcpurple_ftp_request_result(PurpleXfer *x)
 {
-	SilcPurpleXfer xfer = x->data;
+	SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
 	SilcClientFileError status;
 	PurpleConnection *gc = xfer->sg->gc;
 	SilcClientConnectionParams params;
@@ -310,7 +309,7 @@
 			    const char *hostname, SilcUInt16 port)
 {
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcPurpleXfer xfer;
 
 	xfer = silc_calloc(1, sizeof(*xfer));
@@ -337,7 +336,7 @@
 	purple_xfer_set_cancel_recv_fnc(xfer->xfer, silcpurple_ftp_cancel);
 	xfer->xfer->remote_ip = g_strdup(hostname);
 	xfer->xfer->remote_port = port;
-	xfer->xfer->data = xfer;
+	purple_xfer_set_protocol_data(xfer->xfer, xfer);
 
 	/* File transfer request */
 	purple_xfer_request(xfer->xfer);
@@ -346,7 +345,7 @@
 static void
 silcpurple_ftp_send_cancel(PurpleXfer *x)
 {
-	SilcPurpleXfer xfer = x->data;
+	SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
 
 	if (!xfer)
 		return;
@@ -358,7 +357,7 @@
 static void
 silcpurple_ftp_send(PurpleXfer *x)
 {
-	SilcPurpleXfer xfer = x->data;
+	SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
 	const char *name;
 	char *local_ip = NULL, *remote_ip = NULL;
 	gboolean local = TRUE;
@@ -435,7 +434,7 @@
 
 PurpleXfer *silcpurple_ftp_new_xfer(PurpleConnection *gc, const char *name)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcDList clients;
@@ -467,7 +466,7 @@
 	purple_xfer_set_init_fnc(xfer->xfer, silcpurple_ftp_send);
 	purple_xfer_set_request_denied_fnc(xfer->xfer, silcpurple_ftp_request_denied);
 	purple_xfer_set_cancel_send_fnc(xfer->xfer, silcpurple_ftp_send_cancel);
-	xfer->xfer->data = xfer;
+	purple_xfer_set_protocol_data(xfer->xfer, xfer);
 
 	silc_free(clients);
 
--- a/libpurple/protocols/silc/ops.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/silc/ops.c	Sun Sep 11 04:19:01 2011 +0000
@@ -72,7 +72,7 @@
 		gc = client->application;
 
 	if (gc != NULL)
-		purple_connection_error_reason(gc, reason, tmp);
+		purple_connection_error(gc, reason, tmp);
 	else
 		purple_notify_error(NULL, _("Error"), _("Error occurred"), tmp);
 }
@@ -88,7 +88,7 @@
 			gboolean recursive)
 {
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	const char *type;
 	const unsigned char *data;
 	SilcUInt32 data_len;
@@ -264,7 +264,7 @@
 		     SilcUInt32 message_len)
 {
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	PurpleConversation *convo = NULL;
 	char *msg, *tmp;
 
@@ -354,7 +354,7 @@
 		     SilcUInt32 message_len)
 {
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	PurpleConversation *convo = NULL;
 	char *msg, *tmp;
 
@@ -431,7 +431,7 @@
 {
 	va_list va;
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	PurpleAccount *account = purple_connection_get_account(gc);
 	PurpleConversation *convo;
 	SilcClientEntry client_entry, client_entry2;
@@ -941,7 +941,7 @@
 	     SilcUInt32 argc, unsigned char **argv)
 {
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 
 	switch (command) {
 
@@ -1078,7 +1078,7 @@
 		   SilcStatus error, va_list ap)
 {
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	PurpleConversation *convo;
 
 	switch (command) {
@@ -1162,7 +1162,7 @@
 			SilcUInt32 idle, *user_modes;
 			SilcDList channels;
 			SilcClientEntry client_entry;
-			char tmp[1024], *tmp2;
+			char tmp[1024];
 			char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr;
 			PurpleNotifyUserInfo *user_info;
 
@@ -1184,71 +1184,80 @@
 			user_modes = va_arg(ap, SilcUInt32 *);
 
 			user_info = purple_notify_user_info_new();
-			tmp2 = g_markup_escape_text(client_entry->nickname, -1);
-			purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp2);
-			g_free(tmp2);
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Nickname"), client_entry->nickname);
 			if (client_entry->realname) {
-				tmp2 = g_markup_escape_text(client_entry->realname, -1);
-				purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp2);
-				g_free(tmp2);
+				purple_notify_user_info_add_pair_plaintext(user_info, _("Real Name"), client_entry->realname);
 			}
-			tmp2 = g_markup_escape_text(client_entry->username, -1);
 			if (*client_entry->hostname) {
-				gchar *tmp3;
-				tmp3 = g_strdup_printf("%s@%s", tmp2, client_entry->hostname);
-				purple_notify_user_info_add_pair(user_info, _("Username"), tmp3);
-				g_free(tmp3);
+				gchar *tmp2;
+				tmp2 = g_strdup_printf("%s@%s", client_entry->username, client_entry->hostname);
+				purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), tmp2);
+				g_free(tmp2);
 			} else
-				purple_notify_user_info_add_pair(user_info, _("Username"), tmp2);
-			g_free(tmp2);
+				purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), client_entry->username);
 
 			if (client_entry->mode) {
 				memset(tmp, 0, sizeof(tmp));
 				silcpurple_get_umode_string(client_entry->mode,
 							    tmp, sizeof(tmp) - strlen(tmp));
-				purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp);
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, _("User Modes"), tmp);
 			}
 
 			silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr);
 			if (moodstr) {
-				purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr);
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, _("Mood"), moodstr);
 				g_free(moodstr);
 			}
 
 			if (statusstr) {
-				tmp2 = g_markup_escape_text(statusstr, -1);
-				purple_notify_user_info_add_pair(user_info, _("Status Text"), tmp2);
+				purple_notify_user_info_add_pair_plaintext(user_info, _("Status Text"), statusstr);
 				g_free(statusstr);
-				g_free(tmp2);
 			}
 
 			if (contactstr) {
-				purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr);
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, _("Preferred Contact"), contactstr);
 				g_free(contactstr);
 			}
 
 			if (langstr) {
-				purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr);
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, _("Preferred Language"), langstr);
 				g_free(langstr);
 			}
 
 			if (devicestr) {
-				purple_notify_user_info_add_pair(user_info, _("Device"), devicestr);
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, _("Device"), devicestr);
 				g_free(devicestr);
 			}
 
 			if (tzstr) {
-				purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr);
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, _("Timezone"), tzstr);
 				g_free(tzstr);
 			}
 
 			if (geostr) {
-				purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr);
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, _("Geolocation"), geostr);
 				g_free(geostr);
 			}
 
-			if (*client_entry->server)
-				purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server);
+			if (*client_entry->server) {
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, _("Server"), client_entry->server);
+			}
 
 			if (channels && user_modes) {
 				SilcChannelPayload entry;
@@ -1266,9 +1275,7 @@
 					silc_strncat(tmp, sizeof(tmp) - 1, "  ", 1);
 					silc_free(m);
 				}
-				tmp2 = g_markup_escape_text(tmp, -1);
-				purple_notify_user_info_add_pair(user_info, _("Currently on"), tmp2);
-				g_free(tmp2);
+				purple_notify_user_info_add_pair_plaintext(user_info, _("Currently on"), tmp);
 			}
 
 			if (client_entry->public_key) {
@@ -1279,8 +1286,8 @@
 				if (pk) {
 					fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
 					babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
-					purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
-					purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
+					purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Fingerprint"), fingerprint);
+					purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Babbleprint"), babbleprint);
 					silc_free(fingerprint);
 					silc_free(babbleprint);
 					silc_free(pk);
@@ -1304,7 +1311,7 @@
 	case SILC_COMMAND_WHOWAS:
 		{
 			SilcClientEntry client_entry;
-			char *nickname, *realname, *username, *tmp;
+			char *nickname, *realname, *username;
 			PurpleNotifyUserInfo *user_info;
 
 			if (status != SILC_STATUS_OK) {
@@ -1322,27 +1329,23 @@
 				break;
 
 			user_info = purple_notify_user_info_new();
-			tmp = g_markup_escape_text(nickname, -1);
-			purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp);
-			g_free(tmp);
-			if (realname) {
-				tmp = g_markup_escape_text(realname, -1);
-				purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp);
-				g_free(tmp);
-			}
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Nickname"), nickname);
+			if (realname)
+				purple_notify_user_info_add_pair_plaintext(user_info, _("Real Name"), realname);
 			if (username) {
-				tmp = g_markup_escape_text(username, -1);
 				if (client_entry && *client_entry->hostname) {
-					gchar *tmp3;
-					tmp3 = g_strdup_printf("%s@%s", tmp, client_entry->hostname);
-					purple_notify_user_info_add_pair(user_info, _("Username"), tmp3);
-					g_free(tmp3);
+					gchar *tmp;
+					tmp = g_strdup_printf("%s@%s", username, client_entry->hostname);
+					purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), tmp);
+					g_free(tmp);
 				} else
-					purple_notify_user_info_add_pair(user_info, _("Username"), tmp);
-				g_free(tmp);
+					purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), username);
 			}
-			if (client_entry && *client_entry->server)
-				purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server);
+			if (client_entry && *client_entry->server) {
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, _("Server"), client_entry->server);
+			}
 
 
 			if (client_entry && client_entry->public_key) {
@@ -1353,8 +1356,8 @@
 				if (pk) {
 					fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
 					babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
-					purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
-					purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
+					purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Fingerprint"), fingerprint);
+					purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Babbleprint"), babbleprint);
 					silc_free(fingerprint);
 					silc_free(babbleprint);
 					silc_free(pk);
@@ -1721,7 +1724,7 @@
 		     SilcGetAuthMeth completion, void *context)
 {
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcPurpleAskPassphrase internal;
 	const char *password;
 
@@ -1772,7 +1775,7 @@
 		       SilcVerifyPublicKey completion, void *context)
 {
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 
 	if (!sg->conn && (conn_type == SILC_CONN_SERVER ||
 			  conn_type == SILC_CONN_ROUTER)) {
--- a/libpurple/protocols/silc/pk.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/silc/pk.c	Sun Sep 11 04:19:01 2011 +0000
@@ -79,7 +79,7 @@
 static void silcpurple_verify_details(PublicKeyVerify verify, gint id)
 {
 	PurpleConnection *gc = verify->client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 
 	silcpurple_show_public_key(sg, verify->entity_name, verify->public_key,
 				   G_CALLBACK(silcpurple_verify_details_cb),
--- a/libpurple/protocols/silc/silc.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/silc/silc.c	Sun Sep 11 04:19:01 2011 +0000
@@ -78,7 +78,7 @@
 	const char *state;
 
 	if (gc != NULL)
-		sg = gc->proto_data;
+		sg = purple_connection_get_protocol_data(gc);
 
 	if (status == NULL)
 		return;
@@ -125,7 +125,7 @@
 static void
 silcpurple_keepalive(PurpleConnection *gc)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	silc_packet_send(sg->conn->stream, SILC_PACKET_HEARTBEAT, 0,
 			 NULL, 0);
 }
@@ -180,7 +180,7 @@
 {
 	SilcClient client = (SilcClient)context;
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcPurpleTask ptask = NULL;
 
 	if (added) {
@@ -252,7 +252,7 @@
 	struct utsname u;
 #endif
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	switch (status) {
 	case SILC_CLIENT_CONN_SUCCESS:
@@ -316,7 +316,7 @@
 
 		/* Close the connection */
 		if (!sg->detaching)
-		  purple_connection_error_reason(gc,
+		  purple_connection_error(gc,
 		                                 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		                                 _("Disconnected by server"));
 		else
@@ -325,30 +325,30 @@
 		break;
 
 	case SILC_CLIENT_CONN_ERROR:
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		                             _("Error connecting to SILC Server"));
 		g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
 		break;
 
 	case SILC_CLIENT_CONN_ERROR_KE:
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
 		                             _("Key Exchange failed"));
 		break;
 
 	case SILC_CLIENT_CONN_ERROR_AUTH:
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
 		                             _("Authentication failed"));
 		break;
 
 	case SILC_CLIENT_CONN_ERROR_RESUME:
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 		                             _("Resuming detached session failed. "
 		                               "Press Reconnect to create new connection."));
 		g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
 		break;
 
 	case SILC_CLIENT_CONN_ERROR_TIMEOUT:
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		                             _("Connection timed out"));
 		break;
 	}
@@ -367,16 +367,16 @@
 	SilcClientConnectionParams params;
 	const char *dfile;
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	if (status != SILC_SOCKET_OK) {
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Connection failed"));
 		silc_pkcs_public_key_free(sg->public_key);
 		silc_pkcs_private_key_free(sg->private_key);
 		silc_free(sg);
-		gc->proto_data = NULL;
+		purple_connection_set_protocol_data(gc, NULL);
 		return;
 	}
 
@@ -415,15 +415,15 @@
 
 	g_return_if_fail(gc != NULL);
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	if (source < 0) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		                             _("Connection failed"));
 		silc_pkcs_public_key_free(sg->public_key);
 		silc_pkcs_private_key_free(sg->private_key);
 		silc_free(sg);
-		gc->proto_data = NULL;
+		purple_connection_set_protocol_data(gc, NULL);
 		return;
 	}
 
@@ -447,9 +447,9 @@
 				 purple_account_get_int(account, "port", 706),
 				 silcpurple_login_connected, gc) == NULL)
 	{
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		                             _("Unable to connect"));
-		gc->proto_data = NULL;
+		purple_connection_set_protocol_data(gc, NULL);
 		silc_free(sg);
 		return;
 	}
@@ -457,7 +457,7 @@
 
 static void silcpurple_got_password_cb(PurpleConnection *gc, PurpleRequestFields *fields)
 {
-	SilcPurple sg = (SilcPurple)gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	PurpleAccount *account = purple_connection_get_account(gc);
 	char pkd[256], prd[256];
 	const char *password;
@@ -473,7 +473,7 @@
 	if (!password || !*password)
 	{
 		purple_notify_error(gc, NULL, _("Password is required to sign on."), NULL);
-		gc->proto_data = NULL;
+		purple_connection_set_protocol_data(gc, NULL);
 		silc_free(sg);
 		return;
 	}
@@ -490,9 +490,9 @@
 				(char *)purple_account_get_string(account, "private-key", prd),
 				password,
 				&sg->public_key, &sg->private_key)) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 		                             _("Unable to load SILC key pair"));
-		gc->proto_data = NULL;
+		purple_connection_set_protocol_data(gc, NULL);
 		silc_free(sg);
 		return;
 	}
@@ -505,10 +505,10 @@
 	/* The password prompt dialog doesn't get disposed if the account disconnects */
 	if (!PURPLE_CONNECTION_IS_VALID(gc))
 		return;
-	sg = gc->proto_data;
-	purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+	sg = purple_connection_get_protocol_data(gc);
+	purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 			_("Unable to load SILC key pair"));
-	gc->proto_data = NULL;
+	purple_connection_set_protocol_data(gc, NULL);
 	silc_free(sg);
 }
 
@@ -535,9 +535,9 @@
 											G_CALLBACK(silcpurple_no_password_cb), gc);
 			return;
 		}
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 		                             _("Unable to load SILC key pair"));
-		gc->proto_data = NULL;
+		purple_connection_set_protocol_data(gc, NULL);
 		silc_free(sg);
 		return;
 	}
@@ -558,7 +558,7 @@
 	gc = account->gc;
 	if (!gc)
 		return;
-	gc->proto_data = NULL;
+	purple_connection_set_protocol_data(gc, NULL);
 
 	memset(&params, 0, sizeof(params));
 	strcat(params.nickname_format, "%n#a");
@@ -566,7 +566,7 @@
 	/* Allocate SILC client */
 	client = silc_client_alloc(&ops, &params, gc, NULL);
 	if (!client) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 		                             _("Out of memory"));
 		return;
 	}
@@ -612,14 +612,14 @@
 	sg->client = client;
 	sg->gc = gc;
 	sg->account = account;
-	gc->proto_data = sg;
+	purple_connection_set_protocol_data(gc, sg);
 
 	/* Init SILC client */
 	if (!silc_client_init(client, username, hostname, realname,
 			      silcpurple_running, sg)) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 		                             _("Unable to initialize SILC protocol"));
-		gc->proto_data = NULL;
+		purple_connection_set_protocol_data(gc, NULL);
 		silc_free(sg);
 		silc_free(hostname);
 		g_free(username);
@@ -630,9 +630,9 @@
 
 	/* Check the ~/.silc dir and create it, and new key pair if necessary. */
 	if (!silcpurple_check_silc_dir(gc)) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 		                             _("Error loading SILC key pair"));
-		gc->proto_data = NULL;
+		purple_connection_set_protocol_data(gc, NULL);
 		silc_free(sg);
 		return;
 	}
@@ -669,7 +669,7 @@
 static void
 silcpurple_close(PurpleConnection *gc)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 #if __SILC_TOOLKIT_VERSION >= SILC_VERSION(1,1,1)
 	SilcPurpleTask task;
 #endif /* __SILC_TOOLKIT_VERSION */
@@ -733,7 +733,7 @@
 static void
 silcpurple_attrs_cb(PurpleConnection *gc, PurpleRequestFields *fields)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	PurpleRequestField *f;
@@ -744,7 +744,7 @@
 	SilcVCardStruct vcard;
 	const char *val;
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 	if (!sg)
 		return;
 
@@ -905,7 +905,7 @@
 silcpurple_attrs(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *) action->context;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	PurpleRequestFields *fields;
@@ -922,7 +922,7 @@
 	gboolean device = TRUE;
 	char status[1024], tz[16];
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 	if (!sg)
 		return;
 
@@ -1072,7 +1072,7 @@
 
 	if (!gc)
 		return;
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 	if (!sg)
 		return;
 
@@ -1090,7 +1090,7 @@
 
 	if (!gc)
 		return;
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 	if (!sg)
 		return;
 
@@ -1125,7 +1125,7 @@
 	int keylen = SILCPURPLE_DEF_PKCS_LEN;
 	SilcPublicKey public_key;
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 	if (!sg)
 		return;
 
@@ -1208,7 +1208,7 @@
 silcpurple_create_keypair(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *) action->context;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	PurpleRequestFields *fields;
 	PurpleRequestFieldGroup *g;
 	PurpleRequestField *f;
@@ -1356,7 +1356,7 @@
 			    void *context)
 {
 	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcPurpleIM im = context;
 	PurpleConversation *convo;
 	char tmp[256];
@@ -1433,7 +1433,7 @@
 silcpurple_send_im(PurpleConnection *gc, const char *who, const char *message,
 		   PurpleMessageFlags flags)
 {
-	SilcPurple sg = gc->proto_data;
+	SilcPurple sg = purple_connection_get_protocol_data(gc);
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
 	SilcDList clients;
@@ -1718,7 +1718,7 @@
 	if (gc == NULL)
 		return PURPLE_CMD_RET_FAILED;
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	if (sg == NULL)
 		return PURPLE_CMD_RET_FAILED;
@@ -1747,7 +1747,7 @@
 	if (gc == NULL)
 		return PURPLE_CMD_RET_FAILED;
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	if (sg == NULL)
 		return PURPLE_CMD_RET_FAILED;
@@ -1769,10 +1769,10 @@
 
 	gc = purple_conversation_get_gc(conv);
 
-	if (gc == NULL || !args || gc->proto_data == NULL)
+	if (gc == NULL || !args || purple_connection_get_protocol_data(gc) == NULL)
 		return PURPLE_CMD_RET_FAILED;
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	if (args[0])
 		chname = args[0];
@@ -1823,7 +1823,7 @@
 	if (gc == NULL)
 		return PURPLE_CMD_RET_FAILED;
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	if (sg == NULL)
 		return PURPLE_CMD_RET_FAILED;
@@ -1855,7 +1855,7 @@
 	if (gc == NULL)
 		return PURPLE_CMD_RET_FAILED;
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	if (sg == NULL)
 		return PURPLE_CMD_RET_FAILED;
@@ -1892,7 +1892,7 @@
 	if (gc == NULL)
 		return PURPLE_CMD_RET_FAILED;
 
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	if (sg == NULL)
 		return PURPLE_CMD_RET_FAILED;
@@ -2050,6 +2050,7 @@
 
 static PurplePluginProtocolInfo prpl_info =
 {
+	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME |
 	OPT_PROTO_PASSWORD_OPTIONAL | OPT_PROTO_IM_IMAGE |
 	OPT_PROTO_SLASH_COMMANDS_NATIVE,
@@ -2117,15 +2118,12 @@
 	NULL,				        /* unregister_user */
 	NULL,				        /* send_attention */
 	NULL,				        /* get_attention_types */
-	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	NULL,				        /* get_account_text_table */
 	NULL,				        /* initiate_media */
 	NULL,				        /* get_media_caps */
 	NULL,				        /* get_moods */
 	NULL,				        /* set_public_alias */
-	NULL,				        /* get_public_alias */
-	NULL,				        /* add_buddy_with_invite */
-	NULL				        /* add_buddies_with_invite */
+	NULL				        /* get_public_alias */
 };
 
 static PurplePluginInfo info =
--- a/libpurple/protocols/silc/silcpurple.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/silc/silcpurple.h	Sun Sep 11 04:19:01 2011 +0000
@@ -105,7 +105,7 @@
 				  SilcVerifyPublicKey completion,
 				  void *context);
 GList *silcpurple_buddy_menu(PurpleBuddy *buddy);
-void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
+void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message);
 void silcpurple_send_buddylist(PurpleConnection *gc);
 void silcpurple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
 void silcpurple_buddy_keyagr_request(SilcClient client,
--- a/libpurple/protocols/silc/util.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/silc/util.c	Sun Sep 11 04:19:01 2011 +0000
@@ -213,7 +213,7 @@
 						  (gc->password == NULL)
 						  ? "" : gc->password,
 						  NULL, NULL, FALSE)) {
-				purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+				purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 				                             _("Unable to create SILC key pair"));
 				return FALSE;
 			}
@@ -256,7 +256,7 @@
 						  (gc->password == NULL)
 						  ? "" : gc->password,
 						  NULL, NULL, FALSE)) {
-				purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+				purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 				                             _("Unable to create SILC key pair"));
 				return FALSE;
 			}
--- a/libpurple/protocols/silc/wb.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/silc/wb.c	Sun Sep 11 04:19:01 2011 +0000
@@ -105,7 +105,7 @@
 
 PurpleWhiteboard *silcpurple_wb_init(SilcPurple sg, SilcClientEntry client_entry)
 {
-        SilcClientConnection conn;
+	SilcClientConnection conn;
 	PurpleWhiteboard *wb;
 	SilcPurpleWb wbs;
 
@@ -116,7 +116,7 @@
 	if (!wb)
 		return NULL;
 
-	if (!wb->proto_data) {
+	if (!purple_whiteboard_get_protocol_data(wb)) {
 		wbs = silc_calloc(1, sizeof(*wbs));
 		if (!wbs)
 			return NULL;
@@ -126,7 +126,7 @@
 		wbs->height = SILCPURPLE_WB_HEIGHT;
 		wbs->brush_size = SILCPURPLE_WB_BRUSH_SMALL;
 		wbs->brush_color = SILCPURPLE_WB_COLOR_BLACK;
-		wb->proto_data = wbs;
+		purple_whiteboard_set_protocol_data(wb, wbs);
 
 		/* Start the whiteboard */
 		purple_whiteboard_start(wb);
@@ -147,7 +147,7 @@
 	if (!wb)
 		return NULL;
 
-	if (!wb->proto_data) {
+	if (!purple_whiteboard_get_protocol_data(wb)) {
 		wbs = silc_calloc(1, sizeof(*wbs));
 		if (!wbs)
 			return NULL;
@@ -157,7 +157,7 @@
 		wbs->height = SILCPURPLE_WB_HEIGHT;
 		wbs->brush_size = SILCPURPLE_WB_BRUSH_SMALL;
 		wbs->brush_color = SILCPURPLE_WB_COLOR_BLACK;
-		wb->proto_data = wbs;
+		purple_whiteboard_set_protocol_data(wb, wbs);
 
 		/* Start the whiteboard */
 		purple_whiteboard_start(wb);
@@ -168,9 +168,10 @@
 }
 
 static void
-silcpurple_wb_parse(SilcPurpleWb wbs, PurpleWhiteboard *wb,
+silcpurple_wb_parse(PurpleWhiteboard *wb,
 		  unsigned char *message, SilcUInt32 message_len)
 {
+	SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
 	SilcUInt8 command;
 	SilcUInt16 width, height, brush_size;
 	SilcUInt32 brush_color, x, y, dx, dy;
@@ -238,15 +239,15 @@
 {
 	PurpleWhiteboard *wb;
 
-        if (id != 1)
-                goto out;
+	if (id != 1)
+		goto out;
 
 	if (!req->channel)
 		wb = silcpurple_wb_init(req->sg, req->sender);
 	else
 		wb = silcpurple_wb_init_ch(req->sg, req->channel);
 
-	silcpurple_wb_parse(wb->proto_data, wb, req->message, req->message_len);
+	silcpurple_wb_parse(wb, req->message, req->message_len);
 
   out:
 	silc_free(req->message);
@@ -264,7 +265,7 @@
 	SilcPurple sg;
 
 	gc = client->application;
-	sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	/* Open whiteboard automatically if requested */
 	if (purple_account_get_bool(sg->account, "open-wb", FALSE)) {
@@ -275,7 +276,7 @@
 		else
 			wb = silcpurple_wb_init_ch(sg, channel);
 
-		silcpurple_wb_parse(wb->proto_data, wb,
+		silcpurple_wb_parse(wb,
 				    (unsigned char *)message,
 				    message_len);
 		return;
@@ -318,12 +319,11 @@
 			 SilcUInt32 message_len)
 {
 	SilcPurple sg;
-        PurpleConnection *gc;
+	PurpleConnection *gc;
 	PurpleWhiteboard *wb;
-	SilcPurpleWb wbs;
 
 	gc = client->application;
-        sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	wb = purple_whiteboard_get_session(sg->account, sender->nickname);
 	if (!wb) {
@@ -333,8 +333,7 @@
 		return;
 	}
 
-	wbs = wb->proto_data;
-	silcpurple_wb_parse(wbs, wb, (unsigned char *)message, message_len);
+	silcpurple_wb_parse(wb, (unsigned char *)message, message_len);
 }
 
 /* Process incoming whiteboard message on channel */
@@ -347,12 +346,11 @@
 			    SilcUInt32 message_len)
 {
 	SilcPurple sg;
-        PurpleConnection *gc;
+	PurpleConnection *gc;
 	PurpleWhiteboard *wb;
-	SilcPurpleWb wbs;
 
 	gc = client->application;
-        sg = gc->proto_data;
+	sg = purple_connection_get_protocol_data(gc);
 
 	wb = purple_whiteboard_get_session(sg->account, channel->channel_name);
 	if (!wb) {
@@ -362,25 +360,24 @@
 		return;
 	}
 
-	wbs = wb->proto_data;
-	silcpurple_wb_parse(wbs, wb, (unsigned char *)message, message_len);
+	silcpurple_wb_parse(wb, (unsigned char *)message, message_len);
 }
 
 /* Send whiteboard message */
 
 void silcpurple_wb_send(PurpleWhiteboard *wb, GList *draw_list)
 {
-	SilcPurpleWb wbs = wb->proto_data;
+	SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
 	SilcBuffer packet;
 	GList *list;
 	int len;
-        PurpleConnection *gc;
-        SilcPurple sg;
+	PurpleConnection *gc;
+	SilcPurple sg;
 
 	g_return_if_fail(draw_list);
-	gc = purple_account_get_connection(wb->account);
+	gc = purple_account_get_connection(purple_whiteboard_get_account(wb));
 	g_return_if_fail(gc);
- 	sg = gc->proto_data;
+ 	sg = purple_connection_get_protocol_data(gc);
 	g_return_if_fail(sg);
 
 	len = SILCPURPLE_WB_HEADER;
@@ -435,20 +432,22 @@
 
 void silcpurple_wb_end(PurpleWhiteboard *wb)
 {
-	silc_free(wb->proto_data);
-	wb->proto_data = NULL;
+	SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
+
+	silc_free(wbs);
+	purple_whiteboard_set_protocol_data(wb, NULL);
 }
 
 void silcpurple_wb_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height)
 {
-	SilcPurpleWb wbs = wb->proto_data;
+	SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
 	*width = wbs->width;
 	*height = wbs->height;
 }
 
 void silcpurple_wb_set_dimensions(PurpleWhiteboard *wb, int width, int height)
 {
-	SilcPurpleWb wbs = wb->proto_data;
+	SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
 	wbs->width = width > SILCPURPLE_WB_WIDTH_MAX ? SILCPURPLE_WB_WIDTH_MAX :
 			width;
 	wbs->height = height > SILCPURPLE_WB_HEIGHT_MAX ? SILCPURPLE_WB_HEIGHT_MAX :
@@ -460,14 +459,14 @@
 
 void silcpurple_wb_get_brush(const PurpleWhiteboard *wb, int *size, int *color)
 {
-	SilcPurpleWb wbs = wb->proto_data;
+	SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
 	*size = wbs->brush_size;
 	*color = wbs->brush_color;
 }
 
 void silcpurple_wb_set_brush(PurpleWhiteboard *wb, int size, int color)
 {
-	SilcPurpleWb wbs = wb->proto_data;
+	SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
 	wbs->brush_size = size;
 	wbs->brush_color = color;
 
@@ -477,15 +476,15 @@
 
 void silcpurple_wb_clear(PurpleWhiteboard *wb)
 {
-	SilcPurpleWb wbs = wb->proto_data;
+	SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
 	SilcBuffer packet;
 	int len;
-        PurpleConnection *gc;
-        SilcPurple sg;
+	PurpleConnection *gc;
+	SilcPurple sg;
 
-	gc = purple_account_get_connection(wb->account);
+	gc = purple_account_get_connection(purple_whiteboard_get_account(wb));
 	g_return_if_fail(gc);
- 	sg = gc->proto_data;
+ 	sg = purple_connection_get_protocol_data(gc);
 	g_return_if_fail(sg);
 
 	len = SILCPURPLE_WB_HEADER;
--- a/libpurple/protocols/silc10/Makefile.am	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-EXTRA_DIST = \
-	Makefile.mingw \
-	README \
-	TODO
-
-pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
-
-SILCSOURCES = silc.c silcpurple.h buddy.c chat.c ft.c ops.c pk.c util.c wb.c wb.h
-
-AM_CFLAGS = $(st)
-
-libsilcpurple_la_LDFLAGS = -module -avoid-version
-
-if STATIC_SILC
-
-st = -DPURPLE_STATIC_PRPL $(SILC_CFLAGS)
-noinst_LTLIBRARIES       = libsilcpurple.la
-libsilcpurple_la_SOURCES = $(SILCSOURCES)
-libsilcpurple_la_CFLAGS  = $(AM_CFLAGS)
-libsilcpurple_la_LIBADD  = $(SILC_LIBS)
-
-else
-
-st = $(SILC_CFLAGS)
-pkg_LTLIBRARIES          = libsilcpurple.la
-libsilcpurple_la_SOURCES = $(SILCSOURCES)
-libsilcpurple_la_LIBADD  = $(GLIB_LIBS) $(SILC_LIBS)
-
-endif
-
-AM_CPPFLAGS = \
-	-I$(top_srcdir)/libpurple \
-	-I$(top_builddir)/libpurple \
-	$(DEBUG_CFLAGS) \
-	$(GLIB_CFLAGS) \
-	$(SILC_CFLAGS)
--- a/libpurple/protocols/silc10/Makefile.mingw	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-#
-# Makefile.mingw
-#
-# Description: Makefile for win32 (mingw) version of libsilc protocol plugin
-#
-
-PIDGIN_TREE_TOP := ../../..
-include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
-
-DEFINES := $(subst -DWIN32_LEAN_AND_MEAN,,$(DEFINES))
-
-TARGET = libsilc
-NEEDED_DLLS =		$(SILC_TOOLKIT)/lib/silc.dll \
-			$(SILC_TOOLKIT)/lib/silcclient.dll
-TYPE = PLUGIN
-
-# Static or Plugin...
-ifeq ($(TYPE),STATIC)
-  DEFINES += -DSTATIC
-  DLL_INSTALL_DIR =	$(PURPLE_INSTALL_DIR)
-else
-ifeq ($(TYPE),PLUGIN)
-  DLL_INSTALL_DIR =	$(PURPLE_INSTALL_PLUGINS_DIR)
-endif
-endif
-
-##
-## INCLUDE PATHS
-##
-INCLUDE_PATHS +=	-I. \
-			-I$(GTK_TOP)/include \
-			-I$(GTK_TOP)/include/glib-2.0 \
-			-I$(GTK_TOP)/lib/glib-2.0/include \
-			-I$(PURPLE_TOP) \
-			-I$(PURPLE_TOP)/win32 \
-			-I$(PIDGIN_TREE_TOP) \
-			-I$(SILC_TOOLKIT)/include
-
-LIB_PATHS +=		-L$(GTK_TOP)/lib \
-			-L$(PURPLE_TOP) \
-			-L$(SILC_TOOLKIT)/lib
-
-##
-##  SOURCES, OBJECTS
-##
-C_SRC =			silc.c \
-			buddy.c \
-			chat.c \
-			ft.c \
-			ops.c \
-			pk.c \
-			util.c \
-			wb.c
-
-OBJECTS = $(C_SRC:%.c=%.o)
-
-##
-## LIBRARIES
-##
-LIBS = \
-			-lglib-2.0 \
-			-lws2_32 \
-			-lintl \
-			-lpurple \
-			-lsilc \
-			-lsilcclient
-
-include $(PIDGIN_COMMON_RULES)
-
-##
-## TARGET DEFINITIONS
-##
-.PHONY: all install clean
-
-all: $(TARGET).dll
-
-install: all $(DLL_INSTALL_DIR) $(PURPLE_INSTALL_DIR)
-	cp $(TARGET).dll $(DLL_INSTALL_DIR)
-	cp $(NEEDED_DLLS) $(PURPLE_INSTALL_DIR)
-
-$(OBJECTS): $(PURPLE_CONFIG_H)
-
-$(TARGET).dll: $(PURPLE_DLL).a $(OBJECTS)
-	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--image-base,0x64000000 -o $(TARGET).dll
-
-##
-## CLEAN RULES
-##
-clean:
-	rm -f $(OBJECTS)
-	rm -f $(TARGET).dll
-
-include $(PIDGIN_COMMON_TARGETS)
--- a/libpurple/protocols/silc10/README	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-SILC Purple Plugin
-==================
-
-This is the Purple protocol plugin of the protocol called Secure Internet
-Live Conferencing (SILC).  The implementation will use the SILC Toolkit, 
-freely available from the http://silcnet.org/ site, for the actual SILC 
-protocol implementation.
-
-To include SILC into Purple, one needs to first compile and install 
-the SILC Toolkit.  It is done as follows:
-
-	./configure --enable-shared
-	make
-	make install
-
-This will compile shared libraries of the SILC Toolkit.  If the --prefix 
-is not given to ./configure, the binaries are installed into the 
-/usr/local/silc directory.
-
-Once the Toolkit is installed one needs to tell Purple's ./configure
-script where the SILC Toolkit is located.  It is done as simply as:
-
-	./configure
-
-if pkg-config is installed in your system.  If it is isn't it's done as:
-
-	./configure --with-silc-libs=/path/to/silc/lib
-		    --with-silc-includes=/path/to/silc/include
-
-If the SILC Toolkit cannot be found then the SILC protocol plugin will
-not be compiled.
--- a/libpurple/protocols/silc10/TODO	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-Features TODO (maybe)
-=====================
-
-Preferences
-	- Add joined channels to buddy list automatically (during
-	  session)
-	- Add joined channels to buddy list automatically permanently
-
--- a/libpurple/protocols/silc10/buddy.c	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1748 +0,0 @@
-/*
-
-  silcpurple_buddy.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2004 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "wb.h"
-
-/***************************** Key Agreement *********************************/
-
-static void
-silcpurple_buddy_keyagr(PurpleBlistNode *node, gpointer data);
-
-static void
-silcpurple_buddy_keyagr_do(PurpleConnection *gc, const char *name,
-			 			 gboolean force_local);
-
-typedef struct {
-	char *nick;
-	PurpleConnection *gc;
-} *SilcPurpleResolve;
-
-static void
-silcpurple_buddy_keyagr_resolved(SilcClient client,
-			       SilcClientConnection conn,
-			       SilcClientEntry *clients,
-			       SilcUInt32 clients_count,
-			       void *context)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurpleResolve r = context;
-	char tmp[256];
-
-	if (!clients) {
-		g_snprintf(tmp, sizeof(tmp),
-			   _("User %s is not present in the network"), r->nick);
-		purple_notify_error(gc, _("Key Agreement"),
-				  _("Cannot perform the key agreement"), tmp);
-		silc_free(r->nick);
-		silc_free(r);
-		return;
-	}
-
-	silcpurple_buddy_keyagr_do(gc, r->nick, FALSE);
-	silc_free(r->nick);
-	silc_free(r);
-}
-
-typedef struct {
-	gboolean responder;
-} *SilcPurpleKeyAgr;
-
-static void
-silcpurple_buddy_keyagr_cb(SilcClient client,
-			 SilcClientConnection conn,
-			 SilcClientEntry client_entry,
-			 SilcKeyAgreementStatus status,
-			 SilcSKEKeyMaterial *key,
-			 void *context)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-	SilcPurpleKeyAgr a = context;
-
-	if (!sg->conn)
-		return;
-
-	switch (status) {
-	case SILC_KEY_AGREEMENT_OK:
-		{
-			PurpleConversation *convo;
-			char tmp[128];
-
-			/* Set the private key for this client */
-			silc_client_del_private_message_key(client, conn, client_entry);
-			silc_client_add_private_message_key_ske(client, conn, client_entry,
-								NULL, NULL, key, a->responder);
-			silc_ske_free_key_material(key);
-
-
-			/* Open IM window */
-			convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
-									client_entry->nickname, sg->account);
-			if (convo) {
-				/* we don't have windows in the core anymore...but we may want to
-				 * provide some method for asking the UI to show the window
-				purple_conv_window_show(purple_conversation_get_window(convo));
-				 */
-			} else {
-				convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, sg->account,
-							      client_entry->nickname);
-			}
-			g_snprintf(tmp, sizeof(tmp), "%s [private key]", client_entry->nickname);
-			purple_conversation_set_title(convo, tmp);
-		}
-		break;
-
-	case SILC_KEY_AGREEMENT_ERROR:
-		purple_notify_error(gc, _("Key Agreement"),
-				  _("Error occurred during key agreement"), NULL);
-		break;
-
-	case SILC_KEY_AGREEMENT_FAILURE:
-		purple_notify_error(gc, _("Key Agreement"), _("Key Agreement failed"), NULL);
-		break;
-
-	case SILC_KEY_AGREEMENT_TIMEOUT:
-		purple_notify_error(gc, _("Key Agreement"),
-				  _("Timeout during key agreement"), NULL);
-		break;
-
-	case SILC_KEY_AGREEMENT_ABORTED:
-		purple_notify_error(gc, _("Key Agreement"),
-				  _("Key agreement was aborted"), NULL);
-		break;
-
-	case SILC_KEY_AGREEMENT_ALREADY_STARTED:
-		purple_notify_error(gc, _("Key Agreement"),
-				  _("Key agreement is already started"), NULL);
-		break;
-
-	case SILC_KEY_AGREEMENT_SELF_DENIED:
-		purple_notify_error(gc, _("Key Agreement"),
-				  _("Key agreement cannot be started with yourself"),
-				  NULL);
-		break;
-
-	default:
-		break;
-	}
-
-	silc_free(a);
-}
-
-static void
-silcpurple_buddy_keyagr_do(PurpleConnection *gc, const char *name,
-			 gboolean force_local)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClientEntry *clients;
-	SilcUInt32 clients_count;
-	char *local_ip = NULL, *remote_ip = NULL;
-	gboolean local = TRUE;
-	char *nickname;
-	SilcPurpleKeyAgr a;
-
-	if (!sg->conn || !name)
-		return;
-
-	if (!silc_parse_userfqdn(name, &nickname, NULL))
-		return;
-
-	/* Find client entry */
-	clients = silc_client_get_clients_local(sg->client, sg->conn, nickname, name,
-						&clients_count);
-	if (!clients) {
-		/* Resolve unknown user */
-		SilcPurpleResolve r = silc_calloc(1, sizeof(*r));
-		if (!r)
-			return;
-		r->nick = g_strdup(name);
-		r->gc = gc;
-		silc_client_get_clients(sg->client, sg->conn, nickname, NULL,
-					silcpurple_buddy_keyagr_resolved, r);
-		silc_free(nickname);
-		return;
-	}
-
-	/* Resolve the local IP from the outgoing socket connection.  We resolve
-	   it to check whether we have a private range IP address or public IP
-	   address.  If we have public then we will assume that we are not behind
-	   NAT and will provide automatically the point of connection to the
-	   agreement.  If we have private range address we assume that we are
-	   behind NAT and we let the responder provide the point of connection.
-
-	   The algorithm also checks the remote IP address of server connection.
-	   If it is private range address and we have private range address we
-	   assume that we are chatting in LAN and will provide the point of
-	   connection.
-
-	   Naturally this algorithm does not always get things right. */
-
-	if (silc_net_check_local_by_sock(sg->conn->sock->sock, NULL, &local_ip)) {
-		/* Check if the IP is private */
-		if (!force_local && silcpurple_ip_is_private(local_ip)) {
-			local = FALSE;
-
-			/* Local IP is private, resolve the remote server IP to see whether
-			   we are talking to Internet or just on LAN. */
-			if (silc_net_check_host_by_sock(sg->conn->sock->sock, NULL,
-							&remote_ip))
-				if (silcpurple_ip_is_private(remote_ip))
-					/* We assume we are in LAN.  Let's provide
-					   the connection point. */
-					local = TRUE;
-		}
-	}
-
-	if (force_local)
-		local = TRUE;
-
-	if (local && !local_ip)
-		local_ip = silc_net_localip();
-
-	a = silc_calloc(1, sizeof(*a));
-	if (!a)
-		return;
-	a->responder = local;
-
-	/* Send the key agreement request */
-	silc_client_send_key_agreement(sg->client, sg->conn, clients[0],
-				       local ? local_ip : NULL, NULL, 0, 60,
-				       silcpurple_buddy_keyagr_cb, a);
-
-	silc_free(local_ip);
-	silc_free(remote_ip);
-	silc_free(clients);
-}
-
-typedef struct {
-	SilcClient client;
-	SilcClientConnection conn;
-	SilcClientID client_id;
-	char *hostname;
-	SilcUInt16 port;
-} *SilcPurpleKeyAgrAsk;
-
-static void
-silcpurple_buddy_keyagr_request_cb(SilcPurpleKeyAgrAsk a, gint id)
-{
-	SilcPurpleKeyAgr ai;
-	SilcClientEntry client_entry;
-
-	if (id != 1)
-		goto out;
-
-	/* Get the client entry. */
-	client_entry = silc_client_get_client_by_id(a->client, a->conn,
-						    &a->client_id);
-	if (!client_entry) {
-		purple_notify_error(a->client->application, _("Key Agreement"),
-				  _("The remote user is not present in the network any more"),
-				  NULL);
-		goto out;
-	}
-
-	/* If the hostname was provided by the requestor perform the key agreement
-	   now.  Otherwise, we will send him a request to connect to us. */
-	if (a->hostname) {
-		ai = silc_calloc(1, sizeof(*ai));
-		if (!ai)
-			goto out;
-		ai->responder = FALSE;
-		silc_client_perform_key_agreement(a->client, a->conn, client_entry,
-						  a->hostname, a->port,
-						  silcpurple_buddy_keyagr_cb, ai);
-	} else {
-		/* Send request.  Force us as the point of connection since requestor
-		   did not provide the point of connection. */
-		silcpurple_buddy_keyagr_do(a->client->application,
-					 client_entry->nickname, TRUE);
-	}
-
- out:
-	silc_free(a->hostname);
-	silc_free(a);
-}
-
-void silcpurple_buddy_keyagr_request(SilcClient client,
-				   SilcClientConnection conn,
-				   SilcClientEntry client_entry,
-				   const char *hostname, SilcUInt16 port)
-{
-	char tmp[128], tmp2[128];
-	SilcPurpleKeyAgrAsk a;
-	PurpleConnection *gc = client->application;
-
-	g_snprintf(tmp, sizeof(tmp),
-		   _("Key agreement request received from %s. Would you like to "
-		     "perform the key agreement?"), client_entry->nickname);
-	if (hostname)
-		g_snprintf(tmp2, sizeof(tmp2),
-			   _("The remote user is waiting key agreement on:\n"
-			     "Remote host: %s\nRemote port: %d"), hostname, port);
-
-	a = silc_calloc(1, sizeof(*a));
-	if (!a)
-		return;
-	a->client = client;
-	a->conn = conn;
-	a->client_id = *client_entry->id;
-	if (hostname)
-		a->hostname = strdup(hostname);
-	a->port = port;
-
-	purple_request_action(client->application, _("Key Agreement Request"), tmp,
-			    hostname ? tmp2 : NULL, 1, gc->account, client_entry->nickname,
-				NULL, a, 2, _("Yes"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb),
-			    _("No"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb));
-}
-
-static void
-silcpurple_buddy_keyagr(PurpleBlistNode *node, gpointer data)
-{
-	PurpleBuddy *buddy;
-
-	buddy = (PurpleBuddy *)node;
-	silcpurple_buddy_keyagr_do(buddy->account->gc, buddy->name, FALSE);
-}
-
-
-/**************************** Static IM Key **********************************/
-
-static void
-silcpurple_buddy_resetkey(PurpleBlistNode *node, gpointer data)
-{
-	PurpleBuddy *b;
-	PurpleConnection *gc;
-        SilcPurple sg;
-	char *nickname;
-	SilcClientEntry *clients;
-	SilcUInt32 clients_count;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
-	b = (PurpleBuddy *) node;
-	gc = purple_account_get_connection(b->account);
-	sg = gc->proto_data;
-
-	if (!silc_parse_userfqdn(b->name, &nickname, NULL))
-		return;
-
-	/* Find client entry */
-	clients = silc_client_get_clients_local(sg->client, sg->conn,
-						nickname, b->name,
-						&clients_count);
-	if (!clients) {
-		silc_free(nickname);
-		return;
-	}
-
-	clients[0]->prv_resp = FALSE;
-	silc_client_del_private_message_key(sg->client, sg->conn,
-					    clients[0]);
-	silc_free(clients);
-	silc_free(nickname);
-}
-
-typedef struct {
-	SilcClient client;
-	SilcClientConnection conn;
-	SilcClientID client_id;
-} *SilcPurplePrivkey;
-
-static void
-silcpurple_buddy_privkey(PurpleConnection *gc, const char *name);
-
-static void
-silcpurple_buddy_privkey_cb(SilcPurplePrivkey p, const char *passphrase)
-{
-	SilcClientEntry client_entry;
-
-        if (!passphrase || !(*passphrase)) {
-                silc_free(p);
-                return;
-        }
-
-	/* Get the client entry. */
-	client_entry = silc_client_get_client_by_id(p->client, p->conn,
-						    &p->client_id);
-	if (!client_entry) {
-		purple_notify_error(p->client->application, _("IM With Password"),
-				  _("The remote user is not present in the network any more"),
-				  NULL);
-		silc_free(p);
-		return;
-	}
-
-	/* Set the private message key */
-	silc_client_del_private_message_key(p->client, p->conn,
-					    client_entry);
-	silc_client_add_private_message_key(p->client, p->conn,
-					    client_entry, NULL, NULL,
-					    (unsigned char *)passphrase,
-					    strlen(passphrase), FALSE,
-					    client_entry->prv_resp);
-	if (!client_entry->prv_resp)
-		silc_client_send_private_message_key_request(p->client,
-							     p->conn,
-							     client_entry);
-        silc_free(p);
-}
-
-static void
-silcpurple_buddy_privkey_resolved(SilcClient client,
-				SilcClientConnection conn,
-				SilcClientEntry *clients,
-				SilcUInt32 clients_count,
-				void *context)
-{
-	char tmp[256];
-
-	if (!clients) {
-		g_snprintf(tmp, sizeof(tmp),
-			   _("User %s is not present in the network"),
-			   (const char *)context);
-		purple_notify_error(client->application, _("IM With Password"),
-				  _("Cannot set IM key"), tmp);
-		g_free(context);
-		return;
-	}
-
-	silcpurple_buddy_privkey(client->application, context);
-	silc_free(context);
-}
-
-static void
-silcpurple_buddy_privkey(PurpleConnection *gc, const char *name)
-{
-	SilcPurple sg = gc->proto_data;
-	char *nickname;
-	SilcPurplePrivkey p;
-	SilcClientEntry *clients;
-	SilcUInt32 clients_count;
-
-	if (!name)
-		return;
-	if (!silc_parse_userfqdn(name, &nickname, NULL))
-		return;
-
-	/* Find client entry */
-	clients = silc_client_get_clients_local(sg->client, sg->conn,
-						nickname, name,
-						&clients_count);
-	if (!clients) {
-		silc_client_get_clients(sg->client, sg->conn, nickname, NULL,
-					silcpurple_buddy_privkey_resolved,
-					g_strdup(name));
-		silc_free(nickname);
-		return;
-	}
-
-	p = silc_calloc(1, sizeof(*p));
-	if (!p)
-		return;
-	p->client = sg->client;
-	p->conn = sg->conn;
-	p->client_id = *clients[0]->id;
-	purple_request_input(gc, _("IM With Password"), NULL,
-	                     _("Set IM Password"), NULL, FALSE, TRUE, NULL,
-	                     _("OK"), G_CALLBACK(silcpurple_buddy_privkey_cb),
-	                     _("Cancel"), G_CALLBACK(silcpurple_buddy_privkey_cb),
-	                     gc->account, NULL, NULL, p);
-
-	silc_free(clients);
-	silc_free(nickname);
-}
-
-static void
-silcpurple_buddy_privkey_menu(PurpleBlistNode *node, gpointer data)
-{
-	PurpleBuddy *buddy;
-	PurpleConnection *gc;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
-	buddy = (PurpleBuddy *) node;
-	gc = purple_account_get_connection(buddy->account);
-
-	silcpurple_buddy_privkey(gc, buddy->name);
-}
-
-
-/**************************** Get Public Key *********************************/
-
-typedef struct {
-	SilcClient client;
-	SilcClientConnection conn;
-	SilcClientID client_id;
-} *SilcPurpleBuddyGetkey;
-
-static void
-silcpurple_buddy_getkey(PurpleConnection *gc, const char *name);
-
-static void
-silcpurple_buddy_getkey_cb(SilcPurpleBuddyGetkey g,
-			 SilcClientCommandReplyContext cmd)
-{
-	SilcClientEntry client_entry;
-	unsigned char *pk;
-	SilcUInt32 pk_len;
-
-	/* Get the client entry. */
-	client_entry = silc_client_get_client_by_id(g->client, g->conn,
-						    &g->client_id);
-	if (!client_entry) {
-		purple_notify_error(g->client->application, _("Get Public Key"),
-				  _("The remote user is not present in the network any more"),
-				  NULL);
-		silc_free(g);
-		return;
-	}
-
-	if (!client_entry->public_key) {
-		silc_free(g);
-		return;
-	}
-
-	/* Now verify the public key */
-	pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len);
-	silcpurple_verify_public_key(g->client, g->conn, client_entry->nickname,
-				   SILC_SOCKET_TYPE_CLIENT,
-				   pk, pk_len, SILC_SKE_PK_TYPE_SILC,
-				   NULL, NULL);
-	silc_free(pk);
-	silc_free(g);
-}
-
-static void
-silcpurple_buddy_getkey_resolved(SilcClient client,
-			       SilcClientConnection conn,
-			       SilcClientEntry *clients,
-			       SilcUInt32 clients_count,
-			       void *context)
-{
-	char tmp[256];
-
-	if (!clients) {
-		g_snprintf(tmp, sizeof(tmp),
-			   _("User %s is not present in the network"),
-			   (const char *)context);
-		purple_notify_error(client->application, _("Get Public Key"),
-				  _("Cannot fetch the public key"), tmp);
-		g_free(context);
-		return;
-	}
-
-	silcpurple_buddy_getkey(client->application, context);
-	silc_free(context);
-}
-
-static void
-silcpurple_buddy_getkey(PurpleConnection *gc, const char *name)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcClientEntry *clients;
-	SilcUInt32 clients_count;
-	SilcPurpleBuddyGetkey g;
-	char *nickname;
-
-	if (!name)
-		return;
-
-	if (!silc_parse_userfqdn(name, &nickname, NULL))
-		return;
-
-	/* Find client entry */
-	clients = silc_client_get_clients_local(client, conn, nickname, name,
-						&clients_count);
-	if (!clients) {
-		silc_client_get_clients(client, conn, nickname, NULL,
-					silcpurple_buddy_getkey_resolved,
-					g_strdup(name));
-		silc_free(nickname);
-		return;
-	}
-
-	/* Call GETKEY */
-	g = silc_calloc(1, sizeof(*g));
-	if (!g)
-		return;
-	g->client = client;
-	g->conn = conn;
-	g->client_id = *clients[0]->id;
-	silc_client_command_call(client, conn, NULL, "GETKEY",
-				 clients[0]->nickname, NULL);
-	silc_client_command_pending(conn, SILC_COMMAND_GETKEY,
-				    conn->cmd_ident,
-				    (SilcCommandCb)silcpurple_buddy_getkey_cb, g);
-	silc_free(clients);
-	silc_free(nickname);
-}
-
-static void
-silcpurple_buddy_getkey_menu(PurpleBlistNode *node, gpointer data)
-{
-	PurpleBuddy *buddy;
-	PurpleConnection *gc;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
-	buddy = (PurpleBuddy *) node;
-	gc = purple_account_get_connection(buddy->account);
-
-	silcpurple_buddy_getkey(gc, buddy->name);
-}
-
-static void
-silcpurple_buddy_showkey(PurpleBlistNode *node, gpointer data)
-{
-	PurpleBuddy *b;
-	PurpleConnection *gc;
-	SilcPurple sg;
-	SilcPublicKey public_key;
-	const char *pkfile;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
-	b = (PurpleBuddy *) node;
-	gc = purple_account_get_connection(b->account);
-	sg = gc->proto_data;
-
-	pkfile = purple_blist_node_get_string(node, "public-key");
-	if (!silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_PEM) &&
-	    !silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_BIN)) {
-		purple_notify_error(gc,
-				  _("Show Public Key"),
-				  _("Could not load public key"), NULL);
-		return;
-	}
-
-	silcpurple_show_public_key(sg, b->name, public_key, NULL, NULL);
-	silc_pkcs_public_key_free(public_key);
-}
-
-
-/**************************** Buddy routines *********************************/
-
-/* The buddies are implemented by using the WHOIS and WATCH commands that
-   can be used to search users by their public key.  Since nicknames aren't
-   unique in SILC we cannot trust the buddy list using their nickname.  We
-   associate public keys to buddies and use those to search and watch
-   in the network.
-
-   The problem is that Purple does not return PurpleBuddy contexts to the
-   callbacks but the buddy names.  Naturally, this is not going to work
-   with SILC.  But, for now, we have to do what we can... */
-
-typedef struct {
-	SilcClient client;
-	SilcClientConnection conn;
-	SilcClientID client_id;
-	PurpleBuddy *b;
-	unsigned char *offline_pk;
-	SilcUInt32 offline_pk_len;
-	unsigned int offline        : 1;
-	unsigned int pubkey_search  : 1;
-	unsigned int init           : 1;
-} *SilcPurpleBuddyRes;
-
-static void
-silcpurple_add_buddy_ask_pk_cb(SilcPurpleBuddyRes r, gint id);
-static void
-silcpurple_add_buddy_resolved(SilcClient client,
-			    SilcClientConnection conn,
-			    SilcClientEntry *clients,
-			    SilcUInt32 clients_count,
-			    void *context);
-
-void silcpurple_get_info(PurpleConnection *gc, const char *who)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcClientEntry client_entry;
-	PurpleBuddy *b;
-	const char *filename, *nick = who;
-	char tmp[256];
-
-	if (!who)
-		return;
-	if (strlen(who) > 1 && who[0] == '@')
-		nick = who + 1;
-	if (strlen(who) > 1 && who[0] == '*')
-		nick = who + 1;
-	if (strlen(who) > 2 && who[0] == '*' && who[1] == '@')
-		nick = who + 2;
-
-	b = purple_find_buddy(gc->account, nick);
-	if (b) {
-		/* See if we have this buddy's public key.  If we do use that
-		   to search the details. */
-		filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key");
-		if (filename) {
-			/* Call WHOIS.  The user info is displayed in the WHOIS
-			   command reply. */
-			silc_client_command_call(client, conn, NULL, "WHOIS",
-						 "-details", "-pubkey", filename, NULL);
-			return;
-		}
-
-		if (!b->proto_data) {
-			g_snprintf(tmp, sizeof(tmp),
-				   _("User %s is not present in the network"), b->name);
-			purple_notify_error(gc, _("User Information"),
-					  _("Cannot get user information"), tmp);
-			return;
-		}
-
-		client_entry = silc_client_get_client_by_id(client, conn, b->proto_data);
-		if (client_entry) {
-			/* Call WHOIS.  The user info is displayed in the WHOIS
-			   command reply. */
-			silc_client_command_call(client, conn, NULL, "WHOIS",
-						 client_entry->nickname, "-details", NULL);
-		}
-	} else {
-		/* Call WHOIS just with nickname. */
-		silc_client_command_call(client, conn, NULL, "WHOIS", nick, NULL);
-	}
-}
-
-static void
-silcpurple_add_buddy_pk_no(SilcPurpleBuddyRes r)
-{
-	char tmp[512];
-	g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not trusted"),
-		   r->b->name);
-	purple_notify_error(r->client->application, _("Add Buddy"), tmp,
-			  _("You cannot receive buddy notifications until you "
-			    "import his/her public key.  You can use the Get Public Key "
-			    "command to get the public key."));
-	purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_OFFLINE, NULL);
-}
-
-static void
-silcpurple_add_buddy_save(bool success, void *context)
-{
-	SilcPurpleBuddyRes r = context;
-	PurpleBuddy *b = r->b;
-	SilcClient client = r->client;
-	SilcClientEntry client_entry;
-	SilcAttributePayload attr;
-	SilcAttribute attribute;
-	SilcVCardStruct vcard;
-	SilcAttributeObjMime message, extension;
-#ifdef SILC_ATTRIBUTE_USER_ICON
-	SilcAttributeObjMime usericon;
-#endif
-	SilcAttributeObjPk serverpk, usersign, serversign;
-	gboolean usign_success = TRUE, ssign_success = TRUE;
-	char filename[512], filename2[512], *fingerprint = NULL, *tmp;
-	SilcUInt32 len;
-	int i;
-
-	if (!success) {
-		/* The user did not trust the public key. */
-		silcpurple_add_buddy_pk_no(r);
-		silc_free(r);
-		return;
-	}
-
-	if (r->offline) {
-		/* User is offline.  Associate the imported public key with
-		   this user. */
-		fingerprint = silc_hash_fingerprint(NULL, r->offline_pk,
-						    r->offline_pk_len);
-		for (i = 0; i < strlen(fingerprint); i++)
-			if (fingerprint[i] == ' ')
-				fingerprint[i] = '_';
-		g_snprintf(filename, sizeof(filename) - 1,
-			   "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub",
-			   silcpurple_silcdir(), fingerprint);
-		purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename);
-		purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_OFFLINE, NULL);
-		silc_free(fingerprint);
-		silc_free(r->offline_pk);
-		silc_free(r);
-		return;
-	}
-
-	/* Get the client entry. */
-	client_entry = silc_client_get_client_by_id(r->client, r->conn,
-						    &r->client_id);
-	if (!client_entry) {
-		silc_free(r);
-		return;
-	}
-
-	memset(&vcard, 0, sizeof(vcard));
-	memset(&message, 0, sizeof(message));
-	memset(&extension, 0, sizeof(extension));
-#ifdef SILC_ATTRIBUTE_USER_ICON
-	memset(&usericon, 0, sizeof(usericon));
-#endif
-	memset(&serverpk, 0, sizeof(serverpk));
-	memset(&usersign, 0, sizeof(usersign));
-	memset(&serversign, 0, sizeof(serversign));
-
-	/* Now that we have the public key and we trust it now we
-	   save the attributes of the buddy and update its status. */
-
-	if (client_entry->attrs) {
-		silc_dlist_start(client_entry->attrs);
-		while ((attr = silc_dlist_get(client_entry->attrs))
-		       != SILC_LIST_END) {
-			attribute = silc_attribute_get_attribute(attr);
-
-			switch (attribute) {
-			case SILC_ATTRIBUTE_USER_INFO:
-				if (!silc_attribute_get_object(attr, (void *)&vcard,
-							       sizeof(vcard)))
-					continue;
-				break;
-
-			case SILC_ATTRIBUTE_STATUS_MESSAGE:
-				if (!silc_attribute_get_object(attr, (void *)&message,
-							       sizeof(message)))
-					continue;
-				break;
-
-			case SILC_ATTRIBUTE_EXTENSION:
-				if (!silc_attribute_get_object(attr, (void *)&extension,
-							       sizeof(extension)))
-					continue;
-				break;
-
-#ifdef SILC_ATTRIBUTE_USER_ICON
-			case SILC_ATTRIBUTE_USER_ICON:
-				if (!silc_attribute_get_object(attr, (void *)&usericon,
-							       sizeof(usericon)))
-					continue;
-				break;
-#endif
-
-			case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
-				if (serverpk.type)
-					continue;
-				if (!silc_attribute_get_object(attr, (void *)&serverpk,
-							       sizeof(serverpk)))
-					continue;
-				break;
-
-			case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE:
-				if (usersign.data)
-					continue;
-				if (!silc_attribute_get_object(attr, (void *)&usersign,
-							       sizeof(usersign)))
-					continue;
-				break;
-
-			case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE:
-				if (serversign.data)
-					continue;
-				if (!silc_attribute_get_object(attr, (void *)&serversign,
-							       sizeof(serversign)))
-					continue;
-				break;
-
-			default:
-				break;
-			}
-		}
-	}
-
-	/* Verify the attribute signatures */
-
-	if (usersign.data) {
-		SilcPKCS pkcs;
-		unsigned char *verifyd;
-		SilcUInt32 verify_len;
-
-		silc_pkcs_alloc((unsigned char*)"rsa", &pkcs);
-		verifyd = silc_attribute_get_verify_data(client_entry->attrs,
-							 FALSE, &verify_len);
-		if (verifyd && silc_pkcs_public_key_set(pkcs, client_entry->public_key)){
-			if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash,
-							usersign.data,
-							usersign.data_len,
-							verifyd, verify_len))
-				usign_success = FALSE;
-		}
-		silc_free(verifyd);
-	}
-
-	if (serversign.data && !strcmp(serverpk.type, "silc-rsa")) {
-		SilcPublicKey public_key;
-		SilcPKCS pkcs;
-		unsigned char *verifyd;
-		SilcUInt32 verify_len;
-
-		if (silc_pkcs_public_key_decode(serverpk.data, serverpk.data_len,
-						&public_key)) {
-			silc_pkcs_alloc((unsigned char *)"rsa", &pkcs);
-			verifyd = silc_attribute_get_verify_data(client_entry->attrs,
-								 TRUE, &verify_len);
-			if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)) {
-				if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash,
-							       serversign.data,
-							       serversign.data_len,
-							       verifyd, verify_len))
-					ssign_success = FALSE;
-			}
-			silc_pkcs_public_key_free(public_key);
-			silc_free(verifyd);
-		}
-	}
-
-	fingerprint = silc_fingerprint(client_entry->fingerprint,
-				       client_entry->fingerprint_len);
-	for (i = 0; i < strlen(fingerprint); i++)
-		if (fingerprint[i] == ' ')
-			fingerprint[i] = '_';
-
-	if (usign_success || ssign_success) {
-		struct passwd *pw;
-		struct stat st;
-
-		memset(filename2, 0, sizeof(filename2));
-
-		/* Filename for dir */
-		tmp = fingerprint + strlen(fingerprint) - 9;
-		g_snprintf(filename, sizeof(filename) - 1,
-			   "%s" G_DIR_SEPARATOR_S "friends" G_DIR_SEPARATOR_S "%s",
-			   silcpurple_silcdir(), tmp);
-
-		pw = getpwuid(getuid());
-		if (!pw)
-			return;
-
-		/* Create dir if it doesn't exist */
-		if ((g_stat(filename, &st)) == -1) {
-			if (errno == ENOENT) {
-				if (pw->pw_uid == geteuid()) {
-					int ret = g_mkdir(filename, 0755);
-					if (ret < 0)
-						return;
-				}
-			}
-		}
-
-		/* Save VCard */
-		g_snprintf(filename2, sizeof(filename2) - 1,
-			   "%s" G_DIR_SEPARATOR_S "vcard", filename);
-		if (vcard.full_name) {
-			tmp = (char *)silc_vcard_encode(&vcard, &len);
-			silc_file_writefile(filename2, tmp, len);
-			silc_free(tmp);
-		}
-
-		/* Save status message */
-		if (message.mime) {
-			memset(filename2, 0, sizeof(filename2));
-			g_snprintf(filename2, sizeof(filename2) - 1,
-				   "%s" G_DIR_SEPARATOR_S "status_message.mime",
-				   filename);
-			silc_file_writefile(filename2, (char *)message.mime,
-					    message.mime_len);
-		}
-
-		/* Save extension data */
-		if (extension.mime) {
-			memset(filename2, 0, sizeof(filename2));
-			g_snprintf(filename2, sizeof(filename2) - 1,
-				   "%s" G_DIR_SEPARATOR_S "extension.mime",
-				   filename);
-			silc_file_writefile(filename2, (char *)extension.mime,
-					    extension.mime_len);
-		}
-
-#ifdef SILC_ATTRIBUTE_USER_ICON
-		/* Save user icon */
-		if (usericon.mime) {
-			SilcMime m = silc_mime_decode(usericon.mime,
-						      usericon.mime_len);
-			if (m) {
-				const char *type = silc_mime_get_field(m, "Content-Type");
-				if (!strcmp(type, "image/jpeg") ||
-				    !strcmp(type, "image/gif") ||
-				    !strcmp(type, "image/bmp") ||
-				    !strcmp(type, "image/png")) {
-					const unsigned char *data;
-					SilcUInt32 data_len;
-					data = silc_mime_get_data(m, &data_len);
-					if (data) {
-						/* TODO: Check if SILC gives us something to use as the checksum instead */
-						purple_buddy_icons_set_for_user(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), g_memdup(data, data_len), data_len, NULL);
-					}
-				}
-				silc_mime_free(m);
-			}
-		}
-#endif
-	}
-
-	/* Save the public key path to buddy properties, as it is used
-	   to identify the buddy in the network (and not the nickname). */
-	memset(filename, 0, sizeof(filename));
-	g_snprintf(filename, sizeof(filename) - 1,
-		   "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub",
-		   silcpurple_silcdir(), fingerprint);
-	purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename);
-
-	/* Update online status */
-	purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL);
-
-	/* Finally, start watching this user so we receive its status
-	   changes from the server */
-	g_snprintf(filename2, sizeof(filename2) - 1, "+%s", filename);
-	silc_client_command_call(r->client, r->conn, NULL, "WATCH", "-pubkey",
-				 filename2, NULL);
-
-	silc_free(fingerprint);
-	silc_free(r);
-}
-
-static void
-silcpurple_add_buddy_ask_import(void *user_data, const char *name)
-{
-	SilcPurpleBuddyRes r = (SilcPurpleBuddyRes)user_data;
-	SilcPublicKey public_key;
-
-	/* Load the public key */
-	if (!silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_PEM) &&
-	    !silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_BIN)) {
-		silcpurple_add_buddy_ask_pk_cb(r, 0);
-		purple_notify_error(r->client->application,
-				  _("Add Buddy"), _("Could not load public key"), NULL);
-		return;
-	}
-
-	/* Now verify the public key */
-	r->offline_pk = silc_pkcs_public_key_encode(public_key, &r->offline_pk_len);
-	silcpurple_verify_public_key(r->client, r->conn, r->b->name,
-				   SILC_SOCKET_TYPE_CLIENT,
-				   r->offline_pk, r->offline_pk_len,
-				   SILC_SKE_PK_TYPE_SILC,
-				   silcpurple_add_buddy_save, r);
-}
-
-static void
-silcpurple_add_buddy_ask_pk_cancel(void *user_data, const char *name)
-{
-	SilcPurpleBuddyRes r = (SilcPurpleBuddyRes)user_data;
-
-	/* The user did not import public key.  The buddy is unusable. */
-	silcpurple_add_buddy_pk_no(r);
-	silc_free(r);
-}
-
-static void
-silcpurple_add_buddy_ask_pk_cb(SilcPurpleBuddyRes r, gint id)
-{
-	if (id != 0) {
-		/* The user did not import public key.  The buddy is unusable. */
-		silcpurple_add_buddy_pk_no(r);
-		silc_free(r);
-		return;
-	}
-
-	/* Open file selector to select the public key. */
-	purple_request_file(r->client->application, _("Open..."), NULL, FALSE,
-			  G_CALLBACK(silcpurple_add_buddy_ask_import),
-			  G_CALLBACK(silcpurple_add_buddy_ask_pk_cancel),
-			  purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r);
-
-}
-
-static void
-silcpurple_add_buddy_ask_pk(SilcPurpleBuddyRes r)
-{
-	char tmp[512];
-	g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not present in the network"),
-		   r->b->name);
-	purple_request_action(r->client->application, _("Add Buddy"), tmp,
-			    _("To add the buddy you must import his/her public key. "
-			      "Press Import to import a public key."), 0,
-				  purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r, 2,
-			    _("Cancel"), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb),
-			    _("_Import..."), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb));
-}
-
-static void
-silcpurple_add_buddy_getkey_cb(SilcPurpleBuddyRes r,
-			     SilcClientCommandReplyContext cmd)
-{
-	SilcClientEntry client_entry;
-	unsigned char *pk;
-	SilcUInt32 pk_len;
-
-	/* Get the client entry. */
-	client_entry = silc_client_get_client_by_id(r->client, r->conn,
-						    &r->client_id);
-	if (!client_entry || !client_entry->public_key) {
-		/* The buddy is offline/nonexistent. We will require user
-		   to associate a public key with the buddy or the buddy
-		   cannot be added. */
-		r->offline = TRUE;
-		silcpurple_add_buddy_ask_pk(r);
-		return;
-	}
-
-	/* Now verify the public key */
-	pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len);
-	silcpurple_verify_public_key(r->client, r->conn, client_entry->nickname,
-				   SILC_SOCKET_TYPE_CLIENT,
-				   pk, pk_len, SILC_SKE_PK_TYPE_SILC,
-				   silcpurple_add_buddy_save, r);
-	silc_free(pk);
-}
-
-static void
-silcpurple_add_buddy_select_cb(SilcPurpleBuddyRes r, PurpleRequestFields *fields)
-{
-	PurpleRequestField *f;
-	GList *list;
-	SilcClientEntry client_entry;
-
-	f = purple_request_fields_get_field(fields, "list");
-	list = purple_request_field_list_get_selected(f);
-	if (!list) {
-		/* The user did not select any user. */
-		silcpurple_add_buddy_pk_no(r);
-		silc_free(r);
-		return;
-	}
-
-	client_entry = purple_request_field_list_get_data(f, list->data);
-	silcpurple_add_buddy_resolved(r->client, r->conn, &client_entry, 1, r);
-}
-
-static void
-silcpurple_add_buddy_select_cancel(SilcPurpleBuddyRes r, PurpleRequestFields *fields)
-{
-	/* The user did not select any user. */
-	silcpurple_add_buddy_pk_no(r);
-	silc_free(r);
-}
-
-static void
-silcpurple_add_buddy_select(SilcPurpleBuddyRes r,
-			  SilcClientEntry *clients,
-			  SilcUInt32 clients_count)
-{
-	PurpleRequestFields *fields;
-	PurpleRequestFieldGroup *g;
-	PurpleRequestField *f;
-	char tmp[512], tmp2[128];
-	int i;
-	char *fingerprint;
-
-	fields = purple_request_fields_new();
-	g = purple_request_field_group_new(NULL);
-	f = purple_request_field_list_new("list", NULL);
-	purple_request_field_group_add_field(g, f);
-	purple_request_field_list_set_multi_select(f, FALSE);
-	purple_request_fields_add_group(fields, g);
-
-	for (i = 0; i < clients_count; i++) {
-		fingerprint = NULL;
-		if (clients[i]->fingerprint) {
-			fingerprint = silc_fingerprint(clients[i]->fingerprint,
-						       clients[i]->fingerprint_len);
-			g_snprintf(tmp2, sizeof(tmp2), "\n%s", fingerprint);
-		}
-		g_snprintf(tmp, sizeof(tmp), "%s - %s (%s@%s)%s",
-			   clients[i]->realname, clients[i]->nickname,
-			   clients[i]->username, clients[i]->hostname ?
-			   clients[i]->hostname : "",
-			   fingerprint ? tmp2 : "");
-		purple_request_field_list_add_icon(f, tmp, NULL, clients[i]);
-		silc_free(fingerprint);
-	}
-
-	purple_request_fields(r->client->application, _("Add Buddy"),
-				_("Select correct user"),
-				r->pubkey_search
-					? _("More than one user was found with the same public key. Select "
-						"the correct user from the list to add to the buddy list.")
-					: _("More than one user was found with the same name. Select "
-						"the correct user from the list to add to the buddy list."),
-				fields,
-				_("OK"), G_CALLBACK(silcpurple_add_buddy_select_cb),
-				_("Cancel"), G_CALLBACK(silcpurple_add_buddy_select_cancel),
-				purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r);
-}
-
-static void
-silcpurple_add_buddy_resolved(SilcClient client,
-			    SilcClientConnection conn,
-			    SilcClientEntry *clients,
-			    SilcUInt32 clients_count,
-			    void *context)
-{
-	SilcPurpleBuddyRes r = context;
-	PurpleBuddy *b = r->b;
-	SilcAttributePayload pub;
-	SilcAttributeObjPk userpk;
-	unsigned char *pk;
-	SilcUInt32 pk_len;
-	const char *filename;
-
-	filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key");
-
-	/* If the buddy is offline/nonexistent, we will require user
-	   to associate a public key with the buddy or the buddy
-	   cannot be added. */
-	if (!clients_count) {
-		if (r->init) {
-			silc_free(r);
-			return;
-		}
-
-		r->offline = TRUE;
-		/* If the user has already associated a public key, try loading it
-		 * before prompting the user to load it again */
-		if (filename != NULL)
-			silcpurple_add_buddy_ask_import(r, filename);
-		else
-			silcpurple_add_buddy_ask_pk(r);
-		return;
-	}
-
-	/* If more than one client was found with nickname, we need to verify
-	   from user which one is the correct. */
-	if (clients_count > 1 && !r->pubkey_search) {
-		if (r->init) {
-			silc_free(r);
-			return;
-		}
-
-		silcpurple_add_buddy_select(r, clients, clients_count);
-		return;
-	}
-
-	/* If we searched using public keys and more than one entry was found
-	   the same person is logged on multiple times. */
-	if (clients_count > 1 && r->pubkey_search && b->name) {
-		if (r->init) {
-			/* Find the entry that closest matches to the
-			   buddy nickname. */
-			int i;
-			for (i = 0; i < clients_count; i++) {
-				if (!g_ascii_strncasecmp(b->name, clients[i]->nickname,
-						 strlen(b->name))) {
-					clients[0] = clients[i];
-					break;
-				}
-			}
-		} else {
-			/* Verify from user which one is correct */
-			silcpurple_add_buddy_select(r, clients, clients_count);
-			return;
-		}
-	}
-
-	/* The client was found.  Now get its public key and verify
-	   that before adding the buddy. */
-	memset(&userpk, 0, sizeof(userpk));
-	b->proto_data = silc_memdup(clients[0]->id, sizeof(*clients[0]->id));
-	r->client_id = *clients[0]->id;
-
-	/* Get the public key from attributes, if not present then
-	   resolve it with GETKEY unless we have it cached already. */
-	if (clients[0]->attrs && !clients[0]->public_key) {
-		pub = silcpurple_get_attr(clients[0]->attrs,
-					SILC_ATTRIBUTE_USER_PUBLIC_KEY);
-		if (!pub || !silc_attribute_get_object(pub, (void *)&userpk,
-						       sizeof(userpk))) {
-			/* Get public key with GETKEY */
-			silc_client_command_call(client, conn, NULL,
-						 "GETKEY", clients[0]->nickname, NULL);
-			silc_client_command_pending(conn, SILC_COMMAND_GETKEY,
-						    conn->cmd_ident,
-						    (SilcCommandCb)silcpurple_add_buddy_getkey_cb,
-						    r);
-			return;
-		}
-		if (!silc_pkcs_public_key_decode(userpk.data, userpk.data_len,
-						 &clients[0]->public_key))
-			return;
-		silc_free(userpk.data);
-	} else if (filename && !clients[0]->public_key) {
-		if (!silc_pkcs_load_public_key(filename, &clients[0]->public_key,
-					       SILC_PKCS_FILE_PEM) &&
-		    !silc_pkcs_load_public_key(filename, &clients[0]->public_key,
-					       SILC_PKCS_FILE_BIN)) {
-			/* Get public key with GETKEY */
-			silc_client_command_call(client, conn, NULL,
-						 "GETKEY", clients[0]->nickname, NULL);
-			silc_client_command_pending(conn, SILC_COMMAND_GETKEY,
-						    conn->cmd_ident,
-						    (SilcCommandCb)silcpurple_add_buddy_getkey_cb,
-						    r);
-			return;
-		}
-	} else if (!clients[0]->public_key) {
-		/* Get public key with GETKEY */
-		silc_client_command_call(client, conn, NULL,
-					 "GETKEY", clients[0]->nickname, NULL);
-		silc_client_command_pending(conn, SILC_COMMAND_GETKEY,
-					    conn->cmd_ident,
-					    (SilcCommandCb)silcpurple_add_buddy_getkey_cb,
-					    r);
-		return;
-	}
-
-	/* We have the public key, verify it. */
-	pk = silc_pkcs_public_key_encode(clients[0]->public_key, &pk_len);
-	silcpurple_verify_public_key(client, conn, clients[0]->nickname,
-				   SILC_SOCKET_TYPE_CLIENT,
-				   pk, pk_len, SILC_SKE_PK_TYPE_SILC,
-				   silcpurple_add_buddy_save, r);
-	silc_free(pk);
-}
-
-static void
-silcpurple_add_buddy_i(PurpleConnection *gc, PurpleBuddy *b, gboolean init)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcPurpleBuddyRes r;
-	SilcBuffer attrs;
-	const char *filename, *name = b->name;
-
-	r = silc_calloc(1, sizeof(*r));
-	if (!r)
-		return;
-	r->client = client;
-	r->conn = conn;
-	r->b = b;
-	r->init = init;
-
-	/* See if we have this buddy's public key.  If we do use that
-	   to search the details. */
-	filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key");
-	if (filename) {
-		SilcPublicKey public_key;
-		SilcAttributeObjPk userpk;
-
-		if (!silc_pkcs_load_public_key(filename, &public_key,
-					       SILC_PKCS_FILE_PEM) &&
-		    !silc_pkcs_load_public_key(filename, &public_key,
-					       SILC_PKCS_FILE_BIN))
-			return;
-
-		/* Get all attributes, and use the public key to search user */
-		name = NULL;
-		attrs = silc_client_attributes_request(SILC_ATTRIBUTE_USER_INFO,
-						       SILC_ATTRIBUTE_SERVICE,
-						       SILC_ATTRIBUTE_STATUS_MOOD,
-						       SILC_ATTRIBUTE_STATUS_FREETEXT,
-						       SILC_ATTRIBUTE_STATUS_MESSAGE,
-						       SILC_ATTRIBUTE_PREFERRED_LANGUAGE,
-						       SILC_ATTRIBUTE_PREFERRED_CONTACT,
-						       SILC_ATTRIBUTE_TIMEZONE,
-						       SILC_ATTRIBUTE_GEOLOCATION,
-#ifdef SILC_ATTRIBUTE_USER_ICON
-						       SILC_ATTRIBUTE_USER_ICON,
-#endif
-						       SILC_ATTRIBUTE_DEVICE_INFO, 0);
-		userpk.type = "silc-rsa";
-		userpk.data = silc_pkcs_public_key_encode(public_key, &userpk.data_len);
-		attrs = silc_attribute_payload_encode(attrs,
-						      SILC_ATTRIBUTE_USER_PUBLIC_KEY,
-						      SILC_ATTRIBUTE_FLAG_VALID,
-						      &userpk, sizeof(userpk));
-		silc_free(userpk.data);
-		silc_pkcs_public_key_free(public_key);
-		r->pubkey_search = TRUE;
-	} else {
-		/* Get all attributes */
-		attrs = silc_client_attributes_request(0);
-	}
-
-	/* Resolve */
-	silc_client_get_clients_whois(client, conn, name, NULL, attrs,
-				      silcpurple_add_buddy_resolved, r);
-	silc_buffer_free(attrs);
-}
-
-void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
-{
-	/* Don't add if the buddy is already on the list.
-	 *
-	 * SILC doesn't have groups, so we don't need to do anything
-	 * for a move. */
-	if (purple_buddy_get_protocol_data(buddy) == NULL)
-		silcpurple_add_buddy_i(gc, buddy, FALSE);
-}
-
-void silcpurple_send_buddylist(PurpleConnection *gc)
-{
-	PurpleBuddyList *blist;
-	PurpleBlistNode *gnode, *cnode, *bnode;
-	PurpleBuddy *buddy;
-	PurpleAccount *account;
-
-	account = purple_connection_get_account(gc);
-
-	if ((blist = purple_get_blist()) != NULL)
-	{
-		for (gnode = blist->root; gnode != NULL; gnode = gnode->next)
-		{
-			if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))
-				continue;
-			for (cnode = gnode->child; cnode != NULL; cnode = cnode->next)
-			{
-				if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode))
-					continue;
-				for (bnode = cnode->child; bnode != NULL; bnode = bnode->next)
-				{
-					if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
-						continue;
-					buddy = (PurpleBuddy *)bnode;
-					if (purple_buddy_get_account(buddy) == account)
-						silcpurple_add_buddy_i(gc, buddy, TRUE);
-				}
-			}
-		}
-	}
-}
-
-void silcpurple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
-			   PurpleGroup *group)
-{
-	silc_free(buddy->proto_data);
-}
-
-void silcpurple_idle_set(PurpleConnection *gc, int idle)
-
-{
-	SilcPurple sg;
-	SilcClient client;
-	SilcClientConnection conn;
-	SilcAttributeObjService service;
-	const char *server;
-	int port;
-
-	sg = gc->proto_data;
-	if (sg == NULL)
-		return;
-
-	client = sg->client;
-	if (client == NULL)
-		return;
-
-	conn = sg->conn;
-	if (conn == NULL)
-		return;
-
-	server = purple_account_get_string(sg->account, "server",
-					 "silc.silcnet.org");
-	port = purple_account_get_int(sg->account, "port", 706),
-
-	memset(&service, 0, sizeof(service));
-	silc_client_attribute_del(client, conn,
-				  SILC_ATTRIBUTE_SERVICE, NULL);
-	service.port = port;
-	g_snprintf(service.address, sizeof(service.address), "%s", server);
-	service.idle = idle;
-	silc_client_attribute_add(client, conn, SILC_ATTRIBUTE_SERVICE,
-				  &service, sizeof(service));
-}
-
-char *silcpurple_status_text(PurpleBuddy *b)
-{
-	SilcPurple sg = b->account->gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcClientID *client_id = b->proto_data;
-	SilcClientEntry client_entry;
-	SilcAttributePayload attr;
-	SilcAttributeMood mood = 0;
-
-	/* Get the client entry. */
-	client_entry = silc_client_get_client_by_id(client, conn, client_id);
-	if (!client_entry)
-		return NULL;
-
-	/* If user is online, we show the mood status, if available.
-	   If user is offline or away that status is indicated. */
-
-	if (client_entry->mode & SILC_UMODE_DETACHED)
-		return g_strdup(_("Detached"));
-	if (client_entry->mode & SILC_UMODE_GONE)
-		return g_strdup(_("Away"));
-	if (client_entry->mode & SILC_UMODE_INDISPOSED)
-		return g_strdup(_("Indisposed"));
-	if (client_entry->mode & SILC_UMODE_BUSY)
-		return g_strdup(_("Busy"));
-	if (client_entry->mode & SILC_UMODE_PAGE)
-		return g_strdup(_("Wake Me Up"));
-	if (client_entry->mode & SILC_UMODE_HYPER)
-		return g_strdup(_("Hyper Active"));
-	if (client_entry->mode & SILC_UMODE_ROBOT)
-		return g_strdup(_("Robot"));
-
-	attr = silcpurple_get_attr(client_entry->attrs, SILC_ATTRIBUTE_STATUS_MOOD);
-	if (attr && silc_attribute_get_object(attr, &mood, sizeof(mood))) {
-		/* The mood is a bit mask, so we could show multiple moods,
-		   but let's show only one for now. */
-		if (mood & SILC_ATTRIBUTE_MOOD_HAPPY)
-			return g_strdup(_("Happy"));
-		if (mood & SILC_ATTRIBUTE_MOOD_SAD)
-			return g_strdup(_("Sad"));
-		if (mood & SILC_ATTRIBUTE_MOOD_ANGRY)
-			return g_strdup(_("Angry"));
-		if (mood & SILC_ATTRIBUTE_MOOD_JEALOUS)
-			return g_strdup(_("Jealous"));
-		if (mood & SILC_ATTRIBUTE_MOOD_ASHAMED)
-			return g_strdup(_("Ashamed"));
-		if (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE)
-			return g_strdup(_("Invincible"));
-		if (mood & SILC_ATTRIBUTE_MOOD_INLOVE)
-			return g_strdup(_("In Love"));
-		if (mood & SILC_ATTRIBUTE_MOOD_SLEEPY)
-			return g_strdup(_("Sleepy"));
-		if (mood & SILC_ATTRIBUTE_MOOD_BORED)
-			return g_strdup(_("Bored"));
-		if (mood & SILC_ATTRIBUTE_MOOD_EXCITED)
-			return g_strdup(_("Excited"));
-		if (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS)
-			return g_strdup(_("Anxious"));
-	}
-
-	return NULL;
-}
-
-void silcpurple_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full)
-{
-	SilcPurple sg = b->account->gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcClientID *client_id = b->proto_data;
-	SilcClientEntry client_entry;
-	char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr;
-	char tmp[256];
-
-	/* Get the client entry. */
-	client_entry = silc_client_get_client_by_id(client, conn, client_id);
-	if (!client_entry)
-		return;
-
-	if (client_entry->nickname)
-		purple_notify_user_info_add_pair(user_info, _("Nickname"),
-					       client_entry->nickname);
-	if (client_entry->username && client_entry->hostname) {
-		g_snprintf(tmp, sizeof(tmp), "%s@%s", client_entry->username, client_entry->hostname);
-		purple_notify_user_info_add_pair(user_info, _("Username"), tmp);
-	}
-	if (client_entry->mode) {
-		memset(tmp, 0, sizeof(tmp));
-		silcpurple_get_umode_string(client_entry->mode,
-					  tmp, sizeof(tmp) - strlen(tmp));
-		purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp);
-	}
-
-	silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr);
-
-	if (statusstr) {
-		purple_notify_user_info_add_pair(user_info, _("Message"), statusstr);
-		g_free(statusstr);
-	}
-
-	if (full) {
-		if (moodstr) {
-			purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr);
-			g_free(moodstr);
-		}
-
-		if (contactstr) {
-			purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr);
-			g_free(contactstr);
-		}
-
-		if (langstr) {
-			purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr);
-			g_free(langstr);
-		}
-
-		if (devicestr) {
-			purple_notify_user_info_add_pair(user_info, _("Device"), devicestr);
-			g_free(devicestr);
-		}
-
-		if (tzstr) {
-			purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr);
-			g_free(tzstr);
-		}
-
-		if (geostr) {
-			purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr);
-			g_free(geostr);
-		}
-	}
-}
-
-static void
-silcpurple_buddy_kill(PurpleBlistNode *node, gpointer data)
-{
-	PurpleBuddy *b;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
-	b = (PurpleBuddy *) node;
-	gc = purple_account_get_connection(b->account);
-	sg = gc->proto_data;
-
-	/* Call KILL */
-	silc_client_command_call(sg->client, sg->conn, NULL, "KILL",
-				 b->name, "Killed by operator", NULL);
-}
-
-typedef struct {
-	SilcPurple sg;
-	SilcClientEntry client_entry;
-} *SilcPurpleBuddyWb;
-
-static void
-silcpurple_buddy_wb(PurpleBlistNode *node, gpointer data)
-{
-	SilcPurpleBuddyWb wb = data;
-	silcpurple_wb_init(wb->sg, wb->client_entry);
-	silc_free(wb);
-}
-
-GList *silcpurple_buddy_menu(PurpleBuddy *buddy)
-{
-	PurpleConnection *gc = purple_account_get_connection(buddy->account);
-	SilcPurple sg = gc->proto_data;
-	SilcClientConnection conn = sg->conn;
-	const char *pkfile = NULL;
-	SilcClientEntry client_entry = NULL;
-	PurpleMenuAction *act;
-	GList *m = NULL;
-	SilcPurpleBuddyWb wb;
-
-	pkfile = purple_blist_node_get_string((PurpleBlistNode *) buddy, "public-key");
-	client_entry = silc_client_get_client_by_id(sg->client,
-						    sg->conn,
-						    buddy->proto_data);
-
-	if (client_entry && client_entry->send_key) {
-		act = purple_menu_action_new(_("Reset IM Key"),
-		                           PURPLE_CALLBACK(silcpurple_buddy_resetkey),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
-
-	} else {
-		act = purple_menu_action_new(_("IM with Key Exchange"),
-		                           PURPLE_CALLBACK(silcpurple_buddy_keyagr),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
-
-		act = purple_menu_action_new(_("IM with Password"),
-		                           PURPLE_CALLBACK(silcpurple_buddy_privkey_menu),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
-	}
-
-	if (pkfile) {
-		act = purple_menu_action_new(_("Show Public Key"),
-		                           PURPLE_CALLBACK(silcpurple_buddy_showkey),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
-
-	} else {
-		act = purple_menu_action_new(_("Get Public Key..."),
-		                           PURPLE_CALLBACK(silcpurple_buddy_getkey_menu),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
-	}
-
-	if (conn && conn->local_entry->mode & SILC_UMODE_ROUTER_OPERATOR) {
-		act = purple_menu_action_new(_("Kill User"),
-		                           PURPLE_CALLBACK(silcpurple_buddy_kill),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
-	}
-
-	if (client_entry) {
-		wb = silc_calloc(1, sizeof(*wb));
-		wb->sg = sg;
-		wb->client_entry = client_entry;
-		act = purple_menu_action_new(_("Draw On Whiteboard"),
-		                           PURPLE_CALLBACK(silcpurple_buddy_wb),
-		                           (void *)wb, NULL);
-		m = g_list_append(m, act);
-	}
-	return m;
-}
-
-#ifdef SILC_ATTRIBUTE_USER_ICON
-void silcpurple_buddy_set_icon(PurpleConnection *gc, PurpleStoredImage *img)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcMime mime;
-	char type[32];
-	unsigned char *icon;
-	const char *t;
-	SilcAttributeObjMime obj;
-
-	/* Remove */
-	if (!img) {
-		silc_client_attribute_del(client, conn,
-					  SILC_ATTRIBUTE_USER_ICON, NULL);
-		return;
-	}
-
-	/* Add */
-	mime = silc_mime_alloc();
-	if (!mime)
-		return;
-
-	t = purple_imgstore_get_extension(img);
-	if (!t || !strcmp(t, "icon")) {
-		silc_mime_free(mime);
-		return;
-	}
-	if (!strcmp(t, "jpg"))
-		t = "jpeg";
-	g_snprintf(type, sizeof(type), "image/%s", t);
-	silc_mime_add_field(mime, "Content-Type", type);
-	silc_mime_add_data(mime, purple_imgstore_get_data(img), purple_imgstore_get_size(img));
-
-	obj.mime = icon = silc_mime_encode(mime, &obj.mime_len);
-	if (obj.mime)
-		silc_client_attribute_add(client, conn,
-					  SILC_ATTRIBUTE_USER_ICON, &obj, sizeof(obj));
-
-	silc_free(icon);
-	silc_mime_free(mime);
-}
-#endif
--- a/libpurple/protocols/silc10/chat.c	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1456 +0,0 @@
-/*
-
-  silcpurple_chat.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2004 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "wb.h"
-
-/***************************** Channel Routines ******************************/
-
-GList *silcpurple_chat_info(PurpleConnection *gc)
-{
-	GList *ci = NULL;
-	struct proto_chat_entry *pce;
-
-	pce = g_new0(struct proto_chat_entry, 1);
-	pce->label = _("_Channel:");
-	pce->identifier = "channel";
-	pce->required = TRUE;
-	ci = g_list_append(ci, pce);
-
-	pce = g_new0(struct proto_chat_entry, 1);
-	pce->label = _("_Passphrase:");
-	pce->identifier = "passphrase";
-	pce->secret = TRUE;
-	ci = g_list_append(ci, pce);
-
-	return ci;
-}
-
-GHashTable *silcpurple_chat_info_defaults(PurpleConnection *gc, const char *chat_name)
-{
-	GHashTable *defaults;
-
-	defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
-
-	if (chat_name != NULL)
-		g_hash_table_insert(defaults, "channel", g_strdup(chat_name));
-
-	return defaults;
-}
-
-static void
-silcpurple_chat_getinfo(PurpleConnection *gc, GHashTable *components);
-
-static void
-silcpurple_chat_getinfo_res(SilcClient client,
-			  SilcClientConnection conn,
-			  SilcChannelEntry *channels,
-			  SilcUInt32 channels_count,
-			  void *context)
-{
-	GHashTable *components = context;
-	PurpleConnection *gc = client->application;
-	const char *chname;
-	char tmp[256];
-
-	chname = g_hash_table_lookup(components, "channel");
-	if (!chname)
-		return;
-
-	if (!channels) {
-		g_snprintf(tmp, sizeof(tmp),
-			   _("Channel %s does not exist in the network"), chname);
-		purple_notify_error(gc, _("Channel Information"),
-				  _("Cannot get channel information"), tmp);
-		return;
-	}
-
-	silcpurple_chat_getinfo(gc, components);
-}
-
-
-static void
-silcpurple_chat_getinfo(PurpleConnection *gc, GHashTable *components)
-{
-	SilcPurple sg = gc->proto_data;
-	const char *chname;
-	char *buf, tmp[256], *tmp2;
-	GString *s;
-	SilcChannelEntry channel;
-	SilcHashTableList htl;
-	SilcChannelUser chu;
-
-	if (!components)
-		return;
-
-	chname = g_hash_table_lookup(components, "channel");
-	if (!chname)
-		return;
-	channel = silc_client_get_channel(sg->client, sg->conn,
-					  (char *)chname);
-	if (!channel) {
-		silc_client_get_channel_resolve(sg->client, sg->conn,
-						(char *)chname,
-						silcpurple_chat_getinfo_res,
-						components);
-		return;
-	}
-
-	s = g_string_new("");
-	tmp2 = g_markup_escape_text(channel->channel_name, -1);
-	g_string_append_printf(s, _("<b>Channel Name:</b> %s"), tmp2);
-	g_free(tmp2);
-	if (channel->user_list && silc_hash_table_count(channel->user_list))
-		g_string_append_printf(s, _("<br><b>User Count:</b> %d"),
-				       (int)silc_hash_table_count(channel->user_list));
-
-	silc_hash_table_list(channel->user_list, &htl);
-	while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-		if (chu->mode & SILC_CHANNEL_UMODE_CHANFO) {
-			tmp2 = g_markup_escape_text(chu->client->nickname, -1);
-			g_string_append_printf(s, _("<br><b>Channel Founder:</b> %s"),
-					       tmp2);
-			g_free(tmp2);
-			break;
-		}
-	}
-	silc_hash_table_list_reset(&htl);
-
-	if (channel->channel_key)
-		g_string_append_printf(s, _("<br><b>Channel Cipher:</b> %s"),
-				       silc_cipher_get_name(channel->channel_key));
-	if (channel->hmac)
-		/* Definition of HMAC: http://en.wikipedia.org/wiki/HMAC */
-		g_string_append_printf(s, _("<br><b>Channel HMAC:</b> %s"),
-				       silc_hmac_get_name(channel->hmac));
-
-	if (channel->topic) {
-		tmp2 = g_markup_escape_text(channel->topic, -1);
-		g_string_append_printf(s, _("<br><b>Channel Topic:</b><br>%s"), tmp2);
-		g_free(tmp2);
-	}
-
-	if (channel->mode) {
-		g_string_append_printf(s, _("<br><b>Channel Modes:</b> "));
-		silcpurple_get_chmode_string(channel->mode, tmp, sizeof(tmp));
-		g_string_append(s, tmp);
-	}
-
-	if (channel->founder_key) {
-		char *fingerprint, *babbleprint;
-		unsigned char *pk;
-		SilcUInt32 pk_len;
-		pk = silc_pkcs_public_key_encode(channel->founder_key, &pk_len);
-		fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-		babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
-
-		g_string_append_printf(s, _("<br><b>Founder Key Fingerprint:</b><br>%s"), fingerprint);
-		g_string_append_printf(s, _("<br><b>Founder Key Babbleprint:</b><br>%s"), babbleprint);
-
-		silc_free(fingerprint);
-		silc_free(babbleprint);
-		silc_free(pk);
-	}
-
-	buf = g_string_free(s, FALSE);
-	purple_notify_formatted(gc, NULL, _("Channel Information"), NULL, buf, NULL, NULL);
-	g_free(buf);
-}
-
-
-static void
-silcpurple_chat_getinfo_menu(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat = (PurpleChat *)node;
-	silcpurple_chat_getinfo(chat->account->gc, chat->components);
-}
-
-
-#if 0   /* XXX For now these are not implemented.  We need better
-	   listview dialog from Purple for these. */
-/************************** Channel Invite List ******************************/
-
-static void
-silcpurple_chat_invitelist(PurpleBlistNode *node, gpointer data);
-{
-
-}
-
-
-/**************************** Channel Ban List *******************************/
-
-static void
-silcpurple_chat_banlist(PurpleBlistNode *node, gpointer data);
-{
-
-}
-#endif
-
-
-/************************* Channel Authentication ****************************/
-
-typedef struct {
-	SilcPurple sg;
-	SilcChannelEntry channel;
-	PurpleChat *c;
-	SilcBuffer pubkeys;
-} *SilcPurpleChauth;
-
-static void
-silcpurple_chat_chpk_add(void *user_data, const char *name)
-{
-	SilcPurpleChauth sgc = (SilcPurpleChauth)user_data;
-	SilcPurple sg = sgc->sg;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcPublicKey public_key;
-	SilcBuffer chpks, pk, chidp;
-	unsigned char mode[4];
-	SilcUInt32 m;
-
-	/* Load the public key */
-	if (!silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_PEM) &&
-	    !silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_BIN)) {
-		silcpurple_chat_chauth_show(sgc->sg, sgc->channel, sgc->pubkeys);
-		silc_buffer_free(sgc->pubkeys);
-		silc_free(sgc);
-		purple_notify_error(client->application,
-				  _("Add Channel Public Key"),
-				  _("Could not load public key"), NULL);
-		return;
-	}
-
-	pk = silc_pkcs_public_key_payload_encode(public_key);
-	chpks = silc_buffer_alloc_size(2);
-	SILC_PUT16_MSB(1, chpks->head);
-	chpks = silc_argument_payload_encode_one(chpks, pk->data,
-						 pk->len, 0x00);
-	silc_buffer_free(pk);
-
-	m = sgc->channel->mode;
-	m |= SILC_CHANNEL_MODE_CHANNEL_AUTH;
-
-	/* Send CMODE */
-	SILC_PUT32_MSB(m, mode);
-	chidp = silc_id_payload_encode(sgc->channel->id, SILC_ID_CHANNEL);
-	silc_client_command_send(client, conn, SILC_COMMAND_CMODE,
-				 ++conn->cmd_ident, 3,
-				 1, chidp->data, chidp->len,
-				 2, mode, sizeof(mode),
-				 9, chpks->data, chpks->len);
-	silc_buffer_free(chpks);
-	silc_buffer_free(chidp);
-	silc_buffer_free(sgc->pubkeys);
-	silc_free(sgc);
-}
-
-static void
-silcpurple_chat_chpk_cancel(void *user_data, const char *name)
-{
-	SilcPurpleChauth sgc = (SilcPurpleChauth)user_data;
-	silcpurple_chat_chauth_show(sgc->sg, sgc->channel, sgc->pubkeys);
-	silc_buffer_free(sgc->pubkeys);
-	silc_free(sgc);
-}
-
-static void
-silcpurple_chat_chpk_cb(SilcPurpleChauth sgc, PurpleRequestFields *fields)
-{
-	SilcPurple sg = sgc->sg;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	PurpleRequestField *f;
-	GList *list;
-	SilcPublicKey public_key;
-	SilcBuffer chpks, pk, chidp;
-	SilcUInt16 c = 0, ct;
-	unsigned char mode[4];
-	SilcUInt32 m;
-
-	f = purple_request_fields_get_field(fields, "list");
-	if (!purple_request_field_list_get_selected(f)) {
-		/* Add new public key */
-		purple_request_file(sg->gc, _("Open Public Key..."), NULL, FALSE,
-				  G_CALLBACK(silcpurple_chat_chpk_add),
-				  G_CALLBACK(silcpurple_chat_chpk_cancel),
-				  purple_connection_get_account(sg->gc), NULL, NULL, sgc);
-		return;
-	}
-
-	list = purple_request_field_list_get_items(f);
-	chpks = silc_buffer_alloc_size(2);
-
-	for (ct = 0; list; list = list->next, ct++) {
-		public_key = purple_request_field_list_get_data(f, list->data);
-		if (purple_request_field_list_is_selected(f, list->data)) {
-			/* Delete this public key */
-			pk = silc_pkcs_public_key_payload_encode(public_key);
-			chpks = silc_argument_payload_encode_one(chpks, pk->data,
-								 pk->len, 0x01);
-			silc_buffer_free(pk);
-			c++;
-		}
-		silc_pkcs_public_key_free(public_key);
-	}
-	if (!c) {
-		silc_buffer_free(chpks);
-		return;
-	}
-	SILC_PUT16_MSB(c, chpks->head);
-
-	m = sgc->channel->mode;
-	if (ct == c)
-		m &= ~SILC_CHANNEL_MODE_CHANNEL_AUTH;
-
-	/* Send CMODE */
-	SILC_PUT32_MSB(m, mode);
-	chidp = silc_id_payload_encode(sgc->channel->id, SILC_ID_CHANNEL);
-	silc_client_command_send(client, conn, SILC_COMMAND_CMODE,
-				 ++conn->cmd_ident, 3,
-				 1, chidp->data, chidp->len,
-				 2, mode, sizeof(mode),
-				 9, chpks->data, chpks->len);
-	silc_buffer_free(chpks);
-	silc_buffer_free(chidp);
-	silc_buffer_free(sgc->pubkeys);
-	silc_free(sgc);
-}
-
-static void
-silcpurple_chat_chauth_ok(SilcPurpleChauth sgc, PurpleRequestFields *fields)
-{
-	SilcPurple sg = sgc->sg;
-	PurpleRequestField *f;
-	const char *curpass, *val;
-	int set;
-
-	f = purple_request_fields_get_field(fields, "passphrase");
-	val = purple_request_field_string_get_value(f);
-	curpass = purple_blist_node_get_string((PurpleBlistNode *)sgc->c, "passphrase");
-
-	if (!val && curpass)
-		set = 0;
-	else if (val && !curpass)
-		set = 1;
-	else if (val && curpass && strcmp(val, curpass))
-		set = 1;
-	else
-		set = -1;
-
-	if (set == 1) {
-		silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
-					 sgc->channel->channel_name, "+a", val, NULL);
-		purple_blist_node_set_string((PurpleBlistNode *)sgc->c, "passphrase", val);
-	} else if (set == 0) {
-		silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
-					 sgc->channel->channel_name, "-a", NULL);
-		purple_blist_node_remove_setting((PurpleBlistNode *)sgc->c, "passphrase");
-	}
-
-	silc_buffer_free(sgc->pubkeys);
-	silc_free(sgc);
-}
-
-void silcpurple_chat_chauth_show(SilcPurple sg, SilcChannelEntry channel,
-			       SilcBuffer channel_pubkeys)
-{
-	SilcUInt16 argc;
-	SilcArgumentPayload chpks;
-	unsigned char *pk;
-	SilcUInt32 pk_len, type;
-	char *fingerprint, *babbleprint;
-	SilcPublicKey pubkey;
-	SilcPublicKeyIdentifier ident;
-	char tmp2[1024], t[512];
-	PurpleRequestFields *fields;
-	PurpleRequestFieldGroup *g;
-	PurpleRequestField *f;
-	SilcPurpleChauth sgc;
-	const char *curpass = NULL;
-
-	sgc = silc_calloc(1, sizeof(*sgc));
-	if (!sgc)
-		return;
-	sgc->sg = sg;
-	sgc->channel = channel;
-
-	fields = purple_request_fields_new();
-
-	if (sgc->c)
-	  curpass = purple_blist_node_get_string((PurpleBlistNode *)sgc->c, "passphrase");
-
-	g = purple_request_field_group_new(NULL);
-	f = purple_request_field_string_new("passphrase", _("Channel Passphrase"),
-					  curpass, FALSE);
-	purple_request_field_string_set_masked(f, TRUE);
-	purple_request_field_group_add_field(g, f);
-	purple_request_fields_add_group(fields, g);
-
-	g = purple_request_field_group_new(NULL);
-	f = purple_request_field_label_new("l1", _("Channel Public Keys List"));
-	purple_request_field_group_add_field(g, f);
-	purple_request_fields_add_group(fields, g);
-
-	g_snprintf(t, sizeof(t),
-		   _("Channel authentication is used to secure the channel from "
-		     "unauthorized access. The authentication may be based on "
-		     "passphrase and digital signatures. If passphrase is set, it "
-		     "is required to be able to join. If channel public keys are set "
-		     "then only users whose public keys are listed are able to join."));
-
-	if (!channel_pubkeys) {
-		f = purple_request_field_list_new("list", NULL);
-		purple_request_field_group_add_field(g, f);
-		purple_request_fields(sg->gc, _("Channel Authentication"),
-				    _("Channel Authentication"), t, fields,
-				    _("Add / Remove"), G_CALLBACK(silcpurple_chat_chpk_cb),
-				    _("OK"), G_CALLBACK(silcpurple_chat_chauth_ok),
-					purple_connection_get_account(sg->gc), NULL, NULL, sgc);
-		return;
-	}
-	sgc->pubkeys = silc_buffer_copy(channel_pubkeys);
-
-	g = purple_request_field_group_new(NULL);
-	f = purple_request_field_list_new("list", NULL);
-	purple_request_field_group_add_field(g, f);
-	purple_request_fields_add_group(fields, g);
-
-	SILC_GET16_MSB(argc, channel_pubkeys->data);
-	chpks = silc_argument_payload_parse(channel_pubkeys->data + 2,
-					    channel_pubkeys->len - 2, argc);
-	if (!chpks)
-		return;
-
-	pk = silc_argument_get_first_arg(chpks, &type, &pk_len);
-	while (pk) {
-		fingerprint = silc_hash_fingerprint(NULL, pk + 4, pk_len - 4);
-		babbleprint = silc_hash_babbleprint(NULL, pk + 4, pk_len - 4);
-		silc_pkcs_public_key_payload_decode(pk, pk_len, &pubkey);
-		ident = silc_pkcs_decode_identifier(pubkey->identifier);
-
-		g_snprintf(tmp2, sizeof(tmp2), "%s\n  %s\n  %s",
-			   ident->realname ? ident->realname : ident->username ?
-			   ident->username : "", fingerprint, babbleprint);
-		purple_request_field_list_add_icon(f, tmp2, NULL, pubkey);
-
-		silc_free(fingerprint);
-		silc_free(babbleprint);
-		silc_pkcs_free_identifier(ident);
-		pk = silc_argument_get_next_arg(chpks, &type, &pk_len);
-	}
-
-	purple_request_field_list_set_multi_select(f, FALSE);
-	purple_request_fields(sg->gc, _("Channel Authentication"),
-			    _("Channel Authentication"), t, fields,
-			    _("Add / Remove"), G_CALLBACK(silcpurple_chat_chpk_cb),
-			    _("OK"), G_CALLBACK(silcpurple_chat_chauth_ok),
-				purple_connection_get_account(sg->gc), NULL, NULL, sgc);
-
-	silc_argument_payload_free(chpks);
-}
-
-static void
-silcpurple_chat_chauth(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
-	chat = (PurpleChat *) node;
-	gc = purple_account_get_connection(chat->account);
-	sg = gc->proto_data;
-
-	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
-				 g_hash_table_lookup(chat->components, "channel"),
-				 "+C", NULL);
-}
-
-
-/************************** Channel Private Groups **************************/
-
-/* Private groups are "virtual" channels.  They are groups inside a channel.
-   This is implemented by using channel private keys.  By knowing a channel
-   private key user becomes part of that group and is able to talk on that
-   group.  Other users, on the same channel, won't be able to see the
-   messages of that group.  It is possible to have multiple groups inside
-   a channel - and thus having multiple private keys on the channel. */
-
-typedef struct {
-	SilcPurple sg;
-	PurpleChat *c;
-	const char *channel;
-} *SilcPurpleCharPrv;
-
-static void
-silcpurple_chat_prv_add(SilcPurpleCharPrv p, PurpleRequestFields *fields)
-{
-	SilcPurple sg = p->sg;
-	char tmp[512];
-	PurpleRequestField *f;
-	const char *name, *passphrase, *alias;
-	GHashTable *comp;
-	PurpleGroup *g;
-	PurpleChat *cn;
-
-	f = purple_request_fields_get_field(fields, "name");
-	name = purple_request_field_string_get_value(f);
-	if (!name) {
-		silc_free(p);
-		return;
-	}
-	f = purple_request_fields_get_field(fields, "passphrase");
-	passphrase = purple_request_field_string_get_value(f);
-	f = purple_request_fields_get_field(fields, "alias");
-	alias = purple_request_field_string_get_value(f);
-
-	/* Add private group to buddy list */
-	g_snprintf(tmp, sizeof(tmp), "%s [Private Group]", name);
-	comp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
-	g_hash_table_replace(comp, g_strdup("channel"), g_strdup(tmp));
-	g_hash_table_replace(comp, g_strdup("passphrase"), g_strdup(passphrase));
-
-	cn = purple_chat_new(sg->account, alias, comp);
-	g = (PurpleGroup *)p->c->node.parent;
-	purple_blist_add_chat(cn, g, (PurpleBlistNode *)p->c);
-
-	/* Associate to a real channel */
-	purple_blist_node_set_string((PurpleBlistNode *)cn, "parentch", p->channel);
-
-	/* Join the group */
-	silcpurple_chat_join(sg->gc, comp);
-
-	silc_free(p);
-}
-
-static void
-silcpurple_chat_prv_cancel(SilcPurpleCharPrv p, PurpleRequestFields *fields)
-{
-	silc_free(p);
-}
-
-static void
-silcpurple_chat_prv(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	SilcPurpleCharPrv p;
-	PurpleRequestFields *fields;
-	PurpleRequestFieldGroup *g;
-	PurpleRequestField *f;
-	char tmp[512];
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
-	chat = (PurpleChat *) node;
-	gc = purple_account_get_connection(chat->account);
-	sg = gc->proto_data;
-
-	p = silc_calloc(1, sizeof(*p));
-	if (!p)
-		return;
-	p->sg = sg;
-
-	p->channel = g_hash_table_lookup(chat->components, "channel");
-	p->c = purple_blist_find_chat(sg->account, p->channel);
-
-	fields = purple_request_fields_new();
-
-	g = purple_request_field_group_new(NULL);
-	f = purple_request_field_string_new("name", _("Group Name"),
-					  NULL, FALSE);
-	purple_request_field_group_add_field(g, f);
-
-	f = purple_request_field_string_new("passphrase", _("Passphrase"),
-					  NULL, FALSE);
-	purple_request_field_string_set_masked(f, TRUE);
-	purple_request_field_group_add_field(g, f);
-
-	f = purple_request_field_string_new("alias", _("Alias"),
-					  NULL, FALSE);
-	purple_request_field_group_add_field(g, f);
-	purple_request_fields_add_group(fields, g);
-
-	g_snprintf(tmp, sizeof(tmp),
-		   _("Please enter the %s channel private group name and passphrase."),
-		   p->channel);
-	purple_request_fields(gc, _("Add Channel Private Group"), NULL, tmp, fields,
-			    _("Add"), G_CALLBACK(silcpurple_chat_prv_add),
-			    _("Cancel"), G_CALLBACK(silcpurple_chat_prv_cancel),
-				purple_connection_get_account(gc), NULL, NULL, p);
-}
-
-
-/****************************** Channel Modes ********************************/
-
-static void
-silcpurple_chat_permanent_reset(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
-	chat = (PurpleChat *) node;
-	gc = purple_account_get_connection(chat->account);
-	sg = gc->proto_data;
-
-	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
-				 g_hash_table_lookup(chat->components, "channel"),
-				 "-f", NULL);
-}
-
-static void
-silcpurple_chat_permanent(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat;
-	PurpleConnection *gc;
-	SilcPurple sg;
-	const char *channel;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
-	chat = (PurpleChat *) node;
-	gc = purple_account_get_connection(chat->account);
-	sg = gc->proto_data;
-
-	if (!sg->conn)
-		return;
-
-	/* XXX we should have ability to define which founder
-	   key to use.  Now we use the user's own public key
-	   (default key). */
-
-	/* Call CMODE */
-	channel = g_hash_table_lookup(chat->components, "channel");
-	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", channel,
-				 "+f", NULL);
-}
-
-typedef struct {
-	SilcPurple sg;
-	char *channel;
-} *SilcPurpleChatInput;
-
-static void
-silcpurple_chat_ulimit_cb(SilcPurpleChatInput s, const char *limit)
-{
-	SilcChannelEntry channel;
-	int ulimit = 0;
-
-	channel = silc_client_get_channel(s->sg->client, s->sg->conn,
-					  (char *)s->channel);
-	if (!channel)
-		return;
-	if (limit)
-		ulimit = atoi(limit);
-
-	if (!limit || !(*limit) || *limit == '0') {
-		if (limit && ulimit == channel->user_limit) {
-			silc_free(s);
-			return;
-		}
-		silc_client_command_call(s->sg->client, s->sg->conn, NULL, "CMODE",
-					 s->channel, "-l", NULL);
-
-		silc_free(s);
-		return;
-	}
-
-	if (ulimit == channel->user_limit) {
-		silc_free(s);
-		return;
-	}
-
-	/* Call CMODE */
-	silc_client_command_call(s->sg->client, s->sg->conn, NULL, "CMODE",
-				 s->channel, "+l", limit, NULL);
-
-	silc_free(s);
-}
-
-static void
-silcpurple_chat_ulimit(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	SilcPurpleChatInput s;
-	SilcChannelEntry channel;
-	char *ch;
-	char tmp[32];
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
-	chat = (PurpleChat *) node;
-	gc = purple_account_get_connection(chat->account);
-	sg = gc->proto_data;
-
-	if (!sg->conn)
-		return;
-
-	ch = g_strdup(g_hash_table_lookup(chat->components, "channel"));
-	channel = silc_client_get_channel(sg->client, sg->conn, (char *)ch);
-	if (!channel)
-		return;
-
-	s = silc_calloc(1, sizeof(*s));
-	if (!s)
-		return;
-	s->channel = ch;
-	s->sg = sg;
-	g_snprintf(tmp, sizeof(tmp), "%d", (int)channel->user_limit);
-	purple_request_input(gc, _("User Limit"), NULL,
-			   _("Set user limit on channel. Set to zero to reset user limit."),
-			   tmp, FALSE, FALSE, NULL,
-			   _("OK"), G_CALLBACK(silcpurple_chat_ulimit_cb),
-			   _("Cancel"), G_CALLBACK(silcpurple_chat_ulimit_cb),
-			   purple_connection_get_account(gc), NULL, NULL, s);
-}
-
-static void
-silcpurple_chat_resettopic(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
-	chat = (PurpleChat *) node;
-	gc = purple_account_get_connection(chat->account);
-	sg = gc->proto_data;
-
-	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
-				 g_hash_table_lookup(chat->components, "channel"),
-				 "-t", NULL);
-}
-
-static void
-silcpurple_chat_settopic(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
-	chat = (PurpleChat *) node;
-	gc = purple_account_get_connection(chat->account);
-	sg = gc->proto_data;
-
-	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
-				 g_hash_table_lookup(chat->components, "channel"),
-				 "+t", NULL);
-}
-
-static void
-silcpurple_chat_resetprivate(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
-	chat = (PurpleChat *) node;
-	gc = purple_account_get_connection(chat->account);
-	sg = gc->proto_data;
-
-	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
-				 g_hash_table_lookup(chat->components, "channel"),
-				 "-p", NULL);
-}
-
-static void
-silcpurple_chat_setprivate(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
-	chat = (PurpleChat *) node;
-	gc = purple_account_get_connection(chat->account);
-	sg = gc->proto_data;
-
-	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
-				 g_hash_table_lookup(chat->components, "channel"),
-				 "+p", NULL);
-}
-
-static void
-silcpurple_chat_resetsecret(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
-	chat = (PurpleChat *) node;
-	gc = purple_account_get_connection(chat->account);
-	sg = gc->proto_data;
-
-	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
-				 g_hash_table_lookup(chat->components, "channel"),
-				 "-s", NULL);
-}
-
-static void
-silcpurple_chat_setsecret(PurpleBlistNode *node, gpointer data)
-{
-	PurpleChat *chat;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
-	chat = (PurpleChat *) node;
-	gc = purple_account_get_connection(chat->account);
-	sg = gc->proto_data;
-
-	silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
-				 g_hash_table_lookup(chat->components, "channel"),
-				 "+s", NULL);
-}
-
-typedef struct {
-	SilcPurple sg;
-	SilcChannelEntry channel;
-} *SilcPurpleChatWb;
-
-static void
-silcpurple_chat_wb(PurpleBlistNode *node, gpointer data)
-{
-	SilcPurpleChatWb wb = data;
-	silcpurple_wb_init_ch(wb->sg, wb->channel);
-	silc_free(wb);
-}
-
-GList *silcpurple_chat_menu(PurpleChat *chat)
-{
-	GHashTable *components = chat->components;
-	PurpleConnection *gc = purple_account_get_connection(chat->account);
-	SilcPurple sg = gc->proto_data;
-	SilcClientConnection conn = sg->conn;
-	const char *chname = NULL;
-	SilcChannelEntry channel = NULL;
-	SilcChannelUser chu = NULL;
-	SilcUInt32 mode = 0;
-
-	GList *m = NULL;
-	PurpleMenuAction *act;
-
-	if (components)
-		chname = g_hash_table_lookup(components, "channel");
-	if (chname)
-		channel = silc_client_get_channel(sg->client, sg->conn,
-						  (char *)chname);
-	if (channel) {
-		chu = silc_client_on_channel(channel, conn->local_entry);
-		if (chu)
-			mode = chu->mode;
-	}
-
-	if (strstr(chname, "[Private Group]"))
-		return NULL;
-
-	act = purple_menu_action_new(_("Get Info"),
-	                           PURPLE_CALLBACK(silcpurple_chat_getinfo_menu),
-	                           NULL, NULL);
-	m = g_list_append(m, act);
-
-#if 0   /* XXX For now these are not implemented.  We need better
-	   listview dialog from Purple for these. */
-	if (mode & SILC_CHANNEL_UMODE_CHANOP) {
-		act = purple_menu_action_new(_("Invite List"),
-		                           PURPLE_CALLBACK(silcpurple_chat_invitelist),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
-
-		act = purple_menu_action_new(_("Ban List"),
-		                           PURPLE_CALLBACK(silcpurple_chat_banlist),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
-	}
-#endif
-
-	if (chu) {
-		act = purple_menu_action_new(_("Add Private Group"),
-		                           PURPLE_CALLBACK(silcpurple_chat_prv),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
-	}
-
-	if (mode & SILC_CHANNEL_UMODE_CHANFO) {
-		act = purple_menu_action_new(_("Channel Authentication"),
-		                           PURPLE_CALLBACK(silcpurple_chat_chauth),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
-
-		if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
-			act = purple_menu_action_new(_("Reset Permanent"),
-			                           PURPLE_CALLBACK(silcpurple_chat_permanent_reset),
-			                           NULL, NULL);
-			m = g_list_append(m, act);
-		} else {
-			act = purple_menu_action_new(_("Set Permanent"),
-			                           PURPLE_CALLBACK(silcpurple_chat_permanent),
-			                           NULL, NULL);
-			m = g_list_append(m, act);
-		}
-	}
-
-	if (mode & SILC_CHANNEL_UMODE_CHANOP) {
-		act = purple_menu_action_new(_("Set User Limit"),
-		                           PURPLE_CALLBACK(silcpurple_chat_ulimit),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
-
-		if (channel->mode & SILC_CHANNEL_MODE_TOPIC) {
-			act = purple_menu_action_new(_("Reset Topic Restriction"),
-			                           PURPLE_CALLBACK(silcpurple_chat_resettopic),
-			                           NULL, NULL);
-			m = g_list_append(m, act);
-		} else {
-			act = purple_menu_action_new(_("Set Topic Restriction"),
-			                           PURPLE_CALLBACK(silcpurple_chat_settopic),
-			                           NULL, NULL);
-			m = g_list_append(m, act);
-		}
-
-		if (channel->mode & SILC_CHANNEL_MODE_PRIVATE) {
-			act = purple_menu_action_new(_("Reset Private Channel"),
-			                           PURPLE_CALLBACK(silcpurple_chat_resetprivate),
-			                           NULL, NULL);
-			m = g_list_append(m, act);
-		} else {
-			act = purple_menu_action_new(_("Set Private Channel"),
-			                           PURPLE_CALLBACK(silcpurple_chat_setprivate),
-			                           NULL, NULL);
-			m = g_list_append(m, act);
-		}
-
-		if (channel->mode & SILC_CHANNEL_MODE_SECRET) {
-			act = purple_menu_action_new(_("Reset Secret Channel"),
-			                           PURPLE_CALLBACK(silcpurple_chat_resetsecret),
-			                           NULL, NULL);
-			m = g_list_append(m, act);
-		} else {
-			act = purple_menu_action_new(_("Set Secret Channel"),
-			                           PURPLE_CALLBACK(silcpurple_chat_setsecret),
-			                           NULL, NULL);
-			m = g_list_append(m, act);
-		}
-	}
-
-	if (channel) {
-		SilcPurpleChatWb wb;
-		wb = silc_calloc(1, sizeof(*wb));
-		wb->sg = sg;
-		wb->channel = channel;
-		act = purple_menu_action_new(_("Draw On Whiteboard"),
-		                           PURPLE_CALLBACK(silcpurple_chat_wb),
-		                           (void *)wb, NULL);
-		m = g_list_append(m, act);
-	}
-
-	return m;
-}
-
-
-/******************************* Joining Etc. ********************************/
-
-void silcpurple_chat_join_done(SilcClient client,
-			     SilcClientConnection conn,
-			     SilcClientEntry *clients,
-			     SilcUInt32 clients_count,
-			     void *context)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-	SilcChannelEntry channel = context;
-	PurpleConversation *convo;
-	SilcUInt32 retry = SILC_PTR_TO_32(channel->context);
-	SilcHashTableList htl;
-	SilcChannelUser chu;
-	GList *users = NULL, *flags = NULL;
-	char tmp[256];
-
-	if (!clients && retry < 1) {
-		/* Resolving users failed, try again. */
-		channel->context = SILC_32_TO_PTR(retry + 1);
-		silc_client_get_clients_by_channel(client, conn, channel,
-						   silcpurple_chat_join_done, channel);
-		return;
-	}
-
-	/* Add channel to Purple */
-	channel->context = SILC_32_TO_PTR(++sg->channel_ids);
-	serv_got_joined_chat(gc, sg->channel_ids, channel->channel_name);
-	convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-							channel->channel_name, sg->account);
-	if (!convo)
-		return;
-
-	/* Add all users to channel */
-	silc_hash_table_list(channel->user_list, &htl);
-	while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-		PurpleConvChatBuddyFlags f = PURPLE_CBFLAGS_NONE;
-		if (!chu->client->nickname)
-			continue;
-		chu->context = SILC_32_TO_PTR(sg->channel_ids);
-
-		if (chu->mode & SILC_CHANNEL_UMODE_CHANFO)
-			f |= PURPLE_CBFLAGS_FOUNDER;
-		if (chu->mode & SILC_CHANNEL_UMODE_CHANOP)
-			f |= PURPLE_CBFLAGS_OP;
-		users = g_list_append(users, g_strdup(chu->client->nickname));
-		flags = g_list_append(flags, GINT_TO_POINTER(f));
-
-		if (chu->mode & SILC_CHANNEL_UMODE_CHANFO) {
-			if (chu->client == conn->local_entry)
-				g_snprintf(tmp, sizeof(tmp),
-					   _("You are channel founder on <I>%s</I>"),
-					   channel->channel_name);
-			else
-				g_snprintf(tmp, sizeof(tmp),
-					   _("Channel founder on <I>%s</I> is <I>%s</I>"),
-					   channel->channel_name, chu->client->nickname);
-
-			purple_conversation_write(convo, NULL, tmp,
-						PURPLE_MESSAGE_SYSTEM, time(NULL));
-
-		}
-	}
-	silc_hash_table_list_reset(&htl);
-
-	purple_conv_chat_add_users(PURPLE_CONV_CHAT(convo), users, NULL, flags, FALSE);
-	g_list_free(users);
-	g_list_free(flags);
-
-	/* Set topic */
-	if (channel->topic)
-		purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, channel->topic);
-
-	/* Set nick */
-	purple_conv_chat_set_nick(PURPLE_CONV_CHAT(convo), conn->local_entry->nickname);
-}
-
-char *silcpurple_get_chat_name(GHashTable *data)
-{
-	return g_strdup(g_hash_table_lookup(data, "channel"));
-}
-
-void silcpurple_chat_join(PurpleConnection *gc, GHashTable *data)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	const char *channel, *passphrase, *parentch;
-
-	if (!conn)
-		return;
-
-	channel = g_hash_table_lookup(data, "channel");
-	passphrase = g_hash_table_lookup(data, "passphrase");
-
-	/* Check if we are joining a private group.  Handle it
-	   purely locally as it's not a real channel */
-	if (strstr(channel, "[Private Group]")) {
-		SilcChannelEntry channel_entry;
-		SilcChannelPrivateKey key;
-		PurpleChat *c;
-		SilcPurplePrvgrp grp;
-
-		c = purple_blist_find_chat(sg->account, channel);
-		parentch = purple_blist_node_get_string((PurpleBlistNode *)c, "parentch");
-		if (!parentch)
-			return;
-
-		channel_entry = silc_client_get_channel(sg->client, sg->conn,
-							(char *)parentch);
-		if (!channel_entry ||
-		    !silc_client_on_channel(channel_entry, sg->conn->local_entry)) {
-			char tmp[512];
-			g_snprintf(tmp, sizeof(tmp),
-				   _("You have to join the %s channel before you are "
-				     "able to join the private group"), parentch);
-			purple_notify_error(gc, _("Join Private Group"),
-					  _("Cannot join private group"), tmp);
-			return;
-		}
-
-		/* Add channel private key */
-		if (!silc_client_add_channel_private_key(client, conn,
-							 channel_entry, channel,
-							 NULL, NULL,
-							 (unsigned char *)passphrase,
-							 strlen(passphrase), &key))
-			return;
-
-		/* Join the group */
-		grp = silc_calloc(1, sizeof(*grp));
-		if (!grp)
-			return;
-		grp->id = ++sg->channel_ids + SILCPURPLE_PRVGRP;
-		grp->chid = SILC_PTR_TO_32(channel_entry->context);
-		grp->parentch = parentch;
-		grp->channel = channel;
-		grp->key = key;
-		sg->grps = g_list_append(sg->grps, grp);
-		serv_got_joined_chat(gc, grp->id, channel);
-		return;
-	}
-
-	/* XXX We should have other properties here as well:
-	   1. whether to try to authenticate to the channel
-	     1a. with default key,
-	     1b. with specific key.
-	   2. whether to try to authenticate to become founder.
-	     2a. with default key,
-	     2b. with specific key.
-
-	   Since now such variety is not possible in the join dialog
-	   we always use -founder and -auth options, which try to
-	   do both 1 and 2 with default keys. */
-
-	/* Call JOIN */
-	if ((passphrase != NULL) && (*passphrase != '\0'))
-		silc_client_command_call(client, conn, NULL, "JOIN",
-					 channel, passphrase, "-auth", "-founder", NULL);
-	else
-		silc_client_command_call(client, conn, NULL, "JOIN",
-					 channel, "-auth", "-founder", NULL);
-}
-
-void silcpurple_chat_invite(PurpleConnection *gc, int id, const char *msg,
-			  const char *name)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcHashTableList htl;
-	SilcChannelUser chu;
-	gboolean found = FALSE;
-
-	if (!conn)
-		return;
-
-	/* See if we are inviting on a private group.  Invite
-	   to the actual channel */
-	if (id > SILCPURPLE_PRVGRP) {
-		GList *l;
-		SilcPurplePrvgrp prv;
-
-		for (l = sg->grps; l; l = l->next)
-			if (((SilcPurplePrvgrp)l->data)->id == id)
-				break;
-		if (!l)
-			return;
-		prv = l->data;
-		id = prv->chid;
-	}
-
-	/* Find channel by id */
-	silc_hash_table_list(conn->local_entry->channels, &htl);
-	while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-		if (SILC_PTR_TO_32(chu->channel->context) == id ) {
-			found = TRUE;
-			break;
-		}
-	}
-	silc_hash_table_list_reset(&htl);
-	if (!found)
-		return;
-
-	/* Call INVITE */
-	silc_client_command_call(client, conn, NULL, "INVITE",
-				 chu->channel->channel_name,
-				 name, NULL);
-}
-
-void silcpurple_chat_leave(PurpleConnection *gc, int id)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcHashTableList htl;
-	SilcChannelUser chu;
-	gboolean found = FALSE;
-	GList *l;
-	SilcPurplePrvgrp prv;
-
-	if (!conn)
-		return;
-
-	/* See if we are leaving a private group */
-	if (id > SILCPURPLE_PRVGRP) {
-		SilcChannelEntry channel;
-
-		for (l = sg->grps; l; l = l->next)
-			if (((SilcPurplePrvgrp)l->data)->id == id)
-				break;
-		if (!l)
-			return;
-		prv = l->data;
-		channel = silc_client_get_channel(sg->client, sg->conn,
-						  (char *)prv->parentch);
-		if (!channel)
-			return;
-		silc_client_del_channel_private_key(client, conn,
-						    channel, prv->key);
-		silc_free(prv);
-		sg->grps = g_list_remove(sg->grps, prv);
-		serv_got_chat_left(gc, id);
-		return;
-	}
-
-	/* Find channel by id */
-	silc_hash_table_list(conn->local_entry->channels, &htl);
-	while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-		if (SILC_PTR_TO_32(chu->channel->context) == id ) {
-			found = TRUE;
-			break;
-		}
-	}
-	silc_hash_table_list_reset(&htl);
-	if (!found)
-		return;
-
-	/* Call LEAVE */
-	silc_client_command_call(client, conn, NULL, "LEAVE",
-				 chu->channel->channel_name, NULL);
-
-	serv_got_chat_left(gc, id);
-
-	/* Leave from private groups on this channel as well */
-	for (l = sg->grps; l; l = l->next)
-		if (((SilcPurplePrvgrp)l->data)->chid == id) {
-			prv = l->data;
-			silc_client_del_channel_private_key(client, conn,
-							    chu->channel,
-							    prv->key);
-			serv_got_chat_left(gc, prv->id);
-			silc_free(prv);
-			sg->grps = g_list_remove(sg->grps, prv);
-			if (!sg->grps)
-				break;
-		}
-}
-
-int silcpurple_chat_send(PurpleConnection *gc, int id, const char *msg, PurpleMessageFlags msgflags)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcHashTableList htl;
-	SilcChannelUser chu;
-	SilcChannelEntry channel = NULL;
-	SilcChannelPrivateKey key = NULL;
-	SilcUInt32 flags;
-	int ret;
-	char *msg2, *tmp;
-	gboolean found = FALSE;
-	gboolean sign = purple_account_get_bool(sg->account, "sign-verify", FALSE);
-
-	if (!msg || !conn)
-		return 0;
-
-	flags = SILC_MESSAGE_FLAG_UTF8;
-
-	tmp = msg2 = purple_unescape_html(msg);
-
-	if (!g_ascii_strncasecmp(msg2, "/me ", 4))
-	{
-		msg2 += 4;
-		if (!*msg2) {
-			g_free(tmp);
-			return 0;
-		}
-		flags |= SILC_MESSAGE_FLAG_ACTION;
-	} else if (strlen(msg) > 1 && msg[0] == '/') {
-		if (!silc_client_command_call(client, conn, msg + 1))
-			purple_notify_error(gc, _("Call Command"), _("Cannot call command"),
-							  _("Unknown command"));
-		g_free(tmp);
-		return 0;
-	}
-
-
-	if (sign)
-		flags |= SILC_MESSAGE_FLAG_SIGNED;
-
-	/* Get the channel private key if we are sending on
-	   private group */
-	if (id > SILCPURPLE_PRVGRP) {
-		GList *l;
-		SilcPurplePrvgrp prv;
-
-		for (l = sg->grps; l; l = l->next)
-			if (((SilcPurplePrvgrp)l->data)->id == id)
-				break;
-		if (!l) {
-			g_free(tmp);
-			return 0;
-		}
-		prv = l->data;
-		channel = silc_client_get_channel(sg->client, sg->conn,
-						  (char *)prv->parentch);
-		if (!channel) {
-			g_free(tmp);
-			return 0;
-		}
-		key = prv->key;
-	}
-
-	if (!channel) {
-		/* Find channel by id */
-		silc_hash_table_list(conn->local_entry->channels, &htl);
-		while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-			if (SILC_PTR_TO_32(chu->channel->context) == id ) {
-				found = TRUE;
-				break;
-			}
-		}
-		silc_hash_table_list_reset(&htl);
-		if (!found) {
-			g_free(tmp);
-			return 0;
-		}
-		channel = chu->channel;
-	}
-
-	/* Send channel message */
-	ret = silc_client_send_channel_message(client, conn, channel, key,
-					       flags, (unsigned char *)msg2,
-					       strlen(msg2), TRUE);
-	if (ret) {
-		serv_got_chat_in(gc, id, purple_connection_get_display_name(gc), msgflags, msg,
-				 time(NULL));
-	}
-	g_free(tmp);
-
-	return ret;
-}
-
-void silcpurple_chat_set_topic(PurpleConnection *gc, int id, const char *topic)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcHashTableList htl;
-	SilcChannelUser chu;
-	gboolean found = FALSE;
-
-	if (!conn)
-		return;
-
-	/* See if setting topic on private group.  Set it
-	   on the actual channel */
-	if (id > SILCPURPLE_PRVGRP) {
-		GList *l;
-		SilcPurplePrvgrp prv;
-
-		for (l = sg->grps; l; l = l->next)
-			if (((SilcPurplePrvgrp)l->data)->id == id)
-				break;
-		if (!l)
-			return;
-		prv = l->data;
-		id = prv->chid;
-	}
-
-	/* Find channel by id */
-	silc_hash_table_list(conn->local_entry->channels, &htl);
-	while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-		if (SILC_PTR_TO_32(chu->channel->context) == id ) {
-			found = TRUE;
-			break;
-		}
-	}
-	silc_hash_table_list_reset(&htl);
-	if (!found)
-		return;
-
-	/* Call TOPIC */
-	silc_client_command_call(client, conn, NULL, "TOPIC",
-				 chu->channel->channel_name, topic, NULL);
-}
-
-PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	GList *fields = NULL;
-	PurpleRoomlistField *f;
-
-	if (!conn)
-		return NULL;
-
-	if (sg->roomlist)
-		purple_roomlist_unref(sg->roomlist);
-
-	sg->roomlist_cancelled = FALSE;
-
-	sg->roomlist = purple_roomlist_new(purple_connection_get_account(gc));
-	f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "channel", TRUE);
-	fields = g_list_append(fields, f);
-	f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT,
-				    _("Users"), "users", FALSE);
-	fields = g_list_append(fields, f);
-	f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING,
-				    _("Topic"), "topic", FALSE);
-	fields = g_list_append(fields, f);
-	purple_roomlist_set_fields(sg->roomlist, fields);
-
-	/* Call LIST */
-	silc_client_command_call(client, conn, "LIST");
-
-	purple_roomlist_set_in_progress(sg->roomlist, TRUE);
-
-	return sg->roomlist;
-}
-
-void silcpurple_roomlist_cancel(PurpleRoomlist *list)
-{
-	PurpleConnection *gc = purple_account_get_connection(list->account);
-	SilcPurple sg;
-
-	if (!gc)
-		return;
-	sg = gc->proto_data;
-
-	purple_roomlist_set_in_progress(list, FALSE);
-	if (sg->roomlist == list) {
-		purple_roomlist_unref(sg->roomlist);
-		sg->roomlist = NULL;
-		sg->roomlist_cancelled = TRUE;
-	}
-}
--- a/libpurple/protocols/silc10/ft.c	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,412 +0,0 @@
-/*
-
-  silcpurple_ft.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2004 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-
-/****************************** File Transfer ********************************/
-
-/* This implements the secure file transfer protocol (SFTP) using the SILC
-   SFTP library implementation.  The API we use from the SILC Toolkit is the
-   SILC Client file transfer API, as it provides a simple file transfer we
-   need in this case.  We could use the SILC SFTP API directly, but it would
-   be an overkill since we'd effectively re-implement the file transfer what
-   the SILC Client's file transfer API already provides.
-
-   From Purple we do NOT use the FT API to do the transfer as it is very limiting.
-   In fact it does not suite to file transfers like SFTP at all.  For example,
-   it assumes that read operations are synchronous what they are not in SFTP.
-   It also assumes that the file transfer socket is to be handled by the Purple
-   eventloop, and this naturally is something we don't want to do in case of
-   SILC Toolkit.  The FT API suites well to purely stream based file transfers
-   like HTTP GET and similar.
-
-   For this reason, we directly access the Purple GKT FT API and hack the FT
-   API to merely provide the user interface experience and all the magic
-   is done in the SILC Toolkit.  Ie. we update the statistics information in
-   the FT API for user interface, and that's it.  A bit dirty but until the
-   FT API gets better this is the way to go.  Good thing that FT API allowed
-   us to do this. */
-
-typedef struct {
-	SilcPurple sg;
-	SilcClientEntry client_entry;
-	SilcUInt32 session_id;
-	char *hostname;
-	SilcUInt16 port;
-	PurpleXfer *xfer;
-
-	SilcClientFileName completion;
-	void *completion_context;
-} *SilcPurpleXfer;
-
-static void
-silcpurple_ftp_monitor(SilcClient client,
-		     SilcClientConnection conn,
-		     SilcClientMonitorStatus status,
-		     SilcClientFileError error,
-		     SilcUInt64 offset,
-		     SilcUInt64 filesize,
-		     SilcClientEntry client_entry,
-		     SilcUInt32 session_id,
-		     const char *filepath,
-		     void *context)
-{
-	SilcPurpleXfer xfer = context;
-	PurpleConnection *gc = xfer->sg->gc;
-	char tmp[256];
-
-	if (status == SILC_CLIENT_FILE_MONITOR_CLOSED) {
-		purple_xfer_unref(xfer->xfer);
-		silc_free(xfer);
-		return;
-	}
-
-	if (status == SILC_CLIENT_FILE_MONITOR_KEY_AGREEMENT)
-		return;
-
-	if (status == SILC_CLIENT_FILE_MONITOR_ERROR) {
-		if (error == SILC_CLIENT_FILE_NO_SUCH_FILE) {
-			g_snprintf(tmp, sizeof(tmp), "No such file %s",
-				   filepath ? filepath : "[N/A]");
-			purple_notify_error(gc, _("Secure File Transfer"),
-					  _("Error during file transfer"), tmp);
-		} else if (error == SILC_CLIENT_FILE_PERMISSION_DENIED) {
-			purple_notify_error(gc, _("Secure File Transfer"),
-					  _("Error during file transfer"),
-					  _("Permission denied"));
-		} else if (error == SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED) {
-			purple_notify_error(gc, _("Secure File Transfer"),
-					  _("Error during file transfer"),
-					  _("Key agreement failed"));
-		} else if (error == SILC_CLIENT_FILE_UNKNOWN_SESSION) {
-			purple_notify_error(gc, _("Secure File Transfer"),
-					  _("Error during file transfer"),
-					  _("File transfer session does not exist"));
-		} else {
-			purple_notify_error(gc, _("Secure File Transfer"),
-					  _("Error during file transfer"), NULL);
-		}
-		silc_client_file_close(client, conn, session_id);
-		purple_xfer_unref(xfer->xfer);
-		silc_free(xfer);
-		return;
-	}
-
-	/* Update file transfer UI */
-	if (!offset && filesize)
-		purple_xfer_set_size(xfer->xfer, filesize);
-	if (offset && filesize) {
-		xfer->xfer->bytes_sent = offset;
-		xfer->xfer->bytes_remaining = filesize - offset;
-	}
-	purple_xfer_update_progress(xfer->xfer);
-
-	if (status == SILC_CLIENT_FILE_MONITOR_SEND ||
-	    status == SILC_CLIENT_FILE_MONITOR_RECEIVE) {
-		if (offset == filesize) {
-			/* Download finished */
-			purple_xfer_set_completed(xfer->xfer, TRUE);
-			silc_client_file_close(client, conn, session_id);
-		}
-	}
-}
-
-static void
-silcpurple_ftp_cancel(PurpleXfer *x)
-{
-	SilcPurpleXfer xfer = x->data;
-	xfer->xfer->status = PURPLE_XFER_STATUS_CANCEL_LOCAL;
-	purple_xfer_update_progress(xfer->xfer);
-	silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id);
-}
-
-static void
-silcpurple_ftp_ask_name_cancel(PurpleXfer *x)
-{
-	SilcPurpleXfer xfer = x->data;
-
-	/* Cancel the transmission */
-	xfer->completion(NULL, xfer->completion_context);
-	silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id);
-}
-
-static void
-silcpurple_ftp_ask_name_ok(PurpleXfer *x)
-{
-	SilcPurpleXfer xfer = x->data;
-	const char *name;
-
-	name = purple_xfer_get_local_filename(x);
-	g_unlink(name);
-	xfer->completion(name, xfer->completion_context);
-}
-
-static void
-silcpurple_ftp_ask_name(SilcClient client,
-		      SilcClientConnection conn,
-		      SilcUInt32 session_id,
-		      const char *remote_filename,
-		      SilcClientFileName completion,
-		      void *completion_context,
-		      void *context)
-{
-	SilcPurpleXfer xfer = context;
-
-	xfer->completion = completion;
-	xfer->completion_context = completion_context;
-
-	purple_xfer_set_init_fnc(xfer->xfer, silcpurple_ftp_ask_name_ok);
-	purple_xfer_set_request_denied_fnc(xfer->xfer, silcpurple_ftp_ask_name_cancel);
-
-	/* Request to save the file */
-	purple_xfer_set_filename(xfer->xfer, remote_filename);
-	purple_xfer_request(xfer->xfer);
-}
-
-static void
-silcpurple_ftp_request_result(PurpleXfer *x)
-{
-	SilcPurpleXfer xfer = x->data;
-	SilcClientFileError status;
-	PurpleConnection *gc = xfer->sg->gc;
-
-	if (purple_xfer_get_status(x) != PURPLE_XFER_STATUS_ACCEPTED)
-		return;
-
-	/* Start the file transfer */
-	status = silc_client_file_receive(xfer->sg->client, xfer->sg->conn,
-					  silcpurple_ftp_monitor, xfer,
-					  NULL, xfer->session_id,
-					  silcpurple_ftp_ask_name, xfer);
-	switch (status) {
-	case SILC_CLIENT_FILE_OK:
-		return;
-		break;
-
-	case SILC_CLIENT_FILE_UNKNOWN_SESSION:
-		purple_notify_error(gc, _("Secure File Transfer"),
-				  _("No file transfer session active"), NULL);
-		break;
-
-	case SILC_CLIENT_FILE_ALREADY_STARTED:
-		purple_notify_error(gc, _("Secure File Transfer"),
-				  _("File transfer already started"), NULL);
-		break;
-
-	case SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED:
-		purple_notify_error(gc, _("Secure File Transfer"),
-				  _("Could not perform key agreement for file transfer"),
-				  NULL);
-		break;
-
-	default:
-		purple_notify_error(gc, _("Secure File Transfer"),
-				  _("Could not start the file transfer"), NULL);
-		break;
-	}
-
-	/* Error */
-	purple_xfer_unref(xfer->xfer);
-	g_free(xfer->hostname);
-	silc_free(xfer);
-}
-
-static void
-silcpurple_ftp_request_denied(PurpleXfer *x)
-{
-
-}
-
-void silcpurple_ftp_request(SilcClient client, SilcClientConnection conn,
-			  SilcClientEntry client_entry, SilcUInt32 session_id,
-			  const char *hostname, SilcUInt16 port)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-	SilcPurpleXfer xfer;
-
-	xfer = silc_calloc(1, sizeof(*xfer));
-	if (!xfer) {
-		silc_client_file_close(sg->client, sg->conn, session_id);
-		return;
-	}
-
-	xfer->sg = sg;
-	xfer->client_entry = client_entry;
-	xfer->session_id = session_id;
-	xfer->hostname = g_strdup(hostname);
-	xfer->port = port;
-	xfer->xfer = purple_xfer_new(xfer->sg->account, PURPLE_XFER_RECEIVE,
-				   xfer->client_entry->nickname);
-	if (!xfer->xfer) {
-		silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id);
-		g_free(xfer->hostname);
-		silc_free(xfer);
-		return;
-	}
-	purple_xfer_set_init_fnc(xfer->xfer, silcpurple_ftp_request_result);
-	purple_xfer_set_request_denied_fnc(xfer->xfer, silcpurple_ftp_request_denied);
-	purple_xfer_set_cancel_recv_fnc(xfer->xfer, silcpurple_ftp_cancel);
-	xfer->xfer->remote_ip = g_strdup(hostname);
-	xfer->xfer->remote_port = port;
-	xfer->xfer->data = xfer;
-
-	/* File transfer request */
-	purple_xfer_request(xfer->xfer);
-}
-
-static void
-silcpurple_ftp_send_cancel(PurpleXfer *x)
-{
-	SilcPurpleXfer xfer = x->data;
-	silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id);
-	purple_xfer_unref(xfer->xfer);
-	g_free(xfer->hostname);
-	silc_free(xfer);
-}
-
-static void
-silcpurple_ftp_send(PurpleXfer *x)
-{
-	SilcPurpleXfer xfer = x->data;
-	const char *name;
-	char *local_ip = NULL, *remote_ip = NULL;
-	gboolean local = TRUE;
-
-	name = purple_xfer_get_local_filename(x);
-
-	/* Do the same magic what we do with key agreement (see silcpurple_buddy.c)
-	   to see if we are behind NAT. */
-	if (silc_net_check_local_by_sock(xfer->sg->conn->sock->sock,
-					 NULL, &local_ip)) {
-		/* Check if the IP is private */
-		if (silcpurple_ip_is_private(local_ip)) {
-			local = FALSE;
-			/* Local IP is private, resolve the remote server IP to see whether
-			   we are talking to Internet or just on LAN. */
-			if (silc_net_check_host_by_sock(xfer->sg->conn->sock->sock, NULL,
-							&remote_ip))
-				if (silcpurple_ip_is_private(remote_ip))
-					/* We assume we are in LAN.  Let's provide the connection point. */
-					local = TRUE;
-		}
-	}
-
-	if (local && !local_ip)
-		local_ip = silc_net_localip();
-
-	/* Send the file */
-	silc_client_file_send(xfer->sg->client, xfer->sg->conn,
-			      silcpurple_ftp_monitor, xfer,
-			      local_ip, 0, !local, xfer->client_entry,
-			      name, &xfer->session_id);
-
-	silc_free(local_ip);
-	silc_free(remote_ip);
-}
-
-static void
-silcpurple_ftp_send_file_resolved(SilcClient client,
-				SilcClientConnection conn,
-				SilcClientEntry *clients,
-				SilcUInt32 clients_count,
-				void *context)
-{
-	PurpleConnection *gc = client->application;
-	char tmp[256];
-
-	if (!clients) {
-		g_snprintf(tmp, sizeof(tmp),
-			   _("User %s is not present in the network"),
-			   (const char *)context);
-		purple_notify_error(gc, _("Secure File Transfer"),
-				  _("Cannot send file"), tmp);
-		silc_free(context);
-		return;
-	}
-
-	silcpurple_ftp_send_file(client->application, (const char *)context, NULL);
-	silc_free(context);
-}
-
-PurpleXfer *silcpurple_ftp_new_xfer(PurpleConnection *gc, const char *name)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcClientEntry *clients;
-	SilcUInt32 clients_count;
-	SilcPurpleXfer xfer;
-	char *nickname;
-
-	g_return_val_if_fail(name != NULL, NULL);
-
-	if (!silc_parse_userfqdn(name, &nickname, NULL))
-		return NULL;
-
-	/* Find client entry */
-	clients = silc_client_get_clients_local(client, conn, nickname, name,
-											&clients_count);
-	if (!clients) {
-		silc_client_get_clients(client, conn, nickname, NULL,
-								silcpurple_ftp_send_file_resolved,
-								strdup(name));
-		silc_free(nickname);
-		return NULL;
-	}
-
-	xfer = silc_calloc(1, sizeof(*xfer));
-
-	g_return_val_if_fail(xfer != NULL, NULL);
-
-	xfer->sg = sg;
-	xfer->client_entry = clients[0];
-	xfer->xfer = purple_xfer_new(xfer->sg->account, PURPLE_XFER_SEND,
-							   xfer->client_entry->nickname);
-	if (!xfer->xfer) {
-		silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id);
-		g_free(xfer->hostname);
-		silc_free(xfer);
-		return NULL;
-	}
-	purple_xfer_set_init_fnc(xfer->xfer, silcpurple_ftp_send);
-	purple_xfer_set_request_denied_fnc(xfer->xfer, silcpurple_ftp_request_denied);
-	purple_xfer_set_cancel_send_fnc(xfer->xfer, silcpurple_ftp_send_cancel);
-	xfer->xfer->data = xfer;
-
-	silc_free(clients);
-	silc_free(nickname);
-
-	return xfer->xfer;
-}
-
-void silcpurple_ftp_send_file(PurpleConnection *gc, const char *name, const char *file)
-{
-	PurpleXfer *xfer = silcpurple_ftp_new_xfer(gc, name);
-
-	g_return_if_fail(xfer != NULL);
-
-	/* Choose file to send */
-	if (file)
-		purple_xfer_request_accepted(xfer, file);
-	else
-		purple_xfer_request(xfer);
-}
--- a/libpurple/protocols/silc10/ops.c	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2063 +0,0 @@
-/*
-
-  silcpurple_ops.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2004 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "imgstore.h"
-#include "wb.h"
-
-static void
-silc_channel_message(SilcClient client, SilcClientConnection conn,
-		     SilcClientEntry sender, SilcChannelEntry channel,
-		     SilcMessagePayload payload, SilcChannelPrivateKey key,
-		     SilcMessageFlags flags, const unsigned char *message,
-		     SilcUInt32 message_len);
-static void
-silc_private_message(SilcClient client, SilcClientConnection conn,
-		     SilcClientEntry sender, SilcMessagePayload payload,
-		     SilcMessageFlags flags, const unsigned char *message,
-		     SilcUInt32 message_len);
-
-/* Message sent to the application by library. `conn' associates the
-   message to a specific connection.  `conn', however, may be NULL.
-   The `type' indicates the type of the message sent by the library.
-   The application can for example filter the message according the
-   type. */
-
-static void
-silc_say(SilcClient client, SilcClientConnection conn,
-	 SilcClientMessageType type, char *msg, ...)
-{
-	/* Nothing */
-}
-
-#ifdef HAVE_SILCMIME_H
-/* Processes incoming MIME message.  Can be private message or channel
-   message. */
-
-static void
-silcpurple_mime_message(SilcClient client, SilcClientConnection conn,
-		      SilcClientEntry sender, SilcChannelEntry channel,
-		      SilcMessagePayload payload, SilcChannelPrivateKey key,
-		      SilcMessageFlags flags, SilcMime mime,
-		      gboolean recursive)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-	const char *type;
-	const unsigned char *data;
-	SilcUInt32 data_len;
-	PurpleMessageFlags cflags = 0;
-	PurpleConversation *convo = NULL;
-
-	if (!mime)
-		return;
-
-	/* Check for fragmented MIME message */
-	if (silc_mime_is_partial(mime)) {
-		if (!sg->mimeass)
-			sg->mimeass = silc_mime_assembler_alloc();
-
-		/* Defragment */
-		mime = silc_mime_assemble(sg->mimeass, mime);
-		if (!mime)
-			/* More fragments to come */
-			return;
-
-		/* Process the complete message */
-		silcpurple_mime_message(client, conn, sender, channel,
-				      payload, key, flags, mime, FALSE);
-		return;
-	}
-
-	/* Check for multipart message */
-	if (silc_mime_is_multipart(mime)) {
-		SilcMime p;
-		const char *mtype;
-		SilcDList parts = silc_mime_get_multiparts(mime, &mtype);
-
-		/* Only "mixed" type supported */
-		if (strcmp(mtype, "mixed"))
-			goto out;
-
-		silc_dlist_start(parts);
-		while ((p = silc_dlist_get(parts)) != SILC_LIST_END) {
-			/* Recursively process parts */
-			silcpurple_mime_message(client, conn, sender, channel,
-					      payload, key, flags, p, TRUE);
-		}
-		goto out;
-	}
-
-	/* Get content type and MIME data */
-	type = silc_mime_get_field(mime, "Content-Type");
-	if (!type)
-		goto out;
-	data = silc_mime_get_data(mime, &data_len);
-	if (!data)
-		goto out;
-
-	/* Process according to content type */
-
-	/* Plain text */
-	if (strstr(type, "text/plain")) {
-		/* Default is UTF-8, don't check for other charsets */
-		if (!strstr(type, "utf-8"))
-			goto out;
-
-		if (channel)
-			silc_channel_message(client, conn, sender, channel,
-					     payload, key,
-					     SILC_MESSAGE_FLAG_UTF8, data,
-					     data_len);
-		else
-			silc_private_message(client, conn, sender, payload,
-					     SILC_MESSAGE_FLAG_UTF8, data,
-					     data_len);
-		goto out;
-	}
-
-	/* Image */
-	if (strstr(type, "image/png") ||
-	    strstr(type, "image/jpeg") ||
-	    strstr(type, "image/gif") ||
-	    strstr(type, "image/tiff")) {
-		char tmp[32];
-		int imgid;
-
-		/* Get channel convo (if message is for channel) */
-		if (key && channel) {
-			GList *l;
-			SilcPurplePrvgrp prv;
-
-			for (l = sg->grps; l; l = l->next)
-				if (((SilcPurplePrvgrp)l->data)->key == key) {
-					prv = l->data;
-					convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-							prv->channel, sg->account);
-					break;
-				}
-		}
-		if (channel && !convo)
-			convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-								    channel->channel_name, sg->account);
-		if (channel && !convo)
-			goto out;
-
-		imgid = purple_imgstore_add_with_id(g_memdup(data, data_len), data_len, "");
-		if (imgid) {
-			cflags |= PURPLE_MESSAGE_IMAGES | PURPLE_MESSAGE_RECV;
-			g_snprintf(tmp, sizeof(tmp), "<IMG ID=\"%d\">", imgid);
-
-			if (channel)
-				serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
-				 		 sender->nickname ?
-				 		  sender->nickname :
-						 "<unknown>", cflags,
-						 tmp, time(NULL));
-			else
-				serv_got_im(gc, sender->nickname ?
-					    sender->nickname : "<unknown>",
-					    tmp, cflags, time(NULL));
-
-			purple_imgstore_unref_by_id(imgid);
-			cflags = 0;
-		}
-		goto out;
-	}
-
-	/* Whiteboard message */
-	if (strstr(type, "application/x-wb") &&
-	    !purple_account_get_bool(sg->account, "block-wb", FALSE)) {
-		if (channel)
-			silcpurple_wb_receive_ch(client, conn, sender, channel,
-					       payload, flags, data, data_len);
-		else
-			silcpurple_wb_receive(client, conn, sender, payload,
-					    flags, data, data_len);
-		goto out;
-	}
-
- out:
-	if (!recursive)
-		silc_mime_free(mime);
-}
-#endif /* HAVE_SILCMIME_H */
-
-/* Message for a channel. The `sender' is the sender of the message
-   The `channel' is the channel. The `message' is the message.  Note
-   that `message' maybe NULL.  The `flags' indicates message flags
-   and it is used to determine how the message can be interpreted
-   (like it may tell the message is multimedia message). */
-
-static void
-silc_channel_message(SilcClient client, SilcClientConnection conn,
-		     SilcClientEntry sender, SilcChannelEntry channel,
-		     SilcMessagePayload payload, SilcChannelPrivateKey key,
-		     SilcMessageFlags flags, const unsigned char *message,
-		     SilcUInt32 message_len)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-	PurpleConversation *convo = NULL;
-	char *msg, *tmp;
-
-	if (!message)
-		return;
-
-	if (key) {
-		GList *l;
-		SilcPurplePrvgrp prv;
-
-		for (l = sg->grps; l; l = l->next)
-			if (((SilcPurplePrvgrp)l->data)->key == key) {
-				prv = l->data;
-				convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-										prv->channel, sg->account);
-				break;
-			}
-	}
-	if (!convo)
-		convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-								channel->channel_name, sg->account);
-	if (!convo)
-		return;
-
-	if (flags & SILC_MESSAGE_FLAG_SIGNED &&
-	    purple_account_get_bool(sg->account, "sign-verify", FALSE)) {
-		/* XXX */
-	}
-
-	if (flags & SILC_MESSAGE_FLAG_DATA) {
-		/* Process MIME message */
-#ifdef HAVE_SILCMIME_H
-		SilcMime mime;
-		mime = silc_mime_decode(message, message_len);
-		silcpurple_mime_message(client, conn, sender, channel, payload,
-				      key, flags, mime, FALSE);
-#else
-		char type[128], enc[128];
-		unsigned char *data;
-		SilcUInt32 data_len;
-
-		memset(type, 0, sizeof(type));
-		memset(enc, 0, sizeof(enc));
-
-		if (!silc_mime_parse(message, message_len, NULL, 0,
-		    type, sizeof(type) - 1, enc, sizeof(enc) - 1, &data,
-		    &data_len))
-			return;
-
-		if (!strcmp(type, "application/x-wb") &&
-		    !strcmp(enc, "binary") &&
-		    !purple_account_get_bool(sg->account, "block-wb", FALSE))
-			silcpurple_wb_receive_ch(client, conn, sender, channel,
-					       payload, flags, data, data_len);
-#endif
-		return;
-	}
-
-	if (flags & SILC_MESSAGE_FLAG_ACTION) {
-		msg = g_strdup_printf("/me %s",
-				      (const char *)message);
-		if (!msg)
-			return;
-
-		tmp = g_markup_escape_text(msg, -1);
-		/* Send to Purple */
-		serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
-				 sender->nickname ?
-				 sender->nickname : "<unknown>", 0,
-				 tmp, time(NULL));
-		g_free(tmp);
-		g_free(msg);
-		return;
-	}
-
-	if (flags & SILC_MESSAGE_FLAG_NOTICE) {
-		msg = g_strdup_printf("(notice) <I>%s</I> %s",
-				      sender->nickname ?
-				      sender->nickname : "<unknown>",
-				      (const char *)message);
-		if (!msg)
-			return;
-
-		/* Send to Purple */
-		purple_conversation_write(convo, NULL, (const char *)msg,
-					PURPLE_MESSAGE_SYSTEM, time(NULL));
-		g_free(msg);
-		return;
-	}
-
-	if (flags & SILC_MESSAGE_FLAG_UTF8) {
-		tmp = g_markup_escape_text((const char *)message, -1);
-		/* Send to Purple */
-		serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
-				 sender->nickname ?
-				 sender->nickname : "<unknown>", 0,
-				 tmp, time(NULL));
-		g_free(tmp);
-	}
-}
-
-
-/* Private message to the client. The `sender' is the sender of the
-   message. The message is `message'and maybe NULL.  The `flags'
-   indicates message flags  and it is used to determine how the message
-   can be interpreted (like it may tell the message is multimedia
-   message). */
-
-static void
-silc_private_message(SilcClient client, SilcClientConnection conn,
-		     SilcClientEntry sender, SilcMessagePayload payload,
-		     SilcMessageFlags flags, const unsigned char *message,
-		     SilcUInt32 message_len)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-	PurpleConversation *convo = NULL;
-	char *msg, *tmp;
-
-	if (!message)
-		return;
-
-	if (sender->nickname)
-		/* XXX - Should this be PURPLE_CONV_TYPE_IM? */
-		convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,
-								sender->nickname, sg->account);
-
-	if (flags & SILC_MESSAGE_FLAG_SIGNED &&
-	    purple_account_get_bool(sg->account, "sign-verify", FALSE)) {
-		/* XXX */
-	}
-
-	if (flags & SILC_MESSAGE_FLAG_DATA) {
-#ifdef HAVE_SILCMIME_H
-		/* Process MIME message */
-		SilcMime mime;
-		mime = silc_mime_decode(message, message_len);
-		silcpurple_mime_message(client, conn, sender, NULL, payload,
-				      NULL, flags, mime, FALSE);
-#else
-		char type[128], enc[128];
-		unsigned char *data;
-		SilcUInt32 data_len;
-
-		memset(type, 0, sizeof(type));
-		memset(enc, 0, sizeof(enc));
-
-		if (!silc_mime_parse(message, message_len, NULL, 0,
-		    type, sizeof(type) - 1, enc, sizeof(enc) - 1, &data,
-		    &data_len))
-			return;
-
-		if (!strcmp(type, "application/x-wb") &&
-		    !strcmp(enc, "binary") &&
-		    !purple_account_get_bool(sg->account, "block-wb", FALSE))
-			silcpurple_wb_receive(client, conn, sender, payload,
-					    flags, data, data_len);
-#endif
-		return;
-	}
-
-	if (flags & SILC_MESSAGE_FLAG_ACTION && convo) {
-		msg = g_strdup_printf("/me %s",
-				      (const char *)message);
-		if (!msg)
-			return;
-
-		tmp = g_markup_escape_text(msg, -1);
-		/* Send to Purple */
-		serv_got_im(gc, sender->nickname ?
-			    sender->nickname : "<unknown>",
-			    tmp, 0, time(NULL));
-		g_free(msg);
-		g_free(tmp);
-		return;
-	}
-
-	if (flags & SILC_MESSAGE_FLAG_NOTICE && convo) {
-		msg = g_strdup_printf("(notice) <I>%s</I> %s",
-				      sender->nickname ?
-				      sender->nickname : "<unknown>",
-				      (const char *)message);
-		if (!msg)
-			return;
-
-		/* Send to Purple */
-		purple_conversation_write(convo, NULL, (const char *)msg,
-					PURPLE_MESSAGE_SYSTEM, time(NULL));
-		g_free(msg);
-		return;
-	}
-
-	if (flags & SILC_MESSAGE_FLAG_UTF8) {
-		tmp = g_markup_escape_text((const char *)message, -1);
-		/* Send to Purple */
-		serv_got_im(gc, sender->nickname ?
-			    sender->nickname : "<unknown>",
-			    tmp, 0, time(NULL));
-		g_free(tmp);
-	}
-}
-
-
-/* Notify message to the client. The notify arguments are sent in the
-   same order as servers sends them. The arguments are same as received
-   from the server except for ID's.  If ID is received application receives
-   the corresponding entry to the ID. For example, if Client ID is received
-   application receives SilcClientEntry.  Also, if the notify type is
-   for channel the channel entry is sent to application (even if server
-   does not send it because client library gets the channel entry from
-   the Channel ID in the packet's header). */
-
-static void
-silc_notify(SilcClient client, SilcClientConnection conn,
-	    SilcNotifyType type, ...)
-{
-	va_list va;
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-	PurpleConversation *convo;
-	SilcClientEntry client_entry, client_entry2;
-	SilcChannelEntry channel;
-	SilcServerEntry server_entry;
-	SilcIdType idtype;
-	void *entry;
-	SilcUInt32 mode;
-	SilcHashTableList htl;
-	SilcChannelUser chu;
-	char buf[512], buf2[512], *tmp, *name;
-	SilcNotifyType notify;
-	PurpleBuddy *b;
-	int i;
-
-	va_start(va, type);
-	memset(buf, 0, sizeof(buf));
-
-	switch (type) {
-
-	case SILC_NOTIFY_TYPE_NONE:
-		break;
-
-	case SILC_NOTIFY_TYPE_INVITE:
-		{
-			GHashTable *components;
-			va_arg(va, SilcChannelEntry);
-			name = va_arg(va, char *);
-			client_entry = va_arg(va, SilcClientEntry);
-
-			components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
-			g_hash_table_insert(components, strdup("channel"), strdup(name));
-			serv_got_chat_invite(gc, name, client_entry->nickname, NULL, components);
-		}
-		break;
-
-	case SILC_NOTIFY_TYPE_JOIN:
-		client_entry = va_arg(va, SilcClientEntry);
-		channel = va_arg(va, SilcChannelEntry);
-
-		/* If we joined channel, do nothing */
-		if (client_entry == conn->local_entry)
-			break;
-
-		convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-								channel->channel_name, sg->account);
-		if (!convo)
-			break;
-
-		/* Join user to channel */
-		g_snprintf(buf, sizeof(buf), "%s@%s",
-			   client_entry->username, client_entry->hostname);
-		purple_conv_chat_add_user(PURPLE_CONV_CHAT(convo),
-					g_strdup(client_entry->nickname), buf, PURPLE_CBFLAGS_NONE, TRUE);
-
-		break;
-
-	case SILC_NOTIFY_TYPE_LEAVE:
-		client_entry = va_arg(va, SilcClientEntry);
-		channel = va_arg(va, SilcChannelEntry);
-
-		convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-								channel->channel_name, sg->account);
-		if (!convo)
-			break;
-
-		/* Remove user from channel */
-		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
-					   client_entry->nickname, NULL);
-
-		break;
-
-	case SILC_NOTIFY_TYPE_SIGNOFF:
-		client_entry = va_arg(va, SilcClientEntry);
-		tmp = va_arg(va, char *);
-
-		if (!client_entry->nickname)
-			break;
-
-		/* Remove from all channels */
-		silc_hash_table_list(client_entry->channels, &htl);
-		while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-			convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-									chu->channel->channel_name, sg->account);
-			if (!convo)
-				continue;
-			purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
-						   client_entry->nickname,
-						   tmp);
-		}
-		silc_hash_table_list_reset(&htl);
-
-		break;
-
-	case SILC_NOTIFY_TYPE_TOPIC_SET:
-		{
-			char *esc, *tmp2;
-			idtype = va_arg(va, int);
-			entry = va_arg(va, void *);
-			tmp = va_arg(va, char *);
-			channel = va_arg(va, SilcChannelEntry);
-
-			convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-									channel->channel_name, sg->account);
-			if (!convo)
-				break;
-
-			if (!tmp)
-				break;
-
-			esc = g_markup_escape_text(tmp, -1);
-			tmp2 = purple_markup_linkify(esc);
-			g_free(esc);
-
-			if (idtype == SILC_ID_CLIENT) {
-				client_entry = (SilcClientEntry)entry;
-				g_snprintf(buf, sizeof(buf),
-						_("%s has changed the topic of <I>%s</I> to: %s"),
-						client_entry->nickname, channel->channel_name, tmp2);
-				purple_conv_chat_write(PURPLE_CONV_CHAT(convo), client_entry->nickname,
-						buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
-				purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo),
-						client_entry->nickname, tmp);
-			} else if (idtype == SILC_ID_SERVER) {
-				server_entry = (SilcServerEntry)entry;
-				g_snprintf(buf, sizeof(buf),
-						_("%s has changed the topic of <I>%s</I> to: %s"),
-						server_entry->server_name, channel->channel_name, tmp2);
-				purple_conv_chat_write(PURPLE_CONV_CHAT(convo), server_entry->server_name,
-						buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
-				purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo),
-						server_entry->server_name, tmp);
-			} else if (idtype == SILC_ID_CHANNEL) {
-				channel = (SilcChannelEntry)entry;
-				g_snprintf(buf, sizeof(buf),
-						_("%s has changed the topic of <I>%s</I> to: %s"),
-						channel->channel_name, channel->channel_name, tmp2);
-				purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel->channel_name,
-						buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
-				purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo),
-						channel->channel_name, tmp);
-			} else {
-				purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, tmp);
-			}
-
-			g_free(tmp2);
-
-			break;
-
-		}
-	case SILC_NOTIFY_TYPE_NICK_CHANGE:
-		client_entry = va_arg(va, SilcClientEntry);
-		client_entry2 = va_arg(va, SilcClientEntry);
-
-		if (!strcmp(client_entry->nickname, client_entry2->nickname))
-			break;
-
-		/* Change nick on all channels */
-		silc_hash_table_list(client_entry2->channels, &htl);
-		while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-			convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-									chu->channel->channel_name, sg->account);
-			if (!convo)
-				continue;
-			if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(convo), client_entry->nickname))
-				purple_conv_chat_rename_user(PURPLE_CONV_CHAT(convo),
-										   client_entry->nickname,
-										   client_entry2->nickname);
-		}
-		silc_hash_table_list_reset(&htl);
-
-		break;
-
-	case SILC_NOTIFY_TYPE_CMODE_CHANGE:
-		idtype = va_arg(va, int);
-		entry = va_arg(va, void *);
-		mode = va_arg(va, SilcUInt32);
-		(void)va_arg(va, char *);
-		(void)va_arg(va, char *);
-		(void)va_arg(va, char *);
-		(void)va_arg(va, SilcPublicKey);
-		(void)va_arg(va, SilcBuffer);
-		channel = va_arg(va, SilcChannelEntry);
-
-		convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-								channel->channel_name, sg->account);
-		if (!convo)
-			break;
-
-		if (idtype == SILC_ID_CLIENT)
-			name = ((SilcClientEntry)entry)->nickname;
-		else if (idtype == SILC_ID_SERVER)
-			name = ((SilcServerEntry)entry)->server_name;
-		else
-			name = ((SilcChannelEntry)entry)->channel_name;
-		if (!name)
-			break;
-
-		if (mode) {
-			silcpurple_get_chmode_string(mode, buf2, sizeof(buf2));
-			g_snprintf(buf, sizeof(buf),
-				   _("<I>%s</I> set channel <I>%s</I> modes to: %s"), name,
-				   channel->channel_name, buf2);
-		} else {
-			g_snprintf(buf, sizeof(buf),
-				   _("<I>%s</I> removed all channel <I>%s</I> modes"), name,
-				   channel->channel_name);
-		}
-		purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel->channel_name,
-				     buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
-		break;
-
-	case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
-		{
-			PurpleConvChatBuddyFlags flags = PURPLE_CBFLAGS_NONE;
-			idtype = va_arg(va, int);
-			entry = va_arg(va, void *);
-			mode = va_arg(va, SilcUInt32);
-			client_entry2 = va_arg(va, SilcClientEntry);
-			channel = va_arg(va, SilcChannelEntry);
-
-			convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-									channel->channel_name, sg->account);
-			if (!convo)
-				break;
-
-			if (idtype == SILC_ID_CLIENT)
-				name = ((SilcClientEntry)entry)->nickname;
-			else if (idtype == SILC_ID_SERVER)
-				name = ((SilcServerEntry)entry)->server_name;
-			else
-				name = ((SilcChannelEntry)entry)->channel_name;
-			if (!name)
-				break;
-
-			if (mode) {
-				silcpurple_get_chumode_string(mode, buf2, sizeof(buf2));
-				g_snprintf(buf, sizeof(buf),
-						_("<I>%s</I> set <I>%s's</I> modes to: %s"), name,
-						client_entry2->nickname, buf2);
-				if (mode & SILC_CHANNEL_UMODE_CHANFO)
-					flags |= PURPLE_CBFLAGS_FOUNDER;
-				if (mode & SILC_CHANNEL_UMODE_CHANOP)
-					flags |= PURPLE_CBFLAGS_OP;
-			} else {
-				g_snprintf(buf, sizeof(buf),
-						_("<I>%s</I> removed all <I>%s's</I> modes"), name,
-						client_entry2->nickname);
-			}
-			purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel->channel_name,
-					buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
-			purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(convo), client_entry2->nickname, flags);
-			break;
-		}
-
-	case SILC_NOTIFY_TYPE_MOTD:
-		tmp = va_arg(va, char *);
-		silc_free(sg->motd);
-		sg->motd = silc_memdup(tmp, strlen(tmp));
-		break;
-
-	case SILC_NOTIFY_TYPE_KICKED:
-		client_entry = va_arg(va, SilcClientEntry);
-		tmp = va_arg(va, char *);
-		client_entry2 = va_arg(va, SilcClientEntry);
-		channel = va_arg(va, SilcChannelEntry);
-
-		convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-								channel->channel_name, sg->account);
-		if (!convo)
-			break;
-
-		if (client_entry == conn->local_entry) {
-			/* Remove us from channel */
-			g_snprintf(buf, sizeof(buf),
-				   _("You have been kicked off <I>%s</I> by <I>%s</I> (%s)"),
-				   channel->channel_name, client_entry2->nickname,
-				   tmp ? tmp : "");
-			purple_conv_chat_write(PURPLE_CONV_CHAT(convo), client_entry->nickname,
-					     buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
-			serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)));
-		} else {
-			/* Remove user from channel */
-			g_snprintf(buf, sizeof(buf), _("Kicked by %s (%s)"),
-				   client_entry2->nickname, tmp ? tmp : "");
-			purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
-						   client_entry->nickname,
-						   buf);
-		}
-
-		break;
-
-	case SILC_NOTIFY_TYPE_KILLED:
-		client_entry = va_arg(va, SilcClientEntry);
-		tmp = va_arg(va, char *);
-		idtype = va_arg(va, int);
-		entry = va_arg(va, SilcClientEntry);
-
-		if (!client_entry->nickname)
-			break;
-
-		if (client_entry == conn->local_entry) {
-			if (idtype == SILC_ID_CLIENT) {
-				client_entry2 = (SilcClientEntry)entry;
-				g_snprintf(buf, sizeof(buf),
-					   _("You have been killed by %s (%s)"),
-					   client_entry2->nickname, tmp ? tmp : "");
-			} else if (idtype == SILC_ID_SERVER) {
-				server_entry = (SilcServerEntry)entry;
-				g_snprintf(buf, sizeof(buf),
-					   _("You have been killed by %s (%s)"),
-					   server_entry->server_name, tmp ? tmp : "");
-			} else if (idtype == SILC_ID_CHANNEL) {
-				channel = (SilcChannelEntry)entry;
-				g_snprintf(buf, sizeof(buf),
-					   _("You have been killed by %s (%s)"),
-					   channel->channel_name, tmp ? tmp : "");
-			}
-
-			/* Remove us from all channels */
-			silc_hash_table_list(client_entry->channels, &htl);
-			while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-				convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-										chu->channel->channel_name, sg->account);
-				if (!convo)
-					continue;
-				purple_conv_chat_write(PURPLE_CONV_CHAT(convo), client_entry->nickname,
-						     buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
-				serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)));
-			}
-			silc_hash_table_list_reset(&htl);
-
-		} else {
-			if (idtype == SILC_ID_CLIENT) {
-				client_entry2 = (SilcClientEntry)entry;
-				g_snprintf(buf, sizeof(buf),
-					   _("Killed by %s (%s)"),
-					   client_entry2->nickname, tmp ? tmp : "");
-			} else if (idtype == SILC_ID_SERVER) {
-				server_entry = (SilcServerEntry)entry;
-				g_snprintf(buf, sizeof(buf),
-					   _("Killed by %s (%s)"),
-					   server_entry->server_name, tmp ? tmp : "");
-			} else if (idtype == SILC_ID_CHANNEL) {
-				channel = (SilcChannelEntry)entry;
-				g_snprintf(buf, sizeof(buf),
-					   _("Killed by %s (%s)"),
-					   channel->channel_name, tmp ? tmp : "");
-			}
-
-			/* Remove user from all channels */
-			silc_hash_table_list(client_entry->channels, &htl);
-			while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-				convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-										chu->channel->channel_name, sg->account);
-				if (!convo)
-					continue;
-				purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
-							   client_entry->nickname, tmp);
-			}
-			silc_hash_table_list_reset(&htl);
-		}
-
-		break;
-
-	case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
-		break;
-
-	case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
-		{
-			int i;
-			SilcClientEntry *clients;
-			SilcUInt32 clients_count;
-
-			(void)va_arg(va, void *);
-			clients = va_arg(va, SilcClientEntry *);
-			clients_count = va_arg(va, SilcUInt32);
-
-			for (i = 0; i < clients_count; i++) {
-				if (!clients[i]->nickname)
-					break;
-
-				/* Remove from all channels */
-				silc_hash_table_list(clients[i]->channels, &htl);
-				while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-					convo =
-						purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-											chu->channel->channel_name, sg->account);
-					if (!convo)
-						continue;
-					purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
-								   clients[i]->nickname,
-								   _("Server signoff"));
-				}
-				silc_hash_table_list_reset(&htl);
-			}
-		}
-		break;
-
-	case SILC_NOTIFY_TYPE_ERROR:
-		{
-			SilcStatus error = va_arg(va, int);
-			purple_notify_error(gc, "Error Notify",
-					  silc_get_status_message(error),
-					  NULL);
-		}
-		break;
-
-	case SILC_NOTIFY_TYPE_WATCH:
-		{
-			SilcPublicKey public_key;
-			unsigned char *pk;
-			SilcUInt32 pk_len;
-			char *fingerprint;
-
-			client_entry = va_arg(va, SilcClientEntry);
-			(void)va_arg(va, char *);
-			mode = va_arg(va, SilcUInt32);
-			notify = va_arg(va, int);
-			public_key = va_arg(va, SilcPublicKey);
-
-			b = NULL;
-			if (public_key) {
-				PurpleBlistNode *gnode, *cnode, *bnode;
-				const char *f;
-
-				pk = silc_pkcs_public_key_encode(public_key, &pk_len);
-				if (!pk)
-					break;
-				fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-				for (i = 0; i < strlen(fingerprint); i++)
-					if (fingerprint[i] == ' ')
-						fingerprint[i] = '_';
-				g_snprintf(buf, sizeof(buf) - 1,
-					   "%s" G_DIR_SEPARATOR_S "clientkeys"
-					   G_DIR_SEPARATOR_S "clientkey_%s.pub",
-					   silcpurple_silcdir(), fingerprint);
-				silc_free(fingerprint);
-				silc_free(pk);
-
-				/* Find buddy by associated public key */
-				for (gnode = purple_get_blist()->root; gnode;
-				     gnode = gnode->next) {
-					if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))
-						continue;
-					for (cnode = gnode->child; cnode; cnode = cnode->next) {
-						if( !PURPLE_BLIST_NODE_IS_CONTACT(cnode))
-							continue;
-						for (bnode = cnode->child; bnode;
-						     bnode = bnode->next) {
-							if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
-								continue;
-							b = (PurpleBuddy *)bnode;
-							if (b->account != gc->account)
-								continue;
-							f = purple_blist_node_get_string(bnode, "public-key");
-							if (f && !strcmp(f, buf))
-								goto cont;
-							b = NULL;
-						}
-					}
-				}
-			}
-		cont:
-			if (!b) {
-				/* Find buddy by nickname */
-				b = purple_find_buddy(sg->account, client_entry->nickname);
-				if (!b) {
-					purple_debug_warning("silc", "WATCH for %s, unknown buddy\n",
-						client_entry->nickname);
-					break;
-				}
-			}
-
-			silc_free(b->proto_data);
-			b->proto_data = silc_memdup(client_entry->id,
-						    sizeof(*client_entry->id));
-			if (notify == SILC_NOTIFY_TYPE_NICK_CHANGE) {
-				break;
-			} else if (notify == SILC_NOTIFY_TYPE_UMODE_CHANGE) {
-				/* See if client was away and is now present */
-				if (!(mode & (SILC_UMODE_GONE | SILC_UMODE_INDISPOSED |
-					      SILC_UMODE_BUSY | SILC_UMODE_PAGE |
-					      SILC_UMODE_DETACHED)) &&
-				    (client_entry->mode & SILC_UMODE_GONE ||
-				     client_entry->mode & SILC_UMODE_INDISPOSED ||
-				     client_entry->mode & SILC_UMODE_BUSY ||
-				     client_entry->mode & SILC_UMODE_PAGE ||
-				     client_entry->mode & SILC_UMODE_DETACHED)) {
-					client_entry->mode = mode;
-					purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL);
-				}
-				else if ((mode & SILC_UMODE_GONE) ||
-					 (mode & SILC_UMODE_INDISPOSED) ||
-					 (mode & SILC_UMODE_BUSY) ||
-					 (mode & SILC_UMODE_PAGE) ||
-					 (mode & SILC_UMODE_DETACHED)) {
-					client_entry->mode = mode;
-					purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_OFFLINE, NULL);
-				}
-			} else if (notify == SILC_NOTIFY_TYPE_SIGNOFF ||
-				   notify == SILC_NOTIFY_TYPE_SERVER_SIGNOFF ||
-				   notify == SILC_NOTIFY_TYPE_KILLED) {
-				client_entry->mode = mode;
-				purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_OFFLINE, NULL);
-			} else if (notify == SILC_NOTIFY_TYPE_NONE) {
-				client_entry->mode = mode;
-				purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL);
-			}
-		}
-		break;
-
-	default:
-		purple_debug_info("silc", "Unhandled notification: %d\n", type);
-		break;
-	}
-
-	va_end(va);
-}
-
-
-/* Command handler. This function is called always in the command function.
-   If error occurs it will be called as well. `conn' is the associated
-   client connection. `cmd_context' is the command context that was
-   originally sent to the command. `success' is FALSE if error occurred
-   during command. `command' is the command being processed. It must be
-   noted that this is not reply from server. This is merely called just
-   after application has called the command. Just to tell application
-   that the command really was processed. */
-
-static void
-silc_command(SilcClient client, SilcClientConnection conn,
-	     SilcClientCommandContext cmd_context, bool success,
-	     SilcCommand command, SilcStatus status)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-
-	switch (command) {
-
-	case SILC_COMMAND_CMODE:
-		if (cmd_context->argc == 3 &&
-		    !strcmp((char *)cmd_context->argv[2], "+C"))
-			sg->chpk = TRUE;
-		else
-			sg->chpk = FALSE;
-		break;
-
-	default:
-		break;
-	}
-}
-
-#if 0
-static void
-silcpurple_whois_more(SilcClientEntry client_entry, gint id)
-{
-	SilcAttributePayload attr;
-	SilcAttribute attribute;
-	char *buf;
-	GString *s;
-	SilcVCardStruct vcard;
-	int i;
-
-	if (id != 0)
-		return;
-
-	memset(&vcard, 0, sizeof(vcard));
-
-	s = g_string_new("");
-
-	silc_dlist_start(client_entry->attrs);
-	while ((attr = silc_dlist_get(client_entry->attrs)) != SILC_LIST_END) {
-		attribute = silc_attribute_get_attribute(attr);
-		switch (attribute) {
-
-		case SILC_ATTRIBUTE_USER_INFO:
-			if (!silc_attribute_get_object(attr, (void *)&vcard,
-						       sizeof(vcard)))
-				continue;
-			g_string_append_printf(s, "%s:\n\n", _("Personal Information"));
-			if (vcard.full_name)
-				g_string_append_printf(s, "%s:\t\t%s\n",
-						       _("Full Name"),
-						       vcard.full_name);
-			if (vcard.first_name)
-				g_string_append_printf(s, "%s:\t%s\n",
-						       _("First Name"),
-						       vcard.first_name);
-			if (vcard.middle_names)
-				g_string_append_printf(s, "%s:\t%s\n",
-						       _("Middle Name"),
-						       vcard.middle_names);
-			if (vcard.family_name)
-				g_string_append_printf(s, "%s:\t%s\n",
-						       _("Family Name"),
-						       vcard.family_name);
-			if (vcard.nickname)
-				g_string_append_printf(s, "%s:\t\t%s\n",
-						       _("Nickname"),
-						       vcard.nickname);
-			if (vcard.bday)
-				g_string_append_printf(s, "%s:\t\t%s\n",
-						       _("Birth Day"),
-						       vcard.bday);
-			if (vcard.title)
-				g_string_append_printf(s, "%s:\t\t%s\n",
-						       _("Job Title"),
-						       vcard.title);
-			if (vcard.role)
-				g_string_append_printf(s, "%s:\t\t%s\n",
-						       _("Job Role"),
-						       vcard.role);
-			if (vcard.org_name)
-				g_string_append_printf(s, "%s:\t%s\n",
-						       _("Organization"),
-						       vcard.org_name);
-			if (vcard.org_unit)
-				g_string_append_printf(s, "%s:\t\t%s\n",
-						       _("Unit"),
-						       vcard.org_unit);
-			if (vcard.url)
-				g_string_append_printf(s, "%s:\t%s\n",
-						       _("Homepage"),
-						       vcard.url);
-			if (vcard.label)
-				g_string_append_printf(s, "%s:\t%s\n",
-						       _("Address"),
-						       vcard.label);
-			for (i = 0; i < vcard.num_tels; i++) {
-				if (vcard.tels[i].telnum)
-					g_string_append_printf(s, "%s:\t\t\t%s\n",
-							       _("Phone"),
-							       vcard.tels[i].telnum);
-			}
-			for (i = 0; i < vcard.num_emails; i++) {
-				if (vcard.emails[i].address)
-					g_string_append_printf(s, "%s:\t\t%s\n",
-							       _("Email"),
-							       vcard.emails[i].address);
-			}
-			if (vcard.note)
-				g_string_append_printf(s, "\n%s:\t\t%s\n",
-						       _("Note"),
-						       vcard.note);
-			break;
-		}
-	}
-
-	buf = g_string_free(s, FALSE);
-	purple_notify_info(NULL, _("User Information"), _("User Information"),
-			 buf);
-	g_free(buf);
-}
-#endif
-
-/* Command reply handler. This function is called always in the command reply
-   function. If error occurs it will be called as well. Normal scenario
-   is that it will be called after the received command data has been parsed
-   and processed. The function is used to pass the received command data to
-   the application.
-
-   `conn' is the associated client connection. `cmd_payload' is the command
-   payload data received from server and it can be ignored. It is provided
-   if the application would like to re-parse the received command data,
-   however, it must be noted that the data is parsed already by the library
-   thus the payload can be ignored. `success' is FALSE if error occurred.
-   In this case arguments are not sent to the application. The `status' is
-   the command reply status server returned. The `command' is the command
-   reply being processed. The function has variable argument list and each
-   command defines the number and type of arguments it passes to the
-   application (on error they are not sent). */
-
-static void
-silc_command_reply(SilcClient client, SilcClientConnection conn,
-		   SilcCommandPayload cmd_payload, bool success,
-		   SilcCommand command, SilcStatus status, ...)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-	PurpleConversation *convo;
-	va_list vp;
-
-	va_start(vp, status);
-
-	switch (command) {
-	case SILC_COMMAND_JOIN:
-		{
-			SilcChannelEntry channel_entry;
-
-			if (!success) {
-				purple_notify_error(gc, _("Join Chat"), _("Cannot join channel"),
-						  silc_get_status_message(status));
-				return;
-			}
-
-			(void)va_arg(vp, char *);
-			channel_entry = va_arg(vp, SilcChannelEntry);
-
-			/* Resolve users on channel */
-			silc_client_get_clients_by_channel(client, conn, channel_entry,
-							   silcpurple_chat_join_done,
-							   channel_entry);
-		}
-		break;
-
-	case SILC_COMMAND_LEAVE:
-		break;
-
-	case SILC_COMMAND_USERS:
-		break;
-
-	case SILC_COMMAND_WHOIS:
-		{
-			SilcUInt32 idle, mode;
-			SilcBuffer channels, user_modes;
-			SilcClientEntry client_entry;
-			char tmp[1024], *tmp2;
-			char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr;
-			PurpleNotifyUserInfo *user_info;
-
-			if (!success) {
-				purple_notify_error(gc, _("User Information"),
-						_("Cannot get user information"),
-						silc_get_status_message(status));
-				break;
-			}
-
-			client_entry = va_arg(vp, SilcClientEntry);
-			if (!client_entry->nickname)
-				break;
-			(void)va_arg(vp, char *);
-			(void)va_arg(vp, char *);
-			(void)va_arg(vp, char *);
-			channels = va_arg(vp, SilcBuffer);
-			mode = va_arg(vp, SilcUInt32);
-			idle = va_arg(vp, SilcUInt32);
-			(void)va_arg(vp, unsigned char *);
-			user_modes = va_arg(vp, SilcBuffer);
-
-			user_info = purple_notify_user_info_new();
-			tmp2 = g_markup_escape_text(client_entry->nickname, -1);
-			purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp2);
-			g_free(tmp2);
-			if (client_entry->realname) {
-				tmp2 = g_markup_escape_text(client_entry->realname, -1);
-				purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp2);
-				g_free(tmp2);
-			}
-			if (client_entry->username) {
-				tmp2 = g_markup_escape_text(client_entry->username, -1);
-				if (client_entry->hostname) {
-					gchar *tmp3;
-					tmp3 = g_strdup_printf("%s@%s", tmp2, client_entry->hostname);
-					purple_notify_user_info_add_pair(user_info, _("Username"), tmp3);
-					g_free(tmp3);
-				} else
-					purple_notify_user_info_add_pair(user_info, _("Username"), tmp2);
-				g_free(tmp2);
-			}
-
-			if (client_entry->mode) {
-				memset(tmp, 0, sizeof(tmp));
-				silcpurple_get_umode_string(client_entry->mode,
-						tmp, sizeof(tmp) - strlen(tmp));
-				purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp);
-			}
-
-			silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr);
-			if (moodstr) {
-				purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr);
-				g_free(moodstr);
-			}
-
-			if (statusstr) {
-				tmp2 = g_markup_escape_text(statusstr, -1);
-				purple_notify_user_info_add_pair(user_info, _("Status Text"), tmp2);
-				g_free(statusstr);
-				g_free(tmp2);
-			}
-
-			if (contactstr) {
-				purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr);
-				g_free(contactstr);
-			}
-
-			if (langstr) {
-				purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr);
-				g_free(langstr);
-			}
-
-			if (devicestr) {
-				purple_notify_user_info_add_pair(user_info, _("Device"), devicestr);
-				g_free(devicestr);
-			}
-
-			if (tzstr) {
-				purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr);
-				g_free(tzstr);
-			}
-
-			if (geostr) {
-				purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr);
-				g_free(geostr);
-			}
-
-			if (client_entry->server)
-				purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server);
-
-			if (channels && user_modes) {
-				SilcUInt32 *umodes;
-				SilcDList list =
-					silc_channel_payload_parse_list(channels->data,
-							channels->len);
-				if (list && silc_get_mode_list(user_modes,
-							silc_dlist_count(list),
-							&umodes)) {
-					SilcChannelPayload entry;
-					int i = 0;
-
-					memset(tmp, 0, sizeof(tmp));
-					silc_dlist_start(list);
-					while ((entry = silc_dlist_get(list))
-							!= SILC_LIST_END) {
-						SilcUInt32 name_len;
-						char *m = silc_client_chumode_char(umodes[i++]);
-						char *name = (char *)silc_channel_get_name(entry, &name_len);
-						if (m)
-							silc_strncat(tmp, sizeof(tmp) - 1, m, strlen(m));
-						silc_strncat(tmp, sizeof(tmp) - 1, name, name_len);
-						silc_strncat(tmp, sizeof(tmp) - 1, "  ", 1);
-						silc_free(m);
-
-					}
-					tmp2 = g_markup_escape_text(tmp, -1);
-					purple_notify_user_info_add_pair(user_info, _("Currently on"), tmp2);
-					g_free(tmp2);
-					silc_free(umodes);
-				}
-			}
-
-			if (client_entry->public_key) {
-				char *fingerprint, *babbleprint;
-				unsigned char *pk;
-				SilcUInt32 pk_len;
-				pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len);
-				fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-				babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
-				purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
-				purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
-				silc_free(fingerprint);
-				silc_free(babbleprint);
-				silc_free(pk);
-			}
-
-#if 0 /* XXX for now, let's not show attrs here */
-			if (client_entry->attrs)
-				purple_request_action(gc, _("User Information"),
-						_("User Information"),
-						buf, 1, client_entry, 2,
-						_("OK"), G_CALLBACK(silcpurple_whois_more),
-						_("_More..."), G_CALLBACK(silcpurple_whois_more), gc->account, NULL, NULL);
-			else
-#endif
-			purple_notify_userinfo(gc, client_entry->nickname, user_info, NULL, NULL);
-			purple_notify_user_info_destroy(user_info);
-		}
-		break;
-
-	case SILC_COMMAND_WHOWAS:
-		{
-			SilcClientEntry client_entry;
-			char *nickname, *realname, *username, *tmp;
-			PurpleNotifyUserInfo *user_info;
-
-			if (!success) {
-				purple_notify_error(gc, _("User Information"),
-						  _("Cannot get user information"),
-						  silc_get_status_message(status));
-				break;
-			}
-
-			client_entry = va_arg(vp, SilcClientEntry);
-			nickname = va_arg(vp, char *);
-			username = va_arg(vp, char *);
-			realname = va_arg(vp, char *);
-			if (!nickname)
-				break;
-
-			user_info = purple_notify_user_info_new();
-			tmp = g_markup_escape_text(nickname, -1);
-			purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp);
-			g_free(tmp);
-			if (realname) {
-				tmp = g_markup_escape_text(realname, -1);
-				purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp);
-				g_free(tmp);
-			}
-			if (username) {
-				tmp = g_markup_escape_text(username, -1);
-				if (client_entry && client_entry->hostname) {
-					gchar *tmp3;
-					tmp3 = g_strdup_printf("%s@%s", tmp, client_entry->hostname);
-					purple_notify_user_info_add_pair(user_info, _("Username"), tmp3);
-					g_free(tmp3);
-				} else
-					purple_notify_user_info_add_pair(user_info, _("Username"), tmp);
-				g_free(tmp);
-			}
-			if (client_entry && client_entry->server)
-				purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server);
-
-
-			if (client_entry && client_entry->public_key) {
-				char *fingerprint, *babbleprint;
-				unsigned char *pk;
-				SilcUInt32 pk_len;
-				pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len);
-				fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-				babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
-				purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
-				purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
-				silc_free(fingerprint);
-				silc_free(babbleprint);
-				silc_free(pk);
-			}
-
-			purple_notify_userinfo(gc, nickname, user_info, NULL, NULL);
-			purple_notify_user_info_destroy(user_info);
-		}
-		break;
-
-	case SILC_COMMAND_DETACH:
-		if (!success) {
-			purple_notify_error(gc, _("Detach From Server"), _("Cannot detach"),
-					  silc_get_status_message(status));
-			return;
-		}
-		break;
-
-	case SILC_COMMAND_TOPIC:
-		{
-			SilcChannelEntry channel;
-
-			if (!success) {
-				purple_notify_error(gc, _("Topic"), _("Cannot set topic"),
-						  silc_get_status_message(status));
-				return;
-			}
-
-			channel = va_arg(vp, SilcChannelEntry);
-
-			convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-									channel->channel_name, sg->account);
-			if (!convo) {
-				purple_debug_error("silc", "Got a topic for %s, which doesn't exist\n",
-								 channel->channel_name);
-				break;
-			}
-
-			/* Set topic */
-			if (channel->topic)
-				purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, channel->topic);
-		}
-		break;
-
-	case SILC_COMMAND_NICK:
-		{
-			/* I don't think we should need to do this because the server should
-			 * be sending a SILC_NOTIFY_TYPE_NICK_CHANGE when we change our own
-			 * nick, but it isn't, so we deal with it here instead. Stu. */
-			SilcClientEntry local_entry;
-			SilcHashTableList htl;
-			SilcChannelUser chu;
-			const char *oldnick;
-
-			if (!success) {
-				purple_notify_error(gc, _("Nick"), _("Failed to change nickname"),
-						silc_get_status_message(status));
-				return;
-			}
-
-			local_entry = va_arg(vp, SilcClientEntry);
-
-			/* Change nick on all channels */
-			silc_hash_table_list(local_entry->channels, &htl);
-			while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-				convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-									chu->channel->channel_name, sg->account);
-				if (!convo)
-					continue;
-				oldnick = purple_conv_chat_get_nick(PURPLE_CONV_CHAT(convo));
-				if (strcmp(oldnick, purple_normalize(purple_conversation_get_account(convo), local_entry->nickname))) {
-					purple_conv_chat_rename_user(PURPLE_CONV_CHAT(convo),
-							oldnick, local_entry->nickname);
-					purple_conv_chat_set_nick(PURPLE_CONV_CHAT(convo), local_entry->nickname);
-				}
-			}
-			silc_hash_table_list_reset(&htl);
-
-			purple_connection_set_display_name(gc, local_entry->nickname);
-		}
-		break;
-
-	case SILC_COMMAND_LIST:
-		{
-			char *topic, *name;
-			int usercount;
-			PurpleRoomlistRoom *room;
-
-			if (sg->roomlist_cancelled)
-				break;
-
-			if (!success) {
-				purple_notify_error(gc, _("Error"), _("Error retrieving room list"),
-						  silc_get_status_message(status));
-				purple_roomlist_set_in_progress(sg->roomlist, FALSE);
-				purple_roomlist_unref(sg->roomlist);
-				sg->roomlist = NULL;
-				return;
-			}
-
-			(void)va_arg(vp, SilcChannelEntry);
-			name = va_arg(vp, char *);
-			if (!name) {
-				purple_notify_error(gc, _("Roomlist"), _("Cannot get room list"),
-						  silc_get_status_message(status));
-				purple_roomlist_set_in_progress(sg->roomlist, FALSE);
-				purple_roomlist_unref(sg->roomlist);
-				sg->roomlist = NULL;
-				return;
-			}
-			topic = va_arg(vp, char *);
-			usercount = va_arg(vp, int);
-
-			room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, name, NULL);
-			purple_roomlist_room_add_field(sg->roomlist, room, name);
-			purple_roomlist_room_add_field(sg->roomlist, room,
-						     SILC_32_TO_PTR(usercount));
-			purple_roomlist_room_add_field(sg->roomlist, room,
-						     topic ? topic : "");
-			purple_roomlist_room_add(sg->roomlist, room);
-
-			if (status == SILC_STATUS_LIST_END ||
-			    status == SILC_STATUS_OK) {
-				purple_roomlist_set_in_progress(sg->roomlist, FALSE);
-				purple_roomlist_unref(sg->roomlist);
-				sg->roomlist = NULL;
-			}
-		}
-		break;
-
-	case SILC_COMMAND_GETKEY:
-		{
-			SilcPublicKey public_key;
-
-			if (!success) {
-				purple_notify_error(gc, _("Get Public Key"),
-						  _("Cannot fetch the public key"),
-						  silc_get_status_message(status));
-				return;
-			}
-
-			(void)va_arg(vp, SilcUInt32);
-			(void)va_arg(vp, void *);
-			public_key = va_arg(vp, SilcPublicKey);
-
-			if (!public_key)
-				purple_notify_error(gc, _("Get Public Key"),
-						  _("Cannot fetch the public key"),
-						  _("No public key was received"));
-		}
-		break;
-
-	case SILC_COMMAND_INFO:
-		{
-
-			char *server_name;
-			char *server_info;
-			char tmp[256];
-
-			if (!success) {
-				purple_notify_error(gc, _("Server Information"),
-						  _("Cannot get server information"),
-						  silc_get_status_message(status));
-				return;
-			}
-
-			(void)va_arg(vp, SilcServerEntry);
-			server_name = va_arg(vp, char *);
-			server_info = va_arg(vp, char *);
-
-			if (server_name && server_info) {
-				g_snprintf(tmp, sizeof(tmp), "Server: %s\n%s",
-					   server_name, server_info);
-				purple_notify_info(gc, NULL, _("Server Information"), tmp);
-			}
-		}
-		break;
-
-	case SILC_COMMAND_STATS:
-		{
-			SilcUInt32 starttime, uptime, my_clients, my_channels, my_server_ops,
-			my_router_ops, cell_clients, cell_channels, cell_servers,
-			clients, channels, servers, routers, server_ops, router_ops;
-			SilcUInt32 buffer_length;
-			SilcBufferStruct buf;
-
-			unsigned char *server_stats;
-			char *msg;
-
-			if (!success) {
-				purple_notify_error(gc, _("Server Statistics"),
-						_("Cannot get server statistics"),
-						silc_get_status_message(status));
-				return;
-			}
-
-			server_stats = va_arg(vp, unsigned char *);
-			buffer_length = va_arg(vp, SilcUInt32);
-			if (!server_stats || !buffer_length) {
-				purple_notify_error(gc, _("Server Statistics"),
-						_("No server statistics available"), NULL);
-				break;
-			}
-			silc_buffer_set(&buf, server_stats, buffer_length);
-			silc_buffer_unformat(&buf,
-					SILC_STR_UI_INT(&starttime),
-					SILC_STR_UI_INT(&uptime),
-					SILC_STR_UI_INT(&my_clients),
-					SILC_STR_UI_INT(&my_channels),
-					SILC_STR_UI_INT(&my_server_ops),
-					SILC_STR_UI_INT(&my_router_ops),
-					SILC_STR_UI_INT(&cell_clients),
-					SILC_STR_UI_INT(&cell_channels),
-					SILC_STR_UI_INT(&cell_servers),
-					SILC_STR_UI_INT(&clients),
-					SILC_STR_UI_INT(&channels),
-					SILC_STR_UI_INT(&servers),
-					SILC_STR_UI_INT(&routers),
-					SILC_STR_UI_INT(&server_ops),
-					SILC_STR_UI_INT(&router_ops),
-					SILC_STR_END);
-
-			msg = g_strdup_printf(_("Local server start time: %s\n"
-					"Local server uptime: %s\n"
-					"Local server clients: %d\n"
-					"Local server channels: %d\n"
-					"Local server operators: %d\n"
-					"Local router operators: %d\n"
-					"Local cell clients: %d\n"
-					"Local cell channels: %d\n"
-					"Local cell servers: %d\n"
-					"Total clients: %d\n"
-					"Total channels: %d\n"
-					"Total servers: %d\n"
-					"Total routers: %d\n"
-					"Total server operators: %d\n"
-					"Total router operators: %d\n"),
-					silc_get_time(starttime),
-					purple_str_seconds_to_string((int)uptime),
-					(int)my_clients, (int)my_channels, (int)my_server_ops, (int)my_router_ops,
-					(int)cell_clients, (int)cell_channels, (int)cell_servers,
-					(int)clients, (int)channels, (int)servers, (int)routers,
-					(int)server_ops, (int)router_ops);
-
-			purple_notify_info(gc, NULL,
-					_("Network Statistics"), msg);
-			g_free(msg);
-		}
-		break;
-
-	case SILC_COMMAND_PING:
-		{
-			if (!success) {
-				purple_notify_error(gc, _("Ping"), _("Ping failed"),
-								  silc_get_status_message(status));
-				return;
-			}
-
-			purple_notify_info(gc, _("Ping"), _("Ping reply received from server"),
-							 NULL);
-		}
-		break;
-
-	case SILC_COMMAND_KILL:
-		if (!success) {
-			purple_notify_error(gc, _("Kill User"),
-					  _("Could not kill user"),
-					  silc_get_status_message(status));
-			return;
-		}
-		break;
-
-	case SILC_COMMAND_CMODE:
-		{
-			SilcChannelEntry channel_entry;
-			SilcBuffer channel_pubkeys;
-
-			if (!success)
-				return;
-
-			channel_entry = va_arg(vp, SilcChannelEntry);
-			(void)va_arg(vp, SilcUInt32);
-			(void)va_arg(vp, SilcPublicKey);
-			channel_pubkeys = va_arg(vp, SilcBuffer);
-
-			if (sg->chpk)
-				silcpurple_chat_chauth_show(sg, channel_entry, channel_pubkeys);
-		}
-		break;
-
-	default:
-		if (success)
-			purple_debug_info("silc", "Unhandled command: %d (succeeded)\n", command);
-		else
-			purple_debug_info("silc", "Unhandled command: %d (failed: %s)\n", command,
-							silc_get_status_message(status));
-		break;
-	}
-
-	va_end(vp);
-}
-
-
-/* Called to indicate that connection was either successfully established
-   or connecting failed.  This is also the first time application receives
-   the SilcClientConnection object which it should save somewhere.
-   If the `success' is FALSE the application must always call the function
-   silc_client_close_connection. */
-
-static void
-silc_connected(SilcClient client, SilcClientConnection conn,
-	       SilcClientConnectionStatus status)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg;
-
-	if (gc == NULL) {
-		silc_client_close_connection(client, conn);
-		return;
-	}
-	sg = gc->proto_data;
-
-	switch (status) {
-	case SILC_CLIENT_CONN_SUCCESS:
-	case SILC_CLIENT_CONN_SUCCESS_RESUME:
-		purple_connection_set_state(gc, PURPLE_CONNECTED);
-
-		/* Send the server our buddy list */
-		silcpurple_send_buddylist(gc);
-
-		g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
-
-		/* Send any UMODEs configured for account */
-		if (purple_account_get_bool(sg->account, "block-ims", FALSE)) {
-			silc_client_command_call(sg->client, sg->conn, NULL,
-					"UMODE", "+P", NULL);
-		}
-
-		return;
-		break;
-	case SILC_CLIENT_CONN_ERROR:
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-			_("Error during connecting to SILC Server"));
-		g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
-		break;
-
-	case SILC_CLIENT_CONN_ERROR_KE:
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
-			_("Key Exchange failed"));
-		break;
-
-	case SILC_CLIENT_CONN_ERROR_AUTH:
-		purple_connection_error_reason(gc,
-			PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
-			_("Authentication failed"));
-		break;
-
-	case SILC_CLIENT_CONN_ERROR_RESUME:
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
-			_("Resuming detached session failed. "
-			  "Press Reconnect to create new connection."));
-		g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
-		break;
-
-	case SILC_CLIENT_CONN_ERROR_TIMEOUT:
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-			_("Connection timed out"));
-		break;
-	}
-
-	/* Error */
-	sg->conn = NULL;
-	silc_client_close_connection(client, conn);
-}
-
-
-/* Called to indicate that connection was disconnected to the server.
-   The `status' may tell the reason of the disconnection, and if the
-   `message' is non-NULL it may include the disconnection message
-   received from server. */
-
-static void
-silc_disconnected(SilcClient client, SilcClientConnection conn,
-		  SilcStatus status, const char *message)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-
-	if (sg->resuming && !sg->detaching)
-		g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
-
-	sg->conn = NULL;
-
-	/* Close the connection */
-	if (!sg->detaching)
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-			_("Disconnected by server"));
-	else
-		/* TODO: Does this work correctly? Maybe we need to set wants_to_die? */
-		purple_account_disconnect(purple_connection_get_account(gc));
-}
-
-
-typedef struct {
-	SilcGetAuthMeth completion;
-	void *context;
-} *SilcPurpleGetAuthMethod;
-
-/* Callback called when we've received the authentication method information
-   from the server after we've requested it. */
-
-static void silc_get_auth_method_callback(SilcClient client,
-					  SilcClientConnection conn,
-					  SilcAuthMethod auth_meth,
-					  void *context)
-{
-	SilcPurpleGetAuthMethod internal = context;
-
-	switch (auth_meth) {
-	case SILC_AUTH_NONE:
-		/* No authentication required. */
-		(*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
-		break;
-
-	case SILC_AUTH_PASSWORD:
-		/* By returning NULL here the library will ask the passphrase from us
-		   by calling the silc_ask_passphrase. */
-		(*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
-		break;
-
-	case SILC_AUTH_PUBLIC_KEY:
-		/* Do not get the authentication data now, the library will generate
-		   it using our default key, if we do not provide it here. */
-		(*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
-		break;
-	}
-
-	silc_free(internal);
-}
-
-/* Find authentication method and authentication data by hostname and
-   port. The hostname may be IP address as well. When the authentication
-   method has been resolved the `completion' callback with the found
-   authentication method and authentication data is called. The `conn'
-   may be NULL. */
-
-static void
-silc_get_auth_method(SilcClient client, SilcClientConnection conn,
-		     char *hostname, SilcUInt16 port,
-		     SilcGetAuthMeth completion, void *context)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-	SilcPurpleGetAuthMethod internal;
-	const char *password;
-
-	/* Progress */
-	if (sg->resuming)
-		purple_connection_update_progress(gc, _("Resuming session"), 4, 5);
-	else
-		purple_connection_update_progress(gc, _("Authenticating connection"), 4, 5);
-
-	/* Check configuration if we have this connection configured.  If we
-	   have then return that data immediately, as it's faster way. */
-	if (purple_account_get_bool(sg->account, "pubkey-auth", FALSE)) {
-		completion(TRUE, SILC_AUTH_PUBLIC_KEY, NULL, 0, context);
-		return;
-	}
-	password = purple_connection_get_password(gc);
-	if (password && *password) {
-		completion(TRUE, SILC_AUTH_PASSWORD, (unsigned char *)password, strlen(password), context);
-		return;
-	}
-
-	/* Resolve the authentication method from server, as we may not know it. */
-	internal = silc_calloc(1, sizeof(*internal));
-	if (!internal)
-		return;
-	internal->completion = completion;
-	internal->context = context;
-	silc_client_request_authentication_method(client, conn,
-						  silc_get_auth_method_callback,
-						  internal);
-}
-
-
-/* Verifies received public key. The `conn_type' indicates which entity
-   (server, client etc.) has sent the public key. If user decides to trust
-   the application may save the key as trusted public key for later
-   use. The `completion' must be called after the public key has been
-   verified. */
-
-static void
-silc_verify_public_key(SilcClient client, SilcClientConnection conn,
-		       SilcSocketType conn_type, unsigned char *pk,
-		       SilcUInt32 pk_len, SilcSKEPKType pk_type,
-		       SilcVerifyPublicKey completion, void *context)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-
-	if (!sg->conn && (conn_type == SILC_SOCKET_TYPE_SERVER ||
-			  conn_type == SILC_SOCKET_TYPE_ROUTER)) {
-		/* Progress */
-		if (sg->resuming)
-			purple_connection_update_progress(gc, _("Resuming session"), 3, 5);
-		else
-			purple_connection_update_progress(gc, _("Verifying server public key"),
-							3, 5);
-	}
-
-	/* Verify public key */
-	silcpurple_verify_public_key(client, conn, NULL, conn_type, pk,
-				   pk_len, pk_type, completion, context);
-}
-
-typedef struct {
-	SilcAskPassphrase completion;
-	void *context;
-} *SilcPurpleAskPassphrase;
-
-static void
-silc_ask_passphrase_cb(SilcPurpleAskPassphrase internal, const char *passphrase)
-{
-	if (!passphrase || !(*passphrase))
-		internal->completion(NULL, 0, internal->context);
-	else
-		internal->completion((unsigned char *)passphrase,
-				     strlen(passphrase), internal->context);
-	silc_free(internal);
-}
-
-/* Ask (interact, that is) a passphrase from user. The passphrase is
-   returned to the library by calling the `completion' callback with
-   the `context'. The returned passphrase SHOULD be in UTF-8 encoded,
-   if not then the library will attempt to encode. */
-
-static void
-silc_ask_passphrase(SilcClient client, SilcClientConnection conn,
-		    SilcAskPassphrase completion, void *context)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurpleAskPassphrase internal = silc_calloc(1, sizeof(*internal));
-
-	if (!internal)
-		return;
-	internal->completion = completion;
-	internal->context = context;
-	purple_request_input(gc, _("Passphrase"), NULL,
-			   _("Passphrase required"), NULL, FALSE, TRUE, NULL,
-			   _("OK"), G_CALLBACK(silc_ask_passphrase_cb),
-			   _("Cancel"), G_CALLBACK(silc_ask_passphrase_cb),
-			   purple_connection_get_account(gc), NULL, NULL, internal);
-}
-
-
-/* Notifies application that failure packet was received.  This is called
-   if there is some protocol active in the client.  The `protocol' is the
-   protocol context.  The `failure' is opaque pointer to the failure
-   indication.  Note, that the `failure' is protocol dependant and
-   application must explicitly cast it to correct type.  Usually `failure'
-   is 32 bit failure type (see protocol specs for all protocol failure
-   types). */
-
-static void
-silc_failure(SilcClient client, SilcClientConnection conn,
-	     SilcProtocol protocol, void *failure)
-{
-	PurpleConnection *gc = client->application;
-	char buf[128];
-
-	memset(buf, 0, sizeof(buf));
-
-	if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
-		SilcSKEStatus status = (SilcSKEStatus)SILC_PTR_TO_32(failure);
-
-		if (status == SILC_SKE_STATUS_BAD_VERSION)
-			g_snprintf(buf, sizeof(buf),
-				   _("Failure: Version mismatch, upgrade your client"));
-		if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY)
-			g_snprintf(buf, sizeof(buf),
-				   _("Failure: Remote does not trust/support your public key"));
-		if (status == SILC_SKE_STATUS_UNKNOWN_GROUP)
-			g_snprintf(buf, sizeof(buf),
-				   _("Failure: Remote does not support proposed KE group"));
-		if (status == SILC_SKE_STATUS_UNKNOWN_CIPHER)
-			g_snprintf(buf, sizeof(buf),
-				   _("Failure: Remote does not support proposed cipher"));
-		if (status == SILC_SKE_STATUS_UNKNOWN_PKCS)
-			g_snprintf(buf, sizeof(buf),
-				   _("Failure: Remote does not support proposed PKCS"));
-		if (status == SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION)
-			g_snprintf(buf, sizeof(buf),
-				   _("Failure: Remote does not support proposed hash function"));
-		if (status == SILC_SKE_STATUS_UNKNOWN_HMAC)
-			g_snprintf(buf, sizeof(buf),
-				   _("Failure: Remote does not support proposed HMAC"));
-		if (status == SILC_SKE_STATUS_INCORRECT_SIGNATURE)
-			g_snprintf(buf, sizeof(buf), _("Failure: Incorrect signature"));
-		if (status == SILC_SKE_STATUS_INVALID_COOKIE)
-			g_snprintf(buf, sizeof(buf), _("Failure: Invalid cookie"));
-
-		/* Show the error on the progress bar.  A more generic error message
-		   is going to be showed to user after this in the silc_connected. */
-		purple_connection_update_progress(gc, buf, 2, 5);
-	}
-
-	if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
-		SilcUInt32 err = SILC_PTR_TO_32(failure);
-
-		if (err == SILC_AUTH_FAILED)
-			g_snprintf(buf, sizeof(buf), _("Failure: Authentication failed"));
-
-		/* Show the error on the progress bar.  A more generic error message
-		   is going to be showed to user after this in the silc_connected. */
-		purple_connection_update_progress(gc, buf, 4, 5);
-	}
-}
-
-/* Asks whether the user would like to perform the key agreement protocol.
-   This is called after we have received an key agreement packet or an
-   reply to our key agreement packet. This returns TRUE if the user wants
-   the library to perform the key agreement protocol and FALSE if it is not
-   desired (application may start it later by calling the function
-   silc_client_perform_key_agreement). If TRUE is returned also the
-   `completion' and `context' arguments must be set by the application. */
-
-static bool
-silc_key_agreement(SilcClient client, SilcClientConnection conn,
-		   SilcClientEntry client_entry, const char *hostname,
-		   SilcUInt16 port, SilcKeyAgreementCallback *completion,
-		   void **context)
-{
-	silcpurple_buddy_keyagr_request(client, conn, client_entry, hostname, port);
-	*completion = NULL;
-	*context = NULL;
-	return FALSE;
-}
-
-
-/* Notifies application that file transfer protocol session is being
-   requested by the remote client indicated by the `client_entry' from
-   the `hostname' and `port'. The `session_id' is the file transfer
-   session and it can be used to either accept or reject the file
-   transfer request, by calling the silc_client_file_receive or
-   silc_client_file_close, respectively. */
-
-static void
-silc_ftp(SilcClient client, SilcClientConnection conn,
-	 SilcClientEntry client_entry, SilcUInt32 session_id,
-	 const char *hostname, SilcUInt16 port)
-{
-	silcpurple_ftp_request(client, conn, client_entry, session_id,
-			     hostname, port);
-}
-
-
-/* Delivers SILC session detachment data indicated by `detach_data' to the
-   application.  If application has issued SILC_COMMAND_DETACH command
-   the client session in the SILC network is not quit.  The client remains
-   in the network but is detached.  The detachment data may be used later
-   to resume the session in the SILC Network.  The appliation is
-   responsible of saving the `detach_data', to for example in a file.
-
-   The detachment data can be given as argument to the functions
-   silc_client_connect_to_server, or silc_client_add_connection when
-   creating connection to remote server, inside SilcClientConnectionParams
-   structure.  If it is provided the client library will attempt to resume
-   the session in the network.  After the connection is created
-   successfully, the application is responsible of setting the user
-   interface for user into the same state it was before detaching (showing
-   same channels, channel modes, etc).  It can do this by fetching the
-   information (like joined channels) from the client library. */
-
-static void
-silc_detach(SilcClient client, SilcClientConnection conn,
-	    const unsigned char *detach_data, SilcUInt32 detach_data_len)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-	const char *file;
-
-	/* Save the detachment data to file. */
-	file = silcpurple_session_file(purple_account_get_username(sg->account));
-	g_unlink(file);
-	silc_file_writefile(file, (char *)detach_data, detach_data_len);
-}
-
-SilcClientOperations ops = {
-	silc_say,
-	silc_channel_message,
-	silc_private_message,
-	silc_notify,
-	silc_command,
-	silc_command_reply,
-	silc_connected,
-	silc_disconnected,
-	silc_get_auth_method,
-	silc_verify_public_key,
-	silc_ask_passphrase,
-	silc_failure,
-	silc_key_agreement,
-	silc_ftp,
-	silc_detach
-};
--- a/libpurple/protocols/silc10/pk.c	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,274 +0,0 @@
-/*
-
-  silcpurple_pk.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2004 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-
-/************************* Public Key Verification ***************************/
-
-typedef struct {
-	SilcClient client;
-	SilcClientConnection conn;
-	char *filename;
-	char *entity;
-	char *entity_name;
-	char *fingerprint;
-	char *babbleprint;
-	unsigned char *pk;
-	SilcUInt32 pk_len;
-	SilcSKEPKType pk_type;
-	SilcVerifyPublicKey completion;
-	void *context;
-	gboolean changed;
-} *PublicKeyVerify;
-
-static void silcpurple_verify_ask(const char *entity,
-				const char *fingerprint,
-				const char *babbleprint,
-				PublicKeyVerify verify);
-
-static void silcpurple_verify_cb(PublicKeyVerify verify, gint id)
-{
-	if (id != 2) {
-		if (verify->completion)
-			verify->completion(FALSE, verify->context);
-	} else {
-		if (verify->completion)
-			verify->completion(TRUE, verify->context);
-
-		/* Save the key for future checking */
-		silc_pkcs_save_public_key_data(verify->filename, verify->pk,
-					       verify->pk_len, SILC_PKCS_FILE_PEM);
-	}
-
-	silc_free(verify->filename);
-	silc_free(verify->entity);
-	silc_free(verify->entity_name);
-	silc_free(verify->fingerprint);
-	silc_free(verify->babbleprint);
-	silc_free(verify->pk);
-	silc_free(verify);
-}
-
-static void silcpurple_verify_details_cb(PublicKeyVerify verify)
-{
-	/* What a hack.  We have to display the accept dialog _again_
-	   because Purple closes the dialog after you press the button.  Purple
-	   should have option for the dialogs whether the buttons close them
-	   or not. */
-	silcpurple_verify_ask(verify->entity, verify->fingerprint,
-			    verify->babbleprint, verify);
-}
-
-static void silcpurple_verify_details(PublicKeyVerify verify, gint id)
-{
-	SilcPublicKey public_key;
-	PurpleConnection *gc = verify->client->application;
-	SilcPurple sg = gc->proto_data;
-
-	silc_pkcs_public_key_decode(verify->pk, verify->pk_len,
-				    &public_key);
-	silcpurple_show_public_key(sg, verify->entity_name, public_key,
-				 G_CALLBACK(silcpurple_verify_details_cb),
-				 verify);
-	silc_pkcs_public_key_free(public_key);
-}
-
-static void silcpurple_verify_ask(const char *entity,
-				const char *fingerprint,
-				const char *babbleprint,
-				PublicKeyVerify verify)
-{
-	PurpleConnection *gc = verify->client->application;
-	char tmp[256], tmp2[256];
-
-	if (verify->changed) {
-		g_snprintf(tmp, sizeof(tmp),
-			   _("Received %s's public key. Your local copy does not match this "
-			     "key. Would you still like to accept this public key?"),
-			   entity);
-	} else {
-		g_snprintf(tmp, sizeof(tmp),
-			   _("Received %s's public key. Would you like to accept this "
-			     "public key?"), entity);
-	}
-	g_snprintf(tmp2, sizeof(tmp2),
-		   _("Fingerprint and babbleprint for the %s key are:\n\n"
-		     "%s\n%s\n"), entity, fingerprint, babbleprint);
-
-	purple_request_action(gc, _("Verify Public Key"), tmp, tmp2,
-						PURPLE_DEFAULT_ACTION_NONE,
-						purple_connection_get_account(gc), entity, NULL, verify, 3,
-			    _("Yes"), G_CALLBACK(silcpurple_verify_cb),
-			    _("No"), G_CALLBACK(silcpurple_verify_cb),
-			    _("_View..."), G_CALLBACK(silcpurple_verify_details));
-}
-
-void silcpurple_verify_public_key(SilcClient client, SilcClientConnection conn,
-				const char *name, SilcSocketType conn_type,
-				unsigned char *pk, SilcUInt32 pk_len,
-				SilcSKEPKType pk_type,
-				SilcVerifyPublicKey completion, void *context)
-{
-	PurpleConnection *gc = client->application;
-	int i;
-	char file[256], filename[256], filename2[256], *ipf, *hostf = NULL;
-	char *fingerprint, *babbleprint;
-	struct passwd *pw;
-	struct stat st;
-	char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER ||
-			 conn_type == SILC_SOCKET_TYPE_ROUTER) ?
-			"server" : "client");
-	PublicKeyVerify verify;
-
-	if (pk_type != SILC_SKE_PK_TYPE_SILC) {
-		purple_notify_error(gc, _("Verify Public Key"),
-				  _("Unsupported public key type"), NULL);
-		if (completion)
-			completion(FALSE, context);
-		return;
-	}
-
-	pw = getpwuid(getuid());
-	if (!pw) {
-		if (completion)
-			completion(FALSE, context);
-		return;
-	}
-
-	memset(filename, 0, sizeof(filename));
-	memset(filename2, 0, sizeof(filename2));
-	memset(file, 0, sizeof(file));
-
-	if (conn_type == SILC_SOCKET_TYPE_SERVER ||
-	    conn_type == SILC_SOCKET_TYPE_ROUTER) {
-		if (!name) {
-			g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
-				   conn->sock->ip, conn->sock->port);
-			g_snprintf(filename, sizeof(filename) - 1,
-				   "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s",
-				   silcpurple_silcdir(), entity, file);
-
-			g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
-				   conn->sock->hostname, conn->sock->port);
-			g_snprintf(filename2, sizeof(filename2) - 1,
-				   "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s",
-				   silcpurple_silcdir(), entity, file);
-
-			ipf = filename;
-			hostf = filename2;
-		} else {
-			g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
-				   name, conn->sock->port);
-			g_snprintf(filename, sizeof(filename) - 1,
-				   "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s",
-				   silcpurple_silcdir(), entity, file);
-
-			ipf = filename;
-		}
-	} else {
-		/* Replace all whitespaces with `_'. */
-		fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-		for (i = 0; i < strlen(fingerprint); i++)
-			if (fingerprint[i] == ' ')
-				fingerprint[i] = '_';
-
-		g_snprintf(file, sizeof(file) - 1, "%skey_%s.pub", entity, fingerprint);
-		g_snprintf(filename, sizeof(filename) - 1,
-			   "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s",
-			   silcpurple_silcdir(), entity, file);
-		silc_free(fingerprint);
-
-		ipf = filename;
-	}
-
-	verify = silc_calloc(1, sizeof(*verify));
-	if (!verify)
-		return;
-	verify->client = client;
-	verify->conn = conn;
-	verify->filename = strdup(ipf);
-	verify->entity = strdup(entity);
-	verify->entity_name = (conn_type != SILC_SOCKET_TYPE_CLIENT ?
-			       (name ? strdup(name) : strdup(conn->sock->hostname))
-			       : NULL);
-	verify->pk = silc_memdup(pk, pk_len);
-	verify->pk_len = pk_len;
-	verify->pk_type = pk_type;
-	verify->completion = completion;
-	verify->context = context;
-	fingerprint = verify->fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-	babbleprint = verify->babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
-
-	/* Check whether this key already exists */
-	if (g_stat(ipf, &st) < 0 && (!hostf || g_stat(hostf, &st) < 0)) {
-		/* Key does not exist, ask user to verify the key and save it */
-		silcpurple_verify_ask(name ? name : entity,
-				    fingerprint, babbleprint, verify);
-		return;
-	} else {
-		/* The key already exists, verify it. */
-		SilcPublicKey public_key;
-		unsigned char *encpk;
-		SilcUInt32 encpk_len;
-
-		/* Load the key file, try for both IP filename and hostname filename */
-		if (!silc_pkcs_load_public_key(ipf, &public_key,
-					       SILC_PKCS_FILE_PEM) &&
-		    !silc_pkcs_load_public_key(ipf, &public_key,
-					       SILC_PKCS_FILE_BIN) &&
-		    (!hostf || (!silc_pkcs_load_public_key(hostf, &public_key,
-							   SILC_PKCS_FILE_PEM) &&
-				!silc_pkcs_load_public_key(hostf, &public_key,
-							   SILC_PKCS_FILE_BIN)))) {
-			silcpurple_verify_ask(name ? name : entity,
-					    fingerprint, babbleprint, verify);
-			return;
-		}
-
-		/* Encode the key data */
-		encpk = silc_pkcs_public_key_encode(public_key, &encpk_len);
-		if (!encpk) {
-			silcpurple_verify_ask(name ? name : entity,
-					    fingerprint, babbleprint, verify);
-			return;
-		}
-
-		/* Compare the keys */
-		if (memcmp(encpk, pk, encpk_len)) {
-			/* Ask user to verify the key and save it */
-			verify->changed = TRUE;
-			silcpurple_verify_ask(name ? name : entity,
-					    fingerprint, babbleprint, verify);
-			return;
-		}
-
-		/* Local copy matched */
-		if (completion)
-			completion(TRUE, context);
-		silc_free(verify->filename);
-		silc_free(verify->entity);
-		silc_free(verify->entity_name);
-		silc_free(verify->pk);
-		silc_free(verify->fingerprint);
-		silc_free(verify->babbleprint);
-		silc_free(verify);
-	}
-}
--- a/libpurple/protocols/silc10/silc.c	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1965 +0,0 @@
-/*
-
-  silcpurple.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2004 - 2005 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "version.h"
-#include "wb.h"
-#include "core.h"
-
-extern SilcClientOperations ops;
-static PurplePlugin *silc_plugin = NULL;
-
-static const char *
-silcpurple_list_icon(PurpleAccount *a, PurpleBuddy *b)
-{
-	return (const char *)"silc";
-}
-
-static GList *
-silcpurple_away_states(PurpleAccount *account)
-{
-	PurpleStatusType *type;
-	GList *types = NULL;
-
-	type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, SILCPURPLE_STATUS_ID_AVAILABLE, NULL, TRUE, TRUE, FALSE);
-	types = g_list_append(types, type);
-	type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, SILCPURPLE_STATUS_ID_HYPER, _("Hyper Active"), TRUE, TRUE, FALSE);
-	types = g_list_append(types, type);
-	type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_AWAY, NULL, TRUE, TRUE, FALSE);
-	types = g_list_append(types, type);
-	type = purple_status_type_new_full(PURPLE_STATUS_UNAVAILABLE, SILCPURPLE_STATUS_ID_BUSY, _("Busy"), TRUE, TRUE, FALSE);
-	types = g_list_append(types, type);
-	type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_INDISPOSED, _("Indisposed"), TRUE, TRUE, FALSE);
-	types = g_list_append(types, type);
-	type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_PAGE, _("Wake Me Up"), TRUE, TRUE, FALSE);
-	types = g_list_append(types, type);
-	type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE, SILCPURPLE_STATUS_ID_OFFLINE, NULL, TRUE, TRUE, FALSE);
-	types = g_list_append(types, type);
-
-	return types;
-}
-
-static void
-silcpurple_set_status(PurpleAccount *account, PurpleStatus *status)
-{
-	PurpleConnection *gc = purple_account_get_connection(account);
-	SilcPurple sg = NULL;
-	SilcUInt32 mode;
-	SilcBuffer idp;
-	unsigned char mb[4];
-	const char *state;
-
-	if (gc != NULL)
-		sg = gc->proto_data;
-
-	if (status == NULL)
-		return;
-
-	state = purple_status_get_id(status);
-
-	if (state == NULL)
-		return;
-
-	if ((sg == NULL) || (sg->conn == NULL))
-		return;
-
-	mode = sg->conn->local_entry->mode;
-	mode &= ~(SILC_UMODE_GONE |
-		  SILC_UMODE_HYPER |
-		  SILC_UMODE_BUSY |
-		  SILC_UMODE_INDISPOSED |
-		  SILC_UMODE_PAGE);
-
-	if (!strcmp(state, "hyper"))
-		mode |= SILC_UMODE_HYPER;
-	else if (!strcmp(state, "away"))
-		mode |= SILC_UMODE_GONE;
-	else if (!strcmp(state, "busy"))
-		mode |= SILC_UMODE_BUSY;
-	else if (!strcmp(state, "indisposed"))
-		mode |= SILC_UMODE_INDISPOSED;
-	else if (!strcmp(state, "page"))
-		mode |= SILC_UMODE_PAGE;
-
-	/* Send UMODE */
-	idp = silc_id_payload_encode(sg->conn->local_id, SILC_ID_CLIENT);
-	SILC_PUT32_MSB(mode, mb);
-	silc_client_command_send(sg->client, sg->conn, SILC_COMMAND_UMODE,
-				 ++sg->conn->cmd_ident, 2,
-				 1, idp->data, idp->len,
-				 2, mb, sizeof(mb));
-	silc_buffer_free(idp);
-}
-
-
-/*************************** Connection Routines *****************************/
-
-static void
-silcpurple_keepalive(PurpleConnection *gc)
-{
-	SilcPurple sg = gc->proto_data;
-	silc_client_send_packet(sg->client, sg->conn, SILC_PACKET_HEARTBEAT,
-				NULL, 0);
-}
-
-static gboolean
-silcpurple_scheduler(gpointer *context)
-{
-	SilcPurple sg = (SilcPurple)context;
-	silc_client_run_one(sg->client);
-	return TRUE;
-}
-
-static void
-silcpurple_nickname_parse(const char *nickname,
-			char **ret_nickname)
-{
-	silc_parse_userfqdn(nickname, ret_nickname, NULL);
-}
-
-static void
-silcpurple_login_connected(gpointer data, gint source, const gchar *error_message)
-{
-	PurpleConnection *gc = data;
-	SilcPurple sg;
-	SilcClient client;
-	SilcClientConnection conn;
-	PurpleAccount *account;
-	SilcClientConnectionParams params;
-	SilcUInt32 mask;
-	const char *dfile, *tmp;
-#ifdef SILC_ATTRIBUTE_USER_ICON
-	PurpleStoredImage *img;
-#endif
-#ifdef HAVE_SYS_UTSNAME_H
-	struct utsname u;
-#endif
-
-
-	g_return_if_fail(gc != NULL);
-
-	sg = gc->proto_data;
-
-	if (source < 0) {
-		purple_connection_error_reason(gc,
-			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-			_("Connection failed"));
-		return;
-	}
-
-	client = sg->client;
-	account = sg->account;
-
-	/* Get session detachment data, if available */
-	memset(&params, 0, sizeof(params));
-	dfile = silcpurple_session_file(purple_account_get_username(sg->account));
-	params.detach_data = (unsigned char *)silc_file_readfile(dfile, &params.detach_data_len);
-	if (params.detach_data)
-		params.detach_data[params.detach_data_len] = 0;
-
-	/* Add connection to SILC client library */
-	conn = silc_client_add_connection(
-			  sg->client, &params,
-			  (char *)purple_account_get_string(account, "server",
-							  "silc.silcnet.org"),
-			  purple_account_get_int(account, "port", 706), sg);
-	if (!conn) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-			_("Unable to initialize SILC Client connection"));
-		gc->proto_data = NULL;
-		return;
-	}
-	sg->conn = conn;
-
-	/* Progress */
-	if (params.detach_data) {
-		purple_connection_update_progress(gc, _("Resuming session"), 2, 5);
-		sg->resuming = TRUE;
-	} else {
-		purple_connection_update_progress(gc, _("Performing key exchange"), 2, 5);
-	}
-
-	/* Perform SILC Key Exchange.  The "silc_connected" will be called
-	   eventually. */
-	silc_client_start_key_exchange(sg->client, sg->conn, source);
-
-	/* Set default attributes */
-	mask = SILC_ATTRIBUTE_MOOD_NORMAL;
-	silc_client_attribute_add(client, conn,
-				  SILC_ATTRIBUTE_STATUS_MOOD,
-				  SILC_32_TO_PTR(mask),
-				  sizeof(SilcUInt32));
-	mask = SILC_ATTRIBUTE_CONTACT_CHAT;
-	silc_client_attribute_add(client, conn,
-				  SILC_ATTRIBUTE_PREFERRED_CONTACT,
-				  SILC_32_TO_PTR(mask),
-				  sizeof(SilcUInt32));
-#ifdef HAVE_SYS_UTSNAME_H
-	if (!uname(&u)) {
-		SilcAttributeObjDevice dev;
-		memset(&dev, 0, sizeof(dev));
-		dev.type = SILC_ATTRIBUTE_DEVICE_COMPUTER;
-		dev.version = u.release;
-		dev.model = u.sysname;
-		silc_client_attribute_add(client, conn,
-					  SILC_ATTRIBUTE_DEVICE_INFO,
-					  (void *)&dev, sizeof(dev));
-	}
-#endif
-#ifdef _WIN32
-	tmp = _tzname[0];
-#else
-	tmp = tzname[0];
-#endif
-	silc_client_attribute_add(client, conn,
-				  SILC_ATTRIBUTE_TIMEZONE,
-				  (void *)tmp, strlen(tmp));
-
-#ifdef SILC_ATTRIBUTE_USER_ICON
-	/* Set our buddy icon */
-	img = purple_buddy_icons_find_account_icon(account);
-	silcpurple_buddy_set_icon(gc, img);
-	purple_imgstore_unref(img);
-#endif
-
-	silc_free(params.detach_data);
-}
-
-static void
-silcpurple_login(PurpleAccount *account)
-{
-	SilcPurple sg;
-	SilcClient client;
-	SilcClientParams params;
-	PurpleConnection *gc;
-	char pkd[256], prd[256];
-	const char *cipher, *hmac;
-	char *realname;
-	int i;
-
-	gc = account->gc;
-	if (!gc)
-		return;
-	gc->proto_data = NULL;
-
-	memset(&params, 0, sizeof(params));
-	strcat(params.nickname_format, "%n@%h%a");
-	params.nickname_parse = silcpurple_nickname_parse;
-	params.ignore_requested_attributes = FALSE;
-
-	/* Allocate SILC client */
-	client = silc_client_alloc(&ops, &params, gc, NULL);
-	if (!client) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
-		                             _("Out of memory"));
-		return;
-	}
-
-	/* Get username, real name and local hostname for SILC library */
-	if (purple_account_get_username(account)) {
-		const char *u = purple_account_get_username(account);
-		char **up = g_strsplit(u, "@", 2);
-		client->username = strdup(up[0]);
-		g_strfreev(up);
-	} else {
-		client->username = silc_get_username();
-		purple_account_set_username(account, client->username);
-	}
-	realname = silc_get_real_name();
-	if (purple_account_get_user_info(account)) {
-		client->realname = strdup(purple_account_get_user_info(account));
-		free(realname);
-	} else if ((silc_get_real_name() != NULL) && (*realname != '\0')) {
-		client->realname = realname;
-		purple_account_set_user_info(account, client->realname);
-	} else {
-		free(realname);
-		client->realname = strdup(_("John Noname"));
-	}
-	client->hostname = silc_net_localhost();
-
-	purple_connection_set_display_name(gc, client->username);
-
-	/* Register requested cipher and HMAC */
-	cipher = purple_account_get_string(account, "cipher", SILC_DEFAULT_CIPHER);
-	for (i = 0; silc_default_ciphers[i].name; i++)
-		if (!strcmp(silc_default_ciphers[i].name, cipher)) {
-			silc_cipher_register(&(silc_default_ciphers[i]));
-			break;
-		}
-	hmac = purple_account_get_string(account, "hmac", SILC_DEFAULT_HMAC);
-	for (i = 0; silc_default_hmacs[i].name; i++)
-		if (!strcmp(silc_default_hmacs[i].name, hmac)) {
-			silc_hmac_register(&(silc_default_hmacs[i]));
-			break;
-		}
-
-	/* Init SILC client */
-	if (!silc_client_init(client)) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
-		                             _("Unable to initialize SILC protocol"));
-		return;
-	}
-
-	/* Check the ~/.silc dir and create it, and new key pair if necessary. */
-	if (!silcpurple_check_silc_dir(gc)) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
-		                             _("Error loading SILC key pair"));
-		return;
-	}
-
-	/* Progress */
-	purple_connection_update_progress(gc, _("Connecting to SILC Server"), 1, 5);
-
-	/* Load SILC key pair */
-	g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir());
-	g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir());
-	if (!silc_load_key_pair((char *)purple_account_get_string(account, "public-key", pkd),
-							(char *)purple_account_get_string(account, "private-key", prd),
-				(gc->password == NULL) ? "" : gc->password, &client->pkcs,
-				&client->public_key, &client->private_key)) {
-		g_snprintf(pkd, sizeof(pkd), _("Unable to load SILC key pair: %s"), g_strerror(errno));
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
-		                             pkd);
-		return;
-	}
-
-	sg = silc_calloc(1, sizeof(*sg));
-	if (!sg)
-		return;
-	memset(sg, 0, sizeof(*sg));
-	sg->client = client;
-	sg->gc = gc;
-	sg->account = account;
-	gc->proto_data = sg;
-
-	/* Connect to the SILC server */
-	if (purple_proxy_connect(gc, account,
-			       purple_account_get_string(account, "server",
-						       "silc.silcnet.org"),
-			       purple_account_get_int(account, "port", 706),
-			       silcpurple_login_connected, gc) == NULL)
-	{
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-		                             _("Unable to create connection"));
-		return;
-	}
-
-	/* Schedule SILC using Glib's event loop */
-	sg->scheduler = purple_timeout_add(300, (GSourceFunc)silcpurple_scheduler, sg);
-}
-
-static int
-silcpurple_close_final(gpointer *context)
-{
-	SilcPurple sg = (SilcPurple)context;
-	silc_client_stop(sg->client);
-	silc_client_free(sg->client);
-#ifdef HAVE_SILCMIME_H
-	if (sg->mimeass)
-		silc_mime_assembler_free(sg->mimeass);
-#endif
-	silc_free(sg);
-	return 0;
-}
-
-static void
-silcpurple_close(PurpleConnection *gc)
-{
-	SilcPurple sg = gc->proto_data;
-	GHashTable *ui_info;
-	const char *ui_name = NULL, *ui_website = NULL;
-	char *quit_msg;
-
-	g_return_if_fail(sg != NULL);
-
-	ui_info = purple_core_get_ui_info();
-
-	if(ui_info) {
-		ui_name = g_hash_table_lookup(ui_info, "name");
-		ui_website = g_hash_table_lookup(ui_info, "website");
-	}
-
-	if(!ui_name || !ui_website) {
-		ui_name = "Pidgin";
-		ui_website = PURPLE_WEBSITE;
-	}
-	quit_msg = g_strdup_printf(_("Download %s: %s"),
-							   ui_name, ui_website);
-
-	/* Send QUIT */
-	silc_client_command_call(sg->client, sg->conn, NULL,
-				 "QUIT", quit_msg, NULL);
-	g_free(quit_msg);
-
-	if (sg->conn)
-		silc_client_close_connection(sg->client, sg->conn);
-
-	purple_timeout_remove(sg->scheduler);
-	purple_timeout_add(1, (GSourceFunc)silcpurple_close_final, sg);
-}
-
-
-/****************************** Protocol Actions *****************************/
-
-static void
-silcpurple_attrs_cancel(PurpleConnection *gc, PurpleRequestFields *fields)
-{
-	/* Nothing */
-}
-
-static void
-silcpurple_attrs_cb(PurpleConnection *gc, PurpleRequestFields *fields)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	PurpleRequestField *f;
-	char *tmp;
-	SilcUInt32 tmp_len, mask;
-	SilcAttributeObjService service;
-	SilcAttributeObjDevice dev;
-	SilcVCardStruct vcard;
-	const char *val;
-
-	sg = gc->proto_data;
-	if (!sg)
-		return;
-
-	memset(&service, 0, sizeof(service));
-	memset(&dev, 0, sizeof(dev));
-	memset(&vcard, 0, sizeof(vcard));
-
-	silc_client_attribute_del(client, conn,
-				  SILC_ATTRIBUTE_USER_INFO, NULL);
-	silc_client_attribute_del(client, conn,
-				  SILC_ATTRIBUTE_SERVICE, NULL);
-	silc_client_attribute_del(client, conn,
-				  SILC_ATTRIBUTE_STATUS_MOOD, NULL);
-	silc_client_attribute_del(client, conn,
-				  SILC_ATTRIBUTE_STATUS_FREETEXT, NULL);
-	silc_client_attribute_del(client, conn,
-				  SILC_ATTRIBUTE_STATUS_MESSAGE, NULL);
-	silc_client_attribute_del(client, conn,
-				  SILC_ATTRIBUTE_PREFERRED_LANGUAGE, NULL);
-	silc_client_attribute_del(client, conn,
-				  SILC_ATTRIBUTE_PREFERRED_CONTACT, NULL);
-	silc_client_attribute_del(client, conn,
-				  SILC_ATTRIBUTE_TIMEZONE, NULL);
-	silc_client_attribute_del(client, conn,
-				  SILC_ATTRIBUTE_GEOLOCATION, NULL);
-	silc_client_attribute_del(client, conn,
-				  SILC_ATTRIBUTE_DEVICE_INFO, NULL);
-
-	/* Set mood */
-	mask = 0;
-	f = purple_request_fields_get_field(fields, "mood_normal");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_NORMAL;
-	f = purple_request_fields_get_field(fields, "mood_happy");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_HAPPY;
-	f = purple_request_fields_get_field(fields, "mood_sad");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_SAD;
-	f = purple_request_fields_get_field(fields, "mood_angry");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_ANGRY;
-	f = purple_request_fields_get_field(fields, "mood_jealous");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_JEALOUS;
-	f = purple_request_fields_get_field(fields, "mood_ashamed");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_ASHAMED;
-	f = purple_request_fields_get_field(fields, "mood_invincible");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_INVINCIBLE;
-	f = purple_request_fields_get_field(fields, "mood_inlove");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_INLOVE;
-	f = purple_request_fields_get_field(fields, "mood_sleepy");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_SLEEPY;
-	f = purple_request_fields_get_field(fields, "mood_bored");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_BORED;
-	f = purple_request_fields_get_field(fields, "mood_excited");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_EXCITED;
-	f = purple_request_fields_get_field(fields, "mood_anxious");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_MOOD_ANXIOUS;
-	silc_client_attribute_add(client, conn,
-				  SILC_ATTRIBUTE_STATUS_MOOD,
-				  SILC_32_TO_PTR(mask),
-				  sizeof(SilcUInt32));
-
-	/* Set preferred contact */
-	mask = 0;
-	f = purple_request_fields_get_field(fields, "contact_chat");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_CONTACT_CHAT;
-	f = purple_request_fields_get_field(fields, "contact_email");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_CONTACT_EMAIL;
-	f = purple_request_fields_get_field(fields, "contact_call");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_CONTACT_CALL;
-	f = purple_request_fields_get_field(fields, "contact_sms");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_CONTACT_SMS;
-	f = purple_request_fields_get_field(fields, "contact_mms");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_CONTACT_MMS;
-	f = purple_request_fields_get_field(fields, "contact_video");
-	if (f && purple_request_field_bool_get_value(f))
-		mask |= SILC_ATTRIBUTE_CONTACT_VIDEO;
-	if (mask)
-		silc_client_attribute_add(client, conn,
-					  SILC_ATTRIBUTE_PREFERRED_CONTACT,
-					  SILC_32_TO_PTR(mask),
-					  sizeof(SilcUInt32));
-
-	/* Set status text */
-	val = NULL;
-	f = purple_request_fields_get_field(fields, "status_text");
-	if (f)
-		val = purple_request_field_string_get_value(f);
-	if (val && *val)
-		silc_client_attribute_add(client, conn,
-					  SILC_ATTRIBUTE_STATUS_FREETEXT,
-					  (void *)val, strlen(val));
-
-	/* Set vcard */
-	val = NULL;
-	f = purple_request_fields_get_field(fields, "vcard");
-	if (f)
-		val = purple_request_field_string_get_value(f);
-	if (val && *val) {
-		purple_account_set_string(sg->account, "vcard", val);
-		tmp = silc_file_readfile(val, &tmp_len);
-		if (tmp) {
-			tmp[tmp_len] = 0;
-			if (silc_vcard_decode((unsigned char *)tmp, tmp_len, &vcard))
-				silc_client_attribute_add(client, conn,
-							  SILC_ATTRIBUTE_USER_INFO,
-							  (void *)&vcard,
-							  sizeof(vcard));
-		}
-		silc_vcard_free(&vcard);
-		silc_free(tmp);
-	} else {
-		purple_account_set_string(sg->account, "vcard", "");
-	}
-
-#ifdef HAVE_SYS_UTSNAME_H
-	/* Set device info */
-	f = purple_request_fields_get_field(fields, "device");
-	if (f && purple_request_field_bool_get_value(f)) {
-		struct utsname u;
-		if (!uname(&u)) {
-			dev.type = SILC_ATTRIBUTE_DEVICE_COMPUTER;
-			dev.version = u.release;
-			dev.model = u.sysname;
-			silc_client_attribute_add(client, conn,
-						  SILC_ATTRIBUTE_DEVICE_INFO,
-						  (void *)&dev, sizeof(dev));
-		}
-	}
-#endif
-
-	/* Set timezone */
-	val = NULL;
-	f = purple_request_fields_get_field(fields, "timezone");
-	if (f)
-		val = purple_request_field_string_get_value(f);
-	if (val && *val)
-		silc_client_attribute_add(client, conn,
-					  SILC_ATTRIBUTE_TIMEZONE,
-					  (void *)val, strlen(val));
-}
-
-static void
-silcpurple_attrs(PurplePluginAction *action)
-{
-	PurpleConnection *gc = (PurpleConnection *) action->context;
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	PurpleRequestFields *fields;
-	PurpleRequestFieldGroup *g;
-	PurpleRequestField *f;
-	SilcHashTable attrs;
-	SilcAttributePayload attr;
-	gboolean mnormal = TRUE, mhappy = FALSE, msad = FALSE,
-		mangry = FALSE, mjealous = FALSE, mashamed = FALSE,
-		minvincible = FALSE, minlove = FALSE, msleepy = FALSE,
-		mbored = FALSE, mexcited = FALSE, manxious = FALSE;
-	gboolean cemail = FALSE, ccall = FALSE, csms = FALSE,
-		cmms = FALSE, cchat = TRUE, cvideo = FALSE;
-	gboolean device = TRUE;
-	char status[1024];
-
-	sg = gc->proto_data;
-	if (!sg)
-		return;
-
-	memset(status, 0, sizeof(status));
-
-	attrs = silc_client_attributes_get(client, conn);
-	if (attrs) {
-		if (silc_hash_table_find(attrs,
-					 SILC_32_TO_PTR(SILC_ATTRIBUTE_STATUS_MOOD),
-					 NULL, (void *)&attr)) {
-			SilcUInt32 mood = 0;
-			silc_attribute_get_object(attr, &mood, sizeof(mood));
-			mnormal = !mood;
-			mhappy = (mood & SILC_ATTRIBUTE_MOOD_HAPPY);
-			msad = (mood & SILC_ATTRIBUTE_MOOD_SAD);
-			mangry = (mood & SILC_ATTRIBUTE_MOOD_ANGRY);
-			mjealous = (mood & SILC_ATTRIBUTE_MOOD_JEALOUS);
-			mashamed = (mood & SILC_ATTRIBUTE_MOOD_ASHAMED);
-			minvincible = (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE);
-			minlove = (mood & SILC_ATTRIBUTE_MOOD_INLOVE);
-			msleepy = (mood & SILC_ATTRIBUTE_MOOD_SLEEPY);
-			mbored = (mood & SILC_ATTRIBUTE_MOOD_BORED);
-			mexcited = (mood & SILC_ATTRIBUTE_MOOD_EXCITED);
-			manxious = (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS);
-		}
-
-		if (silc_hash_table_find(attrs,
-					 SILC_32_TO_PTR(SILC_ATTRIBUTE_PREFERRED_CONTACT),
-					 NULL, (void *)&attr)) {
-			SilcUInt32 contact = 0;
-			silc_attribute_get_object(attr, &contact, sizeof(contact));
-			cemail = (contact & SILC_ATTRIBUTE_CONTACT_EMAIL);
-			ccall = (contact & SILC_ATTRIBUTE_CONTACT_CALL);
-			csms = (contact & SILC_ATTRIBUTE_CONTACT_SMS);
-			cmms = (contact & SILC_ATTRIBUTE_CONTACT_MMS);
-			cchat = (contact & SILC_ATTRIBUTE_CONTACT_CHAT);
-			cvideo = (contact & SILC_ATTRIBUTE_CONTACT_VIDEO);
-		}
-
-		if (silc_hash_table_find(attrs,
-					 SILC_32_TO_PTR(SILC_ATTRIBUTE_STATUS_FREETEXT),
-					 NULL, (void *)&attr))
-			silc_attribute_get_object(attr, &status, sizeof(status));
-
-		if (!silc_hash_table_find(attrs,
-					  SILC_32_TO_PTR(SILC_ATTRIBUTE_DEVICE_INFO),
-					  NULL, (void *)&attr))
-			device = FALSE;
-	}
-
-	fields = purple_request_fields_new();
-
-	g = purple_request_field_group_new(NULL);
-	f = purple_request_field_label_new("l3", _("Your Current Mood"));
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_normal", _("Normal"), mnormal);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_happy", _("Happy"), mhappy);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_sad", _("Sad"), msad);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_angry", _("Angry"), mangry);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_jealous", _("Jealous"), mjealous);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_ashamed", _("Ashamed"), mashamed);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_invincible", _("Invincible"), minvincible);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_inlove", _("In love"), minlove);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_sleepy", _("Sleepy"), msleepy);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_bored", _("Bored"), mbored);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_excited", _("Excited"), mexcited);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("mood_anxious", _("Anxious"), manxious);
-	purple_request_field_group_add_field(g, f);
-
-	f = purple_request_field_label_new("l4", _("\nYour Preferred Contact Methods"));
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("contact_chat", _("Chat"), cchat);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("contact_email", _("Email"), cemail);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("contact_call", _("Phone"), ccall);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("contact_sms", _("SMS"), csms);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("contact_mms", _("MMS"), cmms);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("contact_video", _("Video conferencing"), cvideo);
-	purple_request_field_group_add_field(g, f);
-	purple_request_fields_add_group(fields, g);
-
-	g = purple_request_field_group_new(NULL);
-	f = purple_request_field_string_new("status_text", _("Your Current Status"),
-					  status[0] ? status : NULL, TRUE);
-	purple_request_field_group_add_field(g, f);
-	purple_request_fields_add_group(fields, g);
-
-	g = purple_request_field_group_new(NULL);
-#if 0
-	f = purple_request_field_label_new("l2", _("Online Services"));
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_bool_new("services",
-					_("Let others see what services you are using"),
-					TRUE);
-	purple_request_field_group_add_field(g, f);
-#endif
-#ifdef HAVE_SYS_UTSNAME_H
-	f = purple_request_field_bool_new("device",
-					_("Let others see what computer you are using"),
-					device);
-	purple_request_field_group_add_field(g, f);
-#endif
-	purple_request_fields_add_group(fields, g);
-
-	g = purple_request_field_group_new(NULL);
-	f = purple_request_field_string_new("vcard", _("Your VCard File"),
-					  purple_account_get_string(sg->account, "vcard", ""),
-					  FALSE);
-	purple_request_field_group_add_field(g, f);
-#ifdef _WIN32
-	f = purple_request_field_string_new("timezone", _("Timezone"), _tzname[0], FALSE);
-#else
-	f = purple_request_field_string_new("timezone", _("Timezone"), tzname[0], FALSE);
-#endif
-	purple_request_field_group_add_field(g, f);
-	purple_request_fields_add_group(fields, g);
-
-	purple_request_fields(gc, _("User Online Status Attributes"),
-			    _("User Online Status Attributes"),
-			    _("You can let other users see your online status information "
-			      "and your personal information. Please fill the information "
-			      "you would like other users to see about yourself."),
-			    fields,
-			    _("OK"), G_CALLBACK(silcpurple_attrs_cb),
-			    _("Cancel"), G_CALLBACK(silcpurple_attrs_cancel),
-				gc->account, NULL, NULL, gc);
-}
-
-static void
-silcpurple_detach(PurplePluginAction *action)
-{
-	PurpleConnection *gc = (PurpleConnection *) action->context;
-	SilcPurple sg;
-
-	if (!gc)
-		return;
-	sg = gc->proto_data;
-	if (!sg)
-		return;
-
-	/* Call DETACH */
-	silc_client_command_call(sg->client, sg->conn, "DETACH");
-	sg->detaching = TRUE;
-}
-
-static void
-silcpurple_view_motd(PurplePluginAction *action)
-{
-	PurpleConnection *gc = (PurpleConnection *) action->context;
-	SilcPurple sg;
-	char *tmp;
-
-	if (!gc)
-		return;
-	sg = gc->proto_data;
-	if (!sg)
-		return;
-
-	if (!sg->motd) {
-		purple_notify_error(
-		     gc, _("Message of the Day"), _("No Message of the Day available"),
-		     _("There is no Message of the Day associated with this connection"));
-		return;
-	}
-
-	tmp = g_markup_escape_text(sg->motd, -1);
-	purple_notify_formatted(gc, NULL, _("Message of the Day"), NULL,
-			      tmp, NULL, NULL);
-	g_free(tmp);
-}
-
-static void
-silcpurple_create_keypair_cancel(PurpleConnection *gc, PurpleRequestFields *fields)
-{
-	/* Nothing */
-}
-
-static void
-silcpurple_create_keypair_cb(PurpleConnection *gc, PurpleRequestFields *fields)
-{
-	SilcPurple sg = gc->proto_data;
-	PurpleRequestField *f;
-	const char *val, *pkfile = NULL, *prfile = NULL;
-	const char *pass1 = NULL, *pass2 = NULL, *un = NULL, *hn = NULL;
-	const char *rn = NULL, *e = NULL, *o = NULL, *c = NULL;
-	char *identifier;
-	int keylen = SILCPURPLE_DEF_PKCS_LEN;
-	SilcPublicKey public_key;
-
-	sg = gc->proto_data;
-	if (!sg)
-		return;
-
-	val = NULL;
-	f = purple_request_fields_get_field(fields, "pass1");
-	if (f)
-		val = purple_request_field_string_get_value(f);
-	if (val && *val)
-		pass1 = val;
-	else
-		pass1 = "";
-	val = NULL;
-	f = purple_request_fields_get_field(fields, "pass2");
-	if (f)
-		val = purple_request_field_string_get_value(f);
-	if (val && *val)
-		pass2 = val;
-	else
-		pass2 = "";
-
-	if (strcmp(pass1, pass2)) {
-		purple_notify_error(
-		     gc, _("Create New SILC Key Pair"), _("Passphrases do not match"), NULL);
-		return;
-	}
-
-	val = NULL;
-	f = purple_request_fields_get_field(fields, "key");
-	if (f)
-		val = purple_request_field_string_get_value(f);
-	if (val && *val)
-		keylen = atoi(val);
-	f = purple_request_fields_get_field(fields, "pkfile");
-	if (f)
-		pkfile = purple_request_field_string_get_value(f);
-	f = purple_request_fields_get_field(fields, "prfile");
-	if (f)
-		prfile = purple_request_field_string_get_value(f);
-
-	f = purple_request_fields_get_field(fields, "un");
-	if (f)
-		un = purple_request_field_string_get_value(f);
-	f = purple_request_fields_get_field(fields, "hn");
-	if (f)
-		hn = purple_request_field_string_get_value(f);
-	f = purple_request_fields_get_field(fields, "rn");
-	if (f)
-		rn = purple_request_field_string_get_value(f);
-	f = purple_request_fields_get_field(fields, "e");
-	if (f)
-		e = purple_request_field_string_get_value(f);
-	f = purple_request_fields_get_field(fields, "o");
-	if (f)
-		o = purple_request_field_string_get_value(f);
-	f = purple_request_fields_get_field(fields, "c");
-	if (f)
-		c = purple_request_field_string_get_value(f);
-
-	identifier = silc_pkcs_encode_identifier((char *)un, (char *)hn,
-						 (char *)rn, (char *)e, (char *)o, (char *)c);
-
-	/* Create the key pair */
-	if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS, keylen, pkfile, prfile,
-				  identifier, pass1, NULL, &public_key, NULL,
-				  FALSE)) {
-		purple_notify_error(
-		     gc, _("Create New SILC Key Pair"), _("Key Pair Generation failed"), NULL);
-		return;
-	}
-
-	silcpurple_show_public_key(sg, NULL, public_key, NULL, NULL);
-
-	silc_pkcs_public_key_free(public_key);
-	silc_free(identifier);
-}
-
-static void
-silcpurple_create_keypair(PurplePluginAction *action)
-{
-	PurpleConnection *gc = (PurpleConnection *) action->context;
-	SilcPurple sg = gc->proto_data;
-	PurpleRequestFields *fields;
-	PurpleRequestFieldGroup *g;
-	PurpleRequestField *f;
-	const char *username, *realname;
-	char *hostname, **u;
-	char tmp[256], pkd[256], pkd2[256], prd[256], prd2[256];
-
-	username = purple_account_get_username(sg->account);
-	u = g_strsplit(username, "@", 2);
-	username = u[0];
-	realname = purple_account_get_user_info(sg->account);
-	hostname = silc_net_localhost();
-	g_snprintf(tmp, sizeof(tmp), "%s@%s", username, hostname);
-
-	g_snprintf(pkd2, sizeof(pkd2), "%s" G_DIR_SEPARATOR_S"public_key.pub", silcpurple_silcdir());
-	g_snprintf(prd2, sizeof(prd2), "%s" G_DIR_SEPARATOR_S"private_key.prv", silcpurple_silcdir());
-	g_snprintf(pkd, sizeof(pkd) - 1, "%s",
-		   purple_account_get_string(gc->account, "public-key", pkd2));
-	g_snprintf(prd, sizeof(prd) - 1, "%s",
-		   purple_account_get_string(gc->account, "private-key", prd2));
-
-	fields = purple_request_fields_new();
-
-	g = purple_request_field_group_new(NULL);
-	f = purple_request_field_string_new("key", _("Key length"), "2048", FALSE);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_string_new("pkfile", _("Public key file"), pkd, FALSE);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_string_new("prfile", _("Private key file"), prd, FALSE);
-	purple_request_field_group_add_field(g, f);
-	purple_request_fields_add_group(fields, g);
-
-	g = purple_request_field_group_new(NULL);
-	f = purple_request_field_string_new("un", _("Username"), username ? username : "", FALSE);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_string_new("hn", _("Hostname"), hostname ? hostname : "", FALSE);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_string_new("rn", _("Real name"), realname ? realname : "", FALSE);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_string_new("e", _("Email"), tmp, FALSE);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_string_new("o", _("Organization"), "", FALSE);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_string_new("c", _("Country"), "", FALSE);
-	purple_request_field_group_add_field(g, f);
-	purple_request_fields_add_group(fields, g);
-
-	g = purple_request_field_group_new(NULL);
-	f = purple_request_field_string_new("pass1", _("Passphrase"), "", FALSE);
-	purple_request_field_string_set_masked(f, TRUE);
-	purple_request_field_group_add_field(g, f);
-	f = purple_request_field_string_new("pass2", _("Passphrase (retype)"), "", FALSE);
-	purple_request_field_string_set_masked(f, TRUE);
-	purple_request_field_group_add_field(g, f);
-	purple_request_fields_add_group(fields, g);
-
-	purple_request_fields(gc, _("Create New SILC Key Pair"),
-			    _("Create New SILC Key Pair"), NULL, fields,
-			    _("Generate Key Pair"), G_CALLBACK(silcpurple_create_keypair_cb),
-			    _("Cancel"), G_CALLBACK(silcpurple_create_keypair_cancel),
-				gc->account, NULL, NULL, gc);
-
-	g_strfreev(u);
-	silc_free(hostname);
-}
-
-static void
-silcpurple_change_pass(PurplePluginAction *action)
-{
-	PurpleConnection *gc = (PurpleConnection *) action->context;
-	purple_account_request_change_password(purple_connection_get_account(gc));
-}
-
-static void
-silcpurple_change_passwd(PurpleConnection *gc, const char *old, const char *new)
-{
-	char prd[256];
-	g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.pub", silcpurple_silcdir());
-	silc_change_private_key_passphrase(purple_account_get_string(gc->account,
-								   "private-key",
-								   prd), old ? old : "", new ? new : "");
-}
-
-static void
-silcpurple_show_set_info(PurplePluginAction *action)
-{
-	PurpleConnection *gc = (PurpleConnection *) action->context;
-	purple_account_request_change_user_info(purple_connection_get_account(gc));
-}
-
-static void
-silcpurple_set_info(PurpleConnection *gc, const char *text)
-{
-}
-
-static GList *
-silcpurple_actions(PurplePlugin *plugin, gpointer context)
-{
-	GList *list = NULL;
-	PurplePluginAction *act;
-
-	act = purple_plugin_action_new(_("Online Status"),
-			silcpurple_attrs);
-	list = g_list_append(list, act);
-
-	act = purple_plugin_action_new(_("Detach From Server"),
-			silcpurple_detach);
-	list = g_list_append(list, act);
-
-	act = purple_plugin_action_new(_("View Message of the Day"),
-			silcpurple_view_motd);
-	list = g_list_append(list, act);
-
-	act = purple_plugin_action_new(_("Create SILC Key Pair..."),
-			silcpurple_create_keypair);
-	list = g_list_append(list, act);
-
-	act = purple_plugin_action_new(_("Change Password..."),
-			silcpurple_change_pass);
-	list = g_list_append(list, act);
-
-	act = purple_plugin_action_new(_("Set User Info..."),
-			silcpurple_show_set_info);
-	list = g_list_append(list, act);
-
-	return list;
-}
-
-
-/******************************* IM Routines *********************************/
-
-typedef struct {
-	char *nick;
-	char *message;
-	SilcUInt32 message_len;
-	SilcMessageFlags flags;
-	PurpleMessageFlags gflags;
-} *SilcPurpleIM;
-
-static void
-silcpurple_send_im_resolved(SilcClient client,
-			  SilcClientConnection conn,
-			  SilcClientEntry *clients,
-			  SilcUInt32 clients_count,
-			  void *context)
-{
-	PurpleConnection *gc = client->application;
-	SilcPurple sg = gc->proto_data;
-	SilcPurpleIM im = context;
-	PurpleConversation *convo;
-	char tmp[256], *nickname = NULL;
-	SilcClientEntry client_entry;
-#ifdef HAVE_SILCMIME_H
-	SilcDList list;
-#endif
-
-	convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, im->nick,
-							sg->account);
-	if (!convo)
-		return;
-
-	if (!clients)
-		goto err;
-
-	if (clients_count > 1) {
-		silc_parse_userfqdn(im->nick, &nickname, NULL);
-
-		/* Find the correct one. The im->nick might be a formatted nick
-		   so this will find the correct one. */
-		clients = silc_client_get_clients_local(client, conn,
-							nickname, im->nick,
-							&clients_count);
-		if (!clients)
-			goto err;
-		client_entry = clients[0];
-		silc_free(clients);
-	} else {
-		client_entry = clients[0];
-	}
-
-#ifdef HAVE_SILCMIME_H
-	/* Check for images */
-	if (im->gflags & PURPLE_MESSAGE_IMAGES) {
-		list = silcpurple_image_message(im->message, (SilcUInt32 *)&im->flags);
-		if (list) {
-			/* Send one or more MIME message.  If more than one, they
-			   are MIME fragments due to over large message */
-			SilcBuffer buf;
-
-			silc_dlist_start(list);
-			while ((buf = silc_dlist_get(list)) != SILC_LIST_END)
-				silc_client_send_private_message(client, conn,
-								 client_entry, im->flags,
-								 buf->data, buf->len,
-								 TRUE);
-			silc_mime_partial_free(list);
-			purple_conv_im_write(PURPLE_CONV_IM(convo), conn->local_entry->nickname,
-				   im->message, 0, time(NULL));
-			goto out;
-		}
-	}
-#endif
-
-	/* Send the message */
-	silc_client_send_private_message(client, conn, client_entry, im->flags,
-					 (unsigned char *)im->message, im->message_len, TRUE);
-	purple_conv_im_write(PURPLE_CONV_IM(convo), conn->local_entry->nickname,
-			   im->message, 0, time(NULL));
-	goto out;
-
- err:
-	g_snprintf(tmp, sizeof(tmp),
-		   _("User <I>%s</I> is not present in the network"), im->nick);
-	purple_conversation_write(convo, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL));
-
- out:
-	g_free(im->nick);
-	g_free(im->message);
-	silc_free(im);
-	silc_free(nickname);
-}
-
-static int
-silcpurple_send_im(PurpleConnection *gc, const char *who, const char *message,
-		 PurpleMessageFlags flags)
-{
-	SilcPurple sg = gc->proto_data;
-	SilcClient client = sg->client;
-	SilcClientConnection conn = sg->conn;
-	SilcClientEntry *clients;
-	SilcUInt32 clients_count, mflags;
-	char *nickname, *msg, *tmp;
-	int ret = 0;
-	gboolean sign = purple_account_get_bool(sg->account, "sign-verify", FALSE);
-#ifdef HAVE_SILCMIME_H
-	SilcDList list;
-#endif
-
-	if (!who || !message)
-		return 0;
-
-	mflags = SILC_MESSAGE_FLAG_UTF8;
-
-	tmp = msg = purple_unescape_html(message);
-
-	if (!g_ascii_strncasecmp(msg, "/me ", 4)) {
-		msg += 4;
-		if (!*msg) {
-			g_free(tmp);
-			return 0;
-		}
-		mflags |= SILC_MESSAGE_FLAG_ACTION;
-	} else if (strlen(msg) > 1 && msg[0] == '/') {
-		if (!silc_client_command_call(client, conn, msg + 1))
-			purple_notify_error(gc, _("Call Command"), _("Cannot call command"),
-					_("Unknown command"));
-		g_free(tmp);
-		return 0;
-	}
-
-
-	if (!silc_parse_userfqdn(who, &nickname, NULL)) {
-		g_free(tmp);
-		return 0;
-	}
-
-	if (sign)
-		mflags |= SILC_MESSAGE_FLAG_SIGNED;
-
-	/* Find client entry */
-	clients = silc_client_get_clients_local(client, conn, nickname, who,
-						&clients_count);
-	if (!clients) {
-		/* Resolve unknown user */
-		SilcPurpleIM im = silc_calloc(1, sizeof(*im));
-		if (!im) {
-			g_free(tmp);
-			return 0;
-		}
-		im->nick = g_strdup(who);
-		im->message = g_strdup(message);
-		im->message_len = strlen(im->message);
-		im->flags = mflags;
-		im->gflags = flags;
-		silc_client_get_clients(client, conn, nickname, NULL,
-					silcpurple_send_im_resolved, im);
-		silc_free(nickname);
-		g_free(tmp);
-		return 0;
-	}
-
-#ifdef HAVE_SILCMIME_H
-	/* Check for images */
-	if (flags & PURPLE_MESSAGE_IMAGES) {
-		list = silcpurple_image_message(message, &mflags);
-		if (list) {
-			/* Send one or more MIME message.  If more than one, they
-			   are MIME fragments due to over large message */
-			SilcBuffer buf;
-
-			silc_dlist_start(list);
-			while ((buf = silc_dlist_get(list)) != SILC_LIST_END)
-				ret =
-			 	silc_client_send_private_message(client, conn,
-								 clients[0], mflags,
-								 buf->data, buf->len,
-								 TRUE);
-			silc_mime_partial_free(list);
-			g_free(tmp);
-			silc_free(nickname);
-			silc_free(clients);
-			return ret;
-		}
-	}
-#endif
-
-	/* Send private message directly */
-	ret = silc_client_send_private_message(client, conn, clients[0],
-					       mflags,
-					       (unsigned char *)msg,
-					       strlen(msg), TRUE);
-
-	g_free(tmp);
-	silc_free(nickname);
-	silc_free(clients);
-	return ret;
-}
-
-
-static GList *silcpurple_blist_node_menu(PurpleBlistNode *node) {
-	/* split this single menu building function back into the two
-	   original: one for buddies and one for chats */
-
-	if(PURPLE_BLIST_NODE_IS_CHAT(node)) {
-		return silcpurple_chat_menu((PurpleChat *) node);
-	} else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
-		return silcpurple_buddy_menu((PurpleBuddy *) node);
-	} else {
-		g_return_val_if_reached(NULL);
-	}
-}
-
-/********************************* Commands **********************************/
-
-static PurpleCmdRet silcpurple_cmd_chat_part(PurpleConversation *conv,
-		const char *cmd, char **args, char **error, void *data)
-{
-	PurpleConnection *gc;
-	PurpleConversation *convo = conv;
-	int id = 0;
-
-	gc = purple_conversation_get_gc(conv);
-
-	if (gc == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	if(args && args[0])
-		convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[0],
-									gc->account);
-
-	if (convo != NULL)
-		id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo));
-
-	if (id == 0)
-		return PURPLE_CMD_RET_FAILED;
-
-	silcpurple_chat_leave(gc, id);
-
-	return PURPLE_CMD_RET_OK;
-
-}
-
-static PurpleCmdRet silcpurple_cmd_chat_topic(PurpleConversation *conv,
-		const char *cmd, char **args, char **error, void *data)
-{
-	PurpleConnection *gc;
-	int id = 0;
-	char *buf, *tmp, *tmp2;
-	const char *topic;
-
-	gc = purple_conversation_get_gc(conv);
-	id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
-
-	if (gc == NULL || id == 0)
-		return PURPLE_CMD_RET_FAILED;
-
-	if (!args || !args[0]) {
-		topic = purple_conv_chat_get_topic (PURPLE_CONV_CHAT(conv));
-		if (topic) {
-			tmp = g_markup_escape_text(topic, -1);
-			tmp2 = purple_markup_linkify(tmp);
-			buf = g_strdup_printf(_("current topic is: %s"), tmp2);
-			g_free(tmp);
-			g_free(tmp2);
-		} else
-			buf = g_strdup(_("No topic is set"));
-		purple_conv_chat_write(PURPLE_CONV_CHAT(conv), gc->account->username, buf,
-							 PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
-		g_free(buf);
-
-	}
-
-	if (args && args[0] && (strlen(args[0]) > 255)) {
-		*error = g_strdup(_("Topic too long"));
-		return PURPLE_CMD_RET_FAILED;
-	}
-
-	silcpurple_chat_set_topic(gc, id, args ? args[0] : NULL);
-
-	return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_chat_join(PurpleConversation *conv,
-        const char *cmd, char **args, char **error, void *data)
-{
-	GHashTable *comp;
-
-	if(!args || !args[0])
-		return PURPLE_CMD_RET_FAILED;
-
-	comp = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
-
-	g_hash_table_replace(comp, "channel", args[0]);
-	if(args[1])
-		g_hash_table_replace(comp, "passphrase", args[1]);
-
-	silcpurple_chat_join(purple_conversation_get_gc(conv), comp);
-
-	g_hash_table_destroy(comp);
-	return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_chat_list(PurpleConversation *conv,
-        const char *cmd, char **args, char **error, void *data)
-{
-	PurpleConnection *gc;
-	gc = purple_conversation_get_gc(conv);
-	purple_roomlist_show_with_account(purple_connection_get_account(gc));
-	return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_whois(PurpleConversation *conv,
-		const char *cmd, char **args, char **error, void *data)
-{
-	PurpleConnection *gc;
-
-	gc = purple_conversation_get_gc(conv);
-
-	if (gc == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	silcpurple_get_info(gc, args[0]);
-
-	return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_msg(PurpleConversation *conv,
-		const char *cmd, char **args, char **error, void *data)
-{
-	int ret;
-	PurpleConnection *gc;
-
-	gc = purple_conversation_get_gc(conv);
-
-	if (gc == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	ret = silcpurple_send_im(gc, args[0], args[1], PURPLE_MESSAGE_SEND);
-
-	if (ret)
-		return PURPLE_CMD_RET_OK;
-	else
-		return PURPLE_CMD_RET_FAILED;
-}
-
-static PurpleCmdRet silcpurple_cmd_query(PurpleConversation *conv,
-		const char *cmd, char **args, char **error, void *data)
-{
-	int ret = 1;
-	PurpleConversation *convo;
-	PurpleConnection *gc;
-	PurpleAccount *account;
-
-	if (!args || !args[0]) {
-		*error = g_strdup(_("You must specify a nick"));
-		return PURPLE_CMD_RET_FAILED;
-	}
-
-	gc = purple_conversation_get_gc(conv);
-
-	if (gc == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	account = purple_connection_get_account(gc);
-
-	convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, args[0]);
-
-	if (args[1]) {
-		ret = silcpurple_send_im(gc, args[0], args[1], PURPLE_MESSAGE_SEND);
-		purple_conv_im_write(PURPLE_CONV_IM(convo), purple_connection_get_display_name(gc),
-				args[1], PURPLE_MESSAGE_SEND, time(NULL));
-	}
-
-	if (ret)
-		return PURPLE_CMD_RET_OK;
-	else
-		return PURPLE_CMD_RET_FAILED;
-}
-
-static PurpleCmdRet silcpurple_cmd_motd(PurpleConversation *conv,
-		const char *cmd, char **args, char **error, void *data)
-{
-	PurpleConnection *gc;
-	SilcPurple sg;
-	char *tmp;
-
-	gc = purple_conversation_get_gc(conv);
-
-	if (gc == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	sg = gc->proto_data;
-
-	if (sg == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	if (!sg->motd) {
-		*error = g_strdup(_("There is no Message of the Day associated with this connection"));
-		return PURPLE_CMD_RET_FAILED;
-	}
-
-	tmp = g_markup_escape_text(sg->motd, -1);
-	purple_notify_formatted(gc, NULL, _("Message of the Day"), NULL,
-			tmp, NULL, NULL);
-	g_free(tmp);
-
-	return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_detach(PurpleConversation *conv,
-		const char *cmd, char **args, char **error, void *data)
-{
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	gc = purple_conversation_get_gc(conv);
-
-	if (gc == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	sg = gc->proto_data;
-
-	if (sg == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	silc_client_command_call(sg->client, sg->conn, "DETACH");
-	sg->detaching = TRUE;
-
-	return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_cmode(PurpleConversation *conv,
-		const char *cmd, char **args, char **error, void *data)
-{
-	PurpleConnection *gc;
-	SilcPurple sg;
-	SilcChannelEntry channel;
-	char *silccmd, *silcargs, *msg, tmp[256];
-	const char *chname;
-
-	gc = purple_conversation_get_gc(conv);
-
-	if (gc == NULL || !args || gc->proto_data == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	sg = gc->proto_data;
-
-	if (args[0])
-		chname = args[0];
-	else
-		chname = purple_conversation_get_name(conv);
-
-	if (!args[1]) {
-		channel = silc_client_get_channel(sg->client, sg->conn,
-										  (char *)chname);
-		if (!channel) {
-			*error = g_strdup_printf(_("channel %s not found"), chname);
-			return PURPLE_CMD_RET_FAILED;
-		}
-		if (channel->mode) {
-			silcpurple_get_chmode_string(channel->mode, tmp, sizeof(tmp));
-			msg = g_strdup_printf(_("channel modes for %s: %s"), chname, tmp);
-		} else {
-			msg = g_strdup_printf(_("no channel modes are set on %s"), chname);
-		}
-		purple_conv_chat_write(PURPLE_CONV_CHAT(conv), "",
-							 msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
-		g_free(msg);
-		return PURPLE_CMD_RET_OK;
-	}
-
-	silcargs = g_strjoinv(" ", args);
-	silccmd = g_strconcat(cmd, " ", args ? silcargs : NULL, NULL);
-	g_free(silcargs);
-	if (!silc_client_command_call(sg->client, sg->conn, silccmd)) {
-		g_free(silccmd);
-		*error = g_strdup_printf(_("Failed to set cmodes for %s"), args[0]);
-		return PURPLE_CMD_RET_FAILED;
-	}
-	g_free(silccmd);
-
-	return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_generic(PurpleConversation *conv,
-		const char *cmd, char **args, char **error, void *data)
-{
-	PurpleConnection *gc;
-	SilcPurple sg;
-	char *silccmd, *silcargs;
-
-	gc = purple_conversation_get_gc(conv);
-
-	if (gc == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	sg = gc->proto_data;
-
-	if (sg == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	silcargs = g_strjoinv(" ", args);
-	silccmd = g_strconcat(cmd, " ", args ? silcargs : NULL, NULL);
-	g_free(silcargs);
-	if (!silc_client_command_call(sg->client, sg->conn, silccmd)) {
-		g_free(silccmd);
-		*error = g_strdup_printf(_("Unknown command: %s, (may be a client bug)"), cmd);
-		return PURPLE_CMD_RET_FAILED;
-	}
-	g_free(silccmd);
-
-	return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_quit(PurpleConversation *conv,
-		const char *cmd, char **args, char **error, void *data)
-{
-	PurpleConnection *gc;
-	SilcPurple sg;
-	GHashTable *ui_info;
-	const char *ui_name = NULL, *ui_website = NULL;
-	char *quit_msg;
-
-	gc = purple_conversation_get_gc(conv);
-
-	if (gc == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	sg = gc->proto_data;
-
-	if (sg == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	ui_info = purple_core_get_ui_info();
-
-	if(ui_info) {
-		ui_name = g_hash_table_lookup(ui_info, "name");
-		ui_website = g_hash_table_lookup(ui_info, "website");
-	}
-
-	if(!ui_name || !ui_website) {
-		ui_name = "Pidgin";
-		ui_website = PURPLE_WEBSITE;
-	}
-	quit_msg = g_strdup_printf(_("Download %s: %s"),
-							   ui_name, ui_website);
-
-	silc_client_command_call(sg->client, sg->conn, NULL,
-				 "QUIT", (args && args[0]) ? args[0] : quit_msg, NULL);
-	g_free(quit_msg);
-
-	return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_call(PurpleConversation *conv,
-		const char *cmd, char **args, char **error, void *data)
-{
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	gc = purple_conversation_get_gc(conv);
-
-	if (gc == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	sg = gc->proto_data;
-
-	if (sg == NULL)
-		return PURPLE_CMD_RET_FAILED;
-
-	if (!silc_client_command_call(sg->client, sg->conn, args[0])) {
-		*error = g_strdup_printf(_("Unknown command: %s"), args[0]);
-		return PURPLE_CMD_RET_FAILED;
-	}
-
-	return PURPLE_CMD_RET_OK;
-}
-
-
-/************************** Plugin Initialization ****************************/
-
-static void
-silcpurple_register_commands(void)
-{
-	purple_cmd_register("part", "w", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
-			PURPLE_CMD_FLAG_PRPL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
-			"prpl-silc", silcpurple_cmd_chat_part, _("part [channel]:  Leave the chat"), NULL);
-	purple_cmd_register("leave", "w", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
-			PURPLE_CMD_FLAG_PRPL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
-			"prpl-silc", silcpurple_cmd_chat_part, _("leave [channel]:  Leave the chat"), NULL);
-	purple_cmd_register("topic", "s", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc",
-			silcpurple_cmd_chat_topic, _("topic [&lt;new topic&gt;]:  View or change the topic"), NULL);
-	purple_cmd_register("join", "ws", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
-			PURPLE_CMD_FLAG_PRPL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
-			"prpl-silc", silcpurple_cmd_chat_join,
-			_("join &lt;channel&gt; [&lt;password&gt;]:  Join a chat on this network"), NULL);
-	purple_cmd_register("list", "", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc",
-			silcpurple_cmd_chat_list, _("list:  List channels on this network"), NULL);
-	purple_cmd_register("whois", "w", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc",
-			silcpurple_cmd_whois, _("whois &lt;nick&gt;:  View nick's information"), NULL);
-	purple_cmd_register("msg", "ws", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc", silcpurple_cmd_msg,
-			_("msg &lt;nick&gt; &lt;message&gt;:  Send a private message to a user"), NULL);
-	purple_cmd_register("query", "ws", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_query,
-			_("query &lt;nick&gt; [&lt;message&gt;]:  Send a private message to a user"), NULL);
-	purple_cmd_register("motd", "", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_motd,
-			_("motd:  View the server's Message Of The Day"), NULL);
-	purple_cmd_register("detach", "", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc", silcpurple_cmd_detach,
-			_("detach:  Detach this session"), NULL);
-	purple_cmd_register("quit", "s", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_quit,
-			_("quit [message]:  Disconnect from the server, with an optional message"), NULL);
-	purple_cmd_register("call", "s", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc", silcpurple_cmd_call,
-			_("call &lt;command&gt;:  Call any silc client command"), NULL);
-	/* These below just get passed through for the silc client library to deal
-	 * with */
-	purple_cmd_register("kill", "ws", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
-			_("kill &lt;nick&gt; [-pubkey|&lt;reason&gt;]:  Kill nick"), NULL);
-	purple_cmd_register("nick", "w", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc", silcpurple_cmd_generic,
-			_("nick &lt;newnick&gt;:  Change your nickname"), NULL);
-	purple_cmd_register("whowas", "ww", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
-			_("whowas &lt;nick&gt;:  View nick's information"), NULL);
-	purple_cmd_register("cmode", "wws", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_cmode,
-			_("cmode &lt;channel&gt; [+|-&lt;modes&gt;] [arguments]:  Change or display channel modes"), NULL);
-	purple_cmd_register("cumode", "wws", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
-			_("cumode &lt;channel&gt; +|-&lt;modes&gt; &lt;nick&gt;:  Change nick's modes on channel"), NULL);
-	purple_cmd_register("umode", "w", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc", silcpurple_cmd_generic,
-			_("umode &lt;usermodes&gt;:  Set your modes in the network"), NULL);
-	purple_cmd_register("oper", "s", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc", silcpurple_cmd_generic,
-			_("oper &lt;nick&gt; [-pubkey]:  Get server operator privileges"), NULL);
-	purple_cmd_register("invite", "ws", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
-			_("invite &lt;channel&gt; [-|+]&lt;nick&gt;:  invite nick or add/remove from channel invite list"), NULL);
-	purple_cmd_register("kick", "wws", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
-			_("kick &lt;channel&gt; &lt;nick&gt; [comment]:  Kick client from channel"), NULL);
-	purple_cmd_register("info", "w", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
-			_("info [server]:  View server administrative details"), NULL);
-	purple_cmd_register("ban", "ww", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
-			_("ban [&lt;channel&gt; +|-&lt;nick&gt;]:  Ban client from channel"), NULL);
-	purple_cmd_register("getkey", "w", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc", silcpurple_cmd_generic,
-			_("getkey &lt;nick|server&gt;:  Retrieve client's or server's public key"), NULL);
-	purple_cmd_register("stats", "", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc", silcpurple_cmd_generic,
-			_("stats:  View server and network statistics"), NULL);
-	purple_cmd_register("ping", "", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc", silcpurple_cmd_generic,
-			_("ping:  Send PING to the connected server"), NULL);
-#if 0 /* Purple doesn't handle these yet */
-	purple_cmd_register("users", "w", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc", silcpurple_cmd_users,
-			_("users &lt;channel&gt;:  List users in channel"));
-	purple_cmd_register("names", "ww", PURPLE_CMD_P_PRPL,
-			PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
-			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_names,
-			_("names [-count|-ops|-halfops|-voices|-normal] &lt;channel(s)&gt;:  List specific users in channel(s)"));
-#endif
-}
-
-static PurpleWhiteboardPrplOps silcpurple_wb_ops =
-{
-	silcpurple_wb_start,
-	silcpurple_wb_end,
-	silcpurple_wb_get_dimensions,
-	silcpurple_wb_set_dimensions,
-	silcpurple_wb_get_brush,
-	silcpurple_wb_set_brush,
-	silcpurple_wb_send,
-	silcpurple_wb_clear,
-
-	/* padding */
-	NULL,
-	NULL,
-	NULL,
-	NULL
-};
-
-static PurplePluginProtocolInfo prpl_info =
-{
-#ifdef HAVE_SILCMIME_H
-	OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME |
-	OPT_PROTO_PASSWORD_OPTIONAL | OPT_PROTO_IM_IMAGE |
-	OPT_PROTO_SLASH_COMMANDS_NATIVE,
-#else
-	OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME |
-	OPT_PROTO_PASSWORD_OPTIONAL |
-	OPT_PROTO_SLASH_COMMANDS_NATIVE,
-#endif
-	NULL,						/* user_splits */
-	NULL,						/* protocol_options */
-#ifdef SILC_ATTRIBUTE_USER_ICON
-	{"jpeg,gif,png,bmp", 0, 0, 96, 96, 0, PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */
-#else
-	NO_BUDDY_ICONS,
-#endif
-	silcpurple_list_icon,			/* list_icon */
-	NULL,				/* list_emblems */
-	silcpurple_status_text,		/* status_text */
-	silcpurple_tooltip_text,		/* tooltip_text */
-	silcpurple_away_states,		/* away_states */
-	silcpurple_blist_node_menu,	/* blist_node_menu */
-	silcpurple_chat_info,			/* chat_info */
-	silcpurple_chat_info_defaults,/* chat_info_defaults */
-	silcpurple_login,				/* login */
-	silcpurple_close,				/* close */
-	silcpurple_send_im,			/* send_im */
-	silcpurple_set_info,			/* set_info */
-	NULL,						/* send_typing */
-	silcpurple_get_info,			/* get_info */
-	silcpurple_set_status,		/* set_status */
-	silcpurple_idle_set,			/* set_idle */
-	silcpurple_change_passwd,		/* change_passwd */
-	silcpurple_add_buddy,			/* add_buddy */
-	NULL,						/* add_buddies */
-	silcpurple_remove_buddy,		/* remove_buddy */
-	NULL,						/* remove_buddies */
-	NULL,						/* add_permit */
-	NULL,						/* add_deny */
-	NULL,						/* rem_permit */
-	NULL,						/* rem_deny */
-	NULL,						/* set_permit_deny */
-	silcpurple_chat_join,			/* join_chat */
-	NULL,						/* reject_chat */
-	silcpurple_get_chat_name,		/* get_chat_name */
-	silcpurple_chat_invite,		/* chat_invite */
-	silcpurple_chat_leave,		/* chat_leave */
-	NULL,						/* chat_whisper */
-	silcpurple_chat_send,			/* chat_send */
-	silcpurple_keepalive,			/* keepalive */
-	NULL,						/* register_user */
-	NULL,						/* get_cb_info */
-	NULL,						/* get_cb_away */
-	NULL,						/* alias_buddy */
-	NULL,						/* group_buddy */
-	NULL,						/* rename_group */
-	NULL,						/* buddy_free */
-	NULL,						/* convo_closed */
-	NULL,						/* normalize */
-#ifdef SILC_ATTRIBUTE_USER_ICON
-	silcpurple_buddy_set_icon,			/* set_buddy_icon */
-#else
-	NULL,
-#endif
-	NULL,						/* remove_group */
-	NULL,						/* get_cb_real_name */
-	silcpurple_chat_set_topic,	/* set_chat_topic */
-	NULL,						/* find_blist_chat */
-	silcpurple_roomlist_get_list,	/* roomlist_get_list */
-	silcpurple_roomlist_cancel,	/* roomlist_cancel */
-	NULL,						/* roomlist_expand_category */
-	NULL,						/* can_receive_file */
-	silcpurple_ftp_send_file,		/* send_file */
-	silcpurple_ftp_new_xfer,		/* new_xfer */
-	NULL,						/* offline_message */
-	&silcpurple_wb_ops,			/* whiteboard_prpl_ops */
-	NULL,                       /* send_raw */
-	NULL,                       /* roomlist_room_serialize */
-	NULL,                       /* unregister_user */
-	NULL,                       /* send_attention */
-	NULL,                       /* get_attention_types */
-	sizeof(PurplePluginProtocolInfo),       /* struct_size */
-	NULL,                       /* get_account_text_table */
-	NULL,                       /* initiate_media */
-	NULL,                       /* get_media_caps */
-	NULL,                       /* get_moods */
-	NULL,                       /* set_public_alias */
-	NULL,                       /* get_public_alias */
-	NULL,                       /* add_buddy_with_invite */
-	NULL                        /* add_buddies_with_invite */
-};
-
-static PurplePluginInfo info =
-{
-	PURPLE_PLUGIN_MAGIC,
-	PURPLE_MAJOR_VERSION,
-	PURPLE_MINOR_VERSION,
-	PURPLE_PLUGIN_PROTOCOL,                             /**< type           */
-	NULL,                                             /**< ui_requirement */
-	0,                                                /**< flags          */
-	NULL,                                             /**< dependencies   */
-	PURPLE_PRIORITY_DEFAULT,                            /**< priority       */
-
-	"prpl-silc",                                      /**< id             */
-	"SILC",                                           /**< name           */
-	"1.0",                                            /**< version        */
-	/**  summary        */
-	N_("SILC Protocol Plugin"),
-	/**  description    */
-	N_("Secure Internet Live Conferencing (SILC) Protocol"),
-	"Pekka Riikonen",                                 /**< author         */
-	"http://silcnet.org/",                            /**< homepage       */
-
-	NULL,                                             /**< load           */
-	NULL,                                             /**< unload         */
-	NULL,                                             /**< destroy        */
-
-	NULL,                                             /**< ui_info        */
-	&prpl_info,                                       /**< extra_info     */
-	NULL,                                             /**< prefs_info     */
-	silcpurple_actions,
-
-	/* padding */
-	NULL,
-	NULL,
-	NULL,
-	NULL
-};
-
-static void
-init_plugin(PurplePlugin *plugin)
-{
-	PurpleAccountOption *option;
-	PurpleAccountUserSplit *split;
-	char tmp[256];
-	int i;
-	PurpleKeyValuePair *kvp;
-	GList *list = NULL;
-
-	silc_plugin = plugin;
-
-	split = purple_account_user_split_new(_("Network"), "silcnet.org", '@');
-	prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
-
-	/* Account options */
-	option = purple_account_option_string_new(_("Connect server"),
-						"server",
-						"silc.silcnet.org");
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-	option = purple_account_option_int_new(_("Port"), "port", 706);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-	g_snprintf(tmp, sizeof(tmp), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir());
-	option = purple_account_option_string_new(_("Public Key file"),
-						"public-key", tmp);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-	g_snprintf(tmp, sizeof(tmp), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir());
-	option = purple_account_option_string_new(_("Private Key file"),
-						"private-key", tmp);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
-	for (i = 0; silc_default_ciphers[i].name; i++) {
-		kvp = g_new0(PurpleKeyValuePair, 1);
-		kvp->key = g_strdup(silc_default_ciphers[i].name);
-		kvp->value = g_strdup(silc_default_ciphers[i].name);
-		list = g_list_append(list, kvp);
-	}
-	option = purple_account_option_list_new(_("Cipher"), "cipher", list);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
-	list = NULL;
-	for (i = 0; silc_default_hmacs[i].name; i++) {
-		kvp = g_new0(PurpleKeyValuePair, 1);
-		kvp->key = g_strdup(silc_default_hmacs[i].name);
-		kvp->value = g_strdup(silc_default_hmacs[i].name);
-		list = g_list_append(list, kvp);
-	}
-	option = purple_account_option_list_new(_("HMAC"), "hmac", list);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
-	option = purple_account_option_bool_new(_("Public key authentication"),
-					      "pubkey-auth", FALSE);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-	option = purple_account_option_bool_new(_("Block IMs without Key Exchange"),
-					      "block-ims", FALSE);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-	option = purple_account_option_bool_new(_("Block messages to whiteboard"),
-					      "block-wb", FALSE);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-	option = purple_account_option_bool_new(_("Automatically open whiteboard"),
-					      "open-wb", FALSE);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-	option = purple_account_option_bool_new(_("Digitally sign and verify all messages"),
-					      "sign-verify", FALSE);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
-	purple_prefs_remove("/plugins/prpl/silc");
-
-	silcpurple_register_commands();
-
-#ifdef _WIN32
-	silc_net_win32_init();
-#endif
-}
-
-PURPLE_INIT_PLUGIN(silc10, init_plugin, info);
--- a/libpurple/protocols/silc10/silcpurple.h	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/*
-
-  silcpurple.h
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2004 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-
-#ifndef SILCPURPLE_H
-#define SILCPURPLE_H
-
-/* Purple includes */
-#include "internal.h"
-#include "account.h"
-#include "accountopt.h"
-#include "cmds.h"
-#include "conversation.h"
-#include "debug.h"
-#include "ft.h"
-#include "notify.h"
-#include "prpl.h"
-#include "request.h"
-#include "roomlist.h"
-#include "server.h"
-#include "util.h"
-
-/* Default public and private key file names */
-#define SILCPURPLE_PUBLIC_KEY_NAME "public_key.pub"
-#define SILCPURPLE_PRIVATE_KEY_NAME "private_key.prv"
-
-/* Default settings for creating key pair */
-#define SILCPURPLE_DEF_PKCS "rsa"
-#define SILCPURPLE_DEF_PKCS_LEN 2048
-
-#define SILCPURPLE_PRVGRP 0x001fffff
-
-/* Status IDs */
-#define SILCPURPLE_STATUS_ID_OFFLINE	"offline"
-#define SILCPURPLE_STATUS_ID_AVAILABLE "available"
-#define SILCPURPLE_STATUS_ID_HYPER	"hyper"
-#define SILCPURPLE_STATUS_ID_AWAY		"away"
-#define SILCPURPLE_STATUS_ID_BUSY		"busy"
-#define SILCPURPLE_STATUS_ID_INDISPOSED "indisposed"
-#define SILCPURPLE_STATUS_ID_PAGE		"page"
-
-typedef struct {
-	unsigned long id;
-	const char *channel;
-	unsigned long chid;
-	const char *parentch;
-	SilcChannelPrivateKey key;
-} *SilcPurplePrvgrp;
-
-/* The SILC Purple plugin context */
-typedef struct SilcPurpleStruct {
-	SilcClient client;
-	SilcClientConnection conn;
-
-	guint scheduler;
-	PurpleConnection *gc;
-	PurpleAccount *account;
-	unsigned long channel_ids;
-	GList *grps;
-
-	char *motd;
-	PurpleRoomlist *roomlist;
-#ifdef HAVE_SILCMIME_H
-	SilcMimeAssembler mimeass;
-#endif
-	unsigned int detaching            : 1;
-	unsigned int resuming             : 1;
-	unsigned int roomlist_cancelled   : 1;
-	unsigned int chpk                 : 1;
-} *SilcPurple;
-
-
-gboolean silcpurple_check_silc_dir(PurpleConnection *gc);
-void silcpurple_chat_join_done(SilcClient client,
-			     SilcClientConnection conn,
-			     SilcClientEntry *clients,
-			     SilcUInt32 clients_count,
-			     void *context);
-const char *silcpurple_silcdir(void);
-const char *silcpurple_session_file(const char *account);
-void silcpurple_verify_public_key(SilcClient client, SilcClientConnection conn,
-				const char *name, SilcSocketType conn_type,
-				unsigned char *pk, SilcUInt32 pk_len,
-				SilcSKEPKType pk_type,
-				SilcVerifyPublicKey completion, void *context);
-GList *silcpurple_buddy_menu(PurpleBuddy *buddy);
-void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
-void silcpurple_send_buddylist(PurpleConnection *gc);
-void silcpurple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
-void silcpurple_buddy_keyagr_request(SilcClient client,
-				   SilcClientConnection conn,
-				   SilcClientEntry client_entry,
-				   const char *hostname, SilcUInt16 port);
-void silcpurple_idle_set(PurpleConnection *gc, int idle);
-void silcpurple_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full);
-char *silcpurple_status_text(PurpleBuddy *b);
-gboolean silcpurple_ip_is_private(const char *ip);
-void silcpurple_ftp_send_file(PurpleConnection *gc, const char *name, const char *file);
-PurpleXfer *silcpurple_ftp_new_xfer(PurpleConnection *gc, const char *name);
-void silcpurple_ftp_request(SilcClient client, SilcClientConnection conn,
-			  SilcClientEntry client_entry, SilcUInt32 session_id,
-			  const char *hostname, SilcUInt16 port);
-void silcpurple_show_public_key(SilcPurple sg,
-			      const char *name, SilcPublicKey public_key,
-			      GCallback callback, void *context);
-void silcpurple_get_info(PurpleConnection *gc, const char *who);
-SilcAttributePayload
-silcpurple_get_attr(SilcDList attrs, SilcAttribute attribute);
-void silcpurple_get_umode_string(SilcUInt32 mode, char *buf,
-			       SilcUInt32 buf_size);
-void silcpurple_get_chmode_string(SilcUInt32 mode, char *buf,
-				SilcUInt32 buf_size);
-void silcpurple_get_chumode_string(SilcUInt32 mode, char *buf,
-				 SilcUInt32 buf_size);
-GList *silcpurple_chat_info(PurpleConnection *gc);
-GHashTable *silcpurple_chat_info_defaults(PurpleConnection *gc, const char *chat_name);
-GList *silcpurple_chat_menu(PurpleChat *);
-void silcpurple_chat_join(PurpleConnection *gc, GHashTable *data);
-char *silcpurple_get_chat_name(GHashTable *data);
-void silcpurple_chat_invite(PurpleConnection *gc, int id, const char *msg,
-			  const char *name);
-void silcpurple_chat_leave(PurpleConnection *gc, int id);
-int silcpurple_chat_send(PurpleConnection *gc, int id, const char *msg, PurpleMessageFlags flags);
-void silcpurple_chat_set_topic(PurpleConnection *gc, int id, const char *topic);
-PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc);
-void silcpurple_roomlist_cancel(PurpleRoomlist *list);
-void silcpurple_chat_chauth_show(SilcPurple sg, SilcChannelEntry channel,
-			       SilcBuffer channel_pubkeys);
-void silcpurple_parse_attrs(SilcDList attrs, char **moodstr, char **statusstr,
-					 char **contactstr, char **langstr, char **devicestr,
-					 char **tzstr, char **geostr);
-#ifdef SILC_ATTRIBUTE_USER_ICON
-void silcpurple_buddy_set_icon(PurpleConnection *gc, PurpleStoredImage *img);
-#endif
-#ifdef HAVE_SILCMIME_H
-char *silcpurple_file2mime(const char *filename);
-SilcDList silcpurple_image_message(const char *msg, SilcUInt32 *mflags);
-#endif
-
-#ifdef _WIN32
-typedef int uid_t;
-
-struct passwd {
-	char	*pw_name;	/* user name */
-	char	*pw_passwd;	/* user password */
-	int		pw_uid;		/* user id */
-	int		pw_gid;		/* group id */
-	char	*pw_gecos;	/* real name */
-	char	*pw_dir;	/* home directory */
-	char	*pw_shell;	/* shell program */
-};
-
-struct passwd *getpwuid(int uid);
-int getuid(void);
-int geteuid(void);
-#endif
-
-#endif /* SILCPURPLE_H */
--- a/libpurple/protocols/silc10/util.c	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,776 +0,0 @@
-/*
-
-  silcpurple_util.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2004 - 2005 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "imgstore.h"
-
-/**************************** Utility Routines *******************************/
-
-static char str[256], str2[256];
-
-const char *silcpurple_silcdir(void)
-{
-	const char *hd = purple_home_dir();
-	memset(str, 0, sizeof(str));
-	g_snprintf(str, sizeof(str) - 1, "%s" G_DIR_SEPARATOR_S ".silc", hd ? hd : "/tmp");
-	return (const char *)str;
-}
-
-const char *silcpurple_session_file(const char *account)
-{
-	memset(str2, 0, sizeof(str2));
-	g_snprintf(str2, sizeof(str2) - 1, "%s" G_DIR_SEPARATOR_S "%s_session",
-		   silcpurple_silcdir(), account);
-	return (const char *)str2;
-}
-
-gboolean silcpurple_ip_is_private(const char *ip)
-{
-	if (silc_net_is_ip4(ip)) {
-		if (!strncmp(ip, "10.", 3)) {
-			return TRUE;
-		} else if (!strncmp(ip, "172.", 4) && strlen(ip) > 6) {
-			char tmp[3];
-			int s;
-			memset(tmp, 0, sizeof(tmp));
-			strncpy(tmp, ip + 4, 2);
-			s = atoi(tmp);
-			if (s >= 16 && s <= 31)
-				return TRUE;
-		} else if (!strncmp(ip, "192.168.", 8)) {
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-/* This checks stats for various SILC files and directories. First it
-   checks if ~/.silc directory exist and is owned by the correct user. If
-   it doesn't exist, it will create the directory. After that it checks if
-   user's Public and Private key files exists and creates them if needed. */
-
-gboolean silcpurple_check_silc_dir(PurpleConnection *gc)
-{
-	char filename[256], file_public_key[256], file_private_key[256];
-	char servfilename[256], clientfilename[256], friendsfilename[256];
-	char pkd[256], prd[256];
-	struct stat st;
-	struct passwd *pw;
-	int fd;
-
-	pw = getpwuid(getuid());
-	if (!pw) {
-		purple_debug_error("silc", "silc: %s\n", g_strerror(errno));
-		return FALSE;
-	}
-
-	g_snprintf(filename, sizeof(filename) - 1, "%s", silcpurple_silcdir());
-	g_snprintf(servfilename, sizeof(servfilename) - 1, "%s" G_DIR_SEPARATOR_S "serverkeys",
-		   silcpurple_silcdir());
-	g_snprintf(clientfilename, sizeof(clientfilename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys",
-		   silcpurple_silcdir());
-	g_snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s" G_DIR_SEPARATOR_S "friends",
-		   silcpurple_silcdir());
-
-	/*
-	 * Check ~/.silc directory
-	 */
-	if ((g_stat(filename, &st)) == -1) {
-		/* If dir doesn't exist */
-		if (errno == ENOENT) {
-			if (pw->pw_uid == geteuid()) {
-				if ((g_mkdir(filename, 0755)) == -1) {
-					purple_debug_error("silc", "Couldn't create '%s' directory\n", filename);
-					return FALSE;
-				}
-			} else {
-				purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n",
-					filename);
-				return FALSE;
-			}
-		} else {
-			purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", filename, g_strerror(errno));
-			return FALSE;
-		}
-	} else {
-#ifndef _WIN32
-		/* Check the owner of the dir */
-		if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
-			purple_debug_error("silc", "You don't seem to own '%s' directory\n",
-				filename);
-			return FALSE;
-		}
-#endif
-	}
-
-	/*
-	 * Check ~./silc/serverkeys directory
-	 */
-	if ((g_stat(servfilename, &st)) == -1) {
-		/* If dir doesn't exist */
-		if (errno == ENOENT) {
-			if (pw->pw_uid == geteuid()) {
-				if ((g_mkdir(servfilename, 0755)) == -1) {
-					purple_debug_error("silc", "Couldn't create '%s' directory\n", servfilename);
-					return FALSE;
-				}
-			} else {
-				purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n",
-					servfilename);
-				return FALSE;
-			}
-		} else {
-			purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n",
-							 servfilename, g_strerror(errno));
-			return FALSE;
-		}
-	}
-
-	/*
-	 * Check ~./silc/clientkeys directory
-	 */
-	if ((g_stat(clientfilename, &st)) == -1) {
-		/* If dir doesn't exist */
-		if (errno == ENOENT) {
-			if (pw->pw_uid == geteuid()) {
-				if ((g_mkdir(clientfilename, 0755)) == -1) {
-					purple_debug_error("silc", "Couldn't create '%s' directory\n", clientfilename);
-					return FALSE;
-				}
-			} else {
-				purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n",
-					clientfilename);
-				return FALSE;
-			}
-		} else {
-			purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n",
-							 clientfilename, g_strerror(errno));
-			return FALSE;
-		}
-	}
-
-	/*
-	 * Check ~./silc/friends directory
-	 */
-	if ((g_stat(friendsfilename, &st)) == -1) {
-		/* If dir doesn't exist */
-		if (errno == ENOENT) {
-			if (pw->pw_uid == geteuid()) {
-				if ((g_mkdir(friendsfilename, 0755)) == -1) {
-					purple_debug_error("silc", "Couldn't create '%s' directory\n", friendsfilename);
-					return FALSE;
-				}
-			} else {
-				purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n",
-					friendsfilename);
-				return FALSE;
-			}
-		} else {
-			purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n",
-							 friendsfilename, g_strerror(errno));
-			return FALSE;
-		}
-	}
-
-	/*
-	 * Check Public and Private keys
-	 */
-	g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir());
-	g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir());
-	g_snprintf(file_public_key, sizeof(file_public_key) - 1, "%s",
-		   purple_account_get_string(gc->account, "public-key", pkd));
-	g_snprintf(file_private_key, sizeof(file_public_key) - 1, "%s",
-		   purple_account_get_string(gc->account, "private-key", prd));
-
-	if ((g_stat(file_public_key, &st)) == -1) {
-		/* If file doesn't exist */
-		if (errno == ENOENT) {
-			purple_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5);
-			if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS,
-					     SILCPURPLE_DEF_PKCS_LEN,
-					     file_public_key, file_private_key, NULL,
-					     (gc->password == NULL) ? "" : gc->password,
-						 NULL, NULL, NULL, FALSE)) {
-				purple_debug_error("silc", "Couldn't create key pair\n");
-				return FALSE;
-			}
-
-			if ((g_stat(file_public_key, &st)) == -1) {
-				purple_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n",
-					file_public_key, g_strerror(errno));
-				return FALSE;
-			}
-		} else {
-			purple_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n",
-							 file_public_key, g_strerror(errno));
-			return FALSE;
-		}
-	}
-
-#ifndef _WIN32
-	/* Check the owner of the public key */
-	if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
-		purple_debug_error("silc", "You don't seem to own your public key!?\n");
-		return FALSE;
-	}
-#endif
-
-	if ((fd = g_open(file_private_key, O_RDONLY, 0)) != -1) {
-		if ((fstat(fd, &st)) == -1) {
-			purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n",
-							 file_private_key, g_strerror(errno));
-			close(fd);
-			return FALSE;
-		}
-	} else if ((g_stat(file_private_key, &st)) == -1) {
-		/* If file doesn't exist */
-		if (errno == ENOENT) {
-			purple_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5);
-			if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS,
-					     SILCPURPLE_DEF_PKCS_LEN,
-					     file_public_key, file_private_key, NULL,
-					     (gc->password == NULL) ? "" : gc->password,
-						 NULL, NULL, NULL, FALSE)) {
-				purple_debug_error("silc", "Couldn't create key pair\n");
-				return FALSE;
-			}
-
-			if ((fd = g_open(file_private_key, O_RDONLY, 0)) != -1) {
-				if ((fstat(fd, &st)) == -1) {
-					purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n",
-							 file_private_key, g_strerror(errno));
-					close(fd);
-					return FALSE;
-				}
-			}
-			/* This shouldn't really happen because silc_create_key_pair()
-			 * will set the permissions */
-			else if ((g_stat(file_private_key, &st)) == -1) {
-				purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n",
-					file_private_key, g_strerror(errno));
-				return FALSE;
-			}
-		} else {
-			purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n",
-							 file_private_key, g_strerror(errno));
-			return FALSE;
-		}
-	}
-
-#ifndef _WIN32
-	/* Check the owner of the private key */
-	if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
-		purple_debug_error("silc", "You don't seem to own your private key!?\n");
-		if (fd != -1)
-			close(fd);
-		return FALSE;
-	}
-
-	/* Check the permissions for the private key */
-	if ((st.st_mode & 0777) != 0600) {
-		purple_debug_warning("silc", "Wrong permissions in your private key file `%s'!\n"
-			"Trying to change them ...\n", file_private_key);
-		if ((fd == -1) || (fchmod(fd, S_IRUSR | S_IWUSR)) == -1) {
-			purple_debug_error("silc",
-				"Failed to change permissions for private key file!\n"
-				"Permissions for your private key file must be 0600.\n");
-			if (fd != -1)
-				close(fd);
-			return FALSE;
-		}
-		purple_debug_warning("silc", "Done.\n\n");
-	}
-#endif
-
-	if (fd != -1)
-		close(fd);
-
-	return TRUE;
-}
-
-#ifdef _WIN32
-struct passwd *getpwuid(uid_t uid) {
-	struct passwd *pwd = calloc(1, sizeof(struct passwd));
-	return pwd;
-}
-
-uid_t getuid() {
-	return 0;
-}
-
-uid_t geteuid() {
-	return 0;
-}
-#endif
-
-void silcpurple_show_public_key(SilcPurple sg,
-			      const char *name, SilcPublicKey public_key,
-			      GCallback callback, void *context)
-{
-	SilcPublicKeyIdentifier ident;
-	SilcPKCS pkcs;
-	char *fingerprint, *babbleprint;
-	unsigned char *pk;
-	SilcUInt32 pk_len, key_len = 0;
-	GString *s;
-	char *buf;
-
-	ident = silc_pkcs_decode_identifier(public_key->identifier);
-	if (!ident)
-		return;
-
-	pk = silc_pkcs_public_key_encode(public_key, &pk_len);
-	fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-	babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
-
-	if (silc_pkcs_alloc((unsigned char *)public_key->name, &pkcs)) {
-		key_len = silc_pkcs_public_key_set(pkcs, public_key);
-		silc_pkcs_free(pkcs);
-	}
-
-	s = g_string_new("");
-	if (ident->realname)
-		/* Hint for translators: Please check the tabulator width here and in
-		   the next strings (short strings: 2 tabs, longer strings 1 tab,
-		   sum: 3 tabs or 24 characters) */
-		g_string_append_printf(s, _("Real Name: \t%s\n"), ident->realname);
-	if (ident->username)
-		g_string_append_printf(s, _("User Name: \t%s\n"), ident->username);
-	if (ident->email)
-		g_string_append_printf(s, _("Email: \t\t%s\n"), ident->email);
-	if (ident->host)
-		g_string_append_printf(s, _("Host Name: \t%s\n"), ident->host);
-	if (ident->org)
-		g_string_append_printf(s, _("Organization: \t%s\n"), ident->org);
-	if (ident->country)
-		g_string_append_printf(s, _("Country: \t%s\n"), ident->country);
-	g_string_append_printf(s, _("Algorithm: \t%s\n"), public_key->name);
-	g_string_append_printf(s, _("Key Length: \t%d bits\n"), (int)key_len);
-	g_string_append_printf(s, "\n");
-	g_string_append_printf(s, _("Public Key Fingerprint:\n%s\n\n"), fingerprint);
-	g_string_append_printf(s, _("Public Key Babbleprint:\n%s"), babbleprint);
-
-	buf = g_string_free(s, FALSE);
-
-	purple_request_action(sg->gc, _("Public Key Information"),
-			    _("Public Key Information"),
-			    buf, 0, purple_connection_get_account(sg->gc),
-				NULL, NULL, context, 1, _("Close"), callback);
-
-	g_free(buf);
-	silc_free(fingerprint);
-	silc_free(babbleprint);
-	silc_free(pk);
-	silc_pkcs_free_identifier(ident);
-}
-
-SilcAttributePayload
-silcpurple_get_attr(SilcDList attrs, SilcAttribute attribute)
-{
-	SilcAttributePayload attr = NULL;
-
-	if (!attrs)
-		return NULL;
-
-	silc_dlist_start(attrs);
-	while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END)
-		if (attribute == silc_attribute_get_attribute(attr))
-			break;
-
-	return attr;
-}
-
-void silcpurple_get_umode_string(SilcUInt32 mode, char *buf,
-			       SilcUInt32 buf_size)
-{
-	memset(buf, 0, buf_size);
-	if ((mode & SILC_UMODE_SERVER_OPERATOR) ||
-	    (mode & SILC_UMODE_ROUTER_OPERATOR)) {
-		strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ?
-		       "[server operator] " :
-		       (mode & SILC_UMODE_ROUTER_OPERATOR) ?
-		       "[SILC operator] " : "[unknown mode] ");
-	}
-	if (mode & SILC_UMODE_GONE)
-		strcat(buf, "[away] ");
-	if (mode & SILC_UMODE_INDISPOSED)
-		strcat(buf, "[indisposed] ");
-	if (mode & SILC_UMODE_BUSY)
-		strcat(buf, "[busy] ");
-	if (mode & SILC_UMODE_PAGE)
-		strcat(buf, "[wake me up] ");
-	if (mode & SILC_UMODE_HYPER)
-		strcat(buf, "[hyperactive] ");
-	if (mode & SILC_UMODE_ROBOT)
-		strcat(buf, "[robot] ");
-	if (mode & SILC_UMODE_ANONYMOUS)
-		strcat(buf, "[anonymous] ");
-	if (mode & SILC_UMODE_BLOCK_PRIVMSG)
-		strcat(buf, "[blocks private messages] ");
-	if (mode & SILC_UMODE_DETACHED)
-		strcat(buf, "[detached] ");
-	if (mode & SILC_UMODE_REJECT_WATCHING)
-		strcat(buf, "[rejects watching] ");
-	if (mode & SILC_UMODE_BLOCK_INVITE)
-		strcat(buf, "[blocks invites] ");
-	g_strchomp(buf);
-}
-
-void silcpurple_get_chmode_string(SilcUInt32 mode, char *buf,
-				SilcUInt32 buf_size)
-{
-	memset(buf, 0, buf_size);
-	if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
-		strcat(buf, "[permanent] ");
-	if (mode & SILC_CHANNEL_MODE_PRIVATE)
-		strcat(buf, "[private] ");
-	if (mode & SILC_CHANNEL_MODE_SECRET)
-		strcat(buf, "[secret] ");
-	if (mode & SILC_CHANNEL_MODE_PRIVKEY)
-		strcat(buf, "[private key] ");
-	if (mode & SILC_CHANNEL_MODE_INVITE)
-		strcat(buf, "[invite only] ");
-	if (mode & SILC_CHANNEL_MODE_TOPIC)
-		strcat(buf, "[topic restricted] ");
-	if (mode & SILC_CHANNEL_MODE_ULIMIT)
-		strcat(buf, "[user count limit] ");
-	if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
-		strcat(buf, "[passphrase auth] ");
-	if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
-		strcat(buf, "[public key auth] ");
-	if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
-		strcat(buf, "[users silenced] ");
-	if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
-		strcat(buf, "[operators silenced] ");
-	g_strchomp(buf);
-}
-
-void silcpurple_get_chumode_string(SilcUInt32 mode, char *buf,
-				 SilcUInt32 buf_size)
-{
-	memset(buf, 0, buf_size);
-	if (mode & SILC_CHANNEL_UMODE_CHANFO)
-		strcat(buf, "[founder] ");
-	if (mode & SILC_CHANNEL_UMODE_CHANOP)
-		strcat(buf, "[operator] ");
-	if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
-		strcat(buf, "[blocks messages] ");
-	if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)
-		strcat(buf, "[blocks user messages] ");
-	if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)
-		strcat(buf, "[blocks robot messages] ");
-	if (mode & SILC_CHANNEL_UMODE_QUIET)
-		strcat(buf, "[quieted] ");
-	g_strchomp(buf);
-}
-
-void
-silcpurple_parse_attrs(SilcDList attrs, char **moodstr, char **statusstr,
-					 char **contactstr, char **langstr, char **devicestr,
-					 char **tzstr, char **geostr)
-{
-	SilcAttributePayload attr;
-	SilcAttributeMood mood = 0;
-	SilcAttributeContact contact;
-	SilcAttributeObjDevice device;
-	SilcAttributeObjGeo geo;
-
-	char tmp[1024];
-	GString *s;
-
-	*moodstr = NULL;
-	*statusstr = NULL;
-	*contactstr = NULL;
-	*langstr = NULL;
-	*devicestr = NULL;
-	*tzstr = NULL;
-	*geostr = NULL;
-
-	if (!attrs)
-		return;
-
-	s = g_string_new("");
-	attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_STATUS_MOOD);
-	if (attr && silc_attribute_get_object(attr, &mood, sizeof(mood))) {
-		if (mood & SILC_ATTRIBUTE_MOOD_HAPPY)
-			g_string_append_printf(s, "[%s] ", _("Happy"));
-		if (mood & SILC_ATTRIBUTE_MOOD_SAD)
-			g_string_append_printf(s, "[%s] ", _("Sad"));
-		if (mood & SILC_ATTRIBUTE_MOOD_ANGRY)
-			g_string_append_printf(s, "[%s] ", _("Angry"));
-		if (mood & SILC_ATTRIBUTE_MOOD_JEALOUS)
-			g_string_append_printf(s, "[%s] ", _("Jealous"));
-		if (mood & SILC_ATTRIBUTE_MOOD_ASHAMED)
-			g_string_append_printf(s, "[%s] ", _("Ashamed"));
-		if (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE)
-			g_string_append_printf(s, "[%s] ", _("Invincible"));
-		if (mood & SILC_ATTRIBUTE_MOOD_INLOVE)
-			g_string_append_printf(s, "[%s] ", _("In Love"));
-		if (mood & SILC_ATTRIBUTE_MOOD_SLEEPY)
-			g_string_append_printf(s, "[%s] ", _("Sleepy"));
-		if (mood & SILC_ATTRIBUTE_MOOD_BORED)
-			g_string_append_printf(s, "[%s] ", _("Bored"));
-		if (mood & SILC_ATTRIBUTE_MOOD_EXCITED)
-			g_string_append_printf(s, "[%s] ", _("Excited"));
-		if (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS)
-			g_string_append_printf(s, "[%s] ", _("Anxious"));
-	}
-	if (strlen(s->str)) {
-		*moodstr = s->str;
-		g_string_free(s, FALSE);
-		g_strchomp(*moodstr);
-	} else
-		g_string_free(s, TRUE);
-
-	attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_STATUS_FREETEXT);
-	memset(tmp, 0, sizeof(tmp));
-	if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp)))
-		*statusstr = g_strdup(tmp);
-
-	s = g_string_new("");
-	attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_CONTACT);
-	if (attr && silc_attribute_get_object(attr, &contact, sizeof(contact))) {
-		if (contact & SILC_ATTRIBUTE_CONTACT_CHAT)
-			g_string_append_printf(s, "[%s] ", _("Chat"));
-		if (contact & SILC_ATTRIBUTE_CONTACT_EMAIL)
-			g_string_append_printf(s, "[%s] ", _("Email"));
-		if (contact & SILC_ATTRIBUTE_CONTACT_CALL)
-			g_string_append_printf(s, "[%s] ", _("Phone"));
-		if (contact & SILC_ATTRIBUTE_CONTACT_PAGE)
-			g_string_append_printf(s, "[%s] ", _("Paging"));
-		if (contact & SILC_ATTRIBUTE_CONTACT_SMS)
-			g_string_append_printf(s, "[%s] ", _("SMS"));
-		if (contact & SILC_ATTRIBUTE_CONTACT_MMS)
-			g_string_append_printf(s, "[%s] ", _("MMS"));
-		if (contact & SILC_ATTRIBUTE_CONTACT_VIDEO)
-			g_string_append_printf(s, "[%s] ", _("Video Conferencing"));
-	}
-	if (strlen(s->str)) {
-		*contactstr = s->str;
-		g_string_free(s, FALSE);
-		g_strchomp(*contactstr);
-	} else
-		g_string_free(s, TRUE);
-
-	attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_LANGUAGE);
-	memset(tmp, 0, sizeof(tmp));
-	if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp)))
-		*langstr = g_strdup(tmp);
-
-	s = g_string_new("");
-	attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_DEVICE_INFO);
-	memset(&device, 0, sizeof(device));
-	if (attr && silc_attribute_get_object(attr, &device, sizeof(device))) {
-		if (device.type == SILC_ATTRIBUTE_DEVICE_COMPUTER)
-			g_string_append_printf(s, "%s: ", _("Computer"));
-		if (device.type == SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE)
-			g_string_append_printf(s, "%s: ", _("Mobile Phone"));
-		if (device.type == SILC_ATTRIBUTE_DEVICE_PDA)
-			g_string_append_printf(s, "%s: ", _("PDA"));
-		if (device.type == SILC_ATTRIBUTE_DEVICE_TERMINAL)
-			g_string_append_printf(s, "%s: ", _("Terminal"));
-		g_string_append_printf(s, "%s %s %s %s",
-				device.manufacturer ? device.manufacturer : "",
-				device.version ? device.version : "",
-				device.model ? device.model : "",
-				device.language ? device.language : "");
-	}
-	if (strlen(s->str)) {
-		*devicestr = s->str;
-		g_string_free(s, FALSE);
-	} else
-		g_string_free(s, TRUE);
-
-	attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_TIMEZONE);
-	memset(tmp, 0, sizeof(tmp));
-	if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp)))
-		*tzstr = g_strdup(tmp);
-
-	attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_GEOLOCATION);
-	memset(&geo, 0, sizeof(geo));
-	if (attr && silc_attribute_get_object(attr, &geo, sizeof(geo)))
-		*geostr = g_strdup_printf("%s %s %s (%s)",
-				geo.longitude ? geo.longitude : "",
-				geo.latitude ? geo.latitude : "",
-				geo.altitude ? geo.altitude : "",
-				geo.accuracy ? geo.accuracy : "");
-}
-
-#ifdef HAVE_SILCMIME_H
-/* Returns MIME type of filetype */
-
-char *silcpurple_file2mime(const char *filename)
-{
-	const char *ct;
-
-	ct = strrchr(filename, '.');
-	if (!ct)
-		return NULL;
-	else if (!g_ascii_strcasecmp(".png", ct))
-		return strdup("image/png");
-	else if (!g_ascii_strcasecmp(".jpg", ct))
-		return strdup("image/jpeg");
-	else if (!g_ascii_strcasecmp(".jpeg", ct))
-		return strdup("image/jpeg");
-	else if (!g_ascii_strcasecmp(".gif", ct))
-		return strdup("image/gif");
-	else if (!g_ascii_strcasecmp(".tiff", ct))
-		return strdup("image/tiff");
-
-	return NULL;
-}
-
-/* Checks if message has images, and assembles MIME message if it has.
-   If only one image is present, creates simple MIME image message.  If
-   there are multiple images and/or text with images multipart MIME
-   message is created. */
-
-SilcDList silcpurple_image_message(const char *msg, SilcUInt32 *mflags)
-{
-	SilcMime mime = NULL, p;
-	SilcDList list, parts = NULL;
-	const char *start, *end, *last;
-	GData *attribs;
-	char *type;
-	gboolean images = FALSE;
-
-	last = msg;
-	while (last && *last && purple_markup_find_tag("img", last, &start,
-						     &end, &attribs)) {
-		PurpleStoredImage *image = NULL;
-		const char *id;
-
-		/* Check if there is text before image */
-		if (start - last) {
-			char *text, *tmp;
-			p = silc_mime_alloc();
-
-			/* Add content type */
-			silc_mime_add_field(p, "Content-Type",
-					    "text/plain; charset=utf-8");
-
-			tmp = g_strndup(last, start - last);
-			text = purple_unescape_html(tmp);
-			g_free(tmp);
-			/* Add text */
-			silc_mime_add_data(p, (unsigned char *)text, strlen(text));
-			g_free(text);
-
-			if (!parts)
-				parts = silc_dlist_init();
-			silc_dlist_add(parts, p);
-		}
-
-		id = g_datalist_get_data(&attribs, "id");
-		if (id && (image = purple_imgstore_find_by_id(atoi(id)))) {
-			unsigned long imglen = purple_imgstore_get_size(image);
-			gconstpointer img = purple_imgstore_get_data(image);
-
-			p = silc_mime_alloc();
-
-			/* Add content type */
-			type = silcpurple_file2mime(purple_imgstore_get_filename(image));
-			if (!type) {
-				g_datalist_clear(&attribs);
-				last = end + 1;
-				continue;
-			}
-			silc_mime_add_field(p, "Content-Type", type);
-			silc_free(type);
-
-			/* Add content transfer encoding */
-			silc_mime_add_field(p, "Content-Transfer-Encoding", "binary");
-
-			/* Add image data */
-			silc_mime_add_data(p, img, imglen);
-
-			if (!parts)
-				parts = silc_dlist_init();
-			silc_dlist_add(parts, p);
-			images = TRUE;
-		}
-
-		g_datalist_clear(&attribs);
-
-		/* Continue after tag */
-		last = end + 1;
-	}
-
-	/* Check for text after the image(s) */
-	if (images && last && *last) {
-		char *tmp = purple_unescape_html(last);
-		p = silc_mime_alloc();
-
-		/* Add content type */
-		silc_mime_add_field(p, "Content-Type",
-				    "text/plain; charset=utf-8");
-
-		/* Add text */
-		silc_mime_add_data(p, (unsigned char *)tmp, strlen(tmp));
-		g_free(tmp);
-
-		if (!parts)
-			parts = silc_dlist_init();
-		silc_dlist_add(parts, p);
-	}
-
-	/* If there weren't any images, don't return anything. */
-	if (!images) {
-		if (parts)
-			silc_dlist_uninit(parts);
-		return NULL;
-	}
-
-	if (silc_dlist_count(parts) > 1) {
-		/* Multipart MIME message */
-		char b[32];
-		mime = silc_mime_alloc();
-		silc_mime_add_field(mime, "MIME-Version", "1.0");
-		g_snprintf(b, sizeof(b), "b%4X%4X",
-			   (unsigned int)time(NULL),
-			   silc_dlist_count(parts));
-		silc_mime_set_multipart(mime, "mixed", b);
-		silc_dlist_start(parts);
-		while ((p = silc_dlist_get(parts)) != SILC_LIST_END)
-			silc_mime_add_multipart(mime, p);
-	} else {
-		/* Simple MIME message */
-		silc_dlist_start(parts);
-		mime = silc_dlist_get(parts);
-		silc_mime_add_field(mime, "MIME-Version", "1.0");
-	}
-
-	*mflags &= ~SILC_MESSAGE_FLAG_UTF8;
-	*mflags |= SILC_MESSAGE_FLAG_DATA;
-
-	/* Encode message. Fragment if it is too large */
-	list = silc_mime_encode_partial(mime, 0xfc00);
-
-	silc_dlist_uninit(parts);
-
-	/* Added multiparts gets freed here */
-	silc_mime_free(mime);
-
-	return list;
-}
-
-#endif /* HAVE_SILCMIME_H */
--- a/libpurple/protocols/silc10/wb.c	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,520 +0,0 @@
-/*
-
-  wb.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2005 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "wb.h"
-
-/*
-  SILC Whiteboard packet:
-
-  1 byte	command
-  2 bytes	width
-  2 bytes	height
-  4 bytes	brush color
-  2 bytes	brush size
-  n bytes	data
-
-  Data:
-
-  4 bytes	x
-  4 bytes	y
-
-  Commands:
-
-  0x01		draw
-  0x02		clear
-
-  MIME:
-
-  MIME-Version: 1.0
-  Content-Type: application/x-wb
-  Content-Transfer-Encoding: binary
-
-*/
-
-#define SILCPURPLE_WB_MIME "MIME-Version: 1.0\r\nContent-Type: application/x-wb\r\nContent-Transfer-Encoding: binary\r\n\r\n"
-#define SILCPURPLE_WB_HEADER strlen(SILCPURPLE_WB_MIME) + 11
-
-#define SILCPURPLE_WB_WIDTH 500
-#define SILCPURPLE_WB_HEIGHT 400
-#define SILCPURPLE_WB_WIDTH_MAX 1024
-#define SILCPURPLE_WB_HEIGHT_MAX 1024
-
-/* Commands */
-typedef enum {
-	SILCPURPLE_WB_DRAW 	= 0x01,
-	SILCPURPLE_WB_CLEAR	= 0x02
-} SilcPurpleWbCommand;
-
-/* Brush size */
-typedef enum {
-	SILCPURPLE_WB_BRUSH_SMALL = 2,
-	SILCPURPLE_WB_BRUSH_MEDIUM = 5,
-	SILCPURPLE_WB_BRUSH_LARGE = 10
-} SilcPurpleWbBrushSize;
-
-/* Brush color (XXX Purple should provide default colors) */
-typedef enum {
-	SILCPURPLE_WB_COLOR_BLACK		= 0,
-	SILCPURPLE_WB_COLOR_RED		= 13369344,
-	SILCPURPLE_WB_COLOR_GREEN		= 52224,
-	SILCPURPLE_WB_COLOR_BLUE		= 204,
-	SILCPURPLE_WB_COLOR_YELLOW 	= 15658496,
-	SILCPURPLE_WB_COLOR_ORANGE	= 16737792,
-	SILCPURPLE_WB_COLOR_CYAN		= 52428,
-	SILCPURPLE_WB_COLOR_VIOLET	= 5381277,
-	SILCPURPLE_WB_COLOR_PURPLE	= 13369548,
-	SILCPURPLE_WB_COLOR_TAN		= 12093547,
-	SILCPURPLE_WB_COLOR_BROWN		= 5256485,
-	SILCPURPLE_WB_COLOR_GREY		= 11184810,
-	SILCPURPLE_WB_COLOR_WHITE		= 16777215
-} SilcPurpleWbColor;
-
-typedef struct {
-	int type;		/* 0 = buddy, 1 = channel */
-	union {
-		SilcClientEntry client;
-		SilcChannelEntry channel;
-	} u;
-	int width;
-	int height;
-	int brush_size;
-	int brush_color;
-} *SilcPurpleWb;
-
-/* Initialize whiteboard */
-
-PurpleWhiteboard *silcpurple_wb_init(SilcPurple sg, SilcClientEntry client_entry)
-{
-        SilcClientConnection conn;
-	PurpleWhiteboard *wb;
-	SilcPurpleWb wbs;
-
-	conn = sg->conn;
-	wb = purple_whiteboard_get_session(sg->account, client_entry->nickname);
-	if (!wb)
-		wb = purple_whiteboard_create(sg->account, client_entry->nickname, 0);
-	if (!wb)
-		return NULL;
-
-	if (!wb->proto_data) {
-		wbs = silc_calloc(1, sizeof(*wbs));
-		if (!wbs)
-			return NULL;
-		wbs->type = 0;
-		wbs->u.client = client_entry;
-		wbs->width = SILCPURPLE_WB_WIDTH;
-		wbs->height = SILCPURPLE_WB_HEIGHT;
-		wbs->brush_size = SILCPURPLE_WB_BRUSH_SMALL;
-		wbs->brush_color = SILCPURPLE_WB_COLOR_BLACK;
-		wb->proto_data = wbs;
-
-		/* Start the whiteboard */
-		purple_whiteboard_start(wb);
-		purple_whiteboard_clear(wb);
-	}
-
-	return wb;
-}
-
-PurpleWhiteboard *silcpurple_wb_init_ch(SilcPurple sg, SilcChannelEntry channel)
-{
-	PurpleWhiteboard *wb;
-	SilcPurpleWb wbs;
-
-	wb = purple_whiteboard_get_session(sg->account, channel->channel_name);
-	if (!wb)
-		wb = purple_whiteboard_create(sg->account, channel->channel_name, 0);
-	if (!wb)
-		return NULL;
-
-	if (!wb->proto_data) {
-		wbs = silc_calloc(1, sizeof(*wbs));
-		if (!wbs)
-			return NULL;
-		wbs->type = 1;
-		wbs->u.channel = channel;
-		wbs->width = SILCPURPLE_WB_WIDTH;
-		wbs->height = SILCPURPLE_WB_HEIGHT;
-		wbs->brush_size = SILCPURPLE_WB_BRUSH_SMALL;
-		wbs->brush_color = SILCPURPLE_WB_COLOR_BLACK;
-		wb->proto_data = wbs;
-
-		/* Start the whiteboard */
-		purple_whiteboard_start(wb);
-		purple_whiteboard_clear(wb);
-	}
-
-	return wb;
-}
-
-static void
-silcpurple_wb_parse(SilcPurpleWb wbs, PurpleWhiteboard *wb,
-		  unsigned char *message, SilcUInt32 message_len)
-{
-	SilcUInt8 command;
-	SilcUInt16 width, height, brush_size;
-	SilcUInt32 brush_color, x, y, dx, dy;
-	SilcBufferStruct buf;
-	int ret;
-
-	/* Parse the packet */
-	silc_buffer_set(&buf, message, message_len);
-	ret = silc_buffer_unformat(&buf,
-				   SILC_STR_UI_CHAR(&command),
-				   SILC_STR_UI_SHORT(&width),
-				   SILC_STR_UI_SHORT(&height),
-				   SILC_STR_UI_INT(&brush_color),
-				   SILC_STR_UI_SHORT(&brush_size),
-				   SILC_STR_END);
-	if (ret < 0)
-		return;
-	silc_buffer_pull(&buf, ret);
-
-	/* Update whiteboard if its dimensions changed */
-	if (width != wbs->width || height != wbs->height)
-		silcpurple_wb_set_dimensions(wb, height, width);
-
-	if (command == SILCPURPLE_WB_DRAW) {
-		/* Parse data and draw it */
-		ret = silc_buffer_unformat(&buf,
-					   SILC_STR_UI_INT(&dx),
-					   SILC_STR_UI_INT(&dy),
-					   SILC_STR_END);
-		if (ret < 0)
-			return;
-		silc_buffer_pull(&buf, 8);
-		x = dx;
-		y = dy;
-		while (buf.len > 0) {
-			ret = silc_buffer_unformat(&buf,
-						   SILC_STR_UI_INT(&dx),
-						   SILC_STR_UI_INT(&dy),
-						   SILC_STR_END);
-			if (ret < 0)
-				return;
-			silc_buffer_pull(&buf, 8);
-
-			purple_whiteboard_draw_line(wb, x, y, x + dx, y + dy,
-						  brush_color, brush_size);
-			x += dx;
-			y += dy;
-		}
-	}
-
-	if (command == SILCPURPLE_WB_CLEAR)
-		purple_whiteboard_clear(wb);
-}
-
-typedef struct {
-  unsigned char *message;
-  SilcUInt32 message_len;
-  SilcPurple sg;
-  SilcClientEntry sender;
-  SilcChannelEntry channel;
-} *SilcPurpleWbRequest;
-
-static void
-silcpurple_wb_request_cb(SilcPurpleWbRequest req, gint id)
-{
-	PurpleWhiteboard *wb;
-
-        if (id != 1)
-                goto out;
-
-	if (!req->channel)
-		wb = silcpurple_wb_init(req->sg, req->sender);
-	else
-		wb = silcpurple_wb_init_ch(req->sg, req->channel);
-
-	silcpurple_wb_parse(wb->proto_data, wb, req->message, req->message_len);
-
-  out:
-	silc_free(req->message);
-	silc_free(req);
-}
-
-static void
-silcpurple_wb_request(SilcClient client, const unsigned char *message,
-		    SilcUInt32 message_len, SilcClientEntry sender,
-		    SilcChannelEntry channel)
-{
-	char tmp[128];
-	SilcPurpleWbRequest req;
-	PurpleConnection *gc;
-	SilcPurple sg;
-
-	gc = client->application;
-	sg = gc->proto_data;
-
-	/* Open whiteboard automatically if requested */
-	if (purple_account_get_bool(sg->account, "open-wb", FALSE)) {
-		PurpleWhiteboard *wb;
-
-		if (!channel)
-			wb = silcpurple_wb_init(sg, sender);
-		else
-			wb = silcpurple_wb_init_ch(sg, channel);
-
-		silcpurple_wb_parse(wb->proto_data, wb, (unsigned char *)message,
-				  message_len);
-		return;
-	}
-
-	/* Close any previous unaccepted requests */
-	purple_request_close_with_handle(sender);
-
-	if (!channel) {
-		g_snprintf(tmp, sizeof(tmp),
-			_("%s sent message to whiteboard. Would you like "
-			  "to open the whiteboard?"), sender->nickname);
-	} else {
-		g_snprintf(tmp, sizeof(tmp),
-			_("%s sent message to whiteboard on %s channel. "
-			  "Would you like to open the whiteboard?"),
-			sender->nickname, channel->channel_name);
-	}
-
-	req = silc_calloc(1, sizeof(*req));
-	if (!req)
-		return;
-	req->message = silc_memdup(message, message_len);
-	req->message_len = message_len;
-	req->sender = sender;
-	req->channel = channel;
-	req->sg = sg;
-
-	purple_request_action(sender, _("Whiteboard"), tmp, NULL, 1,
-				sg->account, sender->nickname, NULL, req, 2,
-			    _("Yes"), G_CALLBACK(silcpurple_wb_request_cb),
-			    _("No"), G_CALLBACK(silcpurple_wb_request_cb));
-}
-
-/* Process incoming whiteboard message */
-
-void silcpurple_wb_receive(SilcClient client, SilcClientConnection conn,
-			 SilcClientEntry sender, SilcMessagePayload payload,
-			 SilcMessageFlags flags, const unsigned char *message,
-			 SilcUInt32 message_len)
-{
-	SilcPurple sg;
-        PurpleConnection *gc;
-	PurpleWhiteboard *wb;
-	SilcPurpleWb wbs;
-
-	gc = client->application;
-        sg = gc->proto_data;
-
-	wb = purple_whiteboard_get_session(sg->account, sender->nickname);
-	if (!wb) {
-		/* Ask user if they want to open the whiteboard */
-		silcpurple_wb_request(client, message, message_len,
-				    sender, NULL);
-		return;
-	}
-
-	wbs = wb->proto_data;
-	silcpurple_wb_parse(wbs, wb, (unsigned char *)message, message_len);
-}
-
-/* Process incoming whiteboard message on channel */
-
-void silcpurple_wb_receive_ch(SilcClient client, SilcClientConnection conn,
-			    SilcClientEntry sender, SilcChannelEntry channel,
-			    SilcMessagePayload payload,
-			    SilcMessageFlags flags,
-			    const unsigned char *message,
-			    SilcUInt32 message_len)
-{
-	SilcPurple sg;
-        PurpleConnection *gc;
-	PurpleWhiteboard *wb;
-	SilcPurpleWb wbs;
-
-	gc = client->application;
-        sg = gc->proto_data;
-
-	wb = purple_whiteboard_get_session(sg->account, channel->channel_name);
-	if (!wb) {
-		/* Ask user if they want to open the whiteboard */
-		silcpurple_wb_request(client, message, message_len,
-				    sender, channel);
-		return;
-	}
-
-	wbs = wb->proto_data;
-	silcpurple_wb_parse(wbs, wb, (unsigned char *)message, message_len);
-}
-
-/* Send whiteboard message */
-
-void silcpurple_wb_send(PurpleWhiteboard *wb, GList *draw_list)
-{
-	SilcPurpleWb wbs = wb->proto_data;
-	SilcBuffer packet;
-	GList *list;
-	int len;
-        PurpleConnection *gc;
-        SilcPurple sg;
-
-	g_return_if_fail(draw_list);
-	gc = purple_account_get_connection(wb->account);
-	g_return_if_fail(gc);
- 	sg = gc->proto_data;
-	g_return_if_fail(sg);
-
-	len = SILCPURPLE_WB_HEADER;
-	for (list = draw_list; list; list = list->next)
-		len += 4;
-
-	packet = silc_buffer_alloc_size(len);
-	if (!packet)
-		return;
-
-	/* Assmeble packet */
-	silc_buffer_format(packet,
-			   SILC_STR_UI32_STRING(SILCPURPLE_WB_MIME),
-			   SILC_STR_UI_CHAR(SILCPURPLE_WB_DRAW),
-			   SILC_STR_UI_SHORT(wbs->width),
-			   SILC_STR_UI_SHORT(wbs->height),
-			   SILC_STR_UI_INT(wbs->brush_color),
-			   SILC_STR_UI_SHORT(wbs->brush_size),
-			   SILC_STR_END);
-	silc_buffer_pull(packet, SILCPURPLE_WB_HEADER);
-	for (list = draw_list; list; list = list->next) {
-		silc_buffer_format(packet,
-				   SILC_STR_UI_INT(GPOINTER_TO_INT(list->data)),
-				   SILC_STR_END);
-		silc_buffer_pull(packet, 4);
-	}
-
-	/* Send the message */
-	if (wbs->type == 0) {
-		/* Private message */
-		silc_client_send_private_message(sg->client, sg->conn,
-						 wbs->u.client,
-						 SILC_MESSAGE_FLAG_DATA,
-						 packet->head, len, TRUE);
-	} else if (wbs->type == 1) {
-		/* Channel message. Channel private keys are not supported. */
-		silc_client_send_channel_message(sg->client, sg->conn,
-						 wbs->u.channel, NULL,
-						 SILC_MESSAGE_FLAG_DATA,
-						 packet->head, len, TRUE);
-	}
-
-	silc_buffer_free(packet);
-}
-
-/* Purple Whiteboard operations */
-
-void silcpurple_wb_start(PurpleWhiteboard *wb)
-{
-	/* Nothing here.  Everything is in initialization */
-}
-
-void silcpurple_wb_end(PurpleWhiteboard *wb)
-{
-	silc_free(wb->proto_data);
-	wb->proto_data = NULL;
-}
-
-void silcpurple_wb_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height)
-{
-	SilcPurpleWb wbs = wb->proto_data;
-	*width = wbs->width;
-	*height = wbs->height;
-}
-
-void silcpurple_wb_set_dimensions(PurpleWhiteboard *wb, int width, int height)
-{
-	SilcPurpleWb wbs = wb->proto_data;
-	wbs->width = width > SILCPURPLE_WB_WIDTH_MAX ? SILCPURPLE_WB_WIDTH_MAX :
-			width;
-	wbs->height = height > SILCPURPLE_WB_HEIGHT_MAX ? SILCPURPLE_WB_HEIGHT_MAX :
-			height;
-
-	/* Update whiteboard */
-	purple_whiteboard_set_dimensions(wb, wbs->width, wbs->height);
-}
-
-void silcpurple_wb_get_brush(const PurpleWhiteboard *wb, int *size, int *color)
-{
-	SilcPurpleWb wbs = wb->proto_data;
-	*size = wbs->brush_size;
-	*color = wbs->brush_color;
-}
-
-void silcpurple_wb_set_brush(PurpleWhiteboard *wb, int size, int color)
-{
-	SilcPurpleWb wbs = wb->proto_data;
-	wbs->brush_size = size;
-	wbs->brush_color = color;
-
-	/* Update whiteboard */
-	purple_whiteboard_set_brush(wb, size, color);
-}
-
-void silcpurple_wb_clear(PurpleWhiteboard *wb)
-{
-	SilcPurpleWb wbs = wb->proto_data;
-	SilcBuffer packet;
-	int len;
-        PurpleConnection *gc;
-        SilcPurple sg;
-
-	gc = purple_account_get_connection(wb->account);
-	g_return_if_fail(gc);
- 	sg = gc->proto_data;
-	g_return_if_fail(sg);
-
-	len = SILCPURPLE_WB_HEADER;
-	packet = silc_buffer_alloc_size(len);
-	if (!packet)
-		return;
-
-	/* Assmeble packet */
-	silc_buffer_format(packet,
-			   SILC_STR_UI32_STRING(SILCPURPLE_WB_MIME),
-			   SILC_STR_UI_CHAR(SILCPURPLE_WB_CLEAR),
-			   SILC_STR_UI_SHORT(wbs->width),
-			   SILC_STR_UI_SHORT(wbs->height),
-			   SILC_STR_UI_INT(wbs->brush_color),
-			   SILC_STR_UI_SHORT(wbs->brush_size),
-			   SILC_STR_END);
-
-	/* Send the message */
-	if (wbs->type == 0) {
-		/* Private message */
-		silc_client_send_private_message(sg->client, sg->conn,
-						 wbs->u.client,
-						 SILC_MESSAGE_FLAG_DATA,
-						 packet->head, len, TRUE);
-	} else if (wbs->type == 1) {
-		/* Channel message */
-		silc_client_send_channel_message(sg->client, sg->conn,
-						 wbs->u.channel, NULL,
-						 SILC_MESSAGE_FLAG_DATA,
-						 packet->head, len, TRUE);
-	}
-
-	silc_buffer_free(packet);
-}
--- a/libpurple/protocols/silc10/wb.h	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
-
-  silcpurple.h
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2005 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-
-#ifndef SILCPURPLE_WB_H
-#define SILCPURPLE_WB_H
-
-#include "silcpurple.h"
-#include "whiteboard.h"
-
-PurpleWhiteboard *
-silcpurple_wb_init(SilcPurple sg, SilcClientEntry client_entry);
-PurpleWhiteboard *
-silcpurple_wb_init_ch(SilcPurple sg, SilcChannelEntry channel);
-void silcpurple_wb_receive(SilcClient client, SilcClientConnection conn,
-			 SilcClientEntry sender, SilcMessagePayload payload,
-			 SilcMessageFlags flags, const unsigned char *message,
-			 SilcUInt32 message_len);
-void silcpurple_wb_receive_ch(SilcClient client, SilcClientConnection conn,
-			    SilcClientEntry sender, SilcChannelEntry channel,
-			    SilcMessagePayload payload,
-			    SilcMessageFlags flags,
-			    const unsigned char *message,
-			    SilcUInt32 message_len);
-void silcpurple_wb_start(PurpleWhiteboard *wb);
-void silcpurple_wb_end(PurpleWhiteboard *wb);
-void silcpurple_wb_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height);
-void silcpurple_wb_set_dimensions(PurpleWhiteboard *wb, int width, int height);
-void silcpurple_wb_get_brush(const PurpleWhiteboard *wb, int *size, int *color);
-void silcpurple_wb_set_brush(PurpleWhiteboard *wb, int size, int color);
-void silcpurple_wb_send(PurpleWhiteboard *wb, GList *draw_list);
-void silcpurple_wb_clear(PurpleWhiteboard *wb);
-
-#endif /* SILCPURPLE_WB_H */
--- a/libpurple/protocols/simple/simple.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/simple/simple.c	Sun Sep 11 04:19:01 2011 +0000
@@ -67,7 +67,7 @@
 }
 
 static void simple_keep_alive(PurpleConnection *gc) {
-	struct simple_account_data *sip = gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 	if(sip->udp) { /* in case of UDP send a packet only with a 0 byte to
 			 remain in the NAT table */
 		gchar buf[2] = {0, 0};
@@ -100,14 +100,15 @@
 }
 
 static void simple_set_status(PurpleAccount *account, PurpleStatus *status) {
+	PurpleConnection *gc = purple_account_get_connection(account);
 	PurpleStatusPrimitive primitive = purple_status_type_get_primitive(purple_status_get_type(status));
 	struct simple_account_data *sip = NULL;
 
 	if (!purple_status_is_active(status))
 		return;
 
-	if (account->gc)
-		sip = account->gc->proto_data;
+	if (gc)
+		sip = purple_connection_get_protocol_data(gc);
 
 	if (sip)
 	{
@@ -192,9 +193,9 @@
 	}
 }
 
-static void simple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
+static void simple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
 {
-	struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 	struct simple_buddy *b;
 	const char *name = purple_buddy_get_name(buddy);
 	if(strncmp(name, "sip:", 4)) {
@@ -222,7 +223,7 @@
 	buddies = purple_find_buddies(account, NULL);
 	while (buddies) {
 		PurpleBuddy *buddy = buddies->data;
-		simple_add_buddy(gc, buddy, purple_buddy_get_group(buddy));
+		simple_add_buddy(gc, buddy, purple_buddy_get_group(buddy), NULL);
 
 		buddies = g_slist_delete_link(buddies, buddies);
 	}
@@ -231,7 +232,7 @@
 static void simple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
 {
 	const char *name = purple_buddy_get_name(buddy);
-	struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 	struct simple_buddy *b = g_hash_table_lookup(sip->buddies, name);
 	g_hash_table_remove(sip->buddies, name);
 	g_free(b->name);
@@ -412,7 +413,7 @@
 
 static void simple_canwrite_cb(gpointer data, gint source, PurpleInputCondition cond) {
 	PurpleConnection *gc = data;
-	struct simple_account_data *sip = gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 	gsize max_write;
 	gssize written;
 
@@ -432,7 +433,7 @@
 		/*TODO: do we really want to disconnect on a failure to write?*/
 		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
 				g_strerror(errno));
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
@@ -451,13 +452,13 @@
 	if(source < 0) {
 		gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
 				error_message);
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	}
 
-	sip = gc->proto_data;
+	sip = purple_connection_get_protocol_data(gc);
 	sip->fd = source;
 	sip->connecting = FALSE;
 
@@ -474,12 +475,12 @@
 
 
 static void sendlater(PurpleConnection *gc, const char *buf) {
-	struct simple_account_data *sip = gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 
 	if(!sip->connecting) {
 		purple_debug_info("simple", "connecting to %s port %d\n", sip->realhostname ? sip->realhostname : "{NULL}", sip->realport);
 		if (purple_proxy_connect(gc, sip->account, sip->realhostname, sip->realport, send_later_cb, gc) == NULL) {
-			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
+			purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
 		}
 		sip->connecting = TRUE;
 	}
@@ -491,7 +492,7 @@
 }
 
 static void sendout_pkt(PurpleConnection *gc, const char *buf) {
-	struct simple_account_data *sip = gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 	time_t currtime = time(NULL);
 	int writelen = strlen(buf);
 
@@ -629,7 +630,7 @@
 static void send_sip_request(PurpleConnection *gc, const gchar *method,
 		const gchar *url, const gchar *to, const gchar *addheaders,
 		const gchar *body, struct sip_dialog *dialog, TransCallback tc) {
-	struct simple_account_data *sip = gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 	char *callid = dialog ? g_strdup(dialog->callid) : gencallid();
 	char *auth = NULL;
 	const char *addh = "";
@@ -1026,7 +1027,7 @@
 }
 
 static int simple_im_send(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags) {
-	struct simple_account_data *sip = gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 	char *to = g_strdup(who);
 	char *text = purple_unescape_html(what);
 	simple_send_message(sip, to, text, NULL);
@@ -1122,7 +1123,7 @@
 				if(sip->registrar.retries > SIMPLE_REGISTER_RETRY_MAX) {
 					if (!purple_account_get_remember_password(sip->gc->account))
 						purple_account_set_password(sip->gc->account, NULL);
-					purple_connection_error_reason(sip->gc,
+					purple_connection_error(sip->gc,
 						PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
 						_("Incorrect password"));
 					return TRUE;
@@ -1137,7 +1138,7 @@
 			if (sip->registerstatus != SIMPLE_REGISTER_RETRY) {
 				purple_debug_info("simple", "Unrecognized return code for REGISTER.\n");
 				if (sip->registrar.retries > SIMPLE_REGISTER_RETRY_MAX) {
-					purple_connection_error_reason(sip->gc,
+					purple_connection_error(sip->gc,
 						PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 						_("Unknown server response"));
 					return TRUE;
@@ -1285,7 +1286,7 @@
 }
 
 static unsigned int simple_typing(PurpleConnection *gc, const char *name, PurpleTypingState state) {
-	struct simple_account_data *sip = gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 
 	gchar *xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
 			"<isComposing xmlns=\"urn:ietf:params:xml:ns:im-iscomposing\"\n"
@@ -1661,7 +1662,7 @@
 
 static void simple_udp_process(gpointer data, gint source, PurpleInputCondition con) {
 	PurpleConnection *gc = data;
-	struct simple_account_data *sip = gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 	struct sipmsg *msg;
 	int len;
 	time_t currtime = time(NULL);
@@ -1681,7 +1682,7 @@
 static void simple_input_cb(gpointer data, gint source, PurpleInputCondition cond)
 {
 	PurpleConnection *gc = data;
-	struct simple_account_data *sip = gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 	int len;
 	struct sip_connection *conn = connection_find(sip, source);
 	if(!conn) {
@@ -1714,7 +1715,7 @@
 /* Callback for new connections on incoming TCP port */
 static void simple_newconn_cb(gpointer data, gint source, PurpleInputCondition cond) {
 	PurpleConnection *gc = data;
-	struct simple_account_data *sip = gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 	struct sip_connection *conn;
 	int newfd, flags;
 
@@ -1739,13 +1740,13 @@
 	if(source < 0) {
 		gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
 				error_message);
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	}
 
-	sip = gc->proto_data;
+	sip = purple_connection_get_protocol_data(gc);
 	sip->fd = source;
 
 	conn = connection_create(sip, source);
@@ -1775,7 +1776,7 @@
 	sip->listen_data = NULL;
 
 	if(listenfd == -1) {
-		purple_connection_error_reason(sip->gc,
+		purple_connection_error(sip->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to create listen socket"));
 		return;
@@ -1804,7 +1805,7 @@
 	sip->query_data = NULL;
 
 	if (!hosts || !hosts->data) {
-		purple_connection_error_reason(sip->gc,
+		purple_connection_error(sip->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to resolve hostname"));
 		return;
@@ -1825,7 +1826,7 @@
 	sip->listen_data = purple_network_listen_range(5060, 5160, SOCK_DGRAM,
 				simple_udp_host_resolved_listen_cb, sip);
 	if (sip->listen_data == NULL) {
-		purple_connection_error_reason(sip->gc,
+		purple_connection_error(sip->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to create listen socket"));
 		return;
@@ -1840,7 +1841,7 @@
 
 	sip->listenfd = listenfd;
 	if(sip->listenfd == -1) {
-		purple_connection_error_reason(sip->gc,
+		purple_connection_error(sip->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to create listen socket"));
 		return;
@@ -1855,7 +1856,7 @@
 	/* open tcp connection to the server */
 	if (purple_proxy_connect(sip->gc, sip->account, sip->realhostname,
 			sip->realport, login_cb, sip->gc) == NULL) {
-		purple_connection_error_reason(sip->gc,
+		purple_connection_error(sip->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to connect"));
 	}
@@ -1895,7 +1896,7 @@
 		sip->listen_data = purple_network_listen_range(5060, 5160, SOCK_STREAM,
 					simple_tcp_connect_listen_cb, sip);
 		if (sip->listen_data == NULL) {
-			purple_connection_error_reason(sip->gc,
+			purple_connection_error(sip->gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Unable to create listen socket"));
 			return;
@@ -1903,10 +1904,10 @@
 	} else { /* UDP */
 		purple_debug_info("simple", "using udp with server %s and port %d\n", hostname, port);
 
-		sip->query_data = purple_dnsquery_a_account(sip->account, hostname,
+		sip->query_data = purple_dnsquery_a(sip->account, hostname,
 			port, simple_udp_host_resolved, sip);
 		if (sip->query_data == NULL) {
-			purple_connection_error_reason(sip->gc,
+			purple_connection_error(sip->gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Unable to resolve hostname"));
 		}
@@ -1924,13 +1925,14 @@
 	gc = purple_account_get_connection(account);
 
 	if (strpbrk(username, " \t\v\r\n") != NULL) {
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 			_("SIP usernames may not contain whitespaces or @ symbols"));
 		return;
 	}
 
-	gc->proto_data = sip = g_new0(struct simple_account_data, 1);
+	sip = g_new0(struct simple_account_data, 1);
+	purple_connection_set_protocol_data(gc, sip);
 	sip->gc = gc;
 	sip->fd = -1;
 	sip->listenfd = -1;
@@ -1943,7 +1945,7 @@
 
 	userserver = g_strsplit(username, "@", 2);
 	if (userserver[1] == NULL || userserver[1][0] == '\0') {
-		purple_connection_error_reason(gc,
+		purple_connection_error(gc,
 			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 			_("SIP connect server not specified"));
 		return;
@@ -1968,13 +1970,13 @@
 		hosttoconnect = purple_account_get_string(account, "proxy", sip->servername);
 	}
 
-	sip->srv_query_data = purple_srv_resolve_account(account, "sip",
+	sip->srv_query_data = purple_srv_resolve(account, "sip",
 			sip->udp ? "udp" : "tcp", hosttoconnect, srvresolved, sip);
 }
 
 static void simple_close(PurpleConnection *gc)
 {
-	struct simple_account_data *sip = gc->proto_data;
+	struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
 
 	if (!sip)
 		return;
@@ -2005,7 +2007,7 @@
 		purple_dnsquery_destroy(sip->query_data);
 
 	if (sip->srv_query_data != NULL)
-		purple_srv_cancel(sip->srv_query_data);
+		purple_srv_txt_query_destroy(sip->srv_query_data);
 
 	if (sip->listen_data != NULL)
 		purple_network_listen_cancel(sip->listen_data);
@@ -2039,11 +2041,12 @@
 	g_free(sip->realhostname);
 
 	g_free(sip);
-	gc->proto_data = NULL;
+	purple_connection_set_protocol_data(gc, NULL);
 }
 
 static PurplePluginProtocolInfo prpl_info =
 {
+	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	0,
 	NULL,					/* user_splits */
 	NULL,					/* protocol_options */
@@ -2109,15 +2112,12 @@
 	NULL,					/* unregister_user */
 	NULL,					/* send_attention */
 	NULL,					/* get_attention_types */
-	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	NULL,					/* get_account_text_table */
 	NULL,					/* initiate_media */
 	NULL,					/* get_media_caps */
 	NULL,					/* get_moods */
 	NULL,					/* set_public_alias */
-	NULL,					/* get_public_alias */
-	NULL,					/* add_buddy_with_invite */
-	NULL					/* add_buddies_with_invite */
+	NULL					/* get_public_alias */
 };
 
 
--- a/libpurple/protocols/yahoo/libyahoo.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/libyahoo.c	Sun Sep 11 04:19:01 2011 +0000
@@ -194,6 +194,7 @@
 
 static PurplePluginProtocolInfo prpl_info =
 {
+	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC,
 	NULL, /* user_splits */
 	NULL, /* protocol_options */
@@ -257,19 +258,14 @@
 	NULL, /* send_raw */
 	NULL, /* roomlist_room_serialize */
 	NULL, /* unregister_user */
-
 	yahoo_send_attention,
 	yahoo_attention_types,
-
-	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	yahoo_get_account_text_table,    /* get_account_text_table */
 	NULL, /* initiate_media */
 	NULL,  /* get_media_caps */
 	NULL,  /* get_moods */
 	NULL,  /* set_public_alias */
-	NULL,  /* get_public_alias */
-	NULL,  /* add_buddy_with_invite */
-	NULL   /* add_buddies_with_invite */
+	NULL   /* get_public_alias */
 };
 
 static PurplePluginInfo info =
--- a/libpurple/protocols/yahoo/libyahoojp.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/libyahoojp.c	Sun Sep 11 04:19:01 2011 +0000
@@ -90,6 +90,7 @@
 
 static PurplePluginProtocolInfo prpl_info =
 {
+	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC,
 	NULL, /* user_splits */
 	NULL, /* protocol_options */
@@ -157,15 +158,12 @@
 	yahoo_send_attention,
 	yahoo_attention_types,
 
-	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	yahoojp_get_account_text_table,    /* get_account_text_table */
 	NULL, /* initiate_media */
 	NULL, /* get_media_caps */
 	NULL, /* get_moods */
 	NULL, /* set_public_alias */
-	NULL, /* get_public_alias */
-	NULL, /* add_buddy_with_invite */
-	NULL  /* add_buddies_with_invite */
+	NULL  /* get_public_alias */
 };
 
 static PurplePluginInfo info =
--- a/libpurple/protocols/yahoo/libymsg.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/libymsg.c	Sun Sep 11 04:19:01 2011 +0000
@@ -159,7 +159,7 @@
 	if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) {
 		if (!purple_account_get_remember_password(account))
 			purple_account_set_password(account, NULL);
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE,
 			_("You have signed on from another location"));
 		return;
 	}
@@ -496,7 +496,7 @@
 	GSList *l = pkt->hash;
 
 	PurpleAccount *account = purple_connection_get_account(gc);
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	GHashTable *ht;
 	char *norm_bud = NULL;
 	char *temp = NULL;
@@ -638,7 +638,7 @@
 	gboolean got_serv_list = FALSE;
 	YahooFriend *f = NULL;
 	PurpleAccount *account = purple_connection_get_account(gc);
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	GHashTable *ht;
 
 	char **lines;
@@ -787,7 +787,7 @@
 	YahooFriend *f = NULL;
 	GSList *l = pkt->hash;
 	gint val_11 = 0;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	YahooFederation fed = YAHOO_FEDERATION_NONE;
 
 	account = purple_connection_get_account(gc);
@@ -899,7 +899,7 @@
 	char *server_msg = NULL;
 	char *m;
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 	account = purple_connection_get_account(gc);
 
 	while (l != NULL) {
@@ -960,7 +960,7 @@
 static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt, yahoo_pkt_type pkt_type)
 {
 	PurpleAccount *account;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	GSList *l = pkt->hash;
 	GSList *list = NULL;
 	struct _yahoo_im *im = NULL;
@@ -1061,7 +1061,7 @@
 							doodle_session *ds;
 							wb = purple_whiteboard_create(account, im->from,
 											DOODLE_STATE_REQUESTED);
-							ds = wb->proto_data;
+							ds = purple_whiteboard_get_protocol_data(wb);
 							ds->imv_key = g_strdup(pair->value);
 
 							yahoo_doodle_command_send_request(gc, im->from, pair->value);
@@ -1202,7 +1202,7 @@
 {
 	struct yahoo_add_request *add_req = data;
 	struct yahoo_packet *pkt;
-	YahooData *yd = add_req->gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(add_req->gc);
 	const char *who = add_req->who;
 
 	pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH_REQ_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -1233,7 +1233,7 @@
 static void
 yahoo_buddy_add_deny_cb(struct yahoo_add_request *add_req, const char *msg)
 {
-	YahooData *yd = add_req->gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(add_req->gc);
 	struct yahoo_packet *pkt;
 	char *encoded_msg = NULL;
 	const char *who = add_req->who;
@@ -1295,7 +1295,7 @@
 static void yahoo_buddy_denied_our_add(PurpleConnection *gc, const char *who, const char *reason)
 {
 	char *notify_msg;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	if (who == NULL)
 		return;
@@ -1625,7 +1625,7 @@
 static void yahoo_process_mail(PurpleConnection *gc, struct yahoo_packet *pkt)
 {
 	PurpleAccount *account = purple_connection_get_account(gc);
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	const char *who = NULL;
 	const char *email = NULL;
 	const char *subj = NULL;
@@ -1709,7 +1709,7 @@
 
 static void yahoo_auth16_stage3(PurpleConnection *gc, const char *crypt)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	PurpleAccount *account = purple_connection_get_account(gc);
 	const char *name = purple_normalize(account, purple_account_get_username(account));
 	PurpleCipher *md5_cipher;
@@ -1803,7 +1803,7 @@
 
 	if (error_message != NULL) {
 		purple_debug_error("yahoo", "Login Failed, unable to retrieve stage 2 url: %s\n", error_message);
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
 		g_free(auth_data->seed);
 		g_free(auth_data);
 		return;
@@ -1890,7 +1890,7 @@
 			if(error_reason) {
 				purple_debug_error("yahoo", "Authentication error: %s. "
 				                   "Code %d\n", error_reason, response_no);
-				purple_connection_error_reason(gc, error, error_reason);
+				purple_connection_error(gc, error, error_reason);
 				g_free(error_reason);
 				g_free(auth_data->seed);
 				g_free(auth_data);
@@ -1919,7 +1919,7 @@
 
 	if (error_message != NULL) {
 		purple_debug_error("yahoo", "Login Failed, unable to retrieve login url: %s\n", error_message);
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
 		g_free(auth_data->seed);
 		g_free(auth_data);
 		return;
@@ -2000,7 +2000,7 @@
 			}
 			purple_debug_error("yahoo", "Authentication error: %s. Code %d\n",
 			                   error_reason, response_no);
-			purple_connection_error_reason(gc, error, error_reason);
+			purple_connection_error(gc, error, error_reason);
 			g_free(error_reason);
 			g_free(auth_data->seed);
 			g_free(auth_data);
@@ -2014,7 +2014,7 @@
 			gboolean proxy_ssl = purple_account_get_bool(account, "proxy_ssl", FALSE);
 
 			url = g_strdup_printf(yahoojp ? YAHOOJP_LOGIN_URL : YAHOO_LOGIN_URL, token);
-			url_data = purple_util_fetch_url_request_len_with_account(
+			url_data = purple_util_fetch_url_request_len(
 					proxy_ssl ? account : NULL, url, TRUE, YAHOO_CLIENT_USERAGENT,
 					TRUE, NULL, TRUE, -1, yahoo_auth16_stage2, auth_data);
 			if (url_data)
@@ -2040,7 +2040,7 @@
 	purple_debug_info("yahoo", "Authentication: In yahoo_auth16_stage1\n");
 
 	if(!purple_ssl_is_supported()) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support unavailable"));
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support unavailable"));
 		return;
 	}
 
@@ -2055,7 +2055,7 @@
 	g_free(encoded_password);
 	g_free(encoded_username);
 
-	url_data = purple_util_fetch_url_request_len_with_account(
+	url_data = purple_util_fetch_url_request_len(
 			proxy_ssl ? account : NULL, url, TRUE,
 			YAHOO_CLIENT_USERAGENT, TRUE, NULL, FALSE, -1,
 			yahoo_auth16_stage1_cb, auth_data);
@@ -2207,7 +2207,7 @@
 static void yahoo_process_authresp(PurpleConnection *gc, struct yahoo_packet *pkt)
 {
 #ifdef TRY_WEBMESSENGER_LOGIN
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 #endif /* TRY_WEBMESSENGER_LOGIN */
 	GSList *l = pkt->hash;
 	int err = 0;
@@ -2285,7 +2285,7 @@
 	else
 		fullmsg = g_strdup(msg);
 
-	purple_connection_error_reason(gc, reason, fullmsg);
+	purple_connection_error(gc, reason, fullmsg);
 	g_free(msg);
 	g_free(fullmsg);
 }
@@ -2300,7 +2300,7 @@
 	char *buf;
 	YahooFriend *f;
 	GSList *l = pkt->hash;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	YahooFederation fed = YAHOO_FEDERATION_NONE;
 
 	while (l) {
@@ -2394,7 +2394,7 @@
 	PurpleConnection *gc = user_data;
 	struct yahoo_packet *pkt_to_send;
 	PurpleAccount *account;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	account = purple_connection_get_account(gc);
 
@@ -2413,7 +2413,7 @@
 static gboolean yahoo_p2p_keepalive(gpointer data)
 {
 	PurpleConnection *gc = data;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	g_hash_table_foreach(yd->peers, yahoo_p2p_keepalive_cb, gc);
 
@@ -2460,7 +2460,7 @@
 	if(!(p2p_data = data))
 		return ;
 
-	yd = p2p_data->gc->proto_data;
+	yd = purple_connection_get_protocol_data(p2p_data->gc);
 
 	/* lets see whats in the packet */
 	while (l) {
@@ -2545,7 +2545,7 @@
 
 	if(!(p2p_data = data))
 		return ;
-	yd = p2p_data->gc->proto_data;
+	yd = purple_connection_get_protocol_data(p2p_data->gc);
 
 	len = read(source, buf, sizeof(buf));
 	if ((len < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
@@ -2617,7 +2617,7 @@
 
 	if(!(p2p_data = data))
 		return ;
-	yd = p2p_data->gc->proto_data;
+	yd = purple_connection_get_protocol_data(p2p_data->gc);
 
 	acceptfd = accept(source, NULL, 0);
 	if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
@@ -2657,7 +2657,7 @@
 	if(!(p2p_data = data))
 		return FALSE;
 
-	yd = p2p_data->gc->proto_data;
+	yd = purple_connection_get_protocol_data(p2p_data->gc);
 
 	purple_debug_warning("yahoo","yahoo p2p server timeout, peer failed to connect\n");
 	yahoo_p2p_disconnect_destroy_data(data);
@@ -2678,7 +2678,7 @@
 	if(!(p2p_data = data))
 		return ;
 
-	yd = p2p_data->gc->proto_data;
+	yd = purple_connection_get_protocol_data(p2p_data->gc);
 	yd->listen_data = NULL;
 
 	if(listenfd == -1) {
@@ -2706,7 +2706,7 @@
 	YahooFriend *f;
 	struct yahoo_packet *pkt;
 	PurpleAccount *account;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_p2p_data *p2p_data;
 	const char *norm_username;
 
@@ -2787,7 +2787,7 @@
 	YahooData *yd;
 
 	p2p_data = data;
-	yd = p2p_data->gc->proto_data;
+	yd = purple_connection_get_protocol_data(p2p_data->gc);
 
 	if(error_message != NULL) {
 		purple_debug_warning("yahoo","p2p: %s\n",error_message);
@@ -3132,7 +3132,7 @@
 static void yahoo_pending(gpointer data, gint source, PurpleInputCondition cond)
 {
 	PurpleConnection *gc = data;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	char buf[1024];
 	int len;
 
@@ -3147,11 +3147,11 @@
 
 		tmp = g_strdup_printf(_("Lost connection with server: %s"),
 				g_strerror(errno));
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	} else if (len == 0) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Server closed the connection"));
 		return;
 	}
@@ -3235,12 +3235,12 @@
 	if (source < 0) {
 		gchar *tmp;
 		tmp = g_strdup_printf(_("Unable to connect: %s"), error_message);
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	}
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 	yd->fd = source;
 
 	pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, yd->current_status, yd->session_id);
@@ -3261,12 +3261,12 @@
 	if (source < 0) {
 		gchar *tmp;
 		tmp = g_strdup_printf(_("Unable to connect: %s"), error_message);
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	}
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 	yd->fd = source;
 
 	pkt = yahoo_packet_new(YAHOO_SERVICE_WEBLOGIN, YAHOO_STATUS_WEBLOGIN, yd->session_id);
@@ -3285,7 +3285,7 @@
 {
 	PurpleConnection *gc = data;
 	PurpleAccount *account = purple_connection_get_account(gc);
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	char bufread[2048], *i = bufread, *buf = bufread;
 	int len;
 	GString *s;
@@ -3301,11 +3301,11 @@
 
 		tmp = g_strdup_printf(_("Lost connection with server: %s"),
 				g_strerror(errno));
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	} else if (len == 0) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Server closed the connection"));
 		return;
 	}
@@ -3321,7 +3321,7 @@
 
 	if ((strncmp(buf, "HTTP/1.0 302", strlen("HTTP/1.0 302")) &&
 			  strncmp(buf, "HTTP/1.1 302", strlen("HTTP/1.1 302")))) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Received unexpected HTTP response from server"));
 		purple_debug_misc("yahoo", "Unexpected HTTP response: %s\n", buf);
 		return;
@@ -3351,7 +3351,7 @@
 	if (purple_proxy_connect(gc, account, "wcs2.msg.dcn.yahoo.com",
 	                         purple_account_get_int(account, "port", YAHOO_PAGER_PORT),
 	                         yahoo_got_web_connected, gc) == NULL) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		                               _("Unable to connect"));
 		return;
 	}
@@ -3364,7 +3364,7 @@
 	int written, remaining;
 
 	gc = data;
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	remaining = strlen(yd->auth) - yd->auth_written;
 	written = write(source, yd->auth + yd->auth_written, remaining);
@@ -3380,7 +3380,7 @@
 		gc->inpa = 0;
 		tmp = g_strdup_printf(_("Lost connection with %s: %s"),
 				"login.yahoo.com:80", g_strerror(errno));
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	}
@@ -3405,7 +3405,7 @@
 		gchar *tmp;
 		tmp = g_strdup_printf(_("Unable to establish a connection with %s: %s"),
 				"login.yahoo.com:80", error_message);
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 		return;
 	}
@@ -3474,7 +3474,7 @@
 {
 	PurpleConnection *gc = (PurpleConnection *)user_data;
 	PurpleAccount *account = purple_connection_get_account(gc);
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	const char *sn = purple_account_get_username(account);
 	const char *pass = purple_connection_get_password(gc);
 	GHashTable *hash = yahoo_login_page_hash(url_text, len);
@@ -3489,7 +3489,7 @@
 
 	if (error_message != NULL)
 	{
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		                               error_message);
 		return;
 	}
@@ -3539,7 +3539,7 @@
 	g_hash_table_destroy(hash);
 	yd->auth = g_string_free(url, FALSE);
 	if (purple_proxy_connect(gc, account, "login.yahoo.com", 80, yahoo_got_cookies, gc) == NULL) {
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		                               _("Unable to connect"));
 		return;
 	}
@@ -3619,12 +3619,12 @@
 				error_message ? error_message : "(null)");
 
 		if(yahoo_is_japan(a)) { /* We don't know fallback hosts for Yahoo Japan :( */
-			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+			purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 					_("Unable to connect: The server returned an empty response."));
 		} else {
 				if(purple_proxy_connect(gc, a, YAHOO_PAGER_HOST_FALLBACK, port,
 							yahoo_got_connected, gc) == NULL) {
-					purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+					purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 							_("Unable to connect"));
 				}
 		}
@@ -3646,20 +3646,20 @@
 
 		if(cs_server) { /* got an address; get on with connecting */
 			if(purple_proxy_connect(gc, a, cs_server, port, yahoo_got_connected, gc) == NULL)
-				purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+				purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 								_("Unable to connect"));
 		} else {
 			purple_debug_error("yahoo", "No CS address retrieved!  Server "
 					"response:\n%s\n", url_text ? url_text : "(null)");
 
 			if(yahoo_is_japan(a)) { /* We don't know fallback hosts for Yahoo Japan :( */
-				purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+				purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 						_("Unable to connect: The server's response did not contain "
 							"the necessary information"));
 			} else
 				if(purple_proxy_connect(gc, a, YAHOO_PAGER_HOST_FALLBACK, port,
 							yahoo_got_connected, gc) == NULL) {
-					purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+					purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 							_("Unable to connect"));
 				}
 		}
@@ -3671,12 +3671,13 @@
 
 void yahoo_login(PurpleAccount *account) {
 	PurpleConnection *gc = purple_account_get_connection(account);
-	YahooData *yd = gc->proto_data = g_new0(YahooData, 1);
+	YahooData *yd = g_new0(YahooData, 1);
 	PurpleStatus *status = purple_account_get_active_status(account);
 	gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
 	gboolean proxy_ssl = purple_account_get_bool(account, "proxy_ssl", FALSE);
 	PurpleUtilFetchUrlData *url_data;
 
+	purple_connection_set_protocol_data(gc, yd);
 	gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC;
 
 	purple_connection_update_progress(gc, _("Connecting"), 1, 2);
@@ -3708,7 +3709,7 @@
 
 	/* Get the pager server.  Actually start connecting in the callback since we
 	 * must have the contents of the HTTP response to proceed. */
-	url_data = purple_util_fetch_url_request_len_with_account(
+	url_data = purple_util_fetch_url_request_len(
 			proxy_ssl ? purple_connection_get_account(gc) : NULL,
 			yd->jp ? YAHOOJP_PAGER_HOST_REQ_URL : YAHOO_PAGER_HOST_REQ_URL,
 			use_whole_url ? TRUE : FALSE,
@@ -3721,7 +3722,7 @@
 }
 
 void yahoo_close(PurpleConnection *gc) {
-	YahooData *yd = (YahooData *)gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	GSList *l;
 
 	if (gc->inpa)
@@ -3810,7 +3811,7 @@
 	g_free(yd->current_list15_grp);
 
 	g_free(yd);
-	gc->proto_data = NULL;
+	purple_connection_set_protocol_data(gc, NULL);
 }
 
 const char *yahoo_list_icon(PurpleAccount *a, PurpleBuddy *b)
@@ -3827,7 +3828,7 @@
 
 	if (!b || !(account = purple_buddy_get_account(b)) ||
 			!(gc = purple_account_get_connection(account)) ||
-			!gc->proto_data)
+			!purple_connection_get_protocol_data(gc))
 		return NULL;
 
 	f = yahoo_friend_find(gc, purple_buddy_get_name(b));
@@ -3892,7 +3893,7 @@
 
 	buddy = (PurpleBuddy *) node;
 	gc = purple_account_get_connection(purple_buddy_get_account(buddy));
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 	id = yd->conf_id;
 
 	components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
@@ -4036,22 +4037,12 @@
 
 	if (f && full) {
 		YahooPersonalDetails *ypd = &f->ypd;
-		int i;
-		struct {
-			char *id;
-			char *text;
-			char *value;
-		} yfields[] = {
-			{"hp", N_("Home Phone Number"), ypd->phone.home},
-			{"wp", N_("Work Phone Number"), ypd->phone.work},
-			{"mo", N_("Mobile Phone Number"), ypd->phone.mobile},
-			{NULL, NULL, NULL}
-		};
-		for (i = 0; yfields[i].id; i++) {
-			if (!yfields[i].value || !*yfields[i].value)
-				continue;
-			purple_notify_user_info_add_pair(user_info, _(yfields[i].text), yfields[i].value);
-		}
+		if (ypd->phone.home && *ypd->phone.home)
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Home Phone Number"), ypd->phone.home);
+		if (ypd->phone.work && *ypd->phone.work)
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Work Phone Number"), ypd->phone.work);
+		if (ypd->phone.mobile && *ypd->phone.mobile)
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Mobile Phone Number"), ypd->phone.mobile);
 	}
 }
 
@@ -4065,7 +4056,7 @@
 	buddy = (PurpleBuddy *) node;
 	gc = purple_account_get_connection(purple_buddy_get_account(buddy));
 
-	yahoo_add_buddy(gc, buddy, NULL);
+	yahoo_add_buddy(gc, buddy, NULL, NULL);
 }
 
 
@@ -4085,7 +4076,7 @@
 static GList *build_presence_submenu(YahooFriend *f, PurpleConnection *gc) {
 	GList *m = NULL;
 	PurpleMenuAction *act;
-	YahooData *yd = (YahooData *) gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
 		if (f->presence != YAHOO_PRESENCE_ONLINE) {
@@ -4145,7 +4136,7 @@
 	PurpleMenuAction *act;
 
 	PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(buddy));
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	static char buf2[1024];
 	YahooFriend *f;
 
@@ -4228,7 +4219,7 @@
 
 static void yahoo_act_id(PurpleConnection *gc, PurpleRequestFields *fields)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	const char *name = yd->profiles[purple_request_fields_get_choice(fields, "id")];
 
 	struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -4245,7 +4236,7 @@
 	PurpleConnection *gc = user_data;
 	gboolean set_cookie = FALSE;
 	gchar *url;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
 
@@ -4281,7 +4272,7 @@
 	/* XXX I have no idea how this will work with Yahoo! Japan. */
 
 	PurpleConnection *gc = action->context;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	PurpleUtilFetchUrlData *url_data;
 	const char* base_url = "http://login.yahoo.com";
@@ -4296,7 +4287,7 @@
 		use_whole_url ? base_url : "",
 		yd->cookie_t, yd->cookie_y);
 
-	url_data = purple_util_fetch_url_request_len_with_account(
+	url_data = purple_util_fetch_url_request_len(
 			purple_connection_get_account(gc), base_url, use_whole_url,
 			YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
 			yahoo_get_inbox_token_cb, gc);
@@ -4395,7 +4386,7 @@
 {
 	struct yahoo_sms_carrier_cb_data *sms_cb_data = user_data;
 	PurpleConnection *gc = sms_cb_data->gc;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	char *status = NULL;
 	char *carrier = NULL;
 	PurpleAccount *account = purple_connection_get_account(gc);
@@ -4450,7 +4441,7 @@
 
 static void yahoo_get_sms_carrier(PurpleConnection *gc, gpointer data)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	PurpleUtilFetchUrlData *url_data;
 	struct yahoo_sms_carrier_cb_data *sms_cb_data;
 	char *validate_request_str = NULL;
@@ -4485,10 +4476,10 @@
 		YAHOO_CLIENT_VERSION, yd->cookie_t, yd->cookie_y, strlen(validate_request_str), validate_request_str);
 
 	/* use whole URL if using HTTP Proxy */
-	if ((gc->account->proxy_info) && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP))
+	if ((gc->account->proxy_info) && (purple_proxy_info_get_type(gc->account->proxy_info) == PURPLE_PROXY_HTTP))
 	    use_whole_url = TRUE;
 
-	url_data = purple_util_fetch_url_request_len_with_account(
+	url_data = purple_util_fetch_url_request_len(
 			purple_connection_get_account(gc), YAHOO_SMS_CARRIER_URL, use_whole_url,
 			YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
 			yahoo_get_sms_carrier_cb, data);
@@ -4510,7 +4501,7 @@
 
 int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt = NULL;
 	char *msg = yahoo_html_to_codes(what);
 	char *msg2;
@@ -4667,7 +4658,7 @@
 
 unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_p2p_data *p2p_data;
 	YahooFederation fed = YAHOO_FEDERATION_NONE;
 	struct yahoo_packet *pkt = NULL;
@@ -4738,7 +4729,7 @@
 
 	gc = purple_account_get_connection(account);
 	presence = purple_status_get_presence(status);
-	yd = (YahooData *)gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 	old_status = yd->current_status;
 
 	yd->current_status = get_yahoo_status_from_purple_status(status);
@@ -4804,7 +4795,7 @@
 
 void yahoo_set_idle(PurpleConnection *gc, int idle)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt = NULL;
 	char *msg = NULL, *msg2 = NULL;
 	PurpleStatus *status = NULL;
@@ -4923,7 +4914,7 @@
 void yahoo_keepalive(PurpleConnection *gc)
 {
 	struct yahoo_packet *pkt;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	time_t now = time(NULL);
 
 	/* We're only allowed to send a ping once an hour or the servers will boot us */
@@ -4954,9 +4945,9 @@
 
 }
 
-void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g)
+void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g, const char *message)
 {
-	YahooData *yd = (YahooData *)gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	const char *group = NULL;
 	char *group2;
@@ -5019,7 +5010,7 @@
 
 void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
 {
-	YahooData *yd = (YahooData *)gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	GSList *buddies, *l;
 	PurpleGroup *g;
@@ -5075,7 +5066,7 @@
 }
 
 void yahoo_add_deny(PurpleConnection *gc, const char *who) {
-	YahooData *yd = (YahooData *)gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	YahooFederation fed = YAHOO_FEDERATION_NONE;
 
@@ -5098,7 +5089,7 @@
 }
 
 void yahoo_rem_deny(PurpleConnection *gc, const char *who) {
-	YahooData *yd = (YahooData *)gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	YahooFederation fed = YAHOO_FEDERATION_NONE;
 
@@ -5146,7 +5137,7 @@
 void yahoo_change_buddys_group(PurpleConnection *gc, const char *who,
 				   const char *old_group, const char *new_group)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	char *gpn, *gpo;
 	YahooFriend *f = yahoo_friend_find(gc, who);
@@ -5193,7 +5184,7 @@
 void yahoo_rename_group(PurpleConnection *gc, const char *old_name,
 							   PurpleGroup *group, GList *moved_buddies)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	char *gpn, *gpo;
 
--- a/libpurple/protocols/yahoo/libymsg.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/libymsg.h	Sun Sep 11 04:19:01 2011 +0000
@@ -371,7 +371,7 @@
 unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state);
 void yahoo_set_status(PurpleAccount *account, PurpleStatus *status);
 void yahoo_set_idle(PurpleConnection *gc, int idle);
-void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g);
+void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g, const char *message);
 void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
 void yahoo_add_deny(PurpleConnection *gc, const char *who);
 void yahoo_rem_deny(PurpleConnection *gc, const char *who);
--- a/libpurple/protocols/yahoo/util.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/util.c	Sun Sep 11 04:19:01 2011 +0000
@@ -63,8 +63,9 @@
 	char firstflag = 1;
 	gchar *t1,*t2,*t3;
 	GSList *tmp;
-	GSList *cookies;
-	cookies = ((YahooData*)(gc->proto_data))->cookies;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
+	GSList *cookies = yd->cookies;
+
 	tmp = cookies;
 	while(tmp)
 	{
@@ -129,7 +130,7 @@
  */
 char *yahoo_string_encode(PurpleConnection *gc, const char *str, gboolean *utf8)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	char *ret;
 	const char *to_codeset;
 
@@ -158,7 +159,7 @@
  */
 char *yahoo_string_decode(PurpleConnection *gc, const char *str, gboolean utf8)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	char *ret;
 	const char *from_codeset;
 
--- a/libpurple/protocols/yahoo/yahoo_aliases.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/yahoo_aliases.c	Sun Sep 11 04:19:01 2011 +0000
@@ -74,7 +74,7 @@
 yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message)
 {
 	PurpleConnection *gc = user_data;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	yd->url_datas = g_slist_remove(yd->url_datas, url_data);
 
@@ -186,7 +186,7 @@
 void
 yahoo_fetch_aliases(PurpleConnection *gc)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	const char *url;
 	gchar *request, *webpage, *webaddress;
 	PurpleUtilFetchUrlData *url_data;
@@ -207,7 +207,7 @@
 				  webaddress);
 
 	/* We have a URL and some header information, let's connect and get some aliases  */
-	url_data = purple_util_fetch_url_request_len_with_account(purple_connection_get_account(gc),
+	url_data = purple_util_fetch_url_request_len(purple_connection_get_account(gc),
 				url, use_whole_url, NULL, TRUE, request, FALSE, -1,
 				yahoo_fetch_aliases_cb, gc);
 	if (url_data != NULL)
@@ -230,7 +230,7 @@
 	PurpleConnection *gc = cb->gc;
 	YahooData *yd;
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 	yd->url_datas = g_slist_remove(yd->url_datas, url_data);
 
 	if (len == 0 || error_message != NULL) {
@@ -310,7 +310,7 @@
 		return;
 	}
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	/* Using callback_data so I have access to gc in the callback function */
 	cb = g_new0(struct callback_data, 1);
@@ -379,7 +379,7 @@
 				  content);
 
 	/* We have a URL and some header information, let's connect and update the alias  */
-	url_data = purple_util_fetch_url_request_len_with_account(
+	url_data = purple_util_fetch_url_request_len(
 			purple_connection_get_account(gc), url, use_whole_url, NULL, TRUE,
 			request, FALSE, -1, yahoo_update_alias_cb, cb);
 	if (url_data != NULL)
@@ -517,7 +517,7 @@
 	}
 #endif
 
-	url_data = purple_util_fetch_url_request_len_with_account(account, webaddress, FALSE,
+	url_data = purple_util_fetch_url_request_len(account, webaddress, FALSE,
 			YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
 			yahoo_fetch_aliases_cb, gc);
 	if (url_data != NULL)
--- a/libpurple/protocols/yahoo/yahoo_doodle.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/yahoo_doodle.c	Sun Sep 11 04:19:01 2011 +0000
@@ -161,7 +161,7 @@
 		*/
 
 		wb = purple_whiteboard_create(account, from, DOODLE_STATE_REQUESTED);
-		ds = wb->proto_data;
+		ds = purple_whiteboard_get_protocol_data(wb);
 		ds->imv_key = g_strdup(imv_key);
 
 		yahoo_doodle_command_send_ready(gc, from, imv_key);
@@ -189,19 +189,19 @@
 	if(wb == NULL)
 		return;
 
-	if(wb->state == DOODLE_STATE_REQUESTING)
+	if(purple_whiteboard_get_state(wb) == DOODLE_STATE_REQUESTING)
 	{
-		doodle_session *ds = wb->proto_data;
+		doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
 		purple_whiteboard_start(wb);
 
-		wb->state = DOODLE_STATE_ESTABLISHED;
+		purple_whiteboard_set_state(wb, DOODLE_STATE_ESTABLISHED);
 
 		yahoo_doodle_command_send_confirm(gc, from, imv_key);
 		/* Let's steal the imv_key and reuse it */
 		g_free(ds->imv_key);
 		ds->imv_key = g_strdup(imv_key);
 	}
-	else if(wb->state == DOODLE_STATE_ESTABLISHED)
+	else if(purple_whiteboard_get_state(wb) == DOODLE_STATE_ESTABLISHED)
 	{
 		/* TODO Ask whether to save picture too */
 		purple_whiteboard_clear(wb);
@@ -211,7 +211,7 @@
 	 * already thinks we're in a session with them (when their chat message
 	 * contains the doodle imv key)
 	 */
-	else if(wb->state == DOODLE_STATE_REQUESTED)
+	else if(purple_whiteboard_get_state(wb) == DOODLE_STATE_REQUESTED)
 	{
 		/* purple_whiteboard_start(wb); */
 		yahoo_doodle_command_send_ready(gc, from, imv_key);
@@ -292,7 +292,7 @@
 	if(wb == NULL)
 		return;
 
-	if(wb->state == DOODLE_STATE_ESTABLISHED)
+	if(purple_whiteboard_get_state(wb) == DOODLE_STATE_ESTABLISHED)
 	{
 		/* TODO Ask user whether to save the image before clearing it */
 
@@ -333,9 +333,9 @@
 	/* TODO Combine the following IF's? */
 
 	/* Check if we requested a doodle session */
-	/*if(wb->state == DOODLE_STATE_REQUESTING)
+	/*if(purple_whiteboard_get_state(wb) == DOODLE_STATE_REQUESTING)
 	{
-		wb->state = DOODLE_STATE_ESTABLISHED;
+		purple_whiteboard_set_state(wb, DOODLE_STATE_ESTABLISHED);
 
 		purple_whiteboard_start(wb);
 
@@ -343,9 +343,9 @@
 	}*/
 
 	/* Check if we accepted a request for a doodle session */
-	if(wb->state == DOODLE_STATE_REQUESTED)
+	if(purple_whiteboard_get_state(wb) == DOODLE_STATE_REQUESTED)
 	{
-		wb->state = DOODLE_STATE_ESTABLISHED;
+		purple_whiteboard_set_state(wb, DOODLE_STATE_ESTABLISHED);
 
 		purple_whiteboard_start(wb);
 	}
@@ -372,7 +372,7 @@
 
 	/* TODO Ask if user wants to save picture before the session is closed */
 
-	wb->state = DOODLE_STATE_CANCELLED;
+	purple_whiteboard_set_state(wb, DOODLE_STATE_CANCELLED);
 	purple_whiteboard_destroy(wb);
 }
 
@@ -389,7 +389,7 @@
 
 	purple_debug_info("yahoo", "doodle: Sent %s (%s)\n", type, to);
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	/* Make and send an acknowledge (ready) Doodle packet */
 	pkt = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -450,21 +450,23 @@
 	ds->brush_size  = DOODLE_BRUSH_SMALL;
 	ds->brush_color = DOODLE_COLOR_RED;
 
-	wb->proto_data = ds;
+	purple_whiteboard_set_protocol_data(wb, ds);
 }
 
 void yahoo_doodle_end(PurpleWhiteboard *wb)
 {
-	PurpleConnection *gc = purple_account_get_connection(wb->account);
-	doodle_session *ds = wb->proto_data;
+	PurpleAccount *account = purple_whiteboard_get_account(wb);
+	PurpleConnection *gc = purple_account_get_connection(account);
+	doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
 
 	/* g_debug_debug("yahoo", "doodle: yahoo_doodle_end()\n"); */
 
-	if (gc && wb->state != DOODLE_STATE_CANCELLED)
-		yahoo_doodle_command_send_shutdown(gc, wb->who);
+	if (gc && (purple_whiteboard_get_state(wb) != DOODLE_STATE_CANCELLED))
+		yahoo_doodle_command_send_shutdown(gc, purple_whiteboard_get_who(wb));
 
 	g_free(ds->imv_key);
-	g_free(wb->proto_data);
+	g_free(ds);
+	purple_whiteboard_set_protocol_data(wb, NULL);
 }
 
 void yahoo_doodle_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height)
@@ -494,20 +496,25 @@
 
 void yahoo_doodle_send_draw_list(PurpleWhiteboard *wb, GList *draw_list)
 {
-	doodle_session *ds = wb->proto_data;
+	PurpleAccount *account = purple_whiteboard_get_account(wb);
+	PurpleConnection *gc = purple_account_get_connection(account);
+	doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
 	char *message;
 
 	g_return_if_fail(draw_list != NULL);
 
 	message = yahoo_doodle_build_draw_string(ds, draw_list);
-	yahoo_doodle_command_send_draw(wb->account->gc, wb->who, message, ds->imv_key);
+	yahoo_doodle_command_send_draw(gc, purple_whiteboard_get_who(wb), message, ds->imv_key);
 	g_free(message);
 }
 
 void yahoo_doodle_clear(PurpleWhiteboard *wb)
 {
-	doodle_session *ds = wb->proto_data;
-	yahoo_doodle_command_send_clear(wb->account->gc, wb->who, ds->imv_key);
+	PurpleAccount *account = purple_whiteboard_get_account(wb);
+	PurpleConnection *gc = purple_account_get_connection(account);
+	doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
+
+	yahoo_doodle_command_send_clear(gc, purple_whiteboard_get_who(wb), ds->imv_key);
 }
 
 
@@ -560,14 +567,14 @@
 
 void yahoo_doodle_get_brush(const PurpleWhiteboard *wb, int *size, int *color)
 {
-	doodle_session *ds = wb->proto_data;
+	doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
 	*size = ds->brush_size;
 	*color = ds->brush_color;
 }
 
 void yahoo_doodle_set_brush(PurpleWhiteboard *wb, int size, int color)
 {
-	doodle_session *ds = wb->proto_data;
+	doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
 	ds->brush_size = size;
 	ds->brush_color = color;
 
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c	Sun Sep 11 04:19:01 2011 +0000
@@ -43,7 +43,7 @@
 	PurpleConnection *gc;
 	long expires;
 	gboolean started;
-	gchar *txbuf;
+	guchar *txbuf;
 	gsize txbuflen;
 	gsize txbuf_written;
 	guint tx_handler;
@@ -85,7 +85,7 @@
 	GSList *l;
 
 	gc = xd->gc;
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	/* remove entry from map */
 	if(xd->xfer_peer_idstring) {
@@ -120,13 +120,13 @@
 {
 	PurpleXfer *xfer;
 	struct yahoo_xfer_data *xd;
-	int remaining, written;
+	gssize remaining, written;
 
 	xfer = data;
-	xd = xfer->data;
+	xd = purple_xfer_get_protocol_data(xfer);
 
 	remaining = xd->txbuflen - xd->txbuf_written;
-	written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining);
+	written = purple_xfer_write(xfer, xd->txbuf + xd->txbuf_written, remaining);
 
 	if (written < 0 && errno == EAGAIN)
 		written = 0;
@@ -160,11 +160,11 @@
 
 	if (!(xfer = data))
 		return;
-	if (!(xd = xfer->data))
+	if (!(xd = purple_xfer_get_protocol_data(xfer)))
 		return;
 	if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) {
 		purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
-				xfer->who, _("Unable to connect."));
+				purple_xfer_get_remote_user(xfer), _("Unable to connect."));
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
@@ -173,9 +173,10 @@
 
 	/* The first time we get here, assemble the tx buffer */
 	if (xd->txbuflen == 0) {
-		xd->txbuf = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n",
+		gchar *header = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n",
 			      xd->path, xd->host);
-		xd->txbuflen = strlen(xd->txbuf);
+		xd->txbuf = (guchar*) header;
+		xd->txbuflen = strlen(header);
 		xd->txbuf_written = 0;
 	}
 
@@ -191,13 +192,13 @@
 {
 	PurpleXfer *xfer;
 	struct yahoo_xfer_data *xd;
-	int written, remaining;
+	gssize written, remaining;
 
 	xfer = data;
-	xd = xfer->data;
+	xd = purple_xfer_get_protocol_data(xfer);
 
 	remaining = xd->txbuflen - xd->txbuf_written;
-	written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining);
+	written = purple_xfer_write(xfer, xd->txbuf + xd->txbuf_written, remaining);
 
 	if (written < 0 && errno == EAGAIN)
 		written = 0;
@@ -239,12 +240,12 @@
 
 	if (!(xfer = data))
 		return;
-	if (!(xd = xfer->data))
+	if (!(xd = purple_xfer_get_protocol_data(xfer)))
 		return;
 
 	if (source < 0) {
 		purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
-				xfer->who, _("Unable to connect."));
+				purple_xfer_get_remote_user(xfer), _("Unable to connect."));
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
@@ -254,7 +255,7 @@
 	/* Assemble the tx buffer */
 	gc = xd->gc;
 	account = purple_connection_get_account(gc);
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER,
 		YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -264,7 +265,7 @@
 	encoded_filename = yahoo_string_encode(gc, filename, NULL);
 
 	yahoo_packet_hash(pkt, "sssss", 0, purple_connection_get_display_name(gc),
-	  5, xfer->who, 14, "", 27, encoded_filename, 28, size);
+	  5, purple_xfer_get_remote_user(xfer), 14, "", 27, encoded_filename, 28, size);
 	g_free(size);
 	g_free(encoded_filename);
 	g_free(filename);
@@ -313,9 +314,9 @@
 	PurpleAccount *account;
 	YahooData *yd;
 
-	xfer_data = xfer->data;
+	xfer_data = purple_xfer_get_protocol_data(xfer);
 	gc = xfer_data->gc;
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 	account = purple_connection_get_account(gc);
 
 	if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
@@ -357,9 +358,9 @@
 	YahooData *yd;
 	struct yahoo_packet *pkt;
 
-	xfer_data = xfer->data;
+	xfer_data = purple_xfer_get_protocol_data(xfer);
 	gc = xfer_data->gc;
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 	account = purple_connection_get_account(gc);
 
 	if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND)	{
@@ -370,14 +371,14 @@
 							   yd->session_id);
 		yahoo_packet_hash(pkt, "sssiiiisiii",
 			1, purple_normalize(account, purple_account_get_username(account)),
-			5, xfer->who,
+			5, purple_xfer_get_remote_user(xfer),
 			265, xfer_data->xfer_peer_idstring,
 			222, 1,
 			266, 1,
 			302, 268,
 			300, 268,
 			27,  filename,
-			28,  xfer->size,
+			28,  purple_xfer_get_size(xfer),
 			301, 268,
 			303, 268);
 		g_free(filename);
@@ -388,7 +389,7 @@
 
 			yahoo_packet_hash(pkt, "sssi",
 				1, purple_normalize(account, purple_account_get_username(account)),
-				5, xfer->who,
+				5, purple_xfer_get_remote_user(xfer),
 				265, xfer_data->xfer_peer_idstring,
 				222, 3);
 		} else {
@@ -397,7 +398,7 @@
 
 			yahoo_packet_hash(pkt, "sssi",
 				1, purple_normalize(account, purple_account_get_username(account)),
-				5, xfer->who,
+				5, purple_xfer_get_remote_user(xfer),
 				265, xfer_data->xfer_peer_idstring,
 				271, 1);
 		}
@@ -430,7 +431,7 @@
 	gchar *length;
 	gchar *end;
 	int filelen;
-	struct yahoo_xfer_data *xd = xfer->data;
+	struct yahoo_xfer_data *xd = purple_xfer_get_protocol_data(xfer);
 
 	if (purple_xfer_get_type(xfer) != PURPLE_XFER_RECEIVE) {
 		return 0;
@@ -490,7 +491,7 @@
 static gssize yahoo_xfer_write(const guchar *buffer, size_t size, PurpleXfer *xfer)
 {
 	gssize len;
-	struct yahoo_xfer_data *xd = xfer->data;
+	struct yahoo_xfer_data *xd = purple_xfer_get_protocol_data(xfer);
 
 	if (!xd)
 		return -1;
@@ -516,7 +517,7 @@
 {
 	struct yahoo_xfer_data *xfer_data;
 
-	xfer_data = xfer->data;
+	xfer_data = purple_xfer_get_protocol_data(xfer);
 
 	if(purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL && xfer_data->version == 15)
 	{
@@ -526,7 +527,7 @@
 		struct yahoo_packet *pkt;
 
 		gc = xfer_data->gc;
-		yd = gc->proto_data;
+		yd = purple_connection_get_protocol_data(gc);
 		account = purple_connection_get_account(gc);
 		if(xfer_data->xfer_idstring_for_relay) /* hack to see if file trans acc/info packet has been received */
 		{
@@ -535,7 +536,7 @@
 								   yd->session_id);
 			yahoo_packet_hash(pkt, "sssi",
 				1, purple_normalize(account, purple_account_get_username(account)),
-				5, xfer->who,
+				5, purple_xfer_get_remote_user(xfer),
 				265, xfer_data->xfer_peer_idstring,
 				66, -1);
 		}
@@ -546,7 +547,7 @@
 								   yd->session_id);
 			yahoo_packet_hash(pkt, "sssi",
 				1, purple_normalize(account, purple_account_get_username(account)),
-				5, xfer->who,
+				5, purple_xfer_get_remote_user(xfer),
 				265, xfer_data->xfer_peer_idstring,
 				222, 2);
 		}
@@ -556,14 +557,14 @@
 
 	if (xfer_data)
 		yahoo_xfer_data_free(xfer_data);
-	xfer->data = NULL;
+	purple_xfer_set_protocol_data(xfer, NULL);
 }
 
 static void yahoo_xfer_cancel_recv(PurpleXfer *xfer)
 {
 	struct yahoo_xfer_data *xfer_data;
 
-	xfer_data = xfer->data;
+	xfer_data = purple_xfer_get_protocol_data(xfer);
 
 	if(purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL && xfer_data->version == 15)
 	{
@@ -574,7 +575,7 @@
 		struct yahoo_packet *pkt;
 
 		gc = xfer_data->gc;
-		yd = gc->proto_data;
+		yd = purple_connection_get_protocol_data(gc);
 		account = purple_connection_get_account(gc);
 		if(!xfer_data->xfer_idstring_for_relay) /* hack to see if file trans acc/info packet has been received */
 		{
@@ -583,7 +584,7 @@
 								   yd->session_id);
 			yahoo_packet_hash(pkt, "sssi",
 				1, purple_normalize(account, purple_account_get_username(account)),
-				5, xfer->who,
+				5, purple_xfer_get_remote_user(xfer),
 				265, xfer_data->xfer_peer_idstring,
 				222, 4);
 		}
@@ -594,7 +595,7 @@
 								   yd->session_id);
 			yahoo_packet_hash(pkt, "sssi",
 				1, purple_normalize(account, purple_account_get_username(account)),
-				5, xfer->who,
+				5, purple_xfer_get_remote_user(xfer),
 				265, xfer_data->xfer_peer_idstring,
 				66, -1);
 		}
@@ -603,7 +604,7 @@
 
 	if (xfer_data)
 		yahoo_xfer_data_free(xfer_data);
-	xfer->data = NULL;
+	purple_xfer_set_protocol_data(xfer, NULL);
 }
 
 /* Send HTTP OK after receiving file */
@@ -612,7 +613,7 @@
 	char *tx = NULL;
 	int written;
 
-	tx = g_strdup_printf("HTTP/1.1 200 OK\r\nContent-Length: 0\r\nContent-Type: application/octet-stream\r\nConnection: close\r\n\r\n");
+	tx = "HTTP/1.1 200 OK\r\nContent-Length: 0\r\nContent-Type: application/octet-stream\r\nConnection: close\r\n\r\n";
 	written = write(xfer->fd, tx, strlen(tx));
 
 	if (written < 0 && errno == EAGAIN)
@@ -623,7 +624,6 @@
 	/* close connection */
 	close(xfer->fd);
 	xfer->fd = -1;
-	g_free(tx);
 }
 
 static void yahoo_xfer_end(PurpleXfer *xfer_old)
@@ -633,7 +633,7 @@
 	PurpleConnection *gc;
 	YahooData *yd;
 
-	xfer_data = xfer_old->data;
+	xfer_data = purple_xfer_get_protocol_data(xfer_old);
 	if(xfer_data && xfer_data->version == 15
 	   && purple_xfer_get_type(xfer_old) == PURPLE_XFER_RECEIVE
 	   && xfer_data->filename_list) {
@@ -662,7 +662,7 @@
 			filesize = atol( xfer_data->size_list->data );
 
 			gc = xfer_data->gc;
-			yd = gc->proto_data;
+			yd = purple_connection_get_protocol_data(gc);
 
 			/* setting up xfer_data for next file's tranfer */
 			g_free(xfer_data->host);
@@ -689,10 +689,10 @@
 			xfer_data->firstoflist = FALSE;
 
 			/* Dereference xfer_data from old xfer */
-			xfer_old->data = NULL;
+			purple_xfer_set_protocol_data(xfer_old, NULL);
 
 			/* Build the file transfer handle. */
-			xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, xfer_old->who);
+			xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, purple_xfer_get_remote_user(xfer_old));
 
 
 			if (xfer) {
@@ -702,7 +702,7 @@
 				g_free(utf8_filename);
 				purple_xfer_set_size(xfer, filesize);
 
-				xfer->data = xfer_data;
+				purple_xfer_set_protocol_data(xfer, xfer_data);
 
 				/* Setup our I/O op functions */
 				purple_xfer_set_init_fnc(xfer,        yahoo_xfer_init_15);
@@ -726,8 +726,7 @@
 	}
 	if (xfer_data)
 		yahoo_xfer_data_free(xfer_data);
-	xfer_old->data = NULL;
-
+	purple_xfer_set_protocol_data(xfer_old, NULL);
 }
 
 void yahoo_process_p2pfilexfer(PurpleConnection *gc, struct yahoo_packet *pkt)
@@ -806,7 +805,7 @@
 	unsigned long filesize = 0L;
 	GSList *l;
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	for (l = pkt->hash; l; l = l->next) {
 		struct yahoo_pair *pair = l->data;
@@ -886,7 +885,7 @@
 		g_return_if_reached();
 	}
 
-	xfer->data = xfer_data;
+	purple_xfer_set_protocol_data(xfer, xfer_data);
 
 	/* Set the info about the incoming file. */
 	if (filename) {
@@ -943,7 +942,7 @@
 		g_return_val_if_reached(NULL);
 	}
 
-	xfer->data = xfer_data;
+	purple_xfer_set_protocol_data(xfer, xfer_data);
 
 	/* Setup our I/O op functions */
 	purple_xfer_set_init_fnc(xfer,        yahoo_xfer_init);
@@ -993,11 +992,11 @@
 
 	if (!(xfer = data))
 		return;
-	if (!(xd = xfer->data))
+	if (!(xd = purple_xfer_get_protocol_data(xfer)))
 		return;
 	gc = xd->gc;
 	account = purple_connection_get_account(gc);
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	if(!hosts)
 	{
@@ -1057,7 +1056,7 @@
 
 	yahoo_packet_hash(pkt, "ssssis",
 		1, purple_normalize(account, purple_account_get_username(account)),
-		5, xfer->who,
+		5, purple_xfer_get_remote_user(xfer),
 		265, xd->xfer_peer_idstring,
 		27,  filename,
 		249, 3,
@@ -1077,7 +1076,7 @@
 void yahoo_send_file(PurpleConnection *gc, const char *who, const char *file)
 {
 	struct yahoo_xfer_data *xfer_data;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	PurpleXfer *xfer = yahoo_new_xfer(gc, who);
 
 	g_return_if_fail(xfer != NULL);
@@ -1086,7 +1085,7 @@
 	if( !g_hash_table_lookup(yd->peers, who) )
 		yahoo_send_p2p_pkt(gc, who, 0);
 
-	xfer_data = xfer->data;
+	xfer_data = purple_xfer_get_protocol_data(xfer);
 	xfer_data->status_15 = STARTED;
 	purple_xfer_set_init_fnc(xfer, yahoo_xfer_init_15);
 	xfer_data->version = 15;
@@ -1108,26 +1107,22 @@
 	PurpleXfer *xfer;
 	struct yahoo_xfer_data *xd;
 	int did;
-	gchar* buf;
-	gchar* t;
+	guchar buf[1000];
 	PurpleAccount *account;
 	PurpleConnection *gc;
 
 	xfer = data;
-	xd = xfer->data;
+	xd = purple_xfer_get_protocol_data(xfer);
 	account = purple_connection_get_account(xd->gc);
 	gc = xd->gc;
 
-	buf=g_strnfill(1000, 0);
-	while((did = read(source, buf, 998)) > 0)
+	while((did = read(source, buf, sizeof(buf))) > 0)
 	{
+		/* TODO: Convert to circ buffer, this all is pretty horrible */
+		xd->txbuf = g_realloc(xd->txbuf, xd->txbuflen + did);
+		g_memmove(xd->txbuf + xd->txbuflen, buf, did);
 		xd->txbuflen += did;
-		buf[did] = '\0';
-		t = xd->txbuf;
-		xd->txbuf = g_strconcat(t,buf,NULL);
-		g_free(t);
 	}
-	g_free(buf);
 
 	if (did < 0 && errno == EAGAIN)
 		return;
@@ -1167,7 +1162,7 @@
 	int remaining, written;
 
 	xfer = data;
-	xd = xfer->data;
+	xd = purple_xfer_get_protocol_data(xfer);
 	remaining = xd->txbuflen - xd->txbuf_written;
 	written = write(source, xd->txbuf + xd->txbuf_written, remaining);
 
@@ -1239,13 +1234,13 @@
 
 	if (!(xfer = data))
 		return;
-	if (!(xd = xfer->data))
+	if (!(xd = purple_xfer_get_protocol_data(xfer)))
 		return;
 	gc = xd->gc;
 	account = purple_connection_get_account(gc);
 	if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) {
 		purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
-			xfer->who, _("Unable to connect."));
+			purple_xfer_get_remote_user(xfer), _("Unable to connect."));
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
@@ -1253,7 +1248,8 @@
 	if (xd->txbuflen == 0)
 	{
 		gchar* cookies;
-		YahooData *yd = gc->proto_data;
+		gchar* initial_buffer;
+		YahooData *yd = purple_connection_get_protocol_data(gc);
 
 		/* cookies = yahoo_get_cookies(gc);
 		 * This doesn't seem to be working. The function is returning NULL, which yahoo servers don't like
@@ -1266,30 +1262,30 @@
 			if(xd->info_val_249 == 2)
 				{
 				/* sending file via p2p, we are connected as client */
-				xd->txbuf = g_strdup_printf("POST /%s HTTP/1.1\r\n"
+				initial_buffer = g_strdup_printf("POST /%s HTTP/1.1\r\n"
 						"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
 						"Host: %s\r\n"
-						"Content-Length: %ld\r\n"
+						"Content-Length: %" G_GSIZE_FORMAT "\r\n"
 						"Cache-Control: no-cache\r\n\r\n",
 										xd->path,
 										xd->host,
-										(long int)xfer->size);	/* to do, add Referer */
+										purple_xfer_get_size(xfer));	/* to do, add Referer */
 				}
 			else
 				{
 				/* sending file via relaying */
-				xd->txbuf = g_strdup_printf("POST /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
+				initial_buffer = g_strdup_printf("POST /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
 						"Cookie:%s\r\n"
 						"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
 						"Host: %s\r\n"
-						"Content-Length: %ld\r\n"
+						"Content-Length: %" G_GSIZE_FORMAT "\r\n"
 						"Cache-Control: no-cache\r\n\r\n",
 										purple_url_encode(xd->xfer_idstring_for_relay),
 										purple_normalize(account, purple_account_get_username(account)),
-										xfer->who,
+										purple_xfer_get_remote_user(xfer),
 										cookies,
 										xd->host,
-										(long int)xfer->size);
+										purple_xfer_get_size(xfer));	/* to do, add Referer */
 				}
 		}
 		else if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == STARTED)
@@ -1297,7 +1293,7 @@
 			if(xd->info_val_249 == 1)
 				{
 				/* receiving file via p2p, connected as client */
-				xd->txbuf = g_strdup_printf("HEAD /%s HTTP/1.1\r\n"
+				initial_buffer = g_strdup_printf("HEAD /%s HTTP/1.1\r\n"
 						"Accept: */*\r\n"
 						"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
 						"Host: %s\r\n"
@@ -1308,7 +1304,7 @@
 			else
 				{
 				/* receiving file via relaying */
-				xd->txbuf = g_strdup_printf("HEAD /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
+				initial_buffer = g_strdup_printf("HEAD /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
 						"Accept: */*\r\n"
 						"Cookie: %s\r\n"
 						"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
@@ -1317,7 +1313,7 @@
 						"Cache-Control: no-cache\r\n\r\n",
 										purple_url_encode(xd->xfer_idstring_for_relay),
 										purple_normalize(account, purple_account_get_username(account)),
-										xfer->who,
+										purple_xfer_get_remote_user(xfer),
 										cookies,
 										xd->host);
 			}
@@ -1327,7 +1323,7 @@
 			if(xd->info_val_249 == 1)
 				{
 				/* receiving file via p2p, connected as client */
-				xd->txbuf = g_strdup_printf("GET /%s HTTP/1.1\r\n"
+				initial_buffer = g_strdup_printf("GET /%s HTTP/1.1\r\n"
 						"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
 						"Host: %s\r\n"
 						"Connection: Keep-Alive\r\n\r\n",
@@ -1336,14 +1332,14 @@
 			else
 				{
 				/* receiving file via relaying */
-				xd->txbuf = g_strdup_printf("GET /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
+				initial_buffer = g_strdup_printf("GET /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
 						"Cookie: %s\r\n"
 						"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
 						"Host: %s\r\n"
 						"Connection: Keep-Alive\r\n\r\n",
 										purple_url_encode(xd->xfer_idstring_for_relay),
 										purple_normalize(account, purple_account_get_username(account)),
-										xfer->who,
+										purple_xfer_get_remote_user(xfer),
 										cookies,
 										xd->host);
 			}
@@ -1354,7 +1350,8 @@
 			g_free(cookies);
 			return;
 		}
-		xd->txbuflen = strlen(xd->txbuf);
+		xd->txbuf = (guchar*) initial_buffer;
+		xd->txbuflen = strlen(initial_buffer);
 		xd->txbuf_written = 0;
 		g_free(cookies);
 	}
@@ -1373,7 +1370,7 @@
 	struct yahoo_xfer_data *xd;
 
 	xfer = data;
-	if (!(xd = xfer->data))	{
+	if (!(xd = purple_xfer_get_protocol_data(xfer))) {
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
@@ -1396,7 +1393,7 @@
 	char *time_str;
 
 	xfer = data;
-	if (!(xd = xfer->data))	{
+	if (!(xd = purple_xfer_get_protocol_data(xfer))) {
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
@@ -1431,14 +1428,15 @@
 	time_str[strlen(time_str) - 1] = '\0';
 
 	if (xd->txbuflen == 0)	{
-		xd->txbuf = g_strdup_printf("HTTP/1.0 200 OK\r\n"
+		gchar *initial_buffer = g_strdup_printf("HTTP/1.0 200 OK\r\n"
 		                            "Date: %s GMT\r\n"
 		                            "Server: Y!/1.0\r\n"
 		                            "MIME-version: 1.0\r\n"
 		                            "Last-modified: %s GMT\r\n"
 		                            "Content-length: %" G_GSIZE_FORMAT "\r\n\r\n",
-		                            time_str, time_str, xfer->size);
-		xd->txbuflen = strlen(xd->txbuf);
+		                            time_str, time_str, purple_xfer_get_size(xfer));
+		xd->txbuf = (guchar *)initial_buffer;
+		xd->txbuflen = strlen(initial_buffer);
 		xd->txbuf_written = 0;
 	}
 
@@ -1458,7 +1456,7 @@
 	struct yahoo_xfer_data *xd;
 
 	xfer = data;
-	if (!(xd = xfer->data))	{
+	if (!(xd = purple_xfer_get_protocol_data(xfer))) {
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
@@ -1481,7 +1479,7 @@
 
 	/* Add an Input Read event to the file descriptor */
 	xfer->fd = acceptfd;
-	if(xfer->type == PURPLE_XFER_RECEIVE)
+	if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE)
 		xd->input_event = purple_input_add(acceptfd, PURPLE_INPUT_READ, yahoo_p2p_ft_POST_cb, data);
 	else
 		xd->input_event = purple_input_add(acceptfd, PURPLE_INPUT_READ, yahoo_p2p_ft_HEAD_GET_cb, data);
@@ -1500,14 +1498,14 @@
 	char *filename_without_spaces = NULL;
 
 	xfer = data;
-	if (!(xd = xfer->data) || (listenfd == -1))	{
+	if (!(xd = purple_xfer_get_protocol_data(xfer)) || (listenfd == -1))	{
 		purple_debug_warning("yahoo","p2p: error starting server for p2p file transfer\n");
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
 
-	if( (xfer->type == PURPLE_XFER_RECEIVE) || (xd->status_15 != P2P_HEAD_REPLIED) )	{
-		yd = xd->gc->proto_data;
+	if( (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) || (xd->status_15 != P2P_HEAD_REPLIED) )	{
+		yd = purple_connection_get_protocol_data(xd->gc);
 		account = purple_connection_get_account(xd->gc);
 		local_ip = purple_network_get_my_ip(listenfd);
 		xd->yahoo_local_p2p_ft_server_port = purple_network_get_port_from_fd(listenfd);
@@ -1515,18 +1513,18 @@
 		filename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
 		filename_without_spaces = g_strdup(filename);
 		purple_util_chrreplace(filename_without_spaces, ' ', '+');
-		xd->xfer_url = g_strdup_printf("/Messenger.%s.%d000%s?AppID=Messenger&UserID=%s&K=lc9lu2u89gz1llmplwksajkjx", xfer->who, (int)time(NULL), filename_without_spaces, xfer->who);
+		xd->xfer_url = g_strdup_printf("/Messenger.%s.%d000%s?AppID=Messenger&UserID=%s&K=lc9lu2u89gz1llmplwksajkjx", purple_xfer_get_remote_user(xfer), (int)time(NULL), filename_without_spaces, purple_xfer_get_remote_user(xfer));
 		url_to_send = g_strdup_printf("http://%s:%d%s", local_ip, xd->yahoo_local_p2p_ft_server_port, xd->xfer_url);
 
-		if(xfer->type == PURPLE_XFER_RECEIVE)	{
+		if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) {
 			xd->info_val_249 = 2;	/* 249=2: we are p2p server, and receiving file */
 			pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_ACC_15,
 				YAHOO_STATUS_AVAILABLE, yd->session_id);
 			yahoo_packet_hash(pkt, "ssssis",
 				1, purple_normalize(account, purple_account_get_username(account)),
-				5, xfer->who,
+				5, purple_xfer_get_remote_user(xfer),
 				265, xd->xfer_peer_idstring,
-				27, xfer->filename,
+				27, purple_xfer_get_filename(xfer),
 				249, 2,
 				250, url_to_send);
 		}
@@ -1535,7 +1533,7 @@
 			pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_INFO_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
 			yahoo_packet_hash(pkt, "ssssis",
 				1, purple_normalize(account, purple_account_get_username(account)),
-				5, xfer->who,
+				5, purple_xfer_get_remote_user(xfer),
 				265, xd->xfer_peer_idstring,
 				27,  filename,
 				249, 1,
@@ -1564,13 +1562,13 @@
 	gchar *filename;
 	struct yahoo_p2p_data *p2p_data;
 
-	if (!(xd = xfer->data))
+	if (!(xd = purple_xfer_get_protocol_data(xfer)))
 		return;
 
 	account = purple_connection_get_account(gc);
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
-	p2p_data = g_hash_table_lookup(yd->peers, xfer->who);
+	p2p_data = g_hash_table_lookup(yd->peers, purple_xfer_get_remote_user(xfer));
 	if( p2p_data->connection_type == YAHOO_P2P_WE_ARE_SERVER )
 		if(purple_network_listen_range(0, 0, SOCK_STREAM, yahoo_p2p_ft_server_listen_cb, xfer))
 			return;
@@ -1580,7 +1578,7 @@
 
 	yahoo_packet_hash(pkt, "ssssi",
 		1, purple_normalize(account, purple_account_get_username(account)),
-		5, xfer->who,
+		5, purple_xfer_get_remote_user(xfer),
 		265, xd->xfer_peer_idstring,
 		27,  filename,
 		249, 2);	/* 249=2: we are p2p client */
@@ -1609,7 +1607,7 @@
 	GSList *size_list = NULL;
 	int nooffiles = 0;
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	for (l = pkt->hash; l; l = l->next) {
 		struct yahoo_pair *pair = l->data;
@@ -1683,13 +1681,13 @@
 		account = purple_connection_get_account(gc);
 		if (yd->jp)
 		{
-			purple_dnsquery_a_account(account, YAHOOJP_XFER_RELAY_HOST,
+			purple_dnsquery_a(account, YAHOOJP_XFER_RELAY_HOST,
 							YAHOOJP_XFER_RELAY_PORT,
 							yahoo_xfer_dns_connected_15, xfer);
 		}
 		else
 		{
-			purple_dnsquery_a_account(account, YAHOO_XFER_RELAY_HOST,
+			purple_dnsquery_a(account, YAHOO_XFER_RELAY_HOST,
 							YAHOO_XFER_RELAY_PORT,
 							yahoo_xfer_dns_connected_15, xfer);
 		}
@@ -1739,15 +1737,13 @@
 		g_return_if_reached();
 	}
 
-	xfer->message = NULL;
-
 	/* Set the info about the incoming file. */
 	utf8_filename = yahoo_string_decode(gc, filename, TRUE);
 	purple_xfer_set_filename(xfer, utf8_filename);
 	g_free(utf8_filename);
 	purple_xfer_set_size(xfer, filesize);
 
-	xfer->data = xfer_data;
+	purple_xfer_set_protocol_data(xfer, xfer_data);
 
 	/* Setup our I/O op functions */
 	purple_xfer_set_init_fnc(xfer,        yahoo_xfer_init_15);
@@ -1765,7 +1761,7 @@
 
 	if(nooffiles > 1) {
 		gchar* message;
-		message = g_strdup_printf(_("%s is trying to send you a group of %d files.\n"), xfer->who, nooffiles);
+		message = g_strdup_printf(_("%s is trying to send you a group of %d files.\n"), purple_xfer_get_remote_user(xfer), nooffiles);
 		purple_xfer_conversation_write(xfer, message, FALSE);
 		g_free(message);
 	}
@@ -1790,7 +1786,7 @@
 	struct yahoo_packet *pkt_to_send;
 	struct yahoo_p2p_data *p2p_data;
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	for (l = pkt->hash; l; l = l->next) {
 		struct yahoo_pair *pair = l->data;
@@ -1837,7 +1833,7 @@
 		return;
 	}
 
-	xfer_data = xfer->data;
+	xfer_data = purple_xfer_get_protocol_data(xfer);
 
 	xfer_data->info_val_249 = val_249;
 	xfer_data->xfer_idstring_for_relay = g_strdup(xfer_idstring_for_relay);
@@ -1854,9 +1850,9 @@
 			YAHOO_STATUS_AVAILABLE, yd->session_id);
 		yahoo_packet_hash(pkt_to_send, "ssssis",
 			1, purple_normalize(account, purple_account_get_username(account)),
-			5, xfer->who,
+			5, purple_xfer_get_remote_user(xfer),
 			265, xfer_data->xfer_peer_idstring,
-			27, xfer->filename,
+			27, purple_xfer_get_filename(xfer),
 			249, xfer_data->info_val_249,
 			251, xfer_data->xfer_idstring_for_relay);
 
@@ -1870,7 +1866,7 @@
 		}
 	}
 	else if(val_249 == 2)	{
-		p2p_data = g_hash_table_lookup(yd->peers, xfer->who);
+		p2p_data = g_hash_table_lookup(yd->peers, purple_xfer_get_remote_user(xfer));
 		if( !( p2p_data && (p2p_data->connection_type == YAHOO_P2P_WE_ARE_SERVER) ) )	{
 			purple_xfer_cancel_remote(xfer);
 			return;
@@ -1896,7 +1892,7 @@
 	gchar *url = NULL;
 	int val_249 = 0;
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 	for (l = pkt->hash; l; l = l->next) {
 		struct yahoo_pair *pair = l->data;
 
@@ -1934,7 +1930,7 @@
 		return;
 	}
 
-	xfer_data = xfer->data;
+	xfer_data = purple_xfer_get_protocol_data(xfer);
 	if(url)
 		purple_url_parse(url, &(xfer_data->host), &(xfer_data->port), &(xfer_data->path), NULL, NULL);
 
--- a/libpurple/protocols/yahoo/yahoo_friend.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/yahoo_friend.c	Sun Sep 11 04:19:01 2011 +0000
@@ -46,9 +46,10 @@
 	const char *norm;
 
 	g_return_val_if_fail(gc != NULL, NULL);
-	g_return_val_if_fail(gc->proto_data != NULL, NULL);
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
+	g_return_val_if_fail(yd != NULL, NULL);
+
 	norm = purple_normalize(purple_connection_get_account(gc), name);
 
 	return g_hash_table_lookup(yd->friends, norm);
@@ -61,9 +62,10 @@
 	const char *norm;
 
 	g_return_val_if_fail(gc != NULL, NULL);
-	g_return_val_if_fail(gc->proto_data != NULL, NULL);
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
+	g_return_val_if_fail(yd != NULL, NULL);
+
 	norm = purple_normalize(purple_connection_get_account(gc), name);
 
 	f = g_hash_table_lookup(yd->friends, norm);
@@ -225,7 +227,7 @@
 void yahoo_friend_update_presence(PurpleConnection *gc, const char *name,
 		YahooPresenceVisibility presence)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt = NULL;
 	YahooFriend *f;
 	const char *thirtyone, *thirteen;
--- a/libpurple/protocols/yahoo/yahoo_packet.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/yahoo_packet.c	Sun Sep 11 04:19:01 2011 +0000
@@ -302,7 +302,7 @@
 		return;
 	else if (ret < 0) {
 		/* TODO: what to do here - do we really have to disconnect? */
-		purple_connection_error_reason(yd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+		purple_connection_error(yd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		                               _("Write Error"));
 		return;
 	}
--- a/libpurple/protocols/yahoo/yahoo_picture.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/yahoo_picture.c	Sun Sep 11 04:19:01 2011 +0000
@@ -52,7 +52,7 @@
 	YahooData *yd;
 
 	d = user_data;
-	yd = d->gc->proto_data;
+	yd = purple_connection_get_protocol_data(d->gc);
 	yd->url_datas = g_slist_remove(yd->url_datas, url_data);
 
 	if (error_message != NULL) {
@@ -135,7 +135,7 @@
 				"Mozilla/4.0 (compatible; MSIE 5.5)", FALSE,
 				yahoo_fetch_picture_cb, data);
 		if (url_data != NULL) {
-			yd = gc->proto_data;
+			yd = purple_connection_get_protocol_data(gc);
 			yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
 		} else {
 			g_free(data->who);
@@ -185,7 +185,7 @@
 void yahoo_process_picture_upload(PurpleConnection *gc, struct yahoo_packet *pkt)
 {
 	PurpleAccount *account = purple_connection_get_account(gc);
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	GSList *l = pkt->hash;
 	char *url = NULL;
 
@@ -261,7 +261,7 @@
 
 void yahoo_send_picture_info(PurpleConnection *gc, const char *who)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 
 	if (!yd->picture_url) {
@@ -278,7 +278,7 @@
 
 void yahoo_send_picture_request(PurpleConnection *gc, const char *who)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 
 	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -290,7 +290,7 @@
 
 void yahoo_send_picture_checksum(PurpleConnection *gc)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 
 	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -301,7 +301,7 @@
 
 void yahoo_send_picture_update_to_user(PurpleConnection *gc, const char *who, int type)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 
 	pkt = yahoo_packet_new(YAHOO_SERVICE_AVATAR_UPDATE, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -326,7 +326,7 @@
 
 void yahoo_send_picture_update(PurpleConnection *gc, int type)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yspufe data;
 
 	data.gc = gc;
@@ -425,7 +425,7 @@
 	gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
 
 	account = purple_connection_get_account(gc);
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	/* Buddy icon connect is now complete; clear the PurpleProxyConnectData */
 	yd->buddy_icon_connect_data = NULL;
@@ -490,7 +490,7 @@
 void yahoo_buddy_icon_upload(PurpleConnection *gc, struct yahoo_buddy_icon_upload_data *d)
 {
 	PurpleAccount *account = purple_connection_get_account(gc);
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	if (yd->buddy_icon_connect_data != NULL) {
 		/* Cancel any in-progress buddy icon upload */
@@ -535,7 +535,7 @@
 
 void yahoo_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	PurpleAccount *account = gc->account;
 
 	if (img == NULL) {
--- a/libpurple/protocols/yahoo/yahoo_profile.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/yahoo_profile.c	Sun Sep 11 04:19:01 2011 +0000
@@ -789,7 +789,7 @@
 
 	purple_debug_info("yahoo", "In yahoo_got_info\n");
 
-	yd = info_data->gc->proto_data;
+	yd = purple_connection_get_protocol_data(info_data->gc);
 	yd->url_datas = g_slist_remove(yd->url_datas, url_data);
 
 	user_info = purple_notify_user_info_new();
@@ -805,7 +805,7 @@
 	 * to send back HTML, with a 200 status code.
 	 */
 	if (error_message != NULL || url_text == NULL || strcmp(url_text, "") == 0) {
-		purple_notify_user_info_add_pair(user_info, _("Error retrieving profile"), NULL);
+		purple_notify_user_info_add_pair_html(user_info, _("Error retrieving profile"), NULL);
 		purple_notify_userinfo(info_data->gc, info_data->name,
 			user_info, NULL, NULL);
 		purple_notify_user_info_destroy(user_info);
@@ -840,7 +840,7 @@
 						 _("If you wish to view this profile, "
 						"you will need to visit this link in your web browser:"),
 						 profile_url_text, profile_url_text);
-		purple_notify_user_info_add_pair(user_info, NULL, tmp);
+		purple_notify_user_info_add_pair_html(user_info, NULL, tmp);
 		g_free(tmp);
 
 		purple_notify_userinfo(info_data->gc, info_data->name,
@@ -983,7 +983,7 @@
 	/* in to purple_markup_strip_html*/
 	char *fudged_buffer;
 
-	yd = info_data->gc->proto_data;
+	yd = purple_connection_get_protocol_data(info_data->gc);
 	yd->url_datas = g_slist_remove(yd->url_datas, url_data);
 
 	fudged_buffer = purple_strcasereplace(url_buffer, "</dd>", "</dd><br>");
@@ -1048,7 +1048,7 @@
 			id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL);
 
 			tmp = g_strdup_printf("<img id=\"%d\"><br>", id);
-			purple_notify_user_info_add_pair(user_info, NULL, tmp);
+			purple_notify_user_info_add_pair_html(user_info, NULL, tmp);
 			g_free(tmp);
 		}
 	}
@@ -1195,7 +1195,7 @@
 		const gchar *str;
 
 		purple_notify_user_info_add_section_break(user_info);
-		purple_notify_user_info_add_pair(user_info,
+		purple_notify_user_info_add_pair_html(user_info,
 				_("Error retrieving profile"), NULL);
 
 		if (profile_state == PROFILE_STATE_UNKNOWN_LANGUAGE) {
@@ -1228,14 +1228,14 @@
 			str = _("The user's profile is empty.");
 		}
 
-		purple_notify_user_info_add_pair(user_info, NULL, str);
+		purple_notify_user_info_add_pair_plaintext(user_info, NULL, str);
 	}
 
 	/* put a link to the actual profile URL */
 	purple_notify_user_info_add_section_break(user_info);
 	tmp = g_strdup_printf("<a href=\"%s\">%s</a>",
 			profile_url_text, _("View web profile"));
-	purple_notify_user_info_add_pair(user_info, NULL, tmp);
+	purple_notify_user_info_add_pair_html(user_info, NULL, tmp);
 	g_free(tmp);
 
 	g_free(stripped);
@@ -1262,7 +1262,7 @@
 
 void yahoo_get_info(PurpleConnection *gc, const char *name)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	YahooGetInfoData *data;
 	char *url;
 	PurpleUtilFetchUrlData *url_data;
--- a/libpurple/protocols/yahoo/yahoochat.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/yahoochat.c	Sun Sep 11 04:19:01 2011 +0000
@@ -53,7 +53,7 @@
 /* special function to log us on to the yahoo chat service */
 static void yahoo_chat_online(PurpleConnection *gc)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	const char *rll;
 
@@ -101,7 +101,7 @@
 	YahooData *yd;
 	GSList *l;
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	for (l = yd->confs; l; l = l->next) {
 		PurpleConversation *c = l->data;
@@ -372,7 +372,7 @@
 
 static void yahoo_chat_join(PurpleConnection *gc, const char *dn, const char *room, const char *topic, const char *id)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	char *room2;
 	gboolean utf8 = TRUE;
@@ -400,7 +400,7 @@
 /* this is a confirmation of yahoo_chat_online(); */
 void yahoo_process_chat_online(PurpleConnection *gc, struct yahoo_packet *pkt)
 {
-	YahooData *yd = (YahooData *) gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	if (pkt->status == 1) {
 		yd->chat_online = TRUE;
@@ -432,7 +432,7 @@
 /* this is basicly the opposite of chat_online */
 void yahoo_process_chat_logout(PurpleConnection *gc, struct yahoo_packet *pkt)
 {
-	YahooData *yd = (YahooData *) gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	GSList *l;
 
 	for (l = pkt->hash; l; l = l->next) {
@@ -462,7 +462,7 @@
 void yahoo_process_chat_join(PurpleConnection *gc, struct yahoo_packet *pkt)
 {
 	PurpleAccount *account = purple_connection_get_account(gc);
-	YahooData *yd = (YahooData *) gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	PurpleConversation *c = NULL;
 	GSList *l;
 	GList *members = NULL;
@@ -786,7 +786,7 @@
 static int yahoo_conf_send(PurpleConnection *gc, const char *dn, const char *room,
 							GList *members, const char *what)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	GList *who;
 	char *msg, *msg2;
@@ -843,7 +843,7 @@
 static void yahoo_conf_invite(PurpleConnection *gc, PurpleConversation *c,
 		const char *dn, const char *buddy, const char *room, const char *msg)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	GList *members;
 	char *msg2 = NULL;
@@ -873,7 +873,7 @@
 
 static void yahoo_chat_leave(PurpleConnection *gc, const char *room, const char *dn, gboolean logout)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 
 	char *eroom;
@@ -924,7 +924,7 @@
 
 static int yahoo_chat_send(PurpleConnection *gc, const char *dn, const char *room, const char *what, PurpleMessageFlags flags)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	int me = 0;
 	char *msg1, *msg2, *room2;
@@ -969,7 +969,7 @@
 static void yahoo_chat_invite(PurpleConnection *gc, const char *dn, const char *buddy,
 							const char *room, const char *msg)
 {
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	struct yahoo_packet *pkt;
 	char *room2, *msg2 = NULL;
 	gboolean utf8 = TRUE;
@@ -997,7 +997,7 @@
 	YahooData *yd;
 	struct yahoo_packet *pkt;
 
-	yd = gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 
 	if (yd->wm) {
 		g_return_if_fail(yd->ycht != NULL);
@@ -1029,7 +1029,7 @@
 
 void yahoo_c_leave(PurpleConnection *gc, int id)
 {
-	YahooData *yd = (YahooData *) gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	PurpleConversation *c;
 
 	if (!yd)
@@ -1056,7 +1056,7 @@
 	int ret;
 	YahooData *yd;
 
-	yd = (YahooData *) gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 	if (!yd)
 		return -1;
 
@@ -1114,7 +1114,7 @@
 	char *room, *topic, *type;
 	PurpleConversation *c;
 
-	yd = (YahooData *) gc->proto_data;
+	yd = purple_connection_get_protocol_data(gc);
 	if (!yd)
 		return;
 
@@ -1375,7 +1375,9 @@
 	purple_roomlist_set_in_progress(list, FALSE);
 
 	if (yrl) {
-		list->proto_data = g_list_remove(list->proto_data, yrl);
+		GList *proto_data = purple_roomlist_get_proto_data(list);
+		proto_data = g_list_remove(proto_data, yrl);
+		purple_roomlist_set_proto_data(list, proto_data);
 		yahoo_roomlist_destroy(yrl);
 	}
 
@@ -1451,7 +1453,7 @@
 		yrl->inpa = 0;
 		g_free(yrl->txbuf);
 		yrl->txbuf = NULL;
-		purple_notify_error(purple_account_get_connection(list->account), NULL, _("Unable to connect"), _("Fetching the room list failed."));
+		purple_notify_error(purple_account_get_connection(purple_roomlist_get_account(list)), NULL, _("Unable to connect"), _("Fetching the room list failed."));
 		yahoo_roomlist_cleanup(list, yrl);
 		return;
 	}
@@ -1474,10 +1476,12 @@
 {
 	struct yahoo_roomlist *yrl = data;
 	PurpleRoomlist *list = yrl->list;
-	YahooData *yd = purple_account_get_connection(list->account)->proto_data;
+	PurpleAccount *account = purple_roomlist_get_account(list);
+	PurpleConnection *pc = purple_account_get_connection(account);
+	YahooData *yd = purple_connection_get_protocol_data(pc);
 
 	if (source < 0) {
-		purple_notify_error(purple_account_get_connection(list->account), NULL, _("Unable to connect"), _("Fetching the room list failed."));
+		purple_notify_error(pc, NULL, _("Unable to connect"), _("Fetching the room list failed."));
 		yahoo_roomlist_cleanup(list, yrl);
 		return;
 	}
@@ -1506,6 +1510,7 @@
 	struct yahoo_roomlist *yrl;
 	const char *rll, *rlurl;
 	char *url;
+	GList *proto_data;
 
 	account = purple_connection_get_account(gc);
 
@@ -1556,7 +1561,9 @@
 		return NULL;
 	}
 
-	rl->proto_data = g_list_append(rl->proto_data, yrl);
+	proto_data = purple_roomlist_get_proto_data(rl);
+	proto_data = g_list_append(proto_data, yrl);
+	purple_roomlist_set_proto_data(rl, proto_data);
 
 	purple_roomlist_set_in_progress(rl, TRUE);
 	return rl;
@@ -1566,8 +1573,8 @@
 {
 	GList *l, *k;
 
-	k = l = list->proto_data;
-	list->proto_data = NULL;
+	k = l = purple_roomlist_get_proto_data(list);
+	purple_roomlist_set_proto_data(list, NULL);
 
 	purple_roomlist_set_in_progress(list, FALSE);
 
@@ -1580,36 +1587,42 @@
 
 void yahoo_roomlist_expand_category(PurpleRoomlist *list, PurpleRoomlistRoom *category)
 {
+	PurpleAccount *account;
 	struct yahoo_roomlist *yrl;
 	char *url;
 	char *id;
 	const char *rll;
+	GList *proto_data;
 
-	if (category->type != PURPLE_ROOMLIST_ROOMTYPE_CATEGORY)
+	if (purple_roomlist_room_get_type(category) != PURPLE_ROOMLIST_ROOMTYPE_CATEGORY)
 		return;
 
-	if (!(id = g_list_nth_data(category->fields, 1))) {
+	if (!(id = g_list_nth_data(purple_roomlist_room_get_fields(category), 1))) {
 		purple_roomlist_set_in_progress(list, FALSE);
 		return;
 	}
 
-	rll = purple_account_get_string(list->account, "room_list_locale",
+	account = purple_roomlist_get_account(list);
+	rll = purple_account_get_string(account, "room_list_locale",
 								  YAHOO_ROOMLIST_LOCALE);
 
 	if (rll != NULL && *rll != '\0') {
 		url = g_strdup_printf("%s?chatroom_%s=0&intl=%s",
-	       purple_account_get_string(list->account,"room_list",
+	       purple_account_get_string(account,"room_list",
 	       YAHOO_ROOMLIST_URL), id, rll);
 	} else {
 		url = g_strdup_printf("%s?chatroom_%s=0",
-	       purple_account_get_string(list->account,"room_list",
+	       purple_account_get_string(account,"room_list",
 	       YAHOO_ROOMLIST_URL), id);
 	}
 
 	yrl = g_new0(struct yahoo_roomlist, 1);
 	yrl->list = list;
 	yrl->cat = category;
-	list->proto_data = g_list_append(list->proto_data, yrl);
+
+	proto_data = purple_roomlist_get_proto_data(list);
+	proto_data = g_list_append(proto_data, yrl);
+	purple_roomlist_set_proto_data(list, proto_data);
 
 	purple_url_parse(url, &(yrl->host), NULL, &(yrl->path), NULL, NULL);
 	g_free(url);
@@ -1617,11 +1630,11 @@
 	yrl->ucat = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_CATEGORY, _("User Rooms"), yrl->cat);
 	purple_roomlist_room_add(list, yrl->ucat);
 
-	if (purple_proxy_connect(purple_account_get_connection(list->account),
-			list->account, yrl->host, 80,
+	if (purple_proxy_connect(purple_account_get_connection(account),
+			account, yrl->host, 80,
 			yahoo_roomlist_got_connected, yrl) == NULL)
 	{
-		purple_notify_error(purple_account_get_connection(list->account),
+		purple_notify_error(purple_account_get_connection(account),
 		                  NULL, _("Connection problem"), _("Unable to fetch room list."));
 		purple_roomlist_ref(list);
 		yahoo_roomlist_cleanup(list, yrl);
--- a/libpurple/protocols/yahoo/ycht.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/yahoo/ycht.c	Sun Sep 11 04:19:01 2011 +0000
@@ -53,7 +53,7 @@
 static void ycht_process_login(YchtConn *ycht, YchtPkt *pkt)
 {
 	PurpleConnection *gc = ycht->gc;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	if (ycht->logged_in)
 		return;
@@ -68,7 +68,7 @@
 static void ycht_process_logout(YchtConn *ycht, YchtPkt *pkt)
 {
 	PurpleConnection *gc = ycht->gc;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	yd->chat_online = FALSE;
 	ycht->logged_in = FALSE;
@@ -173,7 +173,7 @@
 {
 #if 0
 	PurpleConnection *gc = ycht->gc;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	if (ycht->logged_in)
 		return;
@@ -285,7 +285,7 @@
 /*
 		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
 				g_strerror(errno));
-		purple_connection_error_reason(purple_account_get_connection(irc->account),
+		purple_connection_error(purple_account_get_connection(irc->account),
 			      PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
 */
@@ -429,7 +429,7 @@
 
 void ycht_connection_close(YchtConn *ycht)
 {
-	YahooData *yd = ycht->gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(ycht->gc);
 
 	if (yd) {
 		yd->ycht = NULL;
@@ -541,7 +541,7 @@
 {
 	YchtConn *ycht = data;
 	PurpleConnection *gc = ycht->gc;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	YchtPkt *pkt;
 	char *buf;
 
@@ -568,7 +568,7 @@
 void ycht_connection_open(PurpleConnection *gc)
 {
 	YchtConn *ycht;
-	YahooData *yd = gc->proto_data;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	PurpleAccount *account = purple_connection_get_account(gc);
 
 	ycht = g_new0(YchtConn, 1);
--- a/libpurple/protocols/zephyr/zephyr.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/protocols/zephyr/zephyr.c	Sun Sep 11 04:19:01 2011 +0000
@@ -146,7 +146,7 @@
 					return TRUE;
 
 #define z_call_s(func, err)	if (func != ZERR_NONE) {\
-					purple_connection_error(gc, err);\
+					purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, err);\
 					return;\
 				}
 
@@ -347,7 +347,7 @@
 {
 	gchar *utf8;
 	GError *err = NULL;
-	zephyr_account *zephyr = gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	if (g_utf8_validate(string, -1, NULL)) {
 		return g_strdup(string);
 	} else {
@@ -762,7 +762,7 @@
 
 static void handle_message(PurpleConnection *gc,ZNotice_t notice)
 {
-	zephyr_account* zephyr = gc->proto_data;
+	zephyr_account* zephyr = purple_connection_get_protocol_data(gc);
 
 	if (!g_ascii_strcasecmp(notice.z_class, LOGIN_CLASS)) {
 		/* well, we'll be updating in 20 seconds anyway, might as well ignore this. */
@@ -791,20 +791,23 @@
 				char *tmp;
 				const char *balias;
 
-				purple_notify_user_info_add_pair(user_info, _("User"), (b ? bname : user));
+				/* TODO: Check whether it's correct to call add_pair_html,
+				         or if we should be using add_pair_plaintext */
+				purple_notify_user_info_add_pair_html(user_info, _("User"), (b ? bname : user));
 				balias = purple_buddy_get_local_buddy_alias(b);
 				if (b && balias)
-					purple_notify_user_info_add_pair(user_info, _("Alias"), balias);
+					purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), balias);
 
 				if (!nlocs) {
-					purple_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in"));
+					purple_notify_user_info_add_pair_plaintext(user_info, NULL, _("Hidden or not logged-in"));
 				}
 				for (; nlocs > 0; nlocs--) {
 					/* XXX add real error reporting */
 
 					ZGetLocations(&locs, &one);
+					/* TODO: Need to escape locs.host and locs.time? */
 					tmp = g_strdup_printf(_("<br>At %s since %s"), locs.host, locs.time);
-					purple_notify_user_info_add_pair(user_info, _("Location"), tmp);
+					purple_notify_user_info_add_pair_html(user_info, _("Location"), tmp);
 					g_free(tmp);
 				}
 				purple_notify_userinfo(gc, (b ? bname : user),
@@ -869,7 +872,7 @@
 		} else {
 			zephyr_triple *zt1, *zt2;
 			gchar *send_inst_utf8;
-			zephyr_account *zephyr = gc->proto_data;
+			zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 			zt1 = new_triple(zephyr,notice.z_class, notice.z_class_inst, notice.z_recipient);
 			zt2 = find_sub_by_triple(zephyr,zt1);
 			if (!zt2) {
@@ -1106,7 +1109,7 @@
 static gint check_notify_tzc(gpointer data)
 {
 	PurpleConnection *gc = (PurpleConnection *)data;
-	zephyr_account* zephyr = gc->proto_data;
+	zephyr_account* zephyr = purple_connection_get_protocol_data(gc);
 	parse_tree *newparsetree = read_from_tzc(zephyr);
 	if (newparsetree != NULL) {
 		gchar *spewtype;
@@ -1161,7 +1164,7 @@
 				locations = find_node(newparsetree,"locations");
 				locval = tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents;
 
-				if (!locval || !g_ascii_strcasecmp(locval," ") || (strlen(locval) == 0)) {
+				if (!locval || !g_ascii_strcasecmp(locval," ") || !*locval) {
 					nlocs = 0;
 				} else {
 					nlocs = 1;
@@ -1173,19 +1176,22 @@
 					char *tmp;
 					const char *balias;
 
-					purple_notify_user_info_add_pair(user_info, _("User"), (b ? bname : user));
+					/* TODO: Check whether it's correct to call add_pair_html,
+					         or if we should be using add_pair_plaintext */
+					purple_notify_user_info_add_pair_html(user_info, _("User"), (b ? bname : user));
 
 					balias = b ? purple_buddy_get_local_buddy_alias(b) : NULL;
 					if (balias)
-						purple_notify_user_info_add_pair(user_info, _("Alias"), balias);
+						purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), balias);
 
 					if (!nlocs) {
-						purple_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in"));
+						purple_notify_user_info_add_pair_plaintext(user_info, NULL, _("Hidden or not logged-in"));
 					} else {
+						/* TODO: Need to escape the two strings that make up tmp? */
 						tmp = g_strdup_printf(_("<br>At %s since %s"),
 									  tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents,
 									  tree_child(tree_child(tree_child(tree_child(locations,2),0),2),2)->contents);
-						purple_notify_user_info_add_pair(user_info, _("Location"), tmp);
+						purple_notify_user_info_add_pair_html(user_info, _("Location"), tmp);
 						g_free(tmp);
 					}
 
@@ -1259,7 +1265,7 @@
 	GSList *buddies;
 	ZLocations_t locations;
 	PurpleConnection *gc = data;
-	zephyr_account *zephyr = gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	PurpleAccount *account = purple_connection_get_account(gc);
 	int numlocs;
 	int one = 1;
@@ -1290,7 +1296,7 @@
 	GSList *buddies;
 	ZAsyncLocateData_t ald;
 	PurpleConnection *gc = (PurpleConnection *)data;
-	zephyr_account *zephyr = gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	PurpleAccount *account = purple_connection_get_account(gc);
 
 	if (use_zeph02(zephyr)) {
@@ -1566,7 +1572,8 @@
 	username = purple_account_get_username(account);
 #endif
 	gc->flags |= PURPLE_CONNECTION_AUTO_RESP | PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC;
-	gc->proto_data = zephyr=g_new0(zephyr_account,1);
+	zephyr = g_new0(zephyr_account, 1);
+	purple_connection_set_protocol_data(gc, zephyr);
 
 	zephyr->account = account;
 
@@ -1585,7 +1592,7 @@
 	/* XXX z_call_s should actually try to report the com_err determined error */
 	if (use_tzc(zephyr)) {
 		pid_t pid;
-		/*		  purple_connection_error(gc,"tzc not supported yet"); */
+		/*		  purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "tzc not supported yet"); */
 		if ((pipe(zephyr->totzc) != 0) || (pipe(zephyr->fromtzc) != 0)) {
 			purple_debug_error("zephyr", "pipe creation failed. killing\n");
 			exit(-1);
@@ -1706,7 +1713,7 @@
 				ptr++;
 			}
 			if (ptr >=bufcur) {
-				purple_connection_error(gc,"invalid output by tzc (or bad parsing code)");
+				purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "invalid output by tzc (or bad parsing code)");
 				free(buf);
 				return;
 			}
@@ -1821,7 +1828,7 @@
 		purple_debug_info("zephyr","realm: %s\n",zephyr->realm);
 	}
 	else {
-		purple_connection_error(gc,"Only ZEPH0.2 supported currently");
+		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "Only ZEPH0.2 supported currently");
 		return;
 	}
 	purple_debug_info("zephyr","does it get here\n");
@@ -1955,7 +1962,7 @@
 {
 	GList *l;
 	GSList *s;
-	zephyr_account *zephyr = gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	pid_t tzc_pid = zephyr->tzc_pid;
 
 	l = zephyr->pending_zloc_names;
@@ -2030,7 +2037,7 @@
 	PurpleConvChat *gcc;
 	char *inst;
 	char *recipient;
-	zephyr_account *zephyr = gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 
 	zt = find_sub_by_id(zephyr,id);
 	if (!zt)
@@ -2059,7 +2066,7 @@
 static int zephyr_send_im(PurpleConnection * gc, const char *who, const char *im, PurpleMessageFlags flags)
 {
 	const char *sig;
-	zephyr_account *zephyr = gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	if (flags & PURPLE_MESSAGE_AUTO_RESP)
 		sig = "Automated reply:";
 	else {
@@ -2079,7 +2086,7 @@
 	int pos2 = 0;
 	char *newmsg;
 
-	if (message && (strlen(message) > 0)) {
+	if (message && *message) {
 		newmsg = g_new0(char,1+strlen(message)*2);
 		while(pos < strlen(message)) {
 			if (message[pos]=='\\') {
@@ -2111,7 +2118,7 @@
 	int pos2 = 0;
 	char *newmsg;
 
-	if (message && (strlen(message) > 0)) {
+	if (message && *message) {
 		newmsg = g_new0(char,strlen(message)+1);
 		while(pos < strlen(message)) {
 			if (message[pos]=='\\') {
@@ -2228,7 +2235,7 @@
 	if (gc == NULL)
 		return NULL;
 
-	tmp = local_zephyr_normalize(gc->proto_data, who);
+	tmp = local_zephyr_normalize(purple_connection_get_protocol_data(gc), who);
 
 	if (strlen(tmp) >= sizeof(buf)) {
 		g_free(tmp);
@@ -2244,7 +2251,7 @@
 static void zephyr_zloc(PurpleConnection *gc, const char *who)
 {
 	ZAsyncLocateData_t ald;
-	zephyr_account *zephyr = gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	gchar* normalized_who = local_zephyr_normalize(zephyr,who);
 
 	if (use_zeph02(zephyr)) {
@@ -2271,7 +2278,8 @@
 static void zephyr_set_status(PurpleAccount *account, PurpleStatus *status) {
 	size_t len;
 	size_t result;
-	zephyr_account *zephyr = purple_account_get_connection(account)->proto_data;
+	PurpleConnection *gc = purple_account_get_connection(account);
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	PurpleStatusPrimitive primitive = purple_status_type_get_primitive(purple_status_get_type(status));
 
 	if (zephyr->away) {
@@ -2405,7 +2413,7 @@
 	const char *classname;
 	const char *instname;
 	const char *recip;
-	zephyr_account *zephyr=gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	classname = g_hash_table_lookup(data, "class");
 	instname = g_hash_table_lookup(data, "instance");
 	recip = g_hash_table_lookup(data, "recipient");
@@ -2468,7 +2476,7 @@
 static void zephyr_chat_leave(PurpleConnection * gc, int id)
 {
 	zephyr_triple *zt;
-	zephyr_account *zephyr = gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	zt = find_sub_by_id(zephyr,id);
 
 	if (zt) {
@@ -2518,7 +2526,7 @@
 
 static unsigned int zephyr_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state) {
 	gchar *recipient;
-	zephyr_account *zephyr = gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	if (use_tzc(zephyr))
 		return 0;
 
@@ -2560,7 +2568,7 @@
 	PurpleConversation *gconv;
 	PurpleConvChat *gcc;
 	gchar *topic_utf8;
-	zephyr_account* zephyr = gc->proto_data;
+	zephyr_account* zephyr = purple_connection_get_protocol_data(gc);
 	char *sender = (char *)zephyr->username;
 
 	zt = find_sub_by_id(zephyr,id);
@@ -2583,7 +2591,8 @@
 				      const char *cmd, char **args, char **error, void *data)
 {
 	char *recipient;
-	zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+	PurpleConnection *gc = purple_conversation_get_gc(conv);
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);;
 	if (!g_ascii_strcasecmp(args[0],"*"))
 		return PURPLE_CMD_RET_FAILED;  /* "*" is not a valid argument */
 	else
@@ -2635,7 +2644,8 @@
 				     const char *cmd, char **args, char **error, void *data)
 {
 	/* args = instance, message */
-	zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+	PurpleConnection *gc = purple_conversation_get_gc(conv);
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	if ( zephyr_send_message(zephyr,"message",args[0],"",args[1],zephyr_get_signature(),""))
 		return PURPLE_CMD_RET_OK;
 	else
@@ -2646,7 +2656,8 @@
 				      const char *cmd, char **args, char **error, void *data)
 {
 	/* args = class, instance, message */
-	zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+	PurpleConnection *gc = purple_conversation_get_gc(conv);
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	if ( zephyr_send_message(zephyr,args[0],args[1],"",args[2],zephyr_get_signature(),""))
 		return PURPLE_CMD_RET_OK;
 	else
@@ -2657,7 +2668,8 @@
 				       const char *cmd, char **args, char **error, void *data)
 {
 	/* args = class, instance, recipient, message */
-	zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+	PurpleConnection *gc = purple_conversation_get_gc(conv);
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	if ( zephyr_send_message(zephyr,args[0],args[1],args[2],args[3],zephyr_get_signature(),""))
 		return PURPLE_CMD_RET_OK;
 	else
@@ -2668,7 +2680,8 @@
 				      const char *cmd, char **args, char **error, void *data)
 {
 	/* args = instance, recipient, message */
-	zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+	PurpleConnection *gc = purple_conversation_get_gc(conv);
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	if ( zephyr_send_message(zephyr,"message",args[0],args[1],args[2],zephyr_get_signature(),""))
 		return PURPLE_CMD_RET_OK;
 	else
@@ -2679,7 +2692,8 @@
 				     const char *cmd, char **args, char **error, void *data)
 {
 	/* args = class, message */
-	zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+	PurpleConnection *gc = purple_conversation_get_gc(conv);
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	if ( zephyr_send_message(zephyr,args[0],"PERSONAL","",args[1],zephyr_get_signature(),""))
 		return PURPLE_CMD_RET_OK;
 	else
@@ -2760,7 +2774,7 @@
 {
 	/* Resubscribe to the in-memory list of subscriptions and also
 	   unsubscriptions*/
-	zephyr_account *zephyr = gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	GSList *s = zephyr->subscrips;
 	zephyr_triple *zt;
 	while (s) {
@@ -2785,7 +2799,7 @@
 static void zephyr_action_get_subs_from_server(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *) action->context;
-	zephyr_account *zephyr = gc->proto_data;
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	gchar *title;
 	int retval, nsubs, one,i;
 	ZSubscription_t subs;
@@ -2839,6 +2853,7 @@
 static PurplePlugin *my_protocol = NULL;
 
 static PurplePluginProtocolInfo prpl_info = {
+	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	OPT_PROTO_CHAT_TOPIC | OPT_PROTO_NO_PASSWORD,
 	NULL,					/* ??? user_splits */
 	NULL,					/* ??? protocol_options */
@@ -2905,15 +2920,12 @@
 	NULL,
 	NULL,
 	NULL,
-	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	NULL,					/* get_account_text_table */
 	NULL,					/* initate_media */
 	NULL,					/* get_media_caps */
 	NULL,					/* get_moods */
 	NULL,					/* set_public_alias */
-	NULL,					/* get_public_alias */
-	NULL,					/* add_buddy_with_invite */
-	NULL					/* add_buddies_with_invite */
+	NULL					/* get_public_alias */
 };
 
 static PurplePluginInfo info = {
--- a/libpurple/proxy.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/proxy.c	Sun Sep 11 04:19:01 2011 +0000
@@ -41,6 +41,16 @@
 #include "proxy.h"
 #include "util.h"
 
+struct _PurpleProxyInfo
+{
+	PurpleProxyType type;   /**< The proxy type.  */
+
+	char *host;           /**< The host.        */
+	int   port;           /**< The port number. */
+	char *username;       /**< The username.    */
+	char *password;       /**< The password.    */
+};
+
 struct _PurpleProxyConnectData {
 	void *handle;
 	PurpleProxyConnectFunction connect_cb;
@@ -1369,7 +1379,7 @@
 
 		proxy_do_write(connect_data, connect_data->fd, PURPLE_INPUT_WRITE);
 	} else {
-		connect_data->query_data = purple_dnsquery_a_account(
+		connect_data->query_data = purple_dnsquery_a(
 				connect_data->account, connect_data->host,
 				connect_data->port, s4_host_resolved, connect_data);
 
@@ -2088,7 +2098,7 @@
 
 /**
  * This function attempts to connect to the next IP address in the list
- * of IP addresses returned to us by purple_dnsquery_a() and attemps
+ * of IP addresses returned to us by purple_dnsquery_a() and attempts
  * to connect to each one.  This is called after the hostname is
  * resolved, and each time a connection attempt fails (assuming there
  * is another IP address to try).
@@ -2317,7 +2327,7 @@
 			return NULL;
 	}
 
-	connect_data->query_data = purple_dnsquery_a_account(account, connecthost,
+	connect_data->query_data = purple_dnsquery_a(account, connecthost,
 			connectport, connection_host_resolved, connect_data);
 	if (connect_data->query_data == NULL)
 	{
@@ -2385,7 +2395,7 @@
 			return NULL;
 	}
 
-	connect_data->query_data = purple_dnsquery_a_account(account, connecthost,
+	connect_data->query_data = purple_dnsquery_a(account, connecthost,
 			connectport, connection_host_resolved, connect_data);
 	if (connect_data->query_data == NULL)
 	{
--- a/libpurple/proxy.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/proxy.h	Sun Sep 11 04:19:01 2011 +0000
@@ -47,16 +47,7 @@
 /**
  * Information on proxy settings.
  */
-typedef struct
-{
-	PurpleProxyType type;   /**< The proxy type.  */
-
-	char *host;           /**< The host.        */
-	int   port;           /**< The port number. */
-	char *username;       /**< The username.    */
-	char *password;       /**< The password.    */
-
-} PurpleProxyInfo;
+typedef struct _PurpleProxyInfo PurpleProxyInfo;
 
 typedef struct _PurpleProxyConnectData PurpleProxyConnectData;
 
--- a/libpurple/prpl.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/prpl.c	Sun Sep 11 04:19:01 2011 +0000
@@ -32,6 +32,20 @@
 /**************************************************************************/
 /** @name Attention Type API                                              */
 /**************************************************************************/
+
+/** Represents "nudges" and "buzzes" that you may send to a buddy to attract
+ *  their attention (or vice-versa).
+ */
+struct _PurpleAttentionType
+{
+	const char *name;                  /**< Shown in GUI elements */
+	const char *incoming_description;  /**< Shown when sent */
+	const char *outgoing_description;  /**< Shown when receied */
+	const char *icon_name;             /**< Icon to display (optional) */
+	const char *unlocalized_name;      /**< Unlocalized name for UIs needing it */
+};
+
+
 PurpleAttentionType *
 purple_attention_type_new(const char *ulname, const char *name,
 						const char *inc_desc, const char *out_desc)
--- a/libpurple/prpl.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/prpl.h	Sun Sep 11 04:19:01 2011 +0000
@@ -111,23 +111,6 @@
 	gboolean secret;         /**< True if the entry is secret (password) */
 };
 
-/** Represents "nudges" and "buzzes" that you may send to a buddy to attract
- *  their attention (or vice-versa).
- */
-struct _PurpleAttentionType
-{
-	const char *name;                  /**< Shown in GUI elements */
-	const char *incoming_description;  /**< Shown when sent */
-	const char *outgoing_description;  /**< Shown when receied */
-	const char *icon_name;             /**< Icon to display (optional) */
-	const char *unlocalized_name;      /**< Unlocalized name for UIs needing it */
-
-	/* Reserved fields for future purposes */
-	gpointer _reserved2;
-	gpointer _reserved3;
-	gpointer _reserved4;
-};
-
 /**
  * Protocol options
  *
@@ -222,6 +205,27 @@
  */
 struct _PurplePluginProtocolInfo
 {
+	/**
+	 * The size of the PurplePluginProtocolInfo. This should always be sizeof(PurplePluginProtocolInfo).
+	 * This allows adding more functions to this struct without requiring a major version bump.
+	 */
+	unsigned long struct_size;
+
+	/* NOTE:
+	 * If more functions are added, they should accessed using the following syntax:
+	 *
+	 *		if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl, new_function))
+	 *			prpl->new_function(...);
+	 *
+	 * instead of
+	 *
+	 *		if (prpl->new_function != NULL)
+	 *			prpl->new_function(...);
+	 *
+	 * The PURPLE_PROTOCOL_PLUGIN_HAS_FUNC macro can be used for the older member
+	 * functions (e.g. login, send_im etc.) too.
+	 */
+
 	PurpleProtocolOptions options;  /**< Protocol options.          */
 
 	GList *user_splits;      /**< A GList of PurpleAccountUserSplit */
@@ -333,6 +337,7 @@
 	void (*set_idle)(PurpleConnection *, int idletime);
 	void (*change_passwd)(PurpleConnection *, const char *old_pass,
 						  const char *new_pass);
+
 	/**
 	 * Add a buddy to a group on the server.
 	 *
@@ -341,11 +346,10 @@
 	 * authorization and the user is not already authorized to see the
 	 * status of \a buddy, \a add_buddy should request authorization.
 	 *
-	 * @deprecated Since 2.8.0, add_buddy_with_invite is preferred.
-	 * @see add_buddy_with_invite
+	 * If authorization is required, then use the supplied invite message.
 	 */
-	void (*add_buddy)(PurpleConnection *, PurpleBuddy *buddy, PurpleGroup *group);
-	void (*add_buddies)(PurpleConnection *, GList *buddies, GList *groups);
+	void (*add_buddy)(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group, const char *message);
+	void (*add_buddies)(PurpleConnection *pc, GList *buddies, GList *groups, const char *message);
 	void (*remove_buddy)(PurpleConnection *, PurpleBuddy *buddy, PurpleGroup *group);
 	void (*remove_buddies)(PurpleConnection *, GList *buddies, GList *groups);
 	void (*add_permit)(PurpleConnection *, const char *name);
@@ -534,27 +538,6 @@
 	gboolean (*send_attention)(PurpleConnection *gc, const char *username, guint type);
 	GList *(*get_attention_types)(PurpleAccount *acct);
 
-	/**
-	 * The size of the PurplePluginProtocolInfo. This should always be sizeof(PurplePluginProtocolInfo).
-	 * This allows adding more functions to this struct without requiring a major version bump.
-	 */
-	unsigned long struct_size;
-
-	/* NOTE:
-	 * If more functions are added, they should accessed using the following syntax:
-	 *
-	 *		if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl, new_function))
-	 *			prpl->new_function(...);
-	 *
-	 * instead of
-	 *
-	 *		if (prpl->new_function != NULL)
-	 *			prpl->new_function(...);
-	 *
-	 * The PURPLE_PROTOCOL_PLUGIN_HAS_FUNC macro can be used for the older member
-	 * functions (e.g. login, send_im etc.) too.
-	 */
-
 	/** This allows protocols to specify additional strings to be used for
 	 * various purposes.  The idea is to stuff a bunch of strings in this hash
 	 * table instead of expanding the struct for every addition.  This hash
@@ -632,26 +615,10 @@
 	void (*get_public_alias)(PurpleConnection *gc,
 	                         PurpleGetPublicAliasSuccessCallback success_cb,
 	                         PurpleGetPublicAliasFailureCallback failure_cb);
-
-	/**
-	 * Add a buddy to a group on the server.
-	 *
-	 * This PRPL function may be called in situations in which the buddy is
-	 * already in the specified group. If the protocol supports
-	 * authorization and the user is not already authorized to see the
-	 * status of \a buddy, \a add_buddy should request authorization.
-	 *
-	 * If authorization is required, then use the supplied invite message.
-	 *
-	 * @since 2.8.0
-	 */
-	void (*add_buddy_with_invite)(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group, const char *message);
-	void (*add_buddies_with_invite)(PurpleConnection *pc, GList *buddies, GList *groups, const char *message);
 };
 
 #define PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl, member) \
-	(((G_STRUCT_OFFSET(PurplePluginProtocolInfo, member) < G_STRUCT_OFFSET(PurplePluginProtocolInfo, struct_size)) \
-	  || (G_STRUCT_OFFSET(PurplePluginProtocolInfo, member) < prpl->struct_size)) && \
+	(G_STRUCT_OFFSET(PurplePluginProtocolInfo, member) < prpl->struct_size && \
 	 prpl->member != NULL)
 
 
@@ -680,8 +647,8 @@
  *             should be the same string as @a ulname, with localization.
  * @param inc_desc A localized description shown when the event is received.
  * @param out_desc A localized description shown when the event is sent.
+ *
  * @return A pointer to the new object.
- * @since 2.4.0
  */
 PurpleAttentionType *purple_attention_type_new(const char *ulname, const char *name,
 								const char *inc_desc, const char *out_desc);
@@ -693,7 +660,6 @@
  * @param name The localized name that will be displayed by UIs. This should be
  *             the same string given as the unlocalized name, but with
  *             localization.
- * @since 2.4.0
  */
 void purple_attention_type_set_name(PurpleAttentionType *type, const char *name);
 
@@ -703,7 +669,6 @@
  *
  * @param type The attention type.
  * @param desc The localized description for incoming events.
- * @since 2.4.0
  */
 void purple_attention_type_set_incoming_desc(PurpleAttentionType *type, const char *desc);
 
@@ -713,7 +678,6 @@
  *
  * @param type The attention type.
  * @param desc The localized description for outgoing events.
- * @since 2.4.0
  */
 void purple_attention_type_set_outgoing_desc(PurpleAttentionType *type, const char *desc);
 
@@ -723,7 +687,6 @@
  * @param type The attention type.
  * @param name The icon's name.
  * @note Icons are optional for attention events.
- * @since 2.4.0
  */
 void purple_attention_type_set_icon_name(PurpleAttentionType *type, const char *name);
 
@@ -734,7 +697,6 @@
  * @param type The attention type.
  * @param ulname The unlocalized name.  This should be the same string given as
  *               the localized name, but without localization.
- * @since 2.4.0
  */
 void purple_attention_type_set_unlocalized_name(PurpleAttentionType *type, const char *ulname);
 
@@ -742,8 +704,8 @@
  * Get the attention type's name as displayed by the UI.
  *
  * @param type The attention type.
+ *
  * @return The name.
- * @since 2.4.0
  */
 const char *purple_attention_type_get_name(const PurpleAttentionType *type);
 
@@ -752,7 +714,6 @@
  *
  * @param type The attention type.
  * @return The description.
- * @since 2.4.0
  */
 const char *purple_attention_type_get_incoming_desc(const PurpleAttentionType *type);
 
@@ -761,7 +722,6 @@
  *
  * @param type The attention type.
  * @return The description.
- * @since 2.4.0
  */
 const char *purple_attention_type_get_outgoing_desc(const PurpleAttentionType *type);
 
@@ -771,7 +731,6 @@
  * @param type The attention type.
  * @return The icon name or @c NULL if unset/empty.
  * @note Icons are optional for attention events.
- * @since 2.4.0
  */
 const char *purple_attention_type_get_icon_name(const PurpleAttentionType *type);
 
@@ -780,7 +739,6 @@
  *
  * @param type The attention type
  * @return The unlocalized name.
- * @since 2.4.0
  */
 const char *purple_attention_type_get_unlocalized_name(const PurpleAttentionType *type);
 
--- a/libpurple/purple-2-uninstalled.pc.in	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-abs_srcdir=@abs_srcdir@
-abs_builddir=@abs_builddir@
-
-abs_top_srcdir=@abs_top_srcdir@
-abs_top_builddir=@abs_top_builddir@
-
-plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@
-
-Name: libpurple
-Description: libpurple is a GLib-based instant messenger library.
-Version: @VERSION@
-Requires: glib-2.0
-Cflags: -I${abs_top_srcdir} -I${abs_top_builddir}
-Libs: ${abs_builddir}/libpurple.la
--- a/libpurple/purple-2.pc.in	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@
-
-Name: libpurple
-Description: libpurple is a GLib-based instant messenger library.
-Version: @VERSION@
-Requires: glib-2.0
-Cflags: -I${includedir}
-Libs: -L${libdir} -lpurple
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purple-3-uninstalled.pc.in	Sun Sep 11 04:19:01 2011 +0000
@@ -0,0 +1,22 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@datarootdir@
+datadir=@datadir@
+sysconfdir=@sysconfdir@
+
+abs_srcdir=@abs_srcdir@
+abs_builddir=@abs_builddir@
+
+abs_top_srcdir=@abs_top_srcdir@
+abs_top_builddir=@abs_top_builddir@
+
+plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@
+
+Name: libpurple
+Description: libpurple is a GLib-based instant messenger library.
+Version: @VERSION@
+Requires: glib-2.0
+Cflags: -I${abs_top_srcdir} -I${abs_top_builddir}
+Libs: ${abs_builddir}/libpurple.la
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purple-3.pc.in	Sun Sep 11 04:19:01 2011 +0000
@@ -0,0 +1,16 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@datarootdir@
+datadir=@datadir@
+sysconfdir=@sysconfdir@
+
+plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@
+
+Name: libpurple
+Description: libpurple is a GLib-based instant messenger library.
+Version: @VERSION@
+Requires: glib-2.0
+Cflags: -I${includedir}
+Libs: -L${libdir} -lpurple
--- a/libpurple/purple-uninstalled.pc.in	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-abs_srcdir=@abs_srcdir@
-abs_builddir=@abs_builddir@
-
-plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@
-
-Name: libpurple
-Description: libpurple is a GLib-based instant messenger library.
-Version: @VERSION@
-Requires: glib-2.0
-Cflags: -I${abs_srcdir} -I${abs_builddir}
-Libs: ${abs_builddir}/libpurple.la
--- a/libpurple/purple.pc.in	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@
-
-Name: libpurple
-Description: libpurple is a GLib-based instant messenger library.
-Version: @VERSION@
-Requires: glib-2.0
-Cflags: -I${includedir}/libpurple
-Libs: -L${libdir} -lpurple
--- a/libpurple/request.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/request.c	Sun Sep 11 04:19:01 2011 +0000
@@ -42,6 +42,111 @@
 
 } PurpleRequestInfo;
 
+/**
+ * A request field.
+ */
+struct _PurpleRequestField
+{
+	PurpleRequestFieldType type;
+	PurpleRequestFieldGroup *group;
+
+	char *id;
+	char *label;
+	char *type_hint;
+
+	gboolean visible;
+	gboolean required;
+
+	union
+	{
+		struct
+		{
+			gboolean multiline;
+			gboolean masked;
+			gboolean editable;
+			char *default_value;
+			char *value;
+
+		} string;
+
+		struct
+		{
+			int default_value;
+			int value;
+
+		} integer;
+
+		struct
+		{
+			gboolean default_value;
+			gboolean value;
+
+		} boolean;
+
+		struct
+		{
+			int default_value;
+			int value;
+
+			GList *labels;
+
+		} choice;
+
+		struct
+		{
+			GList *items;
+			GList *icons;
+			GHashTable *item_data;
+			GList *selected;
+			GHashTable *selected_table;
+
+			gboolean multiple_selection;
+
+		} list;
+
+		struct
+		{
+			PurpleAccount *default_account;
+			PurpleAccount *account;
+			gboolean show_all;
+
+			PurpleFilterAccountFunc filter_func;
+
+		} account;
+
+		struct
+		{
+			unsigned int scale_x;
+			unsigned int scale_y;
+			const char *buffer;
+			gsize size;
+		} image;
+
+	} u;
+
+	void *ui_data;
+	char *tooltip;
+};
+
+struct _PurpleRequestFields
+{
+	GList *groups;
+
+	GHashTable *fields;
+
+	GList *required_fields;
+
+	void *ui_data;
+};
+
+struct _PurpleRequestFieldGroup
+{
+	PurpleRequestFields *fields_list;
+
+	char *title;
+
+	GList *fields;
+};
 
 PurpleRequestFields *
 purple_request_fields_new(void)
@@ -271,6 +376,20 @@
 	return purple_request_field_account_get_value(field);
 }
 
+gpointer purple_request_fields_get_ui_data(const PurpleRequestFields *fields)
+{
+	g_return_val_if_fail(fields != NULL, NULL);
+
+	return fields->ui_data;
+}
+
+void purple_request_fields_set_ui_data(PurpleRequestFields *fields, gpointer ui_data)
+{
+	g_return_if_fail(fields != NULL);
+
+	fields->ui_data = ui_data;
+}
+
 PurpleRequestFieldGroup *
 purple_request_field_group_new(const char *title)
 {
@@ -337,6 +456,14 @@
 	return group->fields;
 }
 
+PurpleRequestFields *
+purple_request_field_group_get_fields_list(const PurpleRequestFieldGroup *group)
+{
+	g_return_val_if_fail(group != NULL, NULL);
+
+	return group->fields_list;
+}
+
 PurpleRequestField *
 purple_request_field_new(const char *id, const char *text,
 					   PurpleRequestFieldType type)
@@ -365,6 +492,7 @@
 	g_free(field->id);
 	g_free(field->label);
 	g_free(field->type_hint);
+	g_free(field->tooltip);
 
 	if (field->type == PURPLE_REQUEST_FIELD_STRING)
 	{
@@ -428,6 +556,15 @@
 }
 
 void
+purple_request_field_set_tooltip(PurpleRequestField *field, const char *tooltip)
+{
+	g_return_if_fail(field != NULL);
+
+	g_free(field->tooltip);
+	field->tooltip = g_strdup(tooltip);
+}
+
+void
 purple_request_field_set_required(PurpleRequestField *field, gboolean required)
 {
 	g_return_if_fail(field != NULL);
@@ -502,6 +639,14 @@
 	return field->type_hint;
 }
 
+const char *
+purple_request_field_get_tooltip(const PurpleRequestField *field)
+{
+	g_return_val_if_fail(field != NULL, NULL);
+
+	return field->tooltip;
+}
+
 gboolean
 purple_request_field_is_required(const PurpleRequestField *field)
 {
--- a/libpurple/request.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/request.h	Sun Sep 11 04:19:01 2011 +0000
@@ -33,6 +33,16 @@
 /** @copydoc _PurpleRequestField */
 typedef struct _PurpleRequestField PurpleRequestField;
 
+/**
+ * Multiple fields request data.
+ */
+typedef struct _PurpleRequestFields PurpleRequestFields;
+
+/**
+ * A group of fields with a title.
+ */
+typedef struct _PurpleRequestFieldGroup PurpleRequestFieldGroup;
+
 #include "account.h"
 
 #define PURPLE_DEFAULT_ACTION_NONE	-1
@@ -69,122 +79,6 @@
 } PurpleRequestFieldType;
 
 /**
- * Multiple fields request data.
- */
-typedef struct
-{
-	GList *groups;
-
-	GHashTable *fields;
-
-	GList *required_fields;
-
-	void *ui_data;
-
-} PurpleRequestFields;
-
-/**
- * A group of fields with a title.
- */
-typedef struct
-{
-	PurpleRequestFields *fields_list;
-
-	char *title;
-
-	GList *fields;
-
-} PurpleRequestFieldGroup;
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_REQUEST_C_)
-/**
- * A request field.
- */
-struct _PurpleRequestField
-{
-	PurpleRequestFieldType type;
-	PurpleRequestFieldGroup *group;
-
-	char *id;
-	char *label;
-	char *type_hint;
-
-	gboolean visible;
-	gboolean required;
-
-	union
-	{
-		struct
-		{
-			gboolean multiline;
-			gboolean masked;
-			gboolean editable;
-			char *default_value;
-			char *value;
-
-		} string;
-
-		struct
-		{
-			int default_value;
-			int value;
-
-		} integer;
-
-		struct
-		{
-			gboolean default_value;
-			gboolean value;
-
-		} boolean;
-
-		struct
-		{
-			int default_value;
-			int value;
-
-			GList *labels;
-
-		} choice;
-
-		struct
-		{
-			GList *items;
-			GList *icons;
-			GHashTable *item_data;
-			GList *selected;
-			GHashTable *selected_table;
-
-			gboolean multiple_selection;
-
-		} list;
-
-		struct
-		{
-			PurpleAccount *default_account;
-			PurpleAccount *account;
-			gboolean show_all;
-
-			PurpleFilterAccountFunc filter_func;
-
-		} account;
-
-		struct
-		{
-			unsigned int scale_x;
-			unsigned int scale_y;
-			const char *buffer;
-			gsize size;
-		} image;
-
-	} u;
-
-	void *ui_data;
-
-};
-#endif
-
-/**
  * Request UI operations.
  */
 typedef struct
@@ -410,6 +304,25 @@
 PurpleAccount *purple_request_fields_get_account(const PurpleRequestFields *fields,
 											 const char *id);
 
+/**
+ * Returns the UI data associated with this object.
+ *
+ * @param fields The fields list.
+ *
+ * @return The UI data associated with this object.  This is a
+ *         convenience field provided to the UIs--it is not
+ *         used by the libuprple core.
+ */
+gpointer purple_request_fields_get_ui_data(const PurpleRequestFields *fields);
+
+/**
+ * Set the UI data associated with this object.
+ *
+ * @param fields The fields list.
+ * @param ui_data A pointer to associate with this object.
+ */
+void purple_request_fields_set_ui_data(PurpleRequestFields *fields, gpointer data);
+
 /*@}*/
 
 /**************************************************************************/
@@ -462,6 +375,16 @@
 GList *purple_request_field_group_get_fields(
 		const PurpleRequestFieldGroup *group);
 
+/**
+ * Returns a list of all fields in a group.
+ *
+ * @param group The group.
+ *
+ * @constreturn The list of fields in the group.
+ */
+PurpleRequestFields *purple_request_field_group_get_fields_list(
+		const PurpleRequestFieldGroup *group);
+
 /*@}*/
 
 /**************************************************************************/
@@ -517,6 +440,18 @@
 									  const char *type_hint);
 
 /**
+ * Sets the tooltip for the field.
+ *
+ * This is optionally used by the UIs to provide a tooltip for
+ * the field.
+ *
+ * @param field     The field.
+ * @param tooltip   The tooltip text.
+ */
+void purple_request_field_set_tooltip(PurpleRequestField *field,
+									const char *tooltip);
+
+/**
  * Sets whether or not a field is required.
  *
  * @param field    The field.
@@ -582,6 +517,15 @@
 const char *purple_request_field_get_type_hint(const PurpleRequestField *field);
 
 /**
+ * Returns the field's tooltip.
+ *
+ * @param field The field.
+ *
+ * @return The field's tooltip.
+ */
+const char *purple_request_field_get_tooltip(const PurpleRequestField *field);
+
+/**
  * Returns whether or not a field is required.
  *
  * @param field The field.
--- a/libpurple/roomlist.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/roomlist.c	Sun Sep 11 04:19:01 2011 +0000
@@ -32,6 +32,39 @@
 #include "roomlist.h"
 #include "server.h"
 
+/**
+ * Represents a list of rooms for a given connection on a given protocol.
+ */
+struct _PurpleRoomlist {
+	PurpleAccount *account; /**< The account this list belongs to. */
+	GList *fields; /**< The fields. */
+	GList *rooms; /**< The list of rooms. */
+	gboolean in_progress; /**< The listing is in progress. */
+	gpointer ui_data; /**< UI private data. */
+	gpointer proto_data; /** Prpl private data. */
+	guint ref; /**< The reference count. */
+};
+
+/**
+ * Represents a room.
+ */
+struct _PurpleRoomlistRoom {
+	PurpleRoomlistRoomType type; /**< The type of room. */
+	gchar *name; /**< The name of the room. */
+	GList *fields; /**< Other fields. */
+	PurpleRoomlistRoom *parent; /**< The parent room, or NULL. */
+	gboolean expanded_once; /**< A flag the UI uses to avoid multiple expand prpl cbs. */
+};
+
+/**
+ * A field a room might have.
+ */
+struct _PurpleRoomlistField {
+	PurpleRoomlistFieldType type; /**< The type of field. */
+	gchar *label; /**< The i18n user displayed name of the field. */
+	gchar *name; /**< The internal name of the field. */
+	gboolean hidden; /**< Hidden? */
+};
 
 static PurpleRoomlistUiOps *ops = NULL;
 
@@ -127,6 +160,13 @@
 		purple_roomlist_destroy(list);
 }
 
+PurpleAccount *purple_roomlist_get_account(PurpleRoomlist *list)
+{
+	g_return_val_if_fail(list != NULL, NULL);
+
+	return list->account;
+}
+
 void purple_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
 {
 	g_return_if_fail(list != NULL);
@@ -234,6 +274,34 @@
 	return list->fields;
 }
 
+gpointer purple_roomlist_get_proto_data(PurpleRoomlist *list)
+{
+	g_return_val_if_fail(list != NULL, NULL);
+
+	return list->proto_data;
+}
+
+void purple_roomlist_set_proto_data(PurpleRoomlist *list, gpointer proto_data)
+{
+	g_return_if_fail(list != NULL);
+
+	list->proto_data = proto_data;
+}
+
+gpointer purple_roomlist_get_ui_data(PurpleRoomlist *list)
+{
+	g_return_val_if_fail(list != NULL, NULL);
+
+	return list->ui_data;
+}
+
+void purple_roomlist_set_ui_data(PurpleRoomlist *list, gpointer ui_data)
+{
+	g_return_if_fail(list != NULL);
+
+	list->ui_data = ui_data;
+}
+
 /*@}*/
 
 /**************************************************************************/
@@ -329,7 +397,21 @@
 	return room->parent;
 }
 
-GList * purple_roomlist_room_get_fields(PurpleRoomlistRoom *room)
+gboolean purple_roomlist_room_get_expanded_once(PurpleRoomlistRoom *room)
+{
+	g_return_val_if_fail(room != NULL, FALSE);
+
+	return room->expanded_once;
+}
+
+void purple_roomlist_room_set_expanded_once(PurpleRoomlistRoom *room, gboolean expanded_once)
+{
+	g_return_if_fail(room != NULL);
+
+	room->expanded_once = expanded_once;
+}
+
+GList *purple_roomlist_room_get_fields(PurpleRoomlistRoom *room)
 {
 	return room->fields;
 }
--- a/libpurple/roomlist.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/roomlist.h	Sun Sep 11 04:19:01 2011 +0000
@@ -64,40 +64,6 @@
 /**************************************************************************/
 
 /**
- * Represents a list of rooms for a given connection on a given protocol.
- */
-struct _PurpleRoomlist {
-	PurpleAccount *account; /**< The account this list belongs to. */
-	GList *fields; /**< The fields. */
-	GList *rooms; /**< The list of rooms. */
-	gboolean in_progress; /**< The listing is in progress. */
-	gpointer ui_data; /**< UI private data. */
-	gpointer proto_data; /** Prpl private data. */
-	guint ref; /**< The reference count. */
-};
-
-/**
- * Represents a room.
- */
-struct _PurpleRoomlistRoom {
-	PurpleRoomlistRoomType type; /**< The type of room. */
-	gchar *name; /**< The name of the room. */
-	GList *fields; /**< Other fields. */
-	PurpleRoomlistRoom *parent; /**< The parent room, or NULL. */
-	gboolean expanded_once; /**< A flag the UI uses to avoid multiple expand prpl cbs. */
-};
-
-/**
- * A field a room might have.
- */
-struct _PurpleRoomlistField {
-	PurpleRoomlistFieldType type; /**< The type of field. */
-	gchar *label; /**< The i18n user displayed name of the field. */
-	gchar *name; /**< The internal name of the field. */
-	gboolean hidden; /**< Hidden? */
-};
-
-/**
  * The room list ops to be filled out by the UI.
  */
 struct _PurpleRoomlistUiOps {
@@ -163,6 +129,14 @@
 void purple_roomlist_unref(PurpleRoomlist *list);
 
 /**
+ * Retrieve the PurpleAccount that was given when the room list was
+ * created.
+ *
+ * @return The PurpleAccount tied to this room list.
+ */
+PurpleAccount *purple_roomlist_get_account(PurpleRoomlist *list);
+
+/**
  * Set the different field types and their names for this protocol.
  *
  * This must be called before purple_roomlist_room_add().
@@ -241,11 +215,49 @@
 /**
  * Get the list of fields for a roomlist.
  *
- * @param roomlist  The roomlist, which must not be @c NULL.
+ * @param roomlist The roomlist, which must not be @c NULL.
  * @constreturn A list of fields
  * @since 2.4.0
  */
-GList * purple_roomlist_get_fields(PurpleRoomlist *roomlist);
+GList *purple_roomlist_get_fields(PurpleRoomlist *roomlist);
+
+/**
+ * Get the protocol data associated with this room list.
+ *
+ * @param roomlist The roomlist, which must not be @c NULL.
+ *
+ * @return The protocol data associated with this room list.  This is a
+ *         convenience field provided to the protocol plugin--it is not
+ *         used the libpurple core.
+ */
+gpointer purple_roomlist_get_proto_data(PurpleRoomlist *list);
+
+/**
+ * Set the protocol data associated with this room list.
+ *
+ * @param list The roomlist, which must not be @c NULL.
+ * @param proto_data A pointer to associate with this room list.
+ */
+void purple_roomlist_set_proto_data(PurpleRoomlist *list, gpointer proto_data);
+
+/**
+ * Get the UI data associated with this room list.
+ *
+ * @param roomlist The roomlist, which must not be @c NULL.
+ *
+ * @return The UI data associated with this room list.  This is a
+ *         convenience field provided to the UIs--it is not
+ *         used by the libpurple core.
+ */
+gpointer purple_roomlist_get_ui_data(PurpleRoomlist *list);
+
+/**
+ * Set the UI data associated with this room list.
+ *
+ * @param list The roomlist, which must not be @c NULL.
+ * @param UI_data A pointer to associate with this room list.
+ */
+void purple_roomlist_set_ui_data(PurpleRoomlist *list, gpointer ui_data);
 
 /*@}*/
 
@@ -308,6 +320,23 @@
 PurpleRoomlistRoom * purple_roomlist_room_get_parent(PurpleRoomlistRoom *room);
 
 /**
+ * Get the value of the expanded_once flag.
+ *
+ * @param room  The room, which must not be @c NULL.
+ *
+ * @return The value of the expanded_once flag.
+ */
+gboolean purple_roomlist_room_get_expanded_once(PurpleRoomlistRoom *room);
+
+/**
+ * Set the expanded_once flag.
+ *
+ * @param room The room, which must not be @c NULL.
+ * @param expanded_once The new value of the expanded_once flag.
+ */
+void purple_roomlist_room_set_expanded_once(PurpleRoomlistRoom *room, gboolean expanded_once);
+
+/**
  * Get the list of fields for a room.
  *
  * @param room  The room, which must not be @c NULL.
--- a/libpurple/savedstatuses.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/savedstatuses.c	Sun Sep 11 04:19:01 2011 +0000
@@ -387,7 +387,6 @@
 		const char *protocol;
 		acct_name = xmlnode_get_data(node);
 		protocol = xmlnode_get_attrib(node, "protocol");
-		protocol = _purple_oscar_convert(acct_name, protocol); /* XXX: Remove */
 		if ((acct_name != NULL) && (protocol != NULL))
 			ret->account = purple_accounts_find(acct_name, protocol);
 		g_free(acct_name);
--- a/libpurple/server.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/server.c	Sun Sep 11 04:19:01 2011 +0000
@@ -325,18 +325,6 @@
 	return attn;
 }
 
-void
-serv_send_attention(PurpleConnection *gc, const char *who, guint type_code)
-{
-	purple_prpl_send_attention(gc, who, type_code);
-}
-
-void
-serv_got_attention(PurpleConnection *gc, const char *who, guint type_code)
-{
-	purple_prpl_got_attention(gc, who, type_code);
-}
-
 
 /*
  * Move a buddy from one group to another on server.
--- a/libpurple/server.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/server.h	Sun Sep 11 04:19:01 2011 +0000
@@ -61,32 +61,6 @@
  */
 PurpleAttentionType *purple_get_attention_type_from_code(PurpleAccount *account, guint type_code);
 
-/** Send an attention request message.
- *
- * @deprecated Use purple_prpl_send_attention() instead.
- *
- * @param gc The connection to send the message on.
- * @param who Whose attention to request.
- * @param type_code An index into the prpl's attention_types list determining the type
- * 	of the attention request command to send. 0 if prpl only defines one
- * 	(for example, Yahoo and MSN), but some protocols define more (MySpaceIM).
- *
- * Note that you can't send arbitrary PurpleAttentionType's, because there is
- * only a fixed set of attention commands.
- */
-void serv_send_attention(PurpleConnection *gc, const char *who, guint type_code);
-
-/** Process an incoming attention message.
- *
- * @deprecated Use purple_prpl_got_attention() instead.
- *
- * @param gc The connection that received the attention message.
- * @param who Who requested your attention.
- * @param type_code An index into the prpl's attention_types list determining the type
- * 	of the attention request command to send.
- */
-void serv_got_attention(PurpleConnection *gc, const char *who, guint type_code);
-
 void serv_get_info(PurpleConnection *, const char *);
 void serv_set_info(PurpleConnection *, const char *);
 
--- a/libpurple/sound.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/sound.h	Sun Sep 11 04:19:01 2011 +0000
@@ -38,7 +38,7 @@
  * A type of sound.
  */
 
-typedef enum _PurpleSoundEventID
+typedef enum
 {
 	PURPLE_SOUND_BUDDY_ARRIVE = 0, /**< Buddy signs on.                       */
 	PURPLE_SOUND_BUDDY_LEAVE,      /**< Buddy signs off.                      */
--- a/libpurple/status.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/status.c	Sun Sep 11 04:19:01 2011 +0000
@@ -44,7 +44,6 @@
 
 	char *id;
 	char *name;
-	char *primary_attr_id;
 
 	gboolean saveable;
 	gboolean user_settable;
@@ -258,6 +257,42 @@
 			user_settable, FALSE);
 }
 
+static void
+status_type_add_attr(PurpleStatusType *status_type, const char *id,
+		const char *name, PurpleValue *value)
+{
+	PurpleStatusAttr *attr;
+
+	g_return_if_fail(status_type != NULL);
+	g_return_if_fail(id          != NULL);
+	g_return_if_fail(name        != NULL);
+	g_return_if_fail(value       != NULL);
+
+	attr = purple_status_attr_new(id, name, value);
+
+	status_type->attrs = g_list_append(status_type->attrs, attr);
+}
+
+static void
+status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args)
+{
+	const char *id, *name;
+	PurpleValue *value;
+
+	g_return_if_fail(status_type != NULL);
+
+	while ((id = va_arg(args, const char *)) != NULL)
+	{
+		name = va_arg(args, const char *);
+		g_return_if_fail(name != NULL);
+
+		value = va_arg(args, PurpleValue *);
+		g_return_if_fail(value != NULL);
+
+		status_type_add_attr(status_type, id, name, value);
+	}
+}
+
 PurpleStatusType *
 purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive,
 		const char *id, const char *name,
@@ -278,10 +313,10 @@
 			user_settable, independent);
 
 	/* Add the first attribute */
-	purple_status_type_add_attr(status_type, attr_id, attr_name, attr_value);
+	status_type_add_attr(status_type, attr_id, attr_name, attr_value);
 
 	va_start(args, attr_value);
-	purple_status_type_add_attrs_vargs(status_type, args);
+	status_type_add_attrs_vargs(status_type, args);
 	va_end(args);
 
 	return status_type;
@@ -294,7 +329,6 @@
 
 	g_free(status_type->id);
 	g_free(status_type->name);
-	g_free(status_type->primary_attr_id);
 
 	g_list_foreach(status_type->attrs, (GFunc)purple_status_attr_destroy, NULL);
 	g_list_free(status_type->attrs);
@@ -303,70 +337,6 @@
 	g_free(status_type);
 }
 
-void
-purple_status_type_set_primary_attr(PurpleStatusType *status_type, const char *id)
-{
-	g_return_if_fail(status_type != NULL);
-
-	g_free(status_type->primary_attr_id);
-	status_type->primary_attr_id = g_strdup(id);
-}
-
-void
-purple_status_type_add_attr(PurpleStatusType *status_type, const char *id,
-		const char *name, PurpleValue *value)
-{
-	PurpleStatusAttr *attr;
-
-	g_return_if_fail(status_type != NULL);
-	g_return_if_fail(id          != NULL);
-	g_return_if_fail(name        != NULL);
-	g_return_if_fail(value       != NULL);
-
-	attr = purple_status_attr_new(id, name, value);
-
-	status_type->attrs = g_list_append(status_type->attrs, attr);
-}
-
-void
-purple_status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args)
-{
-	const char *id, *name;
-	PurpleValue *value;
-
-	g_return_if_fail(status_type != NULL);
-
-	while ((id = va_arg(args, const char *)) != NULL)
-	{
-		name = va_arg(args, const char *);
-		g_return_if_fail(name != NULL);
-
-		value = va_arg(args, PurpleValue *);
-		g_return_if_fail(value != NULL);
-
-		purple_status_type_add_attr(status_type, id, name, value);
-	}
-}
-
-void
-purple_status_type_add_attrs(PurpleStatusType *status_type, const char *id,
-		const char *name, PurpleValue *value, ...)
-{
-	va_list args;
-
-	g_return_if_fail(status_type != NULL);
-	g_return_if_fail(id          != NULL);
-	g_return_if_fail(name        != NULL);
-	g_return_if_fail(value       != NULL);
-
-	/* Add the first attribute */
-	purple_status_type_add_attr(status_type, id, name, value);
-
-	va_start(args, value);
-	purple_status_type_add_attrs_vargs(status_type, args);
-	va_end(args);
-}
-
 PurpleStatusPrimitive
 purple_status_type_get_primitive(const PurpleStatusType *status_type)
 {
@@ -435,14 +405,6 @@
 	return (primitive == PURPLE_STATUS_AVAILABLE);
 }
 
-const char *
-purple_status_type_get_primary_attr(const PurpleStatusType *status_type)
-{
-	g_return_val_if_fail(status_type != NULL, NULL);
-
-	return status_type->primary_attr_id;
-}
-
 PurpleStatusAttr *
 purple_status_type_get_attr(const PurpleStatusType *status_type, const char *id)
 {
@@ -706,6 +668,68 @@
 	notify_status_update(presence, old_status, status);
 }
 
+static void
+status_set_attr_boolean(PurpleStatus *status, const char *id,
+		gboolean value)
+{
+	PurpleValue *attr_value;
+
+	g_return_if_fail(status != NULL);
+	g_return_if_fail(id     != NULL);
+
+	/* Make sure this attribute exists and is the correct type. */
+	attr_value = purple_status_get_attr_value(status, id);
+	g_return_if_fail(attr_value != NULL);
+	g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_BOOLEAN);
+
+	purple_value_set_boolean(attr_value, value);
+}
+
+static void
+status_set_attr_int(PurpleStatus *status, const char *id, int value)
+{
+	PurpleValue *attr_value;
+
+	g_return_if_fail(status != NULL);
+	g_return_if_fail(id     != NULL);
+
+	/* Make sure this attribute exists and is the correct type. */
+	attr_value = purple_status_get_attr_value(status, id);
+	g_return_if_fail(attr_value != NULL);
+	g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_INT);
+
+	purple_value_set_int(attr_value, value);
+}
+
+static void
+status_set_attr_string(PurpleStatus *status, const char *id,
+		const char *value)
+{
+	PurpleValue *attr_value;
+
+	g_return_if_fail(status != NULL);
+	g_return_if_fail(id     != NULL);
+
+	/* Make sure this attribute exists and is the correct type. */
+	attr_value = purple_status_get_attr_value(status, id);
+	/* This used to be g_return_if_fail, but it's failing a LOT, so
+	 * let's generate a log error for now. */
+	/* g_return_if_fail(attr_value != NULL); */
+	if (attr_value == NULL) {
+		purple_debug_error("status",
+				 "Attempted to set status attribute '%s' for "
+				 "status '%s', which is not legal.  Fix "
+                                 "this!\n", id,
+				 purple_status_type_get_name(purple_status_get_type(status)));
+		return;
+	}
+	g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_STRING);
+
+	/* XXX: Check if the value has actually changed. If it has, and the status
+	 * is active, should this trigger 'status_has_changed'? */
+	purple_value_set_string(attr_value, value);
+}
+
 void
 purple_status_set_active(PurpleStatus *status, gboolean active)
 {
@@ -782,31 +806,31 @@
 
 		specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id);
 
-		if (value->type == PURPLE_TYPE_STRING)
+		if (purple_value_get_type(value) == PURPLE_TYPE_STRING)
 		{
 			const gchar *string_data = l->data;
 			l = l->next;
-			if (purple_strequal(string_data, value->data.string_data))
+			if (purple_strequal(string_data, purple_value_get_string(value)))
 				continue;
-			purple_status_set_attr_string(status, id, string_data);
+			status_set_attr_string(status, id, string_data);
 			changed = TRUE;
 		}
-		else if (value->type == PURPLE_TYPE_INT)
+		else if (purple_value_get_type(value) == PURPLE_TYPE_INT)
 		{
 			int int_data = GPOINTER_TO_INT(l->data);
 			l = l->next;
-			if (int_data == value->data.int_data)
+			if (int_data == purple_value_get_int(value))
 				continue;
-			purple_status_set_attr_int(status, id, int_data);
+			status_set_attr_int(status, id, int_data);
 			changed = TRUE;
 		}
-		else if (value->type == PURPLE_TYPE_BOOLEAN)
+		else if (purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN)
 		{
 			gboolean boolean_data = GPOINTER_TO_INT(l->data);
 			l = l->next;
-			if (boolean_data == value->data.boolean_data)
+			if (boolean_data == purple_value_get_boolean(value))
 				continue;
-			purple_status_set_attr_boolean(status, id, boolean_data);
+			status_set_attr_boolean(status, id, boolean_data);
 			changed = TRUE;
 		}
 		else
@@ -828,7 +852,7 @@
 		if (!g_list_find_custom(specified_attr_ids, attr->id, (GCompareFunc)strcmp)) {
 			PurpleValue *default_value;
 			default_value = purple_status_attr_get_value(attr);
-			if (default_value->type == PURPLE_TYPE_STRING) {
+			if (purple_value_get_type(default_value) == PURPLE_TYPE_STRING) {
 				const char *cur = purple_status_get_attr_string(status, attr->id);
 				const char *def = purple_value_get_string(default_value);
 				if ((cur == NULL && def == NULL)
@@ -837,21 +861,21 @@
 					continue;
 				}
 
-				purple_status_set_attr_string(status, attr->id, def);
-			} else if (default_value->type == PURPLE_TYPE_INT) {
+				status_set_attr_string(status, attr->id, def);
+			} else if (purple_value_get_type(default_value) == PURPLE_TYPE_INT) {
 				int cur = purple_status_get_attr_int(status, attr->id);
 				int def = purple_value_get_int(default_value);
 				if (cur == def)
 					continue;
 
-				purple_status_set_attr_int(status, attr->id, def);
-			} else if (default_value->type == PURPLE_TYPE_BOOLEAN) {
+				status_set_attr_int(status, attr->id, def);
+			} else if (purple_value_get_type(default_value) == PURPLE_TYPE_BOOLEAN) {
 				gboolean cur = purple_status_get_attr_boolean(status, attr->id);
 				gboolean def = purple_value_get_boolean(default_value);
 				if (cur == def)
 					continue;
 
-				purple_status_set_attr_boolean(status, attr->id, def);
+				status_set_attr_boolean(status, attr->id, def);
 			}
 			changed = TRUE;
 		}
@@ -863,68 +887,6 @@
 	status_has_changed(status);
 }
 
-void
-purple_status_set_attr_boolean(PurpleStatus *status, const char *id,
-		gboolean value)
-{
-	PurpleValue *attr_value;
-
-	g_return_if_fail(status != NULL);
-	g_return_if_fail(id     != NULL);
-
-	/* Make sure this attribute exists and is the correct type. */
-	attr_value = purple_status_get_attr_value(status, id);
-	g_return_if_fail(attr_value != NULL);
-	g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_BOOLEAN);
-
-	purple_value_set_boolean(attr_value, value);
-}
-
-void
-purple_status_set_attr_int(PurpleStatus *status, const char *id, int value)
-{
-	PurpleValue *attr_value;
-
-	g_return_if_fail(status != NULL);
-	g_return_if_fail(id     != NULL);
-
-	/* Make sure this attribute exists and is the correct type. */
-	attr_value = purple_status_get_attr_value(status, id);
-	g_return_if_fail(attr_value != NULL);
-	g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_INT);
-
-	purple_value_set_int(attr_value, value);
-}
-
-void
-purple_status_set_attr_string(PurpleStatus *status, const char *id,
-		const char *value)
-{
-	PurpleValue *attr_value;
-
-	g_return_if_fail(status != NULL);
-	g_return_if_fail(id     != NULL);
-
-	/* Make sure this attribute exists and is the correct type. */
-	attr_value = purple_status_get_attr_value(status, id);
-	/* This used to be g_return_if_fail, but it's failing a LOT, so
-	 * let's generate a log error for now. */
-	/* g_return_if_fail(attr_value != NULL); */
-	if (attr_value == NULL) {
-		purple_debug_error("status",
-				 "Attempted to set status attribute '%s' for "
-				 "status '%s', which is not legal.  Fix "
-                                 "this!\n", id,
-				 purple_status_type_get_name(purple_status_get_type(status)));
-		return;
-	}
-	g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_STRING);
-
-	/* XXX: Check if the value has actually changed. If it has, and the status
-	 * is active, should this trigger 'status_has_changed'? */
-	purple_value_set_string(attr_value, value);
-}
-
 PurpleStatusType *
 purple_status_get_type(const PurpleStatus *status)
 {
@@ -1186,30 +1148,6 @@
 }
 
 void
-purple_presence_add_status(PurplePresence *presence, PurpleStatus *status)
-{
-	g_return_if_fail(presence != NULL);
-	g_return_if_fail(status   != NULL);
-
-	presence->statuses = g_list_append(presence->statuses, status);
-
-	g_hash_table_insert(presence->status_table,
-	g_strdup(purple_status_get_id(status)), status);
-}
-
-void
-purple_presence_add_list(PurplePresence *presence, GList *source_list)
-{
-	GList *l;
-
-	g_return_if_fail(presence    != NULL);
-	g_return_if_fail(source_list != NULL);
-
-	for (l = source_list; l != NULL; l = l->next)
-		purple_presence_add_status(presence, (PurpleStatus *)l->data);
-}
-
-void
 purple_presence_set_status_active(PurplePresence *presence, const char *status_id,
 		gboolean active)
 {
--- a/libpurple/status.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/status.h	Sun Sep 11 04:19:01 2011 +0000
@@ -271,73 +271,6 @@
  */
 void purple_status_type_destroy(PurpleStatusType *status_type);
 
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Sets a status type's primary attribute.
- *
- * The value for the primary attribute is used as the description for
- * the particular status type. An example is an away message. The message
- * would be the primary attribute.
- *
- * @param status_type The status type.
- * @param attr_id     The ID of the primary attribute.
- *
- * @deprecated This function isn't used and should be removed in 3.0.0.
- */
-void purple_status_type_set_primary_attr(PurpleStatusType *status_type,
-									   const char *attr_id);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Adds an attribute to a status type.
- *
- * @param status_type The status type to add the attribute to.
- * @param id          The ID of the attribute.
- * @param name        The name presented to the user.
- * @param value       The value type of this attribute.
- *
- * @deprecated This function isn't needed and should be removed in 3.0.0.
- *             Status type attributes should be set when the status type
- *             is created, in the call to purple_status_type_new_with_attrs.
- */
-void purple_status_type_add_attr(PurpleStatusType *status_type, const char *id,
-							   const char *name, PurpleValue *value);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Adds multiple attributes to a status type.
- *
- * @param status_type The status type to add the attribute to.
- * @param id          The ID of the first attribute.
- * @param name        The description of the first attribute.
- * @param value       The value type of the first attribute attribute.
- * @param ...         Additional attribute information.
- *
- * @deprecated This function isn't needed and should be removed in 3.0.0.
- *             Status type attributes should be set when the status type
- *             is created, in the call to purple_status_type_new_with_attrs.
- */
-void purple_status_type_add_attrs(PurpleStatusType *status_type, const char *id,
-								const char *name, PurpleValue *value, ...) G_GNUC_NULL_TERMINATED;
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Adds multiple attributes to a status type using a va_list.
- *
- * @param status_type The status type to add the attribute to.
- * @param args        The va_list of attributes.
- *
- * @deprecated This function isn't needed and should be removed in 3.0.0.
- *             Status type attributes should be set when the status type
- *             is created, in the call to purple_status_type_new_with_attrs.
- */
-void purple_status_type_add_attrs_vargs(PurpleStatusType *status_type,
-									  va_list args);
-#endif
-
 /**
  * Returns the primitive type of a status type.
  *
@@ -419,19 +352,6 @@
  */
 gboolean purple_status_type_is_available(const PurpleStatusType *status_type);
 
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Returns a status type's primary attribute ID.
- *
- * @param type The status type.
- *
- * @return The primary attribute's ID.
- *
- * @deprecated This function isn't used and should be removed in 3.0.0.
- */
-const char *purple_status_type_get_primary_attr(const PurpleStatusType *type);
-#endif
-
 /**
  * Returns the attribute with the specified ID.
  *
@@ -582,51 +502,6 @@
 void purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
 											GList *attrs);
 
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Sets the boolean value of an attribute in a status with the specified ID.
- *
- * @param status The status.
- * @param id     The attribute ID.
- * @param value  The boolean value.
- *
- * @deprecated This function is only used by status.c and should be made
- *             static in 3.0.0.
- */
-void purple_status_set_attr_boolean(PurpleStatus *status, const char *id,
-								  gboolean value);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Sets the integer value of an attribute in a status with the specified ID.
- *
- * @param status The status.
- * @param id     The attribute ID.
- * @param value  The integer value.
- *
- * @deprecated This function is only used by status.c and should be made
- *             static in 3.0.0.
- */
-void purple_status_set_attr_int(PurpleStatus *status, const char *id,
-							  int value);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Sets the string value of an attribute in a status with the specified ID.
- *
- * @param status The status.
- * @param id     The attribute ID.
- * @param value  The string value.
- *
- * @deprecated This function is only used by status.c and should be made
- *             static in 3.0.0.
- */
-void purple_status_set_attr_string(PurpleStatus *status, const char *id,
-								 const char *value);
-#endif
-
 /**
  * Returns the status's type.
  *
@@ -833,32 +708,6 @@
  */
 void purple_presence_destroy(PurplePresence *presence);
 
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Adds a status to a presence.
- *
- * @param presence The presence.
- * @param status   The status to add.
- *
- * @deprecated This function is only used by purple_presence_add_list,
- *             and both should be removed in 3.0.0.
- */
-void purple_presence_add_status(PurplePresence *presence, PurpleStatus *status);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Adds a list of statuses to the presence.
- *
- * @param presence    The presence.
- * @param source_list The source list of statuses to add, which is not
- *                    modified or freed by this function.
- *
- * @deprecated This function isn't used and should be removed in 3.0.0.
- */
-void purple_presence_add_list(PurplePresence *presence, GList *source_list);
-#endif
-
 /**
  * Sets the active state of a status in a presence.
  *
--- a/libpurple/stun.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/stun.c	Sun Sep 11 04:19:01 2011 +0000
@@ -365,7 +365,7 @@
 	purple_debug_info("stun", "got %d SRV responses, server: %s, port: %d\n",
 		results, servername, port);
 
-	purple_dnsquery_a_account(NULL, servername, port, hbn_cb, NULL);
+	purple_dnsquery_a(NULL, servername, port, hbn_cb, NULL);
 	g_free(resp);
 }
 
@@ -424,7 +424,7 @@
 	nattype.servername = g_strdup(servername);
 
 	callbacks = g_slist_append(callbacks, cb);
-	purple_srv_resolve_account(NULL, "stun", "udp", servername, do_test1,
+	purple_srv_resolve(NULL, "stun", "udp", servername, do_test1,
 		(gpointer) servername);
 
 	return &nattype;
--- a/libpurple/tests/test_xmlnode.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/tests/test_xmlnode.c	Sun Sep 11 04:19:01 2011 +0000
@@ -21,6 +21,101 @@
 }
 END_TEST
 
+#define check_doc_structure(x) { \
+	xmlnode *ping, *child1, *child2; \
+	fail_if(x == NULL, "Failed to parse document"); \
+	ping = xmlnode_get_child(x, "ping"); \
+	fail_if(ping == NULL, "Failed to find 'ping' child"); \
+	child1 = xmlnode_get_child(ping, "child1"); \
+	fail_if(child1 == NULL, "Failed to find 'child1'"); \
+	child2 = xmlnode_get_child(child1, "child2"); \
+	fail_if(child2 == NULL, "Failed to find 'child2'"); \
+	xmlnode_new_child(child2, "a"); \
+	\
+	assert_string_equal("jabber:client", xmlnode_get_namespace(x)); \
+	/* NOTE: xmlnode_get_namespace() returns the namespace of the element, not the
+	 * current default namespace.  See http://www.w3.org/TR/xml-names/#defaulting and
+	 * http://www.w3.org/TR/xml-names/#dt-defaultNS.
+	 */ \
+	assert_string_equal("urn:xmpp:ping", xmlnode_get_namespace(ping)); \
+	assert_string_equal("jabber:client", xmlnode_get_namespace(child1)); \
+	assert_string_equal("urn:xmpp:ping", xmlnode_get_namespace(child2)); \
+	/*
+	 * This fails (well, actually crashes [the ns is NULL]) unless
+	 * xmlnode_new_child() actually sets the element namespace.
+	assert_string_equal("jabber:client", xmlnode_get_namespace(xmlnode_get_child(child2, "a")));
+	 */ \
+	\
+	assert_string_equal("jabber:client", xmlnode_get_default_namespace(x)); \
+	assert_string_equal("jabber:client", xmlnode_get_default_namespace(ping)); \
+	assert_string_equal("jabber:client", xmlnode_get_default_namespace(child1)); \
+	assert_string_equal("jabber:client", xmlnode_get_default_namespace(child2)); \
+}
+
+START_TEST(test_xmlnode_prefixes)
+{
+	const char *xml_doc =
+		"<iq type='get' xmlns='jabber:client' xmlns:ping='urn:xmpp:ping'>"
+			"<ping:ping>"
+				"<child1>"
+					"<ping:child2></ping:child2>" /* xmlns='jabber:child' */
+				"</child1>"
+			"</ping:ping>"
+		"</iq>";
+	char *str;
+	xmlnode *xml, *reparsed;
+
+	xml = xmlnode_from_str(xml_doc, -1);
+	check_doc_structure(xml);
+
+	/* Check that xmlnode_from_str(xmlnode_to_str(xml, NULL), -1) is idempotent. */
+	str = xmlnode_to_str(xml, NULL);
+	fail_if(str == NULL, "Failed to serialize XMLnode");
+	reparsed = xmlnode_from_str(str, -1);
+	fail_if(reparsed == NULL, "Failed to reparse xml document");
+	check_doc_structure(reparsed);
+
+	g_free(str);
+	xmlnode_free(xml);
+	xmlnode_free(reparsed);
+}
+END_TEST
+
+
+START_TEST(test_strip_prefixes)
+{
+	const char *xml_doc = "<message xmlns='jabber:client' from='user@gmail.com/resource' to='another_user@darkrain42.org' type='chat' id='purple'>"
+		"<cha:active xmlns:cha='http://jabber.org/protocol/chatstates'/>"
+		"<body>xvlc xvlc</body>"
+		"<im:html xmlns:im='http://jabber.org/protocol/xhtml-im'>"
+			"<xht:body xmlns:xht='http://www.w3.org/1999/xhtml'>"
+				"<xht:p>xvlc <xht:span style='font-weight: bold;'>xvlc</xht:span></xht:p>"
+			"</xht:body>"
+		"</im:html>"
+	"</message>";
+	const char *out = "<message xmlns='jabber:client' from='user@gmail.com/resource' to='another_user@darkrain42.org' type='chat' id='purple'>"
+		"<active xmlns:cha='http://jabber.org/protocol/chatstates' xmlns='http://jabber.org/protocol/chatstates'/>"
+		"<body>xvlc xvlc</body>"
+		"<html xmlns:im='http://jabber.org/protocol/xhtml-im' xmlns='http://jabber.org/protocol/xhtml-im'>"
+			"<body xmlns:xht='http://www.w3.org/1999/xhtml' xmlns='http://www.w3.org/1999/xhtml'>"
+				"<p>xvlc <span style='font-weight: bold;'>xvlc</span></p>"
+			"</body>"
+		"</html>"
+	"</message>";
+	char *str;
+	xmlnode *xml;
+
+	xml = xmlnode_from_str(xml_doc, -1);
+	fail_if(xml == NULL, "Failed to parse XML");
+
+	xmlnode_strip_prefixes(xml);
+	str = xmlnode_to_str(xml, NULL);
+	assert_string_equal_free(out, str);
+
+	xmlnode_free(xml);
+}
+END_TEST
+
 Suite *
 xmlnode_suite(void)
 {
@@ -28,6 +123,9 @@
 
 	TCase *tc = tcase_create("xmlnode");
 	tcase_add_test(tc, test_xmlnode_billion_laughs_attack);
+	tcase_add_test(tc, test_xmlnode_prefixes);
+	tcase_add_test(tc, test_strip_prefixes);
+
 	suite_add_tcase(s, tc);
 
 	return s;
--- a/libpurple/upnp.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/upnp.c	Sun Sep 11 04:19:01 2011 +0000
@@ -464,7 +464,7 @@
 	purple_timeout_remove(dd->tima);
 	dd->tima = 0;
 
-	purple_util_fetch_url_request_len(descriptionURL, TRUE, NULL, TRUE, httpRequest,
+	purple_util_fetch_url_request_len(NULL, descriptionURL, TRUE, NULL, TRUE, httpRequest,
 			TRUE, MAX_UPNP_DOWNLOAD, upnp_parse_description_cb, dd);
 
 	g_free(httpRequest);
@@ -730,7 +730,7 @@
 	g_free(pathOfControl);
 	g_free(soapMessage);
 
-	gfud = purple_util_fetch_url_request_len(control_info.control_url, FALSE, NULL, TRUE,
+	gfud = purple_util_fetch_url_request_len(NULL, control_info.control_url, FALSE, NULL, TRUE,
 				totalSendMessage, TRUE, MAX_UPNP_DOWNLOAD, cb, cb_data);
 
 	g_free(totalSendMessage);
@@ -744,7 +744,7 @@
 {
 	if (control_info.status == PURPLE_UPNP_STATUS_DISCOVERED
 			&& control_info.publicip
-			&& strlen(control_info.publicip) > 0)
+			&& *control_info.publicip)
 		return control_info.publicip;
 
 	/* Trigger another UPnP discovery if 5 minutes have elapsed since the
@@ -803,7 +803,7 @@
 {
 	if (control_info.status == PURPLE_UPNP_STATUS_DISCOVERED
 			&& control_info.internalip
-			&& strlen(control_info.internalip) > 0)
+			&& *control_info.internalip)
 		return control_info.internalip;
 
 	/* Trigger another UPnP discovery if 5 minutes have elapsed since the
--- a/libpurple/util.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/util.c	Sun Sep 11 04:19:01 2011 +0000
@@ -73,6 +73,14 @@
 	PurpleAccount *account;
 };
 
+struct _PurpleMenuAction
+{
+	char *label;
+	PurpleCallback callback;
+	gpointer data;
+	GList *children;
+};
+
 static char *custom_user_dir = NULL;
 static char *user_dir = NULL;
 
@@ -98,6 +106,63 @@
 	g_free(act);
 }
 
+char * purple_menu_action_get_label(const PurpleMenuAction *act)
+{
+	g_return_val_if_fail(act != NULL, NULL);
+
+	return act->label;
+}
+
+PurpleCallback *
+purple_menu_action_get_callback(const PurpleMenuAction *act)
+{
+	g_return_val_if_fail(act != NULL, NULL);
+
+	return act->callback;
+}
+
+gpointer purple_menu_action_get_data(const PurpleMenuAction *act)
+{
+	g_return_val_if_fail(act != NULL, NULL);
+
+	return act->data;
+}
+
+GList* purple_menu_action_get_children(const PurpleMenuAction *act)
+{
+	g_return_val_if_fail(act != NULL, NULL);
+
+	return act->children;
+}
+
+void purple_menu_action_set_label(PurpleMenuAction *act, char *label)
+{
+	g_return_if_fail(act != NULL);
+
+	act-> label = label;
+}
+
+void purple_menu_action_set_callback(PurpleMenuAction *act, PurpleCallback callback)
+{
+	g_return_if_fail(act != NULL);
+
+	act->callback = callback;
+}
+
+void purple_menu_action_set_data(PurpleMenuAction *act, gpointer data)
+{
+	g_return_if_fail(act != NULL);
+
+	act->data = data;
+}
+
+void purple_menu_action_set_children(PurpleMenuAction *act, GList *children)
+{
+	g_return_if_fail(act != NULL);
+
+	act->children = children;
+}
+
 void
 purple_util_init(void)
 {
@@ -147,7 +212,7 @@
 
 	len = strlen(str);
 
-	g_return_val_if_fail(strlen(str) > 0, 0);
+	g_return_val_if_fail(*str, 0);
 	g_return_val_if_fail(len % 2 == 0,    0);
 
 	data = g_malloc(len / 2);
@@ -612,7 +677,7 @@
 	}
 	else
 	{
-		purple_strlcpy(buf, utf8);
+		g_strlcpy(buf, utf8, sizeof(buf));
 		g_free(utf8);
 	}
 
@@ -1321,7 +1386,7 @@
 				g_string_append_len(dest, p, q - p);
 		}
 
-		purple_notify_user_info_add_pair(user_info, display_name, dest->str);
+		purple_notify_user_info_add_pair_html(user_info, display_name, dest->str);
 		g_string_free(dest, TRUE);
 
 		return TRUE;
@@ -2267,7 +2332,7 @@
 					url_buf = g_string_free(gurl_buf, FALSE);
 
 					/* strip off trailing periods */
-					if (strlen(url_buf) > 0) {
+					if (*url_buf) {
 						for (d = url_buf + strlen(url_buf) - 1; *d == '.'; d--, t--)
 							*d = '\0';
 					}
@@ -4108,25 +4173,14 @@
 		const char *request, gboolean include_headers,
 		PurpleUtilFetchUrlCallback callback, void *user_data)
 {
-	return purple_util_fetch_url_request_len_with_account(NULL, url, full,
+	return purple_util_fetch_url_request_len(NULL, url, full,
 					     user_agent, http11,
 					     request, include_headers, -1,
 					     callback, user_data);
 }
 
 PurpleUtilFetchUrlData *
-purple_util_fetch_url_request_len(const char *url, gboolean full,
-		const char *user_agent, gboolean http11,
-		const char *request, gboolean include_headers, gssize max_len,
-		PurpleUtilFetchUrlCallback callback, void *user_data)
-{
-	return purple_util_fetch_url_request_len_with_account(NULL, url, full,
-			user_agent, http11, request, include_headers, max_len, callback,
-			user_data);
-}
-
-PurpleUtilFetchUrlData *
-purple_util_fetch_url_request_len_with_account(PurpleAccount *account,
+purple_util_fetch_url_request_len(PurpleAccount *account,
 		const char *url, gboolean full,	const char *user_agent, gboolean http11,
 		const char *request, gboolean include_headers, gssize max_len,
 		PurpleUtilFetchUrlCallback callback, void *user_data)
@@ -4943,18 +4997,6 @@
 	return buf;
 }
 
-const char *_purple_oscar_convert(const char *act, const char *protocol)
-{
-	if (act && purple_strequal(protocol, "prpl-oscar")) {
-		int i;
-		for (i = 0; act[i] != '\0'; i++)
-			if (!isdigit(act[i]))
-				return "prpl-aim";
-		return "prpl-icq";
-	}
-	return protocol;
-}
-
 void purple_restore_default_signal_handlers(void)
 {
 #ifndef _WIN32
--- a/libpurple/util.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/util.h	Sun Sep 11 04:19:01 2011 +0000
@@ -51,14 +51,6 @@
 extern "C" {
 #endif
 
-struct _PurpleMenuAction
-{
-	char *label;
-	PurpleCallback callback;
-	gpointer data;
-	GList *children;
-};
-
 typedef char *(*PurpleInfoFieldFormatCallback)(const char *field, size_t len);
 
 /**
@@ -96,12 +88,79 @@
 void purple_menu_action_free(PurpleMenuAction *act);
 
 /**
+ * Returns the label of the PurpleMenuAction.
+ *
+ * @param act	The PurpleMenuAction.
+ *
+ * @return The label string.
+ */
+char * purple_menu_action_get_label(const PurpleMenuAction *act);
+
+/**
+ * Returns the callback of the PurpleMenuAction.
+ *
+ * @param act	The PurpleMenuAction.
+ *
+ * @return The callback function.
+ */
+PurpleCallback *purple_menu_action_get_callback(const PurpleMenuAction *act);
+
+/**
+ * Returns the data stored in the PurpleMenuAction.
+ *
+ * @param act	The PurpleMenuAction.
+ *
+ * @return The data.
+ */
+gpointer purple_menu_action_get_data(const PurpleMenuAction *act);
+
+/**
+ * Returns the children of the PurpleMenuAction.
+ *
+ * @param act	The PurpleMenuAction.
+ *
+ * @return The  GList of children.
+ */
+GList* purple_menu_action_get_children(const PurpleMenuAction *act);
+
+/**
+ * Set the label to the PurpleMenuAction.
+ *
+ * @param act   The menu action.
+ * @param label The label for the menu action.
+ */
+void purple_menu_action_set_label(PurpleMenuAction *act, char *label);
+
+/**
+ * Set the callback that will be used by the PurpleMenuAction.
+ *
+ * @param act        The menu action.
+ * @param callback   The callback.
+ */
+void purple_menu_action_set_callback(PurpleMenuAction *act, PurpleCallback callback);
+
+/**
+ * Set the label to the PurpleMenuAction.
+ *
+ * @param act   The menu action.
+ * @param data  The data used by this PurpleMenuAction
+ */
+void purple_menu_action_set_data(PurpleMenuAction *act, gpointer data);
+
+/**
+ * Set the children of the PurpleMenuAction.
+ *
+ * @param act       The menu action.
+ * @param children  The PurpleMenuAtion children
+ */
+void purple_menu_action_set_children(PurpleMenuAction *act, GList *children);
+
+/**
  * Set the appropriate presence values for the currently playing song.
  *
  * @param title     The title of the song, @c NULL to unset the value.
  * @param artist    The artist of the song, can be @c NULL.
  * @param album     The album of the song, can be @c NULL.
- * @since 2.4.0
  */
 void purple_util_set_current_song(const char *title, const char *artist,
 		const char *album);
@@ -115,7 +174,6 @@
  * @param unused    Currently unused, must be @c NULL.
  *
  * @return   The formatted string. The caller must g_free the returned string.
- * @since 2.4.0
  */
 char * purple_util_format_song_info(const char *title, const char *artist,
 		const char *album, gpointer unused);
@@ -127,15 +185,11 @@
 
 /**
  * Initializes the utility subsystem.
- *
- * @since 2.3.0
  */
 void purple_util_init(void);
 
 /**
  * Uninitializes the util subsystem.
- *
- * @since 2.3.0
  */
 void purple_util_uninit(void);
 
@@ -429,8 +483,6 @@
  * This is exactly the same as g_markup_escape_text(), except that it
  * does not change ' to &apos; because &apos; is not a valid HTML 4 entity,
  * and is displayed literally in IE7.
- *
- * @since 2.6.0
  */
 gchar *purple_markup_escape_text(const gchar *text, gssize length);
 
@@ -531,7 +583,6 @@
  *         this string when finished with it.
  *
  * @see purple_unescape_html()
- * @since 2.7.0
  */
 char *purple_unescape_text(const char *text);
 
@@ -624,8 +675,6 @@
  * @param html  The HTML text.
  *
  * @return  TRUE if the text contains RTL text, FALSE otherwise.
- *
- * @since 2.6.0
  */
 gboolean purple_markup_is_rtl(const char *html);
 
@@ -826,7 +875,6 @@
  *
  * @return The address family of the socket (AF_INET, AF_INET6, etc) or -1
  *         on error.
- * @since 2.7.0
  */
 int purple_socket_get_family(int fd);
 
@@ -838,7 +886,6 @@
  *
  * @param fd The socket file descriptor
  * @return TRUE if a socket can speak IPv4.
- * @since 2.7.0
  */
 gboolean purple_socket_speaks_ipv4(int fd);
 
@@ -860,8 +907,6 @@
  * @param right A string to compare with left
  *
  * @return @c TRUE if the strings are the same, else @c FALSE.
- *
- * @since 2.6.0
  */
 gboolean purple_strequal(const gchar *left, const gchar *right);
 
@@ -1138,7 +1183,7 @@
  * @deprecated       In 3.0.0, we'll rename this to "purple_util_fetch_url" and get rid of the old one
  */
 #define purple_util_fetch_url_len(url, full, user_agent, http11, max_len, cb, data) \
-	purple_util_fetch_url_request_len(url, full, user_agent, http11, NULL, \
+	purple_util_fetch_url_request_len(NULL, url, full, user_agent, http11, NULL, \
 		FALSE, max_len, cb, data);
 
 /**
@@ -1164,28 +1209,6 @@
 /**
  * Fetches the data from a URL, and passes it to a callback function.
  *
- * @param url        The URL.
- * @param full       TRUE if this is the full URL, or FALSE if it's a
- *                   partial URL.
- * @param user_agent The user agent field to use, or NULL.
- * @param http11     TRUE if HTTP/1.1 should be used to download the file.
- * @param request    A HTTP request to send to the server instead of the
- *                   standard GET
- * @param include_headers
- *                   If TRUE, include the HTTP headers in the response.
- * @param max_len    The maximum number of bytes to retrieve (-1 for unlimited)
- * @param callback   The callback function.
- * @param data       The user data to pass to the callback function.
- * @deprecated       In 3.0.0, this will go away.
- */
-PurpleUtilFetchUrlData *purple_util_fetch_url_request_len(const gchar *url,
-		gboolean full, const gchar *user_agent, gboolean http11,
-		const gchar *request, gboolean include_headers, gssize max_len,
-		PurpleUtilFetchUrlCallback callback, gpointer data);
-
-/**
- * Fetches the data from a URL, and passes it to a callback function.
- *
  * @param account    The account for which the request is needed, or NULL.
  * @param url        The URL.
  * @param full       TRUE if this is the full URL, or FALSE if it's a
@@ -1201,7 +1224,7 @@
  * @param data       The user data to pass to the callback function.
  * @deprecated       In 3.0.0, we'll rename this to "purple_util_fetch_url_request" and get rid of the old one
  */
-PurpleUtilFetchUrlData *purple_util_fetch_url_request_len_with_account(
+PurpleUtilFetchUrlData *purple_util_fetch_url_request_len(
 		PurpleAccount *account, const gchar *url,
 		gboolean full, const gchar *user_agent, gboolean http11,
 		const gchar *request, gboolean include_headers, gssize max_len,
@@ -1264,7 +1287,6 @@
  * @param ip The IP address to validate.
  *
  * @return True if the IP address is syntactically correct.
- * @since 2.6.0
  */
 gboolean purple_ipv4_address_is_valid(const char *ip);
 
@@ -1274,7 +1296,6 @@
  * @param ip The IP address to validate.
  *
  * @return True if the IP address is syntactically correct.
- * @since 2.6.0
  */
 gboolean purple_ipv6_address_is_valid(const char *ip);
 
@@ -1342,7 +1363,6 @@
  * @param str A valid UTF-8 string.
  *
  * @return A newly allocated UTF-8 string without the unprintable characters.
- * @since 2.6.0
  */
 gchar *purple_utf8_strip_unprintables(const gchar *str);
 
@@ -1354,7 +1374,6 @@
  * @param errnum The error code.
  *
  * @return The UTF-8 error message.
- * @since 2.4.0
  */
 G_CONST_RETURN gchar *purple_gai_strerror(gint errnum);
 
@@ -1450,16 +1469,6 @@
 const char *purple_escape_filename(const char *str);
 
 /**
- * This is added temporarily to assist the split of oscar into aim and icq.
- * This should not be used by plugins.
- *
- * @deprecated This function should not be used in new code and should be
- *             removed in 3.0.0.  The aim/icq prpl split happened a long
- *             time ago, and we don't need to keep migrating old data.
- */
-const char *_purple_oscar_convert(const char *act, const char *protocol);
-
-/**
  * Restore default signal handlers for signals which might reasonably have
  * handlers. This should be called by a fork()'d child process, since child processes
  * inherit the handlers of the parent.
@@ -1478,7 +1487,6 @@
  * Returns a type 4 (random) UUID
  *
  * @return A UUID, caller is responsible for freeing it
- * @since 2.7.0
  */
 gchar *purple_uuid_random(void);
 
--- a/libpurple/value.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/value.c	Sun Sep 11 04:19:01 2011 +0000
@@ -29,6 +29,44 @@
 
 #define OUTGOING_FLAG 0x01
 
+/**
+ * A wrapper for a type, subtype, and specific type of value.
+ */
+struct _PurpleValue
+{
+	PurpleType type;
+	unsigned short flags;
+
+	union
+	{
+		char char_data;
+		unsigned char uchar_data;
+		gboolean boolean_data;
+		short short_data;
+		unsigned short ushort_data;
+		int int_data;
+		unsigned int uint_data;
+		long long_data;
+		unsigned long ulong_data;
+		gint64 int64_data;
+		guint64 uint64_data;
+		char *string_data;
+		void *object_data;
+		void *pointer_data;
+		int enum_data;
+		void *boxed_data;
+
+	} data;
+
+	union
+	{
+		unsigned int subtype;
+		char *specific_type;
+
+	} u;
+
+};
+
 PurpleValue *
 purple_value_new(PurpleType type, ...)
 {
--- a/libpurple/value.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/value.h	Sun Sep 11 04:19:01 2011 +0000
@@ -86,40 +86,7 @@
 /**
  * A wrapper for a type, subtype, and specific type of value.
  */
-typedef struct
-{
-	PurpleType type;
-	unsigned short flags;
-
-	union
-	{
-		char char_data;
-		unsigned char uchar_data;
-		gboolean boolean_data;
-		short short_data;
-		unsigned short ushort_data;
-		int int_data;
-		unsigned int uint_data;
-		long long_data;
-		unsigned long ulong_data;
-		gint64 int64_data;
-		guint64 uint64_data;
-		char *string_data;
-		void *object_data;
-		void *pointer_data;
-		int enum_data;
-		void *boxed_data;
-
-	} data;
-
-	union
-	{
-		unsigned int subtype;
-		char *specific_type;
-
-	} u;
-
-} PurpleValue;
+typedef struct _PurpleValue PurpleValue;
 
 #ifdef __cplusplus
 extern "C" {
--- a/libpurple/whiteboard.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/whiteboard.c	Sun Sep 11 04:19:01 2011 +0000
@@ -90,6 +90,34 @@
 	g_free(wb);
 }
 
+PurpleAccount *purple_whiteboard_get_account(const PurpleWhiteboard *wb)
+{
+	g_return_val_if_fail(wb != NULL, NULL);
+
+	return wb->account;
+}
+
+const char *purple_whiteboard_get_who(const PurpleWhiteboard *wb)
+{
+	g_return_val_if_fail(wb != NULL, NULL);
+
+	return wb->who;	
+}
+
+void purple_whiteboard_set_state(PurpleWhiteboard *wb, int state)
+{
+	g_return_if_fail(wb != NULL);
+
+	wb->state = state;
+}
+
+int purple_whiteboard_get_state(const PurpleWhiteboard *wb)
+{
+	g_return_val_if_fail(wb != NULL, -1);
+
+	return wb->state;
+}
+
 void purple_whiteboard_start(PurpleWhiteboard *wb)
 {
 	/* Create frontend for whiteboard */
@@ -206,3 +234,44 @@
 		whiteboard_ui_ops->set_brush(wb, size, color);
 }
 
+GList *purple_whiteboard_get_draw_list(const PurpleWhiteboard *wb)
+{
+	g_return_val_if_fail(wb != NULL, NULL);
+
+	return wb->draw_list;
+}
+
+void purple_whiteboard_set_draw_list(PurpleWhiteboard *wb, GList* draw_list)
+{
+	g_return_if_fail(wb != NULL);
+
+	wb->draw_list = draw_list;
+}
+
+void purple_whiteboard_set_protocol_data(PurpleWhiteboard *wb, gpointer proto_data)
+{
+	g_return_if_fail(wb != NULL);
+
+	wb->proto_data = proto_data;
+}
+
+gpointer purple_whiteboard_get_protocol_data(const PurpleWhiteboard *wb)
+{
+	g_return_val_if_fail(wb != NULL, NULL);
+
+	return wb->proto_data;
+}
+
+void purple_whiteboard_set_ui_data(PurpleWhiteboard *wb, gpointer ui_data)
+{
+	g_return_if_fail(wb != NULL);
+
+	wb->ui_data = ui_data;
+}
+
+gpointer purple_whiteboard_get_ui_data(const PurpleWhiteboard *wb)
+{
+	g_return_val_if_fail(wb != NULL, NULL);
+
+	return wb->ui_data;
+}
--- a/libpurple/whiteboard.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/whiteboard.h	Sun Sep 11 04:19:01 2011 +0000
@@ -135,6 +135,41 @@
 void purple_whiteboard_destroy(PurpleWhiteboard *wb);
 
 /**
+ * Returns the whiteboard's account.
+ *
+ * @param wb		The whiteboard.
+ *
+ * @return The whiteboard's account.
+ */
+PurpleAccount *purple_whiteboard_get_account(const PurpleWhiteboard *wb);
+
+/**
+ * Return who you're drawing with.
+ *
+ * @param wb		The whiteboard
+ *
+ * @return Who you're drawing with.
+ */
+const char *purple_whiteboard_get_who(const PurpleWhiteboard *wb);
+
+/**
+ * Set the state of the whiteboard.
+ *
+ * @param wb		The whiteboard.
+ * @param state		The state
+ */
+void purple_whiteboard_set_state(PurpleWhiteboard *wb, int state);
+
+/**
+ * Return the state of the whiteboard.
+ *
+ * @param wb		The whiteboard.
+ *
+ * @return The state of the whiteboard.
+ */
+int purple_whiteboard_get_state(const PurpleWhiteboard *wb);
+
+/**
  * Starts a whiteboard
  *
  * @param wb The whiteboard.
@@ -253,6 +288,59 @@
  */
 void purple_whiteboard_set_brush(PurpleWhiteboard *wb, int size, int color);
 
+/**
+ * Return the drawing list.
+ *
+ * @param wb			The whiteboard.
+ *
+ * @return The drawing list
+ */
+GList *purple_whiteboard_get_draw_list(const PurpleWhiteboard *wb);
+
+/**
+ * Set the drawing list.
+ *
+ * @param wb			The whiteboard
+ * @param draw_list		The drawing list.
+ */
+void purple_whiteboard_set_draw_list(PurpleWhiteboard *wb, GList* draw_list);
+
+/**
+ * Sets the protocol data for a whiteboard.
+ *
+ * @param wb			The whiteboard.
+ * @param protocol_data	The protocol data to set for the whiteboard.
+ */
+void purple_whiteboard_set_protocol_data(PurpleWhiteboard *wb, gpointer proto_data);
+ 
+/**
+ * Gets the protocol data for a whiteboard.
+ *
+ * @param wb			The whiteboard.
+ *
+ * @return The protocol data for the whiteboard.
+ */
+gpointer purple_whiteboard_get_protocol_data(const PurpleWhiteboard *wb);
+
+/**
+ * Set the UI data associated with this whiteboard.
+ *
+ * @param wb			The whiteboard.
+ * @param ui_data		A pointer to associate with this whiteboard.
+ */
+void purple_whiteboard_set_ui_data(PurpleWhiteboard *wb, gpointer ui_data);
+
+/**
+ * Get the UI data associated with this whiteboard.
+ *
+ * @param wb			The whiteboard..
+ *
+ * @return The UI data associated with this whiteboard.  This is a
+ *         convenience field provided to the UIs--it is not
+ *         used by the libpurple core.
+ */
+gpointer purple_whiteboard_get_ui_data(const PurpleWhiteboard *wb);
+
 /*@}*/
 
 #ifdef __cplusplus
--- a/libpurple/win32/libc_interface.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/win32/libc_interface.c	Sun Sep 11 04:19:01 2011 +0000
@@ -467,12 +467,6 @@
 	return res;
 }
 
-/* stdio.h */
-
-int wpurple_rename (const char *oldname, const char *newname) {
-	return g_rename(oldname, newname);
-}
-
 /* time.h */
 
 struct tm * wpurple_localtime_r (const time_t *time, struct tm *resultp) {
--- a/libpurple/win32/libc_interface.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/win32/libc_interface.h	Sun Sep 11 04:19:01 2011 +0000
@@ -135,7 +135,7 @@
 #define vsnprintf _vsnprintf
 
 #define rename( oldname, newname ) \
-wpurple_rename( oldname, newname )
+g_rename( oldname, newname )
 
 /* sys/stat.h */
 #define fchmod(a,b)
--- a/libpurple/win32/libc_internal.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/win32/libc_internal.h	Sun Sep 11 04:19:01 2011 +0000
@@ -141,9 +141,6 @@
 int wpurple_gethostname(char *name, size_t size);
 
 
-/* stdio.h */
-int wpurple_rename(const char *oldname, const char *newname);
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
--- a/libpurple/xmlnode.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/xmlnode.c	Sun Sep 11 04:19:01 2011 +0000
@@ -78,6 +78,19 @@
 	node = new_node(name, XMLNODE_TYPE_TAG);
 
 	xmlnode_insert_child(parent, node);
+#if 0
+	/* This would give xmlnodes more appropriate namespacing
+	 * when creating them.  Otherwise, unless an explicit namespace
+	 * is set, xmlnode_get_namespace() will return NULL, when
+	 * there may be a default namespace.
+	 *
+	 * I'm unconvinced that it's useful, and concerned it may break things.
+	 *
+	 * _insert_child would need the same thing, probably (assuming
+	 * xmlns->node == NULL)
+	 */
+	xmlnode_set_namespace(node, xmlnode_get_default_namespace(node))
+#endif
 
 	return node;
 }
@@ -191,18 +204,6 @@
 }
 
 void
-xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns, const char *value)
-{
-	xmlnode_set_attrib_full(node, attr, xmlns, NULL, value);
-}
-
-void
-xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value)
-{
-	xmlnode_set_attrib_full(node, attr, NULL, prefix, value);
-}
-
-void
 xmlnode_set_attrib_full(xmlnode *node, const char *attr, const char *xmlns, const char *prefix, const char *value)
 {
 	xmlnode *attrib_node;
@@ -261,19 +262,53 @@
 
 void xmlnode_set_namespace(xmlnode *node, const char *xmlns)
 {
+	char *tmp;
 	g_return_if_fail(node != NULL);
 
-	g_free(node->xmlns);
+	tmp = node->xmlns;
 	node->xmlns = g_strdup(xmlns);
+
+	if (node->namespace_map) {
+		g_hash_table_insert(node->namespace_map,
+			g_strdup(""), g_strdup(xmlns));
+	}
+
+	g_free(tmp);
 }
 
-const char *xmlnode_get_namespace(xmlnode *node)
+const char *xmlnode_get_namespace(const xmlnode *node)
 {
 	g_return_val_if_fail(node != NULL, NULL);
 
 	return node->xmlns;
 }
 
+const char *xmlnode_get_default_namespace(const xmlnode *node)
+{
+	const xmlnode *current_node;
+	const char *ns = NULL;
+
+	g_return_val_if_fail(node != NULL, NULL);
+
+	current_node = node;
+	while (current_node) {
+		/* If this node does *not* have a prefix, node->xmlns is the default
+		 * namespace.  Otherwise, it's the prefix namespace.
+		 */
+		if (!current_node->prefix && current_node->xmlns) {
+			return current_node->xmlns;
+		} else if (current_node->namespace_map) {
+			ns = g_hash_table_lookup(current_node->namespace_map, "");
+			if (ns && *ns)
+				return ns;
+		}
+
+		current_node = current_node->parent;
+	}
+
+	return ns;
+}
+
 void xmlnode_set_prefix(xmlnode *node, const char *prefix)
 {
 	g_return_if_fail(node != NULL);
@@ -288,6 +323,53 @@
 	return node->prefix;
 }
 
+const char *xmlnode_get_prefix_namespace(const xmlnode *node, const char *prefix)
+{
+	const xmlnode *current_node;
+
+	g_return_val_if_fail(node != NULL, NULL);
+	g_return_val_if_fail(prefix != NULL, xmlnode_get_default_namespace(node));
+
+	current_node = node;
+	while (current_node) {
+		if (current_node->prefix && g_str_equal(prefix, current_node->prefix) &&
+				current_node->xmlns) {
+			return current_node->xmlns;
+		} else if (current_node->namespace_map) {
+			const char *ns = g_hash_table_lookup(current_node->namespace_map, prefix);
+			if (ns && *ns) {
+				return ns;
+			}
+		}
+
+		current_node = current_node->parent;
+	}
+
+	return NULL;
+}
+
+void xmlnode_strip_prefixes(xmlnode *node)
+{
+	xmlnode *child;
+	const char *prefix;
+
+	g_return_if_fail(node != NULL);
+
+	for (child = node->child; child; child = child->next) {
+		if (child->type == XMLNODE_TYPE_TAG)
+			xmlnode_strip_prefixes(child);
+	}
+
+	prefix = xmlnode_get_prefix(node);
+	if (prefix) {
+		const char *ns = xmlnode_get_prefix_namespace(node, prefix);
+		xmlnode_set_namespace(node, ns);
+		xmlnode_set_prefix(node, NULL);
+	} else {
+		xmlnode_set_namespace(node, xmlnode_get_default_namespace(node));
+	}
+}
+
 xmlnode *xmlnode_get_parent(const xmlnode *child)
 {
 	g_return_val_if_fail(child != NULL, NULL);
@@ -455,12 +537,22 @@
 	if (node->namespace_map) {
 		g_hash_table_foreach(node->namespace_map,
 			(GHFunc)xmlnode_to_str_foreach_append_ns, text);
-	} else if (node->xmlns) {
-		if(!node->parent || !purple_strequal(node->xmlns, node->parent->xmlns))
+	} else {
+		/* Figure out if this node has a different default namespace from parent */
+		const char *xmlns = NULL;
+		const char *parent_xmlns = NULL;
+		if (!prefix)
+			xmlns = node->xmlns;
+
+		if (!xmlns)
+			xmlns = xmlnode_get_default_namespace(node);
+		if (node->parent)
+			parent_xmlns = xmlnode_get_default_namespace(node->parent);
+		if (!purple_strequal(xmlns, parent_xmlns))
 		{
-			char *xmlns = g_markup_escape_text(node->xmlns, -1);
-			g_string_append_printf(text, " xmlns='%s'", xmlns);
-			g_free(xmlns);
+			char *escaped_xmlns = g_markup_escape_text(xmlns, -1);
+			g_string_append_printf(text, " xmlns='%s'", escaped_xmlns);
+			g_free(escaped_xmlns);
 		}
 	}
 	for(c = node->child; c; c = c->next)
--- a/libpurple/xmlnode.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/libpurple/xmlnode.h	Sun Sep 11 04:19:01 2011 +0000
@@ -35,7 +35,7 @@
 /**
  * The valid types for an xmlnode
  */
-typedef enum _XMLNodeType
+typedef enum
 {
 	XMLNODE_TYPE_TAG,		/**< Just a tag */
 	XMLNODE_TYPE_ATTRIB,		/**< Has attributes */
@@ -157,42 +157,14 @@
  */
 void xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value);
 
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_XMLNODE_C_)
-/**
- * Sets a prefixed attribute for a node
- *
- * @param node   The node to set an attribute for.
- * @param attr   The name of the attribute to set
- * @param prefix The prefix of the attribute to ste
- * @param value  The value of the attribute
- *
- * @deprecated Use xmlnode_set_attrib_full instead.
- */
-void xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value);
-
-/**
- * Sets a namespaced attribute for a node
- *
- * @param node  The node to set an attribute for.
- * @param attr  The name of the attribute to set
- * @param xmlns The namespace of the attribute to ste
- * @param value The value of the attribute
- *
- * @deprecated Use xmlnode_set_attrib_full instead.
- */
-void xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns, const char *value);
-#endif /* PURPLE_DISABLE_DEPRECATED */
-
 /**
  * Sets a namespaced attribute for a node
  *
  * @param node   The node to set an attribute for.
  * @param attr   The name of the attribute to set
- * @param xmlns  The namespace of the attribute to ste
- * @param prefix The prefix of the attribute to ste
+ * @param xmlns  The namespace of the attribute to set
+ * @param prefix The prefix of the attribute to set
  * @param value  The value of the attribute
- *
- * @since 2.6.0
  */
 void xmlnode_set_attrib_full(xmlnode *node, const char *attr, const char *xmlns,
 	const char *prefix, const char *value);
@@ -249,7 +221,35 @@
  * @param node The node to get the namepsace from
  * @return The namespace of this node
  */
-const char *xmlnode_get_namespace(xmlnode *node);
+const char *xmlnode_get_namespace(const xmlnode *node);
+
+/**
+ * Returns the current default namespace.  The default
+ * namespace is the current namespace which applies to child
+ * elements which are unprefixed and which do not contain their
+ * own namespace.
+ *
+ * For example, given:
+ * <iq type='get' xmlns='jabber:client' xmlns:ns1='http://example.org/ns1'>
+ *     <ns1:element><child1/></ns1:element>
+ * </iq>
+ *
+ * The default namespace of all nodes (including 'child1') is "jabber:client",
+ * though the namespace for 'element' is "http://example.org/ns1".
+ *
+ * @param node The node for which to return the default namespace
+ * @return The default namespace of this node
+ */
+const char *xmlnode_get_default_namespace(const xmlnode *node);
+
+/**
+ * Returns the defined namespace for a prefix.
+ *
+ * @param node The node from which to start the search.
+ * @param prefix The prefix for which to return the associated namespace.
+ * @return The namespace for this prefix.
+ */
+const char *xmlnode_get_prefix_namespace(const xmlnode *node, const char *prefix);
 
 /**
  * Sets the prefix of a node
@@ -268,13 +268,24 @@
 const char *xmlnode_get_prefix(const xmlnode *node);
 
 /**
+ * Remove all element prefixes from an xmlnode tree.  The prefix's
+ * namespace is transformed into the default namespace for an element.
+ *
+ * Note that this will not necessarily remove all prefixes in use
+ * (prefixed attributes may still exist), and that this usage may
+ * break some applications (SOAP / XPath apparently often rely on
+ * the prefixes having the same name.
+ *
+ * @param node The node from which to strip prefixes
+ */
+void xmlnode_strip_prefixes(xmlnode *node);
+
+/**
  * Gets the parent node.
  *
  * @param child The child node.
  *
  * @return The parent or NULL.
- *
- * @since 2.6.0
  */
 xmlnode *xmlnode_get_parent(const xmlnode *child);
 
@@ -343,8 +354,6 @@
  * 			the category for debugging.
  *
  * @return The new node or NULL if an error occurred.
- *
- * @since 2.6.0
  */
 xmlnode *xmlnode_from_file(const char *dir, const char *filename,
 			   const char *description, const char *process);
@@ -354,3 +363,4 @@
 #endif
 
 #endif /* _PURPLE_XMLNODE_H_ */
+
--- a/pidgin/Makefile.am	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/Makefile.am	Sun Sep 11 04:19:01 2011 +0000
@@ -3,8 +3,8 @@
 		getopt.h \
 		getopt1.c \
 		Makefile.mingw \
-		pidgin.pc.in \
-		pidgin-uninstalled.pc.in \
+		pidgin-3.pc.in \
+		pidgin-3-uninstalled.pc.in \
 		win32/MinimizeToTray.h \
 		win32/MinimizeToTray.c \
 		win32/pidgin_dll_rc.rc.in \
@@ -32,7 +32,7 @@
 if ENABLE_GTK
 
 pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = pidgin.pc
+pkgconfig_DATA = pidgin-3.pc
 
 SUBDIRS = pixmaps plugins
 
@@ -52,7 +52,6 @@
 	gtkdialogs.c \
 	gtkdnd-hints.c \
 	gtkdocklet.c \
-	gtkdocklet-gtk.c \
 	gtkeventloop.c \
 	gtkft.c \
 	gtkicon-theme.c \
@@ -107,7 +106,6 @@
 	gtkicon-theme.h \
 	gtkicon-theme-loader.h \
 	gtkidle.h \
-	gtkgaim-compat.h \
 	gtkimhtml.h \
 	gtkimhtmltoolbar.h \
 	gtklog.h \
@@ -182,3 +180,4 @@
 	$(LIBXML_CFLAGS) \
 	$(INTGG_CFLAGS)
 endif  # ENABLE_GTK
+
--- a/pidgin/Makefile.mingw	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/Makefile.mingw	Sun Sep 11 04:19:01 2011 +0000
@@ -95,8 +95,6 @@
 			minidialog.c \
 			pidginstock.c \
 			pidgintooltip.c \
-			win32/MinimizeToTray.c \
-			win32/gtkdocklet-win32.c \
 			win32/gtkwin32dep.c \
 			win32/untar.c \
 			win32/wspell.c
--- a/pidgin/gtkblist.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkblist.c	Sun Sep 11 04:19:01 2011 +0000
@@ -3774,10 +3774,8 @@
 		connections = purple_connections_get_all();
 		if (full && connections && connections->next)
 		{
-			tmp = g_markup_escape_text(purple_account_get_username(
-									   purple_buddy_get_account(b)), -1);
-			purple_notify_user_info_add_pair(user_info, _("Account"), tmp);
-			g_free(tmp);
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Account"),
+					purple_account_get_username(purple_buddy_get_account(b)));
 		}
 
 		/* Alias */
@@ -3787,9 +3785,8 @@
 		    (c->alias != NULL && c->alias[0] != '\0') &&
 		    strcmp(c->alias, b->alias) != 0)
 		{
-			tmp = g_markup_escape_text(b->alias, -1);
-			purple_notify_user_info_add_pair(user_info, _("Buddy Alias"), tmp);
-			g_free(tmp);
+			purple_notify_user_info_add_pair_plaintext(user_info,
+					_("Buddy Alias"), b->alias);
 		}
 
 		/* Nickname/Server Alias */
@@ -3799,9 +3796,8 @@
 		 * to look at the tooltip. */
 		if (full && b->server_alias != NULL && b->server_alias[0] != '\0')
 		{
-			tmp = g_markup_escape_text(b->server_alias, -1);
-			purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp);
-			g_free(tmp);
+			purple_notify_user_info_add_pair_plaintext(user_info,
+					_("Nickname"), b->server_alias);
 		}
 
 		/* Logged In */
@@ -3817,7 +3813,7 @@
 				tmp = g_strdup(purple_date_format_long(localtime(&signon)));
 			} else
 				tmp = purple_str_seconds_to_string(time(NULL) - signon);
-			purple_notify_user_info_add_pair(user_info, _("Logged In"), tmp);
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Logged In"), tmp);
 			g_free(tmp);
 		}
 
@@ -3828,7 +3824,7 @@
 			if (idle_secs > 0)
 			{
 				tmp = purple_str_seconds_to_string(time(NULL) - idle_secs);
-				purple_notify_user_info_add_pair(user_info, _("Idle"), tmp);
+				purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), tmp);
 				g_free(tmp);
 			}
 		}
@@ -3863,7 +3859,7 @@
 			if (lastseen > 0)
 			{
 				tmp = purple_str_seconds_to_string(time(NULL) - lastseen);
-				purple_notify_user_info_add_pair(user_info, _("Last Seen"), tmp);
+				purple_notify_user_info_add_pair_plaintext(user_info, _("Last Seen"), tmp);
 				g_free(tmp);
 			}
 		}
@@ -3873,7 +3869,7 @@
 		/* FIXME: Why is this status special-cased by the core? --rlaager
 		 * FIXME: Alternatively, why not have the core do all of them? --rlaager */
 		if (!PURPLE_BUDDY_IS_ONLINE(b)) {
-			purple_notify_user_info_add_pair(user_info, _("Status"), _("Offline"));
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Offline"));
 		}
 
 		if (purple_account_is_connected(b->account) &&
@@ -3885,11 +3881,11 @@
 
 		/* These are Easter Eggs.  Patches to remove them will be rejected. */
 		if (!g_ascii_strcasecmp(b->name, "robflynn"))
-			purple_notify_user_info_add_pair(user_info, _("Description"), _("Spooky"));
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Description"), _("Spooky"));
 		if (!g_ascii_strcasecmp(b->name, "seanegn"))
-			purple_notify_user_info_add_pair(user_info, _("Status"), _("Awesome"));
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Awesome"));
 		if (!g_ascii_strcasecmp(b->name, "chipx86"))
-			purple_notify_user_info_add_pair(user_info, _("Status"), _("Rockin'"));
+			purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Rockin'"));
 
 		tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n");
 		g_string_append(str, tmp);
@@ -3904,24 +3900,21 @@
 		user_info = purple_notify_user_info_new();
 
 		count = purple_blist_get_group_online_count(group);
-
 		if (count != 0) {
 			/* Online buddies in group */
-			tmp = g_strdup_printf("%d", count);
-			purple_notify_user_info_add_pair(user_info,
-			                                 _("Online Buddies"),
-			                                 tmp);
-			g_free(tmp);
+			char tmp2[12];
+			sprintf(tmp2, "%d", count);
+			purple_notify_user_info_add_pair_plaintext(user_info,
+					_("Online Buddies"), tmp2);
 		}
 
 		count = purple_blist_get_group_size(group, FALSE);
 		if (count != 0) {
 			/* Total buddies (from online accounts) in group */
-			tmp = g_strdup_printf("%d", count);
-			purple_notify_user_info_add_pair(user_info,
-			                                 _("Total Buddies"),
-			                                 tmp);
-			g_free(tmp);
+			char tmp2[12];
+			sprintf(tmp2, "%d", count);
+			purple_notify_user_info_add_pair_html(user_info,
+					_("Total Buddies"), tmp2);
 		}
 
 		tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n");
@@ -5343,6 +5336,28 @@
 }
 
 
+/**
+ * Was used by the connection API to tell the blist if an account has a
+ * connection error or no longer has a connection error, but the blist now does
+ * this itself with the @ref account-error-changed signal.
+ *
+ * @param account The account that either has a connection error
+ *        or no longer has a connection error.
+ * @param message The connection error message, or NULL if this
+ *        account is no longer in an error state.
+ */
+static void
+pidgin_blist_update_account_error_state(PurpleAccount *account, const char *text)
+{
+	/* connection_errors isn't actually used anywhere; it's just kept in
+	 * sync with reality in case a plugin uses it.
+	 */
+	if (text == NULL)
+		g_hash_table_remove(gtkblist->connection_errors, account);
+	else
+		g_hash_table_insert(gtkblist->connection_errors, account, g_strdup(text));
+}
+
 /* Call appropriate error notification code based on error types */
 static void
 update_account_error_state(PurpleAccount *account,
@@ -5427,18 +5442,6 @@
 	}
 }
 
-void
-pidgin_blist_update_account_error_state(PurpleAccount *account, const char *text)
-{
-	/* connection_errors isn't actually used anywhere; it's just kept in
-	 * sync with reality in case a plugin uses it.
-	 */
-	if (text == NULL)
-		g_hash_table_remove(gtkblist->connection_errors, account);
-	else
-		g_hash_table_insert(gtkblist->connection_errors, account, g_strdup(text));
-}
-
 static gboolean
 paint_headline_hbox  (GtkWidget      *widget,
 		      GdkEventExpose *event,
@@ -7037,7 +7040,7 @@
 			purple_blist_add_buddy(b, NULL, g, NULL);
 		}
 
-		purple_account_add_buddy_with_invite(account, b, invite);
+		purple_account_add_buddy(account, b, invite);
 
 		/* Offer to merge people with the same alias. */
 		if (whoalias != NULL && g != NULL)
--- a/pidgin/gtkblist.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkblist.h	Sun Sep 11 04:19:01 2011 +0000
@@ -370,20 +370,6 @@
 void pidgin_append_blist_node_extended_menu(GtkWidget *menu, PurpleBlistNode *node);
 
 /**
- * Was used by the connection API to tell the blist if an account has a
- * connection error or no longer has a connection error, but the blist now does
- * this itself with the @ref account-error-changed signal.
- *
- * @param account The account that either has a connection error
- *        or no longer has a connection error.
- * @param message The connection error message, or NULL if this
- *        account is no longer in an error state.
- * @deprecated There was no good reason for code other than gtkconn to call
- *             this.
- */
-void pidgin_blist_update_account_error_state(PurpleAccount *account, const char *message);
-
-/**
  * Sets a headline notification
  *
  * This is currently used for mail notification, but could theoretically be used for anything.
--- a/pidgin/gtkcertmgr.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkcertmgr.c	Sun Sep 11 04:19:01 2011 +0000
@@ -333,6 +333,12 @@
 }
 
 static void
+tls_peers_mgmt_activated_cb(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, gpointer data)
+{
+	tls_peers_mgmt_info_cb(NULL, NULL);
+}
+
+static void
 tls_peers_mgmt_delete_confirm_cb(gchar *id, gint choice)
 {
 	if (1 == choice) {
@@ -452,6 +458,9 @@
 	g_signal_connect(G_OBJECT(select), "changed",
 			 G_CALLBACK(tls_peers_mgmt_select_chg_cb), NULL);
 
+	g_signal_connect(G_OBJECT(listview), "row-activated",
+			 G_CALLBACK(tls_peers_mgmt_activated_cb), NULL);
+
 	gtk_box_pack_start(GTK_BOX(mgmt_widget), 
 			pidgin_make_scrollable(GTK_WIDGET(listview), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1),
 			TRUE, TRUE, /* Take up lots of space */
@@ -471,9 +480,8 @@
 	gtk_widget_show(bbox);
 
 	/* Import button */
-	/* TODO: This is the wrong stock button */
 	tpm_dat->importbutton = importbutton =
-		gtk_button_new_from_stock(GTK_STOCK_ADD);
+		gtk_button_new_from_stock(GTK_STOCK_OPEN);
 	gtk_box_pack_start(GTK_BOX(bbox), importbutton, FALSE, FALSE, 0);
 	gtk_widget_show(importbutton);
 	g_signal_connect(G_OBJECT(importbutton), "clicked",
@@ -481,9 +489,8 @@
 
 
 	/* Export button */
-	/* TODO: This is the wrong stock button */
 	tpm_dat->exportbutton = exportbutton =
-		gtk_button_new_from_stock(GTK_STOCK_SAVE);
+		gtk_button_new_from_stock(GTK_STOCK_SAVE_AS);
 	gtk_box_pack_start(GTK_BOX(bbox), exportbutton, FALSE, FALSE, 0);
 	gtk_widget_show(exportbutton);
 	g_signal_connect(G_OBJECT(exportbutton), "clicked",
--- a/pidgin/gtkconn.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkconn.c	Sun Sep 11 04:19:01 2011 +0000
@@ -136,9 +136,9 @@
 }
 
 static void
-pidgin_connection_report_disconnect_reason (PurpleConnection *gc,
-                                            PurpleConnectionError reason,
-                                            const char *text)
+pidgin_connection_report_disconnect(PurpleConnection *gc,
+                                    PurpleConnectionError reason,
+                                    const char *text)
 {
 	PurpleAccount *account = NULL;
 	PidginAutoRecon *info;
@@ -215,10 +215,9 @@
 	pidgin_connection_connected,
 	pidgin_connection_disconnected,
 	pidgin_connection_notice,
-	NULL, /* report_disconnect */
 	pidgin_connection_network_connected,
 	pidgin_connection_network_disconnected,
-	pidgin_connection_report_disconnect_reason,
+	pidgin_connection_report_disconnect,
 	NULL,
 	NULL,
 	NULL
--- a/pidgin/gtkconv.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkconv.c	Sun Sep 11 04:19:01 2011 +0000
@@ -74,6 +74,39 @@
 
 #include "gtknickcolors.h"
 
+/**
+ * A GTK+ Instant Message pane.
+ */
+struct _PidginImPane
+{
+	GtkWidget *block;
+	GtkWidget *send_file;
+	GtkWidget *sep1;
+	GtkWidget *sep2;
+	GtkWidget *check;
+	GtkWidget *progress;
+	guint32 typing_timer;
+
+	/* Buddy icon stuff */
+	GtkWidget *icon_container;
+	GtkWidget *icon;
+	gboolean show_icon;
+	gboolean animate;
+	GdkPixbufAnimation *anim;
+	GdkPixbufAnimationIter *iter;
+	guint32 icon_timer;
+};
+
+/**
+ * GTK+ Chat panes.
+ */
+struct _PidginChatPane
+{
+	GtkWidget *count;
+	GtkWidget *list;
+	GtkWidget *topic_text;
+};
+
 #define CLOSE_CONV_TIMEOUT_SECS  (10 * 60)
 
 #define AUTO_RESPONSE "&lt;AUTO-REPLY&gt; : "
@@ -356,8 +389,32 @@
 		}
 
 		tmp = g_string_free(str, FALSE);
+	} else if (!g_ascii_strcasecmp(args[0], "unsafe")) {
+		if (purple_debug_is_unsafe()) {
+			purple_debug_set_unsafe(FALSE);
+			purple_conversation_write(conv, NULL, _("Unsafe debugging is now disabled."),
+			                          PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL));
+		} else {
+			purple_debug_set_unsafe(TRUE);
+			purple_conversation_write(conv, NULL, _("Unsafe debugging is now enabled."),
+			                          PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL));
+		}
+
+		return PURPLE_CMD_RET_OK;
+	} else if (!g_ascii_strcasecmp(args[0], "verbose")) {
+		if (purple_debug_is_verbose()) {
+			purple_debug_set_verbose(FALSE);
+			purple_conversation_write(conv, NULL, _("Verbose debugging is now disabled."),
+			                          PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL));
+		} else {
+			purple_debug_set_verbose(TRUE);
+			purple_conversation_write(conv, NULL, _("Verbose debugging is now enabled."),
+			                          PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL));
+		}
+
+		return PURPLE_CMD_RET_OK;
 	} else {
-		purple_conversation_write(conv, NULL, _("Supported debug options are: plugins version"),
+		purple_conversation_write(conv, NULL, _("Supported debug options are: plugins version unsafe verbose"),
 		                        PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_ERROR, time(NULL));
 		return PURPLE_CMD_RET_OK;
 	}
@@ -578,7 +635,7 @@
 
 	gtk_widget_grab_focus(gtkconv->entry);
 
-	if (strlen(clean) == 0) {
+	if (!*clean) {
 		g_free(buf);
 		g_free(clean);
 		return;
@@ -4824,7 +4881,7 @@
 
 	gtkchat->list = list;
 
-	gtk_box_pack_start(GTK_BOX(lbox), 
+	gtk_box_pack_start(GTK_BOX(lbox),
 		pidgin_make_scrollable(list, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1),
 		TRUE, TRUE, 0);
 }
@@ -5253,8 +5310,8 @@
 		PurpleBuddy *b = PURPLE_BUDDY(bn);
 		PurpleConversation *conv;
 		if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, b->name, b->account))) {
-			if (conv->ui_data)
-				return conv->ui_data;
+			if (PIDGIN_CONVERSATION(conv))
+				return PIDGIN_CONVERSATION(conv);
 		}
 	}
 
@@ -5342,7 +5399,7 @@
 	PurpleValue *value;
 
 	if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) {
-		conv->ui_data = gtkconv;
+		purple_conversation_set_ui_data(conv, gtkconv);
 		if (!g_list_find(gtkconv->convs, conv))
 			gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
 		pidgin_conv_switch_active_conversation(conv);
@@ -5350,7 +5407,7 @@
 	}
 
 	gtkconv = g_new0(PidginConversation, 1);
-	conv->ui_data = gtkconv;
+	purple_conversation_set_ui_data(conv, gtkconv);
 	gtkconv->active_conv = conv;
 	gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
 	gtkconv->send_history = g_list_append(NULL, NULL);
@@ -5377,7 +5434,7 @@
 			g_free(gtkconv->u.im);
 
 		g_free(gtkconv);
-		conv->ui_data = NULL;
+		purple_conversation_set_ui_data(conv, NULL);
 		return;
 	}
 
@@ -6427,7 +6484,7 @@
 
 	if (!gdk_pixbuf_loader_write(smiley->loader, data, size, &error) || error) {
 		purple_debug_warning("gtkconv", "gdk_pixbuf_loader_write() "
-				"failed with size=%zu: %s\n", size,
+				"failed with size=%" G_GSIZE_FORMAT ": %s\n", size,
 				error ? error->message : "(no error message)");
 		if (error)
 			g_error_free(error);
@@ -6633,7 +6690,7 @@
 
 		if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
 		{
-			gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL) || (prpl_info->add_buddy_with_invite != NULL));
+			gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL));
 			gtk_widget_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
 			gtk_widget_set_sensitive(win->menu.send_file,
 									 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file ||
--- a/pidgin/gtkconv.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkconv.h	Sun Sep 11 04:19:01 2011 +0000
@@ -56,7 +56,7 @@
 };
 
 #define PIDGIN_CONVERSATION(conv) \
-	((PidginConversation *)(conv)->ui_data)
+	((PidginConversation *)purple_conversation_get_ui_data(conv))
 
 #define PIDGIN_IS_PIDGIN_CONVERSATION(conv) \
 	(purple_conversation_get_ui_ops(conv) == \
@@ -77,39 +77,6 @@
  */
 
 /**
- * A GTK+ Instant Message pane.
- */
-struct _PidginImPane
-{
-	GtkWidget *block;
-	GtkWidget *send_file;
-	GtkWidget *sep1;
-	GtkWidget *sep2;
-	GtkWidget *check;
-	GtkWidget *progress;
-	guint32 typing_timer;
-
-	/* Buddy icon stuff */
-	GtkWidget *icon_container;
-	GtkWidget *icon;
-	gboolean show_icon;
-	gboolean animate;
-	GdkPixbufAnimation *anim;
-	GdkPixbufAnimationIter *iter;
-	guint32 icon_timer;
-};
-
-/**
- * GTK+ Chat panes.
- */
-struct _PidginChatPane
-{
-	GtkWidget *count;
-	GtkWidget *list;
-	GtkWidget *topic_text;
-};
-
-/**
  * A GTK+ conversation pane.
  */
 struct _PidginConversation
@@ -132,8 +99,8 @@
 	GtkTextBuffer *entry_buffer;
 	GtkWidget *entry;
 	gboolean auto_resize;   /* this is set to TRUE if the conversation
-		 	 	 * is being resized by a non-user-initiated
-		 		 * event, such as the buddy icon appearing
+				 * is being resized by a non-user-initiated
+				 * event, such as the buddy icon appearing
 				 */
 	gboolean entry_growing; /* True if the size of the entry was set
 				 * automatically by typing too much to fit
@@ -144,12 +111,6 @@
 	GtkWidget *tab_label;
 	GtkWidget *menu_icon;
 	GtkWidget *menu_label;
-#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKCONV_C_)
-	/** @deprecated */
-	GtkSizeGroup *sg;
-#else
-	gpointer depr1;
-#endif
 
 	GtkWidget *lower_hbox;
 
--- a/pidgin/gtkdialogs.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkdialogs.c	Sun Sep 11 04:19:01 2011 +0000
@@ -1114,26 +1114,6 @@
 }
 
 static void
-pidgin_dialogs_alias_contact_cb(PurpleContact *contact, const char *new_alias)
-{
-	purple_blist_alias_contact(contact, new_alias);
-}
-
-void
-pidgin_dialogs_alias_contact(PurpleContact *contact)
-{
-	g_return_if_fail(contact != NULL);
-
-	purple_request_input(NULL, _("Alias Contact"), NULL,
-					   _("Enter an alias for this contact."),
-					   contact->alias, FALSE, FALSE, NULL,
-					   _("Alias"), G_CALLBACK(pidgin_dialogs_alias_contact_cb),
-					   _("Cancel"), NULL,
-					   NULL, purple_contact_get_alias(contact), NULL,
-					   contact);
-}
-
-static void
 pidgin_dialogs_alias_buddy_cb(PurpleBuddy *buddy, const char *new_alias)
 {
 	purple_blist_alias_buddy(buddy, new_alias);
--- a/pidgin/gtkdialogs.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkdialogs.h	Sun Sep 11 04:19:01 2011 +0000
@@ -42,14 +42,6 @@
 void pidgin_dialogs_info(void);
 void pidgin_dialogs_log(void);
 
-#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKDIALOGS_C_)
-/**
- * @deprecated This function is no longer used and will be removed in
- *             Pidgin 3.0.0 unless there is sufficient demand to keep it.
- */
-void pidgin_dialogs_alias_contact(PurpleContact *);
-#endif
-
 void pidgin_dialogs_alias_buddy(PurpleBuddy *);
 void pidgin_dialogs_alias_chat(PurpleChat *);
 void pidgin_dialogs_remove_buddy(PurpleBuddy *);
@@ -58,15 +50,7 @@
 void pidgin_dialogs_remove_contact(PurpleContact *);
 void pidgin_dialogs_merge_groups(PurpleGroup *, const char *);
 
-/* Everything after this should probably be moved elsewhere */
-
-#ifndef PIDGIN_DISABLE_DEPRECATED
-/* This PIDGIN_DISABLE_DEPRECATED doesn't need to be deactivated by
- * _PIDGIN_GTKDIALOGS_C_, because it shouldn't be using this macro. */
-#define PIDGIN_DIALOG(x)	x = gtk_window_new(GTK_WINDOW_TOPLEVEL); \
-			gtk_window_set_type_hint(GTK_WINDOW(x), GDK_WINDOW_TYPE_HINT_DIALOG)
-#endif
-
+/* This macro should probably be moved elsewhere */
 #define PIDGIN_WINDOW_ICONIFIED(x) (gdk_window_get_state(GTK_WIDGET(x)->window) & GDK_WINDOW_STATE_ICONIFIED)
 
 #endif /* _PIDGINDIALOGS_H_ */
--- a/pidgin/gtkdocklet-gtk.c	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,296 +0,0 @@
-/*
- * System tray icon (aka docklet) plugin for Purple
- *
- * Copyright (C) 2007 Anders Hasselqvist
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "internal.h"
-#include "pidgin.h"
-#include "debug.h"
-#include "prefs.h"
-#include "pidginstock.h"
-#include "gtkdocklet.h"
-
-#define SHORT_EMBED_TIMEOUT 5
-#define LONG_EMBED_TIMEOUT 15
-
-/* globals */
-static GtkStatusIcon *docklet = NULL;
-static guint embed_timeout = 0;
-
-/* protos */
-static void docklet_gtk_status_create(gboolean);
-
-static gboolean
-docklet_gtk_recreate_cb(gpointer data)
-{
-	docklet_gtk_status_create(TRUE);
-
-	return FALSE;
-}
-
-static gboolean
-docklet_gtk_embed_timeout_cb(gpointer data)
-{
-#if !GTK_CHECK_VERSION(2,12,0)
-	if (gtk_status_icon_is_embedded(docklet)) {
-		/* Older GTK+ (<2.12) don't implement the embedded signal, but the
-		   information is still accessable through the above function. */
-		purple_debug_info("docklet", "embedded\n");
-
-		pidgin_docklet_embedded();
-		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
-	}
-	else
-#endif
-	{
-		/* The docklet was not embedded within the timeout.
-		 * Remove it as a visibility manager, but leave the plugin
-		 * loaded so that it can embed automatically if/when a notification
-		 * area becomes available.
-		 */
-		purple_debug_info("docklet", "failed to embed within timeout\n");
-		pidgin_docklet_remove();
-		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
-	}
-
-#if GTK_CHECK_VERSION(2,12,0)
-	embed_timeout = 0;
-	return FALSE;
-#else
-	return TRUE;
-#endif
-}
-
-#if GTK_CHECK_VERSION(2,12,0)
-static gboolean
-docklet_gtk_embedded_cb(GtkWidget *widget, gpointer data)
-{
-	if (embed_timeout) {
-		purple_timeout_remove(embed_timeout);
-		embed_timeout = 0;
-	}
-
-	if (gtk_status_icon_is_embedded(docklet)) {
-		purple_debug_info("docklet", "embedded\n");
-
-		pidgin_docklet_embedded();
-		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
-	} else {
-		purple_debug_info("docklet", "detached\n");
-
-		pidgin_docklet_remove();
-		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
-	}
-
-	return TRUE;
-}
-#endif
-
-static void
-docklet_gtk_destroyed_cb(GtkWidget *widget, gpointer data)
-{
-	purple_debug_info("docklet", "destroyed\n");
-
-	pidgin_docklet_remove();
-
-	g_object_unref(G_OBJECT(docklet));
-	docklet = NULL;
-
-	g_idle_add(docklet_gtk_recreate_cb, NULL);
-}
-
-static void
-docklet_gtk_status_activated_cb(GtkStatusIcon *status_icon, gpointer user_data)
-{
-	pidgin_docklet_clicked(1);
-}
-
-static void
-docklet_gtk_status_clicked_cb(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data)
-{
-	purple_debug_info("docklet", "The button is %u\n", button);
-#ifdef GDK_WINDOWING_QUARTZ
-	/* You can only click left mouse button on MacOSX native GTK. Let that be the menu */
-	pidgin_docklet_clicked(3);
-#else
-	pidgin_docklet_clicked(button);
-#endif
-}
-
-static void
-docklet_gtk_status_update_icon(PurpleStatusPrimitive status, gboolean connecting, gboolean pending)
-{
-	const gchar *icon_name = NULL;
-
-	switch (status) {
-		case PURPLE_STATUS_OFFLINE:
-			icon_name = PIDGIN_STOCK_TRAY_OFFLINE;
-			break;
-		case PURPLE_STATUS_AWAY:
-			icon_name = PIDGIN_STOCK_TRAY_AWAY;
-			break;
-		case PURPLE_STATUS_UNAVAILABLE:
-			icon_name = PIDGIN_STOCK_TRAY_BUSY;
-			break;
-		case PURPLE_STATUS_EXTENDED_AWAY:
-			icon_name = PIDGIN_STOCK_TRAY_XA;
-			break;
-		case PURPLE_STATUS_INVISIBLE:
-			icon_name = PIDGIN_STOCK_TRAY_INVISIBLE;
-			break;
-		default:
-			icon_name = PIDGIN_STOCK_TRAY_AVAILABLE;
-			break;
-	}
-
-	if (pending)
-		icon_name = PIDGIN_STOCK_TRAY_PENDING;
-	if (connecting)
-		icon_name = PIDGIN_STOCK_TRAY_CONNECT;
-
-	if (icon_name) {
-		gtk_status_icon_set_from_icon_name(docklet, icon_name);
-	}
-
-	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")) {
-		gtk_status_icon_set_blinking(docklet, (pending && !connecting));
-	} else if (gtk_status_icon_get_blinking(docklet)) {
-		gtk_status_icon_set_blinking(docklet, FALSE);
-	}
-}
-
-static void
-docklet_gtk_status_set_tooltip(gchar *tooltip)
-{
-	gtk_status_icon_set_tooltip(docklet, tooltip);
-}
-
-static void
-docklet_gtk_status_position_menu(GtkMenu *menu,
-                                 int *x, int *y, gboolean *push_in,
-                                 gpointer user_data)
-{
-	gtk_status_icon_position_menu(menu, x, y, push_in, docklet);
-}
-
-static void
-docklet_gtk_status_destroy(void)
-{
-	g_return_if_fail(docklet != NULL);
-
-	pidgin_docklet_remove();
-
-	if (embed_timeout) {
-		purple_timeout_remove(embed_timeout);
-		embed_timeout = 0;
-	}
-
-	gtk_status_icon_set_visible(docklet, FALSE);
-	g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
-	g_object_unref(G_OBJECT(docklet));
-	docklet = NULL;
-
-	purple_debug_info("docklet", "GTK+ destroyed\n");
-}
-
-static void
-docklet_gtk_status_create(gboolean recreate)
-{
-	if (docklet) {
-		/* if this is being called when a tray icon exists, it's because
-		   something messed up. try destroying it before we proceed,
-		   although docklet_refcount may be all hosed. hopefully won't happen. */
-		purple_debug_warning("docklet", "trying to create icon but it already exists?\n");
-		docklet_gtk_status_destroy();
-	}
-
-	docklet = gtk_status_icon_new();
-	g_return_if_fail(docklet != NULL);
-
-	g_signal_connect(G_OBJECT(docklet), "activate", G_CALLBACK(docklet_gtk_status_activated_cb), NULL);
-	g_signal_connect(G_OBJECT(docklet), "popup-menu", G_CALLBACK(docklet_gtk_status_clicked_cb), NULL);
-#if GTK_CHECK_VERSION(2,12,0)
-	g_signal_connect(G_OBJECT(docklet), "notify::embedded", G_CALLBACK(docklet_gtk_embedded_cb), NULL);
-#endif
-	g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
-
-	gtk_status_icon_set_visible(docklet, TRUE);
-
-	/* This is a hack to avoid a race condition between the docklet getting
-	 * embedded in the notification area and the gtkblist restoring its
-	 * previous visibility state.  If the docklet does not get embedded within
-	 * the timeout, it will be removed as a visibility manager until it does
-	 * get embedded.  Ideally, we would only call docklet_embedded() when the
-	 * icon was actually embedded. This only happens when the docklet is first
-	 * created, not when being recreated.
-	 *
-	 * The gtk docklet tracks whether it successfully embedded in a pref and
-	 * allows for a longer timeout period if it successfully embedded the last
-	 * time it was run. This should hopefully solve problems with the buddy
-	 * list not properly starting hidden when Pidgin is started on login.
-	 */
-	if (!recreate) {
-		pidgin_docklet_embedded();
-#if GTK_CHECK_VERSION(2,12,0)
-		if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded")) {
-			embed_timeout = purple_timeout_add_seconds(LONG_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
-		} else {
-			embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
-		}
-#else
-		embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
-#endif
-	}
-
-	purple_debug_info("docklet", "GTK+ created\n");
-}
-
-static void
-docklet_gtk_status_create_ui_op(void)
-{
-	docklet_gtk_status_create(FALSE);
-}
-
-static struct docklet_ui_ops ui_ops =
-{
-	docklet_gtk_status_create_ui_op,
-	docklet_gtk_status_destroy,
-	docklet_gtk_status_update_icon,
-	NULL,
-	docklet_gtk_status_set_tooltip,
-	docklet_gtk_status_position_menu
-};
-
-void
-docklet_ui_init(void)
-{
-	pidgin_docklet_set_ui_ops(&ui_ops);
-
-	purple_prefs_add_none(PIDGIN_PREFS_ROOT "/docklet/gtk");
-	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/x11/embedded")) {
-		purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
-		purple_prefs_remove(PIDGIN_PREFS_ROOT "/docklet/x11/embedded");
-	} else {
-		purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
-	}
-
-	gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
-		DATADIR G_DIR_SEPARATOR_S "pixmaps" G_DIR_SEPARATOR_S "pidgin" G_DIR_SEPARATOR_S "tray");
-}
-
--- a/pidgin/gtkdocklet.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkdocklet.c	Sun Sep 11 04:19:01 2011 +0000
@@ -30,6 +30,7 @@
 #include "prefs.h"
 #include "signals.h"
 #include "sound.h"
+#include "status.h"
 
 #include "gtkaccount.h"
 #include "gtkblist.h"
@@ -48,8 +49,12 @@
 #define DOCKLET_TOOLTIP_LINE_LIMIT 5
 #endif
 
+#define SHORT_EMBED_TIMEOUT 5
+#define LONG_EMBED_TIMEOUT 15
+
 /* globals */
-static struct docklet_ui_ops *ui_ops = NULL;
+static GtkStatusIcon *docklet = NULL;
+static guint embed_timeout = 0;
 static PurpleStatusPrimitive status = PURPLE_STATUS_OFFLINE;
 static gboolean pending = FALSE;
 static gboolean connecting = FALSE;
@@ -58,9 +63,55 @@
 static gboolean visible = FALSE;
 static gboolean visibility_manager = FALSE;
 
+/* protos */
+static void docklet_gtk_status_create(gboolean);
+static void docklet_gtk_status_destroy(void);
+
 /**************************************************************************
  * docklet status and utility functions
  **************************************************************************/
+static void
+docklet_gtk_status_update_icon(PurpleStatusPrimitive status, gboolean connecting, gboolean pending)
+{
+	const gchar *icon_name = NULL;
+
+	switch (status) {
+		case PURPLE_STATUS_OFFLINE:
+			icon_name = PIDGIN_STOCK_TRAY_OFFLINE;
+			break;
+		case PURPLE_STATUS_AWAY:
+			icon_name = PIDGIN_STOCK_TRAY_AWAY;
+			break;
+		case PURPLE_STATUS_UNAVAILABLE:
+			icon_name = PIDGIN_STOCK_TRAY_BUSY;
+			break;
+		case PURPLE_STATUS_EXTENDED_AWAY:
+			icon_name = PIDGIN_STOCK_TRAY_XA;
+			break;
+		case PURPLE_STATUS_INVISIBLE:
+			icon_name = PIDGIN_STOCK_TRAY_INVISIBLE;
+			break;
+		default:
+			icon_name = PIDGIN_STOCK_TRAY_AVAILABLE;
+			break;
+	}
+
+	if (pending)
+		icon_name = PIDGIN_STOCK_TRAY_PENDING;
+	if (connecting)
+		icon_name = PIDGIN_STOCK_TRAY_CONNECT;
+
+	if (icon_name) {
+		gtk_status_icon_set_from_icon_name(docklet, icon_name);
+	}
+
+	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")) {
+		gtk_status_icon_set_blinking(docklet, (pending && !connecting));
+	} else if (gtk_status_icon_get_blinking(docklet)) {
+		gtk_status_icon_set_blinking(docklet, FALSE);
+	}
+}
+
 static gboolean
 docklet_blink_icon(gpointer data)
 {
@@ -70,11 +121,8 @@
 	blinked = !blinked;
 
 	if(pending && !connecting) {
-		if (blinked) {
-			if (ui_ops && ui_ops->blank_icon)
-				ui_ops->blank_icon();
-		} else {
-			pidgin_docklet_update_icon();
+		if (!blinked) {
+			docklet_gtk_status_update_icon(status, connecting, pending);
 		}
 		ret = TRUE; /* keep blinking */
 	} else {
@@ -126,12 +174,12 @@
 	convs = get_pending_list(DOCKLET_TOOLTIP_LINE_LIMIT);
 
 	if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) {
-		if (convs && ui_ops->create && !visible) {
+		if (convs && !visible) {
 			g_list_free(convs);
-			ui_ops->create();
+			docklet_gtk_status_create(FALSE);
 			return FALSE;
-		} else if (!convs && ui_ops->destroy && visible) {
-			ui_ops->destroy();
+		} else if (!convs && visible) {
+			docklet_gtk_status_destroy();
 			return FALSE;
 		}
 	}
@@ -142,53 +190,49 @@
 	}
 
 	if (convs != NULL) {
+		/* set tooltip if messages are pending */
+		GString *tooltip_text = g_string_new("");
 		newpending = TRUE;
 
-		/* set tooltip if messages are pending */
-		if (ui_ops->set_tooltip) {
-			GString *tooltip_text = g_string_new("");
-			for (l = convs, count = 0 ; l != NULL ; l = l->next, count++) {
-				PurpleConversation *conv = (PurpleConversation *)l->data;
-				PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
+		for (l = convs, count = 0 ; l != NULL ; l = l->next, count++) {
+			PurpleConversation *conv = (PurpleConversation *)l->data;
+			PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
 
-				if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) {
-					g_string_append(tooltip_text, _("Right-click for more unread messages...\n"));
-				} else if(gtkconv) {
-					g_string_append_printf(tooltip_text,
-						ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count),
-						gtkconv->unseen_count,
-						purple_conversation_get_title(conv));
-				} else {
-					g_string_append_printf(tooltip_text,
-						ngettext("%d unread message from %s\n", "%d unread messages from %s\n",
-						GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))),
-						GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")),
-						purple_conversation_get_title(conv));
-				}
+			if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) {
+				g_string_append(tooltip_text, _("Right-click for more unread messages...\n"));
+			} else if(gtkconv) {
+				g_string_append_printf(tooltip_text,
+					ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count),
+					gtkconv->unseen_count,
+					purple_conversation_get_title(conv));
+			} else {
+				g_string_append_printf(tooltip_text,
+					ngettext("%d unread message from %s\n", "%d unread messages from %s\n",
+					GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))),
+					GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")),
+					purple_conversation_get_title(conv));
 			}
-
-			/* get rid of the last newline */
-			if (tooltip_text->len > 0)
-				tooltip_text = g_string_truncate(tooltip_text, tooltip_text->len - 1);
-
-			ui_ops->set_tooltip(tooltip_text->str);
-
-			g_string_free(tooltip_text, TRUE);
 		}
 
+		/* get rid of the last newline */
+		if (tooltip_text->len > 0)
+			tooltip_text = g_string_truncate(tooltip_text, tooltip_text->len - 1);
+
+		gtk_status_icon_set_tooltip(docklet, tooltip_text->str);
+
+		g_string_free(tooltip_text, TRUE);
 		g_list_free(convs);
 
-	} else if (ui_ops->set_tooltip) {
+	} else {
 		char *tooltip_text = g_strconcat(PIDGIN_NAME, " - ",
 			purple_savedstatus_get_title(saved_status), NULL);
-		ui_ops->set_tooltip(tooltip_text);
+		gtk_status_icon_set_tooltip(docklet, tooltip_text);
 		g_free(tooltip_text);
 	}
 
 	for(l = purple_accounts_get_all(); l != NULL; l = l->next) {
 
 		PurpleAccount *account = (PurpleAccount*)l->data;
-		PurpleStatus *account_status;
 
 		if (!purple_account_get_enabled(account, PIDGIN_UI))
 			continue;
@@ -196,7 +240,6 @@
 		if (purple_account_is_disconnected(account))
 			continue;
 
-		account_status = purple_account_get_active_status(account);
 		if (purple_account_is_connecting(account))
 			newconnecting = TRUE;
 	}
@@ -209,7 +252,7 @@
 		pending = newpending;
 		connecting = newconnecting;
 
-		pidgin_docklet_update_icon();
+		docklet_gtk_status_update_icon(status, connecting, pending);
 
 		/* and schedule the blinker function if messages are pending */
 		if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")
@@ -288,17 +331,15 @@
 {
 	const char *val = value;
 	if (!strcmp(val, "always")) {
-		if (ui_ops->create) {
-			if (!visible)
-				ui_ops->create();
-			else if (!visibility_manager) {
-				pidgin_blist_visibility_manager_add();
-				visibility_manager = TRUE;
-			}
+		if (!visible)
+			docklet_gtk_status_create(FALSE);
+		else if (!visibility_manager) {
+			pidgin_blist_visibility_manager_add();
+			visibility_manager = TRUE;
 		}
 	} else if (!strcmp(val, "never")) {
-		if (visible && ui_ops->destroy)
-			ui_ops->destroy();
+		if (visible)
+			docklet_gtk_status_destroy();
 	} else {
 		if (visibility_manager) {
 			pidgin_blist_visibility_manager_remove();
@@ -752,21 +793,11 @@
 #endif
 	gtk_widget_show_all(menu);
 	gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
-		       ui_ops->position_menu,
-		       NULL, 0, gtk_get_current_event_time());
+		       gtk_status_icon_position_menu,
+		       docklet, 0, gtk_get_current_event_time());
 }
 
-/**************************************************************************
- * public api for ui_ops
- **************************************************************************/
-void
-pidgin_docklet_update_icon()
-{
-	if (ui_ops && ui_ops->update_icon)
-		ui_ops->update_icon(status, connecting, pending);
-}
-
-void
+static void
 pidgin_docklet_clicked(int button_type)
 {
 	switch (button_type) {
@@ -787,8 +818,8 @@
 	}
 }
 
-void
-pidgin_docklet_embedded()
+static void
+pidgin_docklet_embedded(void)
 {
 	if (!visibility_manager
 	    && strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) {
@@ -797,11 +828,11 @@
 	}
 	visible = TRUE;
 	docklet_update_status();
-	pidgin_docklet_update_icon();
+	docklet_gtk_status_update_icon(status, connecting, pending);
 }
 
-void
-pidgin_docklet_remove()
+static void
+pidgin_docklet_remove(void)
 {
 	if (visible) {
 		if (visibility_manager) {
@@ -817,12 +848,179 @@
 	}
 }
 
-void
-pidgin_docklet_set_ui_ops(struct docklet_ui_ops *ops)
+static gboolean
+docklet_gtk_recreate_cb(gpointer data)
+{
+	docklet_gtk_status_create(TRUE);
+
+	return FALSE;
+}
+
+static gboolean
+docklet_gtk_embed_timeout_cb(gpointer data)
 {
-	ui_ops = ops;
+#if !GTK_CHECK_VERSION(2,12,0)
+	if (gtk_status_icon_is_embedded(docklet)) {
+		/* Older GTK+ (<2.12) don't implement the embedded signal, but the
+		   information is still accessible through the above function. */
+		purple_debug_info("docklet", "embedded\n");
+
+		pidgin_docklet_embedded();
+		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
+	}
+	else
+#endif
+	{
+		/* The docklet was not embedded within the timeout.
+		 * Remove it as a visibility manager, but leave the plugin
+		 * loaded so that it can embed automatically if/when a notification
+		 * area becomes available.
+		 */
+		purple_debug_info("docklet", "failed to embed within timeout\n");
+		pidgin_docklet_remove();
+		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
+	}
+
+#if GTK_CHECK_VERSION(2,12,0)
+	embed_timeout = 0;
+	return FALSE;
+#else
+	return TRUE;
+#endif
+}
+
+#if GTK_CHECK_VERSION(2,12,0)
+static gboolean
+docklet_gtk_embedded_cb(GtkWidget *widget, gpointer data)
+{
+	if (embed_timeout) {
+		purple_timeout_remove(embed_timeout);
+		embed_timeout = 0;
+	}
+
+	if (gtk_status_icon_is_embedded(docklet)) {
+		purple_debug_info("docklet", "embedded\n");
+
+		pidgin_docklet_embedded();
+		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
+	} else {
+		purple_debug_info("docklet", "detached\n");
+
+		pidgin_docklet_remove();
+		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
+	}
+
+	return TRUE;
+}
+#endif
+
+static void
+docklet_gtk_destroyed_cb(GtkWidget *widget, gpointer data)
+{
+	purple_debug_info("docklet", "destroyed\n");
+
+	pidgin_docklet_remove();
+
+	g_object_unref(G_OBJECT(docklet));
+	docklet = NULL;
+
+	g_idle_add(docklet_gtk_recreate_cb, NULL);
+}
+
+static void
+docklet_gtk_status_activated_cb(GtkStatusIcon *status_icon, gpointer user_data)
+{
+	pidgin_docklet_clicked(1);
 }
 
+static void
+docklet_gtk_status_clicked_cb(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data)
+{
+	purple_debug_info("docklet", "The button is %u\n", button);
+#ifdef GDK_WINDOWING_QUARTZ
+	/* You can only click left mouse button on MacOSX native GTK. Let that be the menu */
+	pidgin_docklet_clicked(3);
+#else
+	pidgin_docklet_clicked(button);
+#endif
+}
+
+static void
+docklet_gtk_status_destroy(void)
+{
+	g_return_if_fail(docklet != NULL);
+
+	pidgin_docklet_remove();
+
+	if (embed_timeout) {
+		purple_timeout_remove(embed_timeout);
+		embed_timeout = 0;
+	}
+
+	gtk_status_icon_set_visible(docklet, FALSE);
+	g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
+	g_object_unref(G_OBJECT(docklet));
+	docklet = NULL;
+
+	purple_debug_info("docklet", "GTK+ destroyed\n");
+}
+
+static void
+docklet_gtk_status_create(gboolean recreate)
+{
+	if (docklet) {
+		/* if this is being called when a tray icon exists, it's because
+		   something messed up. try destroying it before we proceed,
+		   although docklet_refcount may be all hosed. hopefully won't happen. */
+		purple_debug_warning("docklet", "trying to create icon but it already exists?\n");
+		docklet_gtk_status_destroy();
+	}
+
+	docklet = gtk_status_icon_new();
+	g_return_if_fail(docklet != NULL);
+
+	g_signal_connect(G_OBJECT(docklet), "activate", G_CALLBACK(docklet_gtk_status_activated_cb), NULL);
+	g_signal_connect(G_OBJECT(docklet), "popup-menu", G_CALLBACK(docklet_gtk_status_clicked_cb), NULL);
+#if GTK_CHECK_VERSION(2,12,0)
+	g_signal_connect(G_OBJECT(docklet), "notify::embedded", G_CALLBACK(docklet_gtk_embedded_cb), NULL);
+#endif
+	g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
+
+	gtk_status_icon_set_visible(docklet, TRUE);
+
+	/* This is a hack to avoid a race condition between the docklet getting
+	 * embedded in the notification area and the gtkblist restoring its
+	 * previous visibility state.  If the docklet does not get embedded within
+	 * the timeout, it will be removed as a visibility manager until it does
+	 * get embedded.  Ideally, we would only call docklet_embedded() when the
+	 * icon was actually embedded. This only happens when the docklet is first
+	 * created, not when being recreated.
+	 *
+	 * The gtk docklet tracks whether it successfully embedded in a pref and
+	 * allows for a longer timeout period if it successfully embedded the last
+	 * time it was run. This should hopefully solve problems with the buddy
+	 * list not properly starting hidden when Pidgin is started on login.
+	 */
+	if (!recreate) {
+		pidgin_docklet_embedded();
+#if GTK_CHECK_VERSION(2,12,0)
+		if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded")) {
+			embed_timeout = purple_timeout_add_seconds(LONG_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
+		} else {
+			embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
+		}
+#else
+		embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
+#endif
+	}
+
+	purple_debug_info("docklet", "GTK+ created\n");
+}
+
+/**************************************************************************
+ * public api
+ **************************************************************************/
+ 
 void*
 pidgin_docklet_get_handle()
 {
@@ -838,6 +1036,7 @@
 	void *accounts_handle = purple_accounts_get_handle();
 	void *status_handle = purple_savedstatuses_get_handle();
 	void *docklet_handle = pidgin_docklet_get_handle();
+	gchar *tmp;
 
 	purple_prefs_add_none(PIDGIN_PREFS_ROOT "/docklet");
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/blink", FALSE);
@@ -845,9 +1044,20 @@
 	purple_prefs_connect_callback(docklet_handle, PIDGIN_PREFS_ROOT "/docklet/show",
 				    docklet_show_pref_changed_cb, NULL);
 
-	docklet_ui_init();
-	if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "always") && ui_ops && ui_ops->create)
-		ui_ops->create();
+	purple_prefs_add_none(PIDGIN_PREFS_ROOT "/docklet/gtk");
+	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/x11/embedded")) {
+		purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
+		purple_prefs_remove(PIDGIN_PREFS_ROOT "/docklet/x11/embedded");
+	} else {
+		purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
+	}
+
+	tmp = g_build_path(G_DIR_SEPARATOR_S, DATADIR, "pixmaps", "pidgin", "tray", NULL);
+	gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), tmp);
+	g_free(tmp);
+
+	if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "always"))
+		docklet_gtk_status_create(FALSE);
 
 	purple_signal_connect(conn_handle, "signed-on",
 			    docklet_handle, PURPLE_CALLBACK(docklet_signed_on_cb), NULL);
@@ -876,6 +1086,7 @@
 void
 pidgin_docklet_uninit()
 {
-	if (visible && ui_ops && ui_ops->destroy)
-		ui_ops->destroy();
+	if (visible)
+		docklet_gtk_status_destroy();
 }
+
--- a/pidgin/gtkdocklet.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkdocklet.h	Sun Sep 11 04:19:01 2011 +0000
@@ -25,31 +25,9 @@
 #ifndef _GTKDOCKLET_H_
 #define _GTKDOCKLET_H_
 
-#include "status.h"
-
-struct docklet_ui_ops
-{
-	void (*create)(void);
-	void (*destroy)(void);
-	void (*update_icon)(PurpleStatusPrimitive, gboolean, gboolean);
-	void (*blank_icon)(void);
-	void (*set_tooltip)(gchar *);
-	GtkMenuPositionFunc position_menu;
-};
-
-
-/* functions in gtkdocklet.c */
-void pidgin_docklet_update_icon(void);
-void pidgin_docklet_clicked(int);
-void pidgin_docklet_embedded(void);
-void pidgin_docklet_remove(void);
-void pidgin_docklet_set_ui_ops(struct docklet_ui_ops *);
-void pidgin_docklet_unload(void);
 void pidgin_docklet_init(void);
 void pidgin_docklet_uninit(void);
 void*pidgin_docklet_get_handle(void);
 
-/* function in gtkdocklet-{gtk,x11,win32}.c */
-void docklet_ui_init(void);
+#endif /* _GTKDOCKLET_H_ */
 
-#endif /* _GTKDOCKLET_H_ */
--- a/pidgin/gtkft.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkft.c	Sun Sep 11 04:19:01 2011 +0000
@@ -37,9 +37,6 @@
 #include "pidginstock.h"
 #include "gtkutils.h"
 
-#define PIDGINXFER(xfer) \
-	(PidginXferUiData *)(xfer)->ui_data
-
 /* the maximum size of files we will try to make a thumbnail for */
 #define PIDGIN_XFER_MAX_SIZE_IMAGE_THUMBNAIL 10 * 1024 * 1024
 
@@ -116,14 +113,17 @@
 	double kbps = 0.0;
 	time_t elapsed, now;
 
-	if (xfer->end_time != 0)
-		now = xfer->end_time;
-	else
+	now = purple_xfer_get_end_time(xfer);
+	if (now == 0)
 		now = time(NULL);
 
 	kb_sent = purple_xfer_get_bytes_sent(xfer) / 1024.0;
 	kb_rem  = purple_xfer_get_bytes_remaining(xfer) / 1024.0;
-	elapsed = (xfer->start_time > 0 ? now - xfer->start_time : 0);
+	elapsed = purple_xfer_get_start_time(xfer);
+	if (elapsed > 0)
+		elapsed = now - elapsed;
+	else
+		elapsed = 0;
 	kbps    = (elapsed > 0 ? (kb_sent / elapsed) : 0);
 
 	if (kbsec != NULL) {
@@ -135,9 +135,9 @@
 		int h, m, s;
 		int secs_elapsed;
 
-		if (xfer->start_time > 0)
+		if (purple_xfer_get_start_time(xfer) > 0)
 		{
-			secs_elapsed = now - xfer->start_time;
+			secs_elapsed = now - purple_xfer_get_start_time(xfer);
 
 			h = secs_elapsed / 3600;
 			m = (secs_elapsed % 3600) / 60;
@@ -243,7 +243,7 @@
 	if (dialog == NULL || xfer == NULL)
 		return;
 
-	data = PIDGINXFER(xfer);
+	data = purple_xfer_get_ui_data(xfer);
 
 	get_xfer_info_strings(xfer, &kbsec, &time_elapsed, &time_remaining);
 
@@ -281,10 +281,10 @@
 	}
 
 	gtk_label_set_text(GTK_LABEL(dialog->local_user_label),
-								 purple_account_get_username(xfer->account));
-	gtk_label_set_text(GTK_LABEL(dialog->remote_user_label), xfer->who);
+								 purple_account_get_username(purple_xfer_get_account(xfer)));
+	gtk_label_set_text(GTK_LABEL(dialog->remote_user_label), purple_xfer_get_remote_user(xfer));
 	gtk_label_set_text(GTK_LABEL(dialog->protocol_label),
-								 purple_account_get_protocol_name(xfer->account));
+								 purple_account_get_protocol_name(purple_xfer_get_account(xfer)));
 
 	if (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) {
 		gtk_label_set_text(GTK_LABEL(dialog->filename_label),
@@ -732,8 +732,8 @@
 	gtk_widget_show(vbox2);
 
 	/* Setup the listbox */
-	gtk_box_pack_start(GTK_BOX(vbox2), 
-		pidgin_make_scrollable(setup_tree(dialog), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 140), 
+	gtk_box_pack_start(GTK_BOX(vbox2),
+		pidgin_make_scrollable(setup_tree(dialog), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 140),
 		TRUE, TRUE, 0);
 
 	/* "Close this window when all transfers finish" */
@@ -869,7 +869,7 @@
 
 	purple_xfer_ref(xfer);
 
-	data = PIDGINXFER(xfer);
+	data = purple_xfer_get_ui_data(xfer);
 	data->in_list = TRUE;
 
 	pidgin_xfer_dialog_show(dialog);
@@ -926,7 +926,7 @@
 	g_return_if_fail(dialog != NULL);
 	g_return_if_fail(xfer != NULL);
 
-	data = PIDGINXFER(xfer);
+	data = purple_xfer_get_ui_data(xfer);
 
 	if (data == NULL)
 		return;
@@ -957,7 +957,7 @@
 	g_return_if_fail(dialog != NULL);
 	g_return_if_fail(xfer != NULL);
 
-	data = PIDGINXFER(xfer);
+	data = purple_xfer_get_ui_data(xfer);
 
 	if (data == NULL)
 		return;
@@ -970,7 +970,7 @@
 		return;
 	}
 
-	data = PIDGINXFER(xfer);
+	data = purple_xfer_get_ui_data(xfer);
 
 	update_detailed_info(dialog, xfer);
 	update_title_progress(dialog);
@@ -1007,7 +1007,7 @@
 	g_return_if_fail(dialog != NULL);
 	g_return_if_fail(xfer != NULL);
 
-	if ((data = PIDGINXFER(xfer)) == NULL)
+	if ((data = purple_xfer_get_ui_data(xfer)) == NULL)
 		return;
 
 	if (data->in_list == FALSE)
@@ -1095,9 +1095,9 @@
 {
 	PidginXferUiData *data;
 
-	/* This is where we're setting xfer->ui_data for the first time. */
+	/* This is where we're setting xfer's "ui_data" for the first time. */
 	data = g_new0(PidginXferUiData, 1);
-	xfer->ui_data = data;
+	purple_xfer_set_ui_data(xfer, data);
 }
 
 static void
@@ -1105,11 +1105,11 @@
 {
 	PidginXferUiData *data;
 
-	data = PIDGINXFER(xfer);
+	data = purple_xfer_get_ui_data(xfer);
 	if (data) {
 		g_free(data->name);
 		g_free(data);
-		xfer->ui_data = NULL;
+		purple_xfer_set_ui_data(xfer, NULL);
 	}
 }
 
--- a/pidgin/gtkgaim-compat.h	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,412 +0,0 @@
-/**
- * @file gtkgaim-compat.h Gtk Gaim Compat macros
- */
-
-/* pidgin
- *
- * Pidgin is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- *
- */
-#ifndef _GTKGAIM_COMPAT_H_
-#define _GTKGAIM_COMPAT_H_
-
-#include <pidginstock.h>
-
-#define GAIM_ALERT_TITLE PIDGIN_ALERT_TITLE
-#define GAIM_BROWSER_CURRENT PIDGIN_BROWSER_CURRENT
-#define GAIM_BROWSER_DEFAULT PIDGIN_BROWSER_DEFAULT
-#define GAIM_BROWSER_NEW_TAB PIDGIN_BROWSER_NEW_TAB
-#define GAIM_BROWSER_NEW_WINDOW PIDGIN_BROWSER_NEW_WINDOW
-#define GaimBrowserPlace PidginBrowserPlace
-#define GAIM_BUTTON_HORIZONTAL PIDGIN_BUTTON_HORIZONTAL
-#define GAIM_BUTTON_IMAGE PIDGIN_BUTTON_IMAGE
-#define GAIM_BUTTON_NONE PIDGIN_BUTTON_NONE
-#define GaimButtonOrientation PidginButtonOrientation
-#define GaimButtonStyle PidginButtonStyle
-#define GAIM_BUTTON_TEXT_IMAGE PIDGIN_BUTTON_TEXT_IMAGE
-#define GAIM_BUTTON_TEXT PIDGIN_BUTTON_TEXT
-#define GAIM_BUTTON_VERTICAL PIDGIN_BUTTON_VERTICAL
-#define GaimConvPlacementFunc PidginConvPlacementFunc
-#define GAIM_DIALOG PIDGIN_DIALOG
-#define gaim_dnd_file_manage pidgin_dnd_file_manage
-#define gaim_get_gtkxfer_dialog pidgin_get_xfer_dialog
-#define gaim_gtk_account_dialog_show pidgin_account_dialog_show
-#define GaimGtkAccountDialogType PidginAccountDialogType
-#define gaim_gtk_account_get_handle pidgin_account_get_handle
-#define gaim_gtk_account_init pidgin_account_init
-#define gaim_gtk_account_option_menu_get_selected pidgin_account_option_menu_get_selected
-#define gaim_gtk_account_option_menu_new pidgin_account_option_menu_new
-#define gaim_gtk_account_option_menu_set_selected pidgin_account_option_menu_set_selected
-#define gaim_gtk_accounts_get_ui_ops pidgin_accounts_get_ui_ops
-#define gaim_gtk_accounts_window_hide pidgin_accounts_window_hide
-#define gaim_gtk_accounts_window_show pidgin_accounts_window_show
-#define gaim_gtk_account_uninit pidgin_account_uninit
-#define GAIM_GTK_ADD_ACCOUNT_DIALOG PIDGIN_ADD_ACCOUNT_DIALOG
-#define gaim_gtk_append_blist_node_extended_menu pidgin_append_blist_node_extended_menu
-#define gaim_gtk_append_blist_node_privacy_menu pidgin_append_blist_node_privacy_menu
-#define gaim_gtk_append_blist_node_proto_menu pidgin_append_blist_node_proto_menu
-#define gaim_gtk_append_menu_action pidgin_append_menu_action
-#define gaim_gtk_blist_add_alert pidgin_blist_add_alert
-#define gaim_gtk_blist_get_default_gtk_blist pidgin_blist_get_default_gtk_blist
-#define gaim_gtk_blist_get_handle pidgin_blist_get_handle
-#define gaim_gtk_blist_get_sort_methods pidgin_blist_get_sort_methods
-#define gaim_gtk_blist_get_status_icon pidgin_blist_get_status_icon
-#define gaim_gtk_blist_get_ui_ops pidgin_blist_get_ui_ops
-#define gaim_gtk_blist_init pidgin_blist_init
-#define gaim_gtk_blist_joinchat_is_showable pidgin_blist_joinchat_is_showable
-#define gaim_gtk_blist_joinchat_show pidgin_blist_joinchat_show
-#define gaim_gtk_blist_make_buddy_menu pidgin_blist_make_buddy_menu
-#define gaim_gtk_blist_node_is_contact_expanded pidgin_blist_node_is_contact_expanded
-#define GAIM_GTK_BLIST PIDGIN_BLIST
-#define gaim_gtk_blist_refresh pidgin_blist_refresh
-#define gaim_gtk_blist_set_headline pidgin_blist_set_headline
-#define gaim_gtk_blist_setup_sort_methods pidgin_blist_setup_sort_methods
-#define gaim_gtk_blist_sort_function pidgin_blist_sort_function
-#define gaim_gtk_blist_sort_method pidgin_blist_sort_method
-#define GaimGtkBlistSortMethod PidginBlistSortMethod
-#define gaim_gtk_blist_sort_method_reg pidgin_blist_sort_method_reg
-#define gaim_gtk_blist_sort_method_set pidgin_blist_sort_method_set
-#define gaim_gtk_blist_sort_method_unreg pidgin_blist_sort_method_unreg
-#define gaim_gtk_blist_toggle_visibility pidgin_blist_toggle_visibility
-#define gaim_gtk_blist_uninit pidgin_blist_uninit
-#define gaim_gtk_blist_update_account_error_state pidgin_blist_update_account_error_state
-#define gaim_gtk_blist_update_accounts_menu pidgin_blist_update_accounts_menu
-#define gaim_gtk_blist_update_columns pidgin_blist_update_columns
-#define gaim_gtk_blist_update_plugin_actions pidgin_blist_update_plugin_actions
-#define gaim_gtk_blist_update_refresh_timeout pidgin_blist_update_refresh_timeout
-#define gaim_gtk_blist_update_sort_methods pidgin_blist_update_sort_methods
-#define gaim_gtk_blist_visibility_manager_add pidgin_blist_visibility_manager_add
-#define gaim_gtk_blist_visibility_manager_remove pidgin_blist_visibility_manager_remove
-#define gaim_gtk_buddy_icon_chooser_new pidgin_buddy_icon_chooser_new
-#define gaim_gtk_buddy_icon_get_scale_size pidgin_buddy_icon_get_scale_size
-#define GaimGtkBuddyList PidginBuddyList
-#define GaimGtkCellRendererExpanderClass PidginCellRendererExpanderClass
-#define gaim_gtk_cell_renderer_expander_get_type pidgin_cell_renderer_expander_get_type
-#define gaim_gtk_cell_renderer_expander_new pidgin_cell_renderer_expander_new
-#define GaimGtkCellRendererExpander PidginCellRendererExpander
-#define GaimGtkCellRendererProgressClass PidginCellRendererProgressClass
-#define gaim_gtk_cell_renderer_progress_get_type pidgin_cell_renderer_progress_get_type
-#define gaim_gtk_cell_renderer_progress_new pidgin_cell_renderer_progress_new
-#define GaimGtkCellRendererProgress PidginCellRendererProgress
-#define GaimGtkChatPane PidginChatPane
-#define gaim_gtk_check_if_dir pidgin_check_if_dir
-#define gaim_gtk_clear_cursor pidgin_clear_cursor
-#define gaim_gtk_connection_get_handle pidgin_connection_get_handle
-#define gaim_gtk_connection_init pidgin_connection_init
-#define gaim_gtk_connections_get_ui_ops pidgin_connections_get_ui_ops
-#define gaim_gtk_connection_uninit pidgin_connection_uninit
-#define GaimGtkConversation PidginConversation
-#define GAIM_GTK_CONVERSATION PIDGIN_CONVERSATION
-#define gaim_gtk_conversations_fill_menu pidgin_conversations_fill_menu
-#define gaim_gtk_conversations_find_unseen_list pidgin_conversations_find_unseen_list
-#define gaim_gtk_conversations_get_conv_ui_ops pidgin_conversations_get_conv_ui_ops
-#define gaim_gtk_conversations_get_handle pidgin_conversations_get_handle
-#define gaim_gtk_conversations_init pidgin_conversations_init
-#define gaim_gtk_conversations_uninit pidgin_conversations_uninit
-#define gaim_gtk_convert_buddy_icon pidgin_convert_buddy_icon
-#define gaim_gtkconv_get_tab_at_xy pidgin_conv_get_tab_at_xy
-#define gaim_gtkconv_get_tab_icon pidgin_conv_get_tab_icon
-#define gaim_gtkconv_get_window pidgin_conv_get_window
-#define gaim_gtkconv_is_hidden pidgin_conv_is_hidden
-#define gaim_gtkconv_new pidgin_conv_new
-#define gaim_gtkconv_placement_add_fnc pidgin_conv_placement_add_fnc
-#define gaim_gtkconv_placement_get_current_func pidgin_conv_placement_get_current_func
-#define gaim_gtkconv_placement_get_fnc pidgin_conv_placement_get_fnc
-#define gaim_gtkconv_placement_get_name pidgin_conv_placement_get_name
-#define gaim_gtkconv_placement_get_options pidgin_conv_placement_get_options
-#define gaim_gtkconv_placement_place pidgin_conv_placement_place
-#define gaim_gtkconv_placement_remove_fnc pidgin_conv_placement_remove_fnc
-#define gaim_gtkconv_placement_set_current_func pidgin_conv_placement_set_current_func
-#define gaim_gtkconv_present_conversation pidgin_conv_present_conversation
-#define gaim_gtkconv_switch_active_conversation pidgin_conv_switch_active_conversation
-#define gaim_gtkconv_update_buddy_icon pidgin_conv_update_buddy_icon
-#define gaim_gtkconv_update_buttons_by_protocol pidgin_conv_update_buttons_by_protocol
-#define gaim_gtk_conv_window_add_gtkconv pidgin_conv_window_add_gtkconv
-#define gaim_gtk_conv_window_destroy pidgin_conv_window_destroy
-#define gaim_gtk_conv_window_first_with_type pidgin_conv_window_first_with_type
-#define gaim_gtk_conv_window_get_active_conversation pidgin_conv_window_get_active_conversation
-#define gaim_gtk_conv_window_get_active_gtkconv pidgin_conv_window_get_active_gtkconv
-#define gaim_gtk_conv_window_get_at_xy pidgin_conv_window_get_at_xy
-#define gaim_gtk_conv_window_get_gtkconv_at_index pidgin_conv_window_get_gtkconv_at_index
-#define gaim_gtk_conv_window_get_gtkconv_count pidgin_conv_window_get_gtkconv_count
-#define gaim_gtk_conv_window_get_gtkconvs pidgin_conv_window_get_gtkconvs
-#define gaim_gtk_conv_window_has_focus pidgin_conv_window_has_focus
-#define gaim_gtk_conv_window_hide pidgin_conv_window_hide
-#define gaim_gtk_conv_window_is_active_conversation pidgin_conv_window_is_active_conversation
-#define gaim_gtk_conv_window_last_with_type pidgin_conv_window_last_with_type
-#define gaim_gtk_conv_window_new pidgin_conv_window_new
-#define gaim_gtk_conv_window_raise pidgin_conv_window_raise
-#define gaim_gtk_conv_window_remove_gtkconv pidgin_conv_window_remove_gtkconv
-#define gaim_gtk_conv_windows_get_list pidgin_conv_windows_get_list
-#define gaim_gtk_conv_window_show pidgin_conv_window_show
-#define gaim_gtk_conv_window_switch_gtkconv pidgin_conv_window_switch_gtkconv
-#define gaim_gtk_create_imhtml pidgin_create_imhtml
-#define gaim_gtk_debug_get_handle pidgin_debug_get_handle
-#define gaim_gtk_debug_get_ui_ops pidgin_debug_get_ui_ops
-#define gaim_gtk_debug_init pidgin_debug_init
-#define gaim_gtk_debug_uninit pidgin_debug_uninit
-#define gaim_gtk_debug_window_hide pidgin_debug_window_hide
-#define gaim_gtk_debug_window_show pidgin_debug_window_show
-#define gaim_gtkdialogs_about pidgin_dialogs_about
-#define gaim_gtkdialogs_alias_buddy pidgin_dialogs_alias_buddy
-#define gaim_gtkdialogs_alias_chat pidgin_dialogs_alias_chat
-#define gaim_gtkdialogs_alias_contact pidgin_dialogs_alias_contact
-#define gaim_gtkdialogs_destroy_all pidgin_dialogs_destroy_all
-#define gaim_gtkdialogs_im pidgin_dialogs_im
-#define gaim_gtkdialogs_im_with_user pidgin_dialogs_im_with_user
-#define gaim_gtkdialogs_info pidgin_dialogs_info
-#define gaim_gtkdialogs_log pidgin_dialogs_log
-#define gaim_gtkdialogs_merge_groups pidgin_dialogs_merge_groups
-#define gaim_gtkdialogs_remove_buddy pidgin_dialogs_remove_buddy
-#define gaim_gtkdialogs_remove_chat pidgin_dialogs_remove_chat
-#define gaim_gtkdialogs_remove_contact pidgin_dialogs_remove_contact
-#define gaim_gtkdialogs_remove_group pidgin_dialogs_remove_group
-#define gaim_gtk_docklet_clicked pidgin_docklet_clicked
-#define gaim_gtk_docklet_embedded pidgin_docklet_embedded
-#define gaim_gtk_docklet_get_handle pidgin_docklet_get_handle
-#define gaim_gtk_docklet_init pidgin_docklet_init
-#define gaim_gtk_docklet_remove pidgin_docklet_remove
-#define gaim_gtk_docklet_set_ui_ops pidgin_docklet_set_ui_ops
-#define gaim_gtk_docklet_uninit pidgin_docklet_uninit
-#define gaim_gtk_docklet_unload pidgin_docklet_unload
-#define gaim_gtk_eventloop_get_ui_ops pidgin_eventloop_get_ui_ops
-#define gaim_gtk_idle_get_ui_ops pidgin_idle_get_ui_ops
-#define GaimGtkImPane PidginImPane
-#define gaim_gtk_load_accels pidgin_load_accels
-#define gaim_gtk_log_get_handle pidgin_log_get_handle
-#define gaim_gtk_log_init pidgin_log_init
-#define gaim_gtk_log_show_contact pidgin_log_show_contact
-#define gaim_gtk_log_show pidgin_log_show
-#define gaim_gtk_log_uninit pidgin_log_uninit
-#define GaimGtkLogViewer PidginLogViewer
-#define gaim_gtk_make_frame pidgin_make_frame
-#define gaim_gtk_make_mini_dialog pidgin_make_mini_dialog
-#define gaim_gtk_make_pretty_arrows pidgin_make_pretty_arrows
-#define gaim_gtk_menu_tray_append pidgin_menu_tray_append
-#define GaimGtkMenuTrayClass PidginMenuTrayClass
-#define gaim_gtk_menu_tray_get_box pidgin_menu_tray_get_box
-#define gaim_gtk_menu_tray_get_gtype pidgin_menu_tray_get_gtype
-#define gaim_gtk_menu_tray_new pidgin_menu_tray_new
-#define GaimGtkMenuTray PidginMenuTray
-#define GAIM_GTK_MENU_TRAY PIDGIN_MENU_TRAY
-#define gaim_gtk_menu_tray_prepend pidgin_menu_tray_prepend
-#define gaim_gtk_menu_tray_set_tooltip pidgin_menu_tray_set_tooltip
-#define GAIM_GTK_MODIFY_ACCOUNT_DIALOG PIDGIN_MODIFY_ACCOUNT_DIALOG
-#define gaim_gtk_notify_get_ui_ops pidgin_notify_get_ui_ops
-#define gaim_gtk_parse_x_im_contact pidgin_parse_x_im_contact
-#define gaim_gtk_plugin_dialog_show pidgin_plugin_dialog_show
-#define gaim_gtk_plugin_get_config_frame pidgin_plugin_get_config_frame
-#define GAIM_GTK_PLUGIN PIDGIN_PLUGIN
-#define gaim_gtk_plugin_pref_create_frame pidgin_plugin_pref_create_frame
-#define gaim_gtk_plugins_save pidgin_plugins_save
-#define GAIM_GTK_PLUGIN_TYPE PIDGIN_PLUGIN_TYPE
-#define GaimGtkPluginUiInfo PidginPluginUiInfo
-#define GAIM_GTK_PLUGIN_UI_INFO PIDGIN_PLUGIN_UI_INFO
-#define gaim_gtk_pounce_editor_show pidgin_pounce_editor_show
-#define gaim_gtk_pounces_get_handle pidgin_pounces_get_handle
-#define gaim_gtk_pounces_init pidgin_pounces_init
-#define gaim_gtk_pounces_manager_hide pidgin_pounces_manager_hide
-#define gaim_gtk_pounces_manager_show pidgin_pounces_manager_show
-#define gaim_gtk_prefs_checkbox pidgin_prefs_checkbox
-#define gaim_gtk_prefs_dropdown_from_list pidgin_prefs_dropdown_from_list
-#define gaim_gtk_prefs_dropdown pidgin_prefs_dropdown
-#define gaim_gtk_prefs_init pidgin_prefs_init
-#define gaim_gtk_prefs_labeled_entry pidgin_prefs_labeled_entry
-#define gaim_gtk_prefs_labeled_spin_button pidgin_prefs_labeled_spin_button
-#define gaim_gtk_prefs_show pidgin_prefs_show
-#define gaim_gtk_prefs_update_old pidgin_prefs_update_old
-#define gaim_gtk_privacy_dialog_hide pidgin_privacy_dialog_hide
-#define gaim_gtk_privacy_dialog_show pidgin_privacy_dialog_show
-#define gaim_gtk_privacy_get_ui_ops pidgin_privacy_get_ui_ops
-#define gaim_gtk_privacy_init pidgin_privacy_init
-#define gaim_gtk_protocol_option_menu_new pidgin_protocol_option_menu_new
-#define gaim_gtk_request_add_block pidgin_request_add_block
-#define gaim_gtk_request_add_permit pidgin_request_add_permit
-#define gaim_gtk_request_get_ui_ops pidgin_request_get_ui_ops
-#define gaim_gtk_roomlist_dialog_show pidgin_roomlist_dialog_show
-#define gaim_gtk_roomlist_dialog_show_with_account pidgin_roomlist_dialog_show_with_account
-#define gaim_gtk_roomlist_init pidgin_roomlist_init
-#define gaim_gtk_roomlist_is_showable pidgin_roomlist_is_showable
-#define gaim_gtk_save_accels_cb pidgin_save_accels_cb
-#define gaim_gtk_save_accels pidgin_save_accels
-#define gaim_gtk_session_end pidgin_session_end
-#define gaim_gtk_session_init pidgin_session_init
-#define gaim_gtk_set_cursor pidgin_set_cursor
-#define gaim_gtk_set_custom_buddy_icon pidgin_set_custom_buddy_icon
-#define gaim_gtk_set_sensitive_if_input pidgin_set_sensitive_if_input
-#define gaim_gtk_setup_gtkspell pidgin_setup_gtkspell
-#define gaim_gtk_setup_screenname_autocomplete pidgin_setup_screenname_autocomplete
-#define gaim_gtk_set_urgent pidgin_set_urgent
-#define gaim_gtk_sound_get_event_label pidgin_sound_get_event_label
-#define gaim_gtk_sound_get_event_option pidgin_sound_get_event_option
-#define gaim_gtk_sound_get_handle pidgin_sound_get_handle
-#define gaim_gtk_sound_get_ui_ops pidgin_sound_get_ui_ops
-#define gaim_gtk_status_editor_show pidgin_status_editor_show
-#define gaim_gtk_status_get_handle pidgin_status_get_handle
-#define gaim_gtk_status_init pidgin_status_init
-#define gaim_gtk_status_menu pidgin_status_menu
-#define gaim_gtk_status_uninit pidgin_status_uninit
-#define gaim_gtk_status_window_hide pidgin_status_window_hide
-#define gaim_gtk_status_window_show pidgin_status_window_show
-#define gaim_gtk_stock_init pidgin_stock_init
-#define gaim_gtk_syslog_show pidgin_syslog_show
-#define gaim_gtkthemes_get_proto_smileys pidgin_themes_get_proto_smileys
-#define gaim_gtkthemes_init pidgin_themes_init
-#define gaim_gtkthemes_load_smiley_theme pidgin_themes_load_smiley_theme
-#define gaim_gtkthemes_smileys_disabled pidgin_themes_smileys_disabled
-#define gaim_gtkthemes_smiley_themeize pidgin_themes_smiley_themeize
-#define gaim_gtkthemes_smiley_theme_probe pidgin_themes_smiley_theme_probe
-#define gaim_gtk_toggle_sensitive_array pidgin_toggle_sensitive_array
-#define gaim_gtk_toggle_sensitive pidgin_toggle_sensitive
-#define gaim_gtk_toggle_showhide pidgin_toggle_showhide
-#define gaim_gtk_treeview_popup_menu_position_func pidgin_treeview_popup_menu_position_func
-#define gaim_gtk_tree_view_search_equal_func pidgin_tree_view_search_equal_func
-#define GAIM_GTK_TYPE_MENU_TRAY PIDGIN_TYPE_MENU_TRAY
-#define GAIM_GTK_UI PIDGIN_UI
-#define gaim_gtk_whiteboard_get_ui_ops pidgin_whiteboard_get_ui_ops
-#define GaimGtkWhiteboard PidginWhiteboard
-#define GaimGtkWindow PidginWindow
-#define gaim_gtkxfer_dialog_add_xfer pidgin_xfer_dialog_add_xfer
-#define gaim_gtkxfer_dialog_cancel_xfer pidgin_xfer_dialog_cancel_xfer
-#define gaim_gtkxfer_dialog_destroy pidgin_xfer_dialog_destroy
-#define gaim_gtkxfer_dialog_hide pidgin_xfer_dialog_hide
-#define gaim_gtkxfer_dialog_new pidgin_xfer_dialog_new
-#define GaimGtkXferDialog PidginXferDialog
-#define gaim_gtkxfer_dialog_remove_xfer pidgin_xfer_dialog_remove_xfer
-#define gaim_gtkxfer_dialog_show pidgin_xfer_dialog_show
-#define gaim_gtkxfer_dialog_update_xfer pidgin_xfer_dialog_update_xfer
-#define gaim_gtk_xfers_get_ui_ops pidgin_xfers_get_ui_ops
-#define gaim_gtk_xfers_init pidgin_xfers_init
-#define gaim_gtk_xfers_uninit pidgin_xfers_uninit
-#define GAIM_HIG_BORDER PIDGIN_HIG_BORDER
-#define GAIM_HIG_BOX_SPACE PIDGIN_HIG_BOX_SPACE
-#define GAIM_HIG_CAT_SPACE PIDGIN_HIG_CAT_SPACE
-#if !GTK_CHECK_VERSION(2,16,0)
-#define GAIM_INVISIBLE_CHAR PIDGIN_INVISIBLE_CHAR
-#endif /* Less than GTK+ 2.16 */
-#define GAIM_IS_GTK_CONVERSATION PIDGIN_IS_PIDGIN_CONVERSATION
-#define GAIM_IS_GTK_PLUGIN PIDGIN_IS_PIDGIN_PLUGIN
-#define gaim_new_check_item pidgin_new_check_item
-#define gaim_new_item_from_stock pidgin_new_item_from_stock
-#define gaim_new_item pidgin_new_item
-#define gaim_pixbuf_button_from_stock pidgin_pixbuf_button_from_stock
-#define gaim_pixbuf_toolbar_button_from_stock pidgin_pixbuf_toolbar_button_from_stock
-#define GaimScrollBookClass PidginScrollBookClass
-#define gaim_scroll_book_get_type pidgin_scroll_book_get_type
-#define gaim_scroll_book_new pidgin_scroll_book_new
-#define GaimScrollBook PidginScrollBook
-#define gaim_separator pidgin_separator
-#define gaim_set_accessible_label pidgin_set_accessible_label
-#define gaim_set_gtkxfer_dialog pidgin_set_xfer_dialog
-#define gaim_setup_imhtml pidgin_setup_imhtml
-#define gaim_status_box_add pidgin_status_box_add
-#define gaim_status_box_add_separator pidgin_status_box_add_separator
-#define GaimStatusBoxClass PidginStatusBoxClass
-#define gaim_status_box_get_buddy_icon pidgin_status_box_get_buddy_icon
-#define gaim_status_box_get_message pidgin_status_box_get_message
-#define gaim_status_box_get_type pidgin_status_box_get_type
-#define GaimStatusBoxItemType PidginStatusBoxItemType
-#define gaim_status_box_new pidgin_status_box_new
-#define gaim_status_box_new_with_account pidgin_status_box_new_with_account
-#define GaimStatusBox PidginStatusBox
-#define gaim_status_box_pulse_connecting pidgin_status_box_pulse_connecting
-#define gaim_status_box_set_buddy_icon pidgin_status_box_set_buddy_icon
-#define gaim_status_box_set_connecting pidgin_status_box_set_connecting
-#define gaim_status_box_set_network_available pidgin_status_box_set_network_available
-#define GAIM_STATUS_ICON_LARGE PIDGIN_STATUS_ICON_LARGE
-#define GaimStatusIconSize PidginStatusIconSize
-#define GAIM_STATUS_ICON_SMALL PIDGIN_STATUS_ICON_SMALL
-#define GAIM_STOCK_ABOUT PIDGIN_STOCK_ABOUT
-#define GAIM_STOCK_ACTION PIDGIN_STOCK_ACTION
-#define GAIM_STOCK_ALIAS PIDGIN_STOCK_ALIAS
-#define GAIM_STOCK_AWAY PIDGIN_STOCK_AWAY
-#define GAIM_STOCK_CHAT PIDGIN_STOCK_CHAT
-#define GAIM_STOCK_CLEAR PIDGIN_STOCK_CLEAR
-#define GAIM_STOCK_CLOSE_TABS PIDGIN_STOCK_CLOSE_TABS
-#define GAIM_STOCK_DEBUG PIDGIN_STOCK_DEBUG
-#define GAIM_STOCK_DIALOG_AUTH PIDGIN_STOCK_DIALOG_AUTH
-#define GAIM_STOCK_DIALOG_COOL PIDGIN_STOCK_DIALOG_COOL
-#define GAIM_STOCK_DIALOG_ERROR PIDGIN_STOCK_DIALOG_ERROR
-#define GAIM_STOCK_DIALOG_INFO PIDGIN_STOCK_DIALOG_INFO
-#define GAIM_STOCK_DIALOG_QUESTION PIDGIN_STOCK_DIALOG_QUESTION
-#define GAIM_STOCK_DIALOG_WARNING PIDGIN_STOCK_DIALOG_WARNING
-#define GAIM_STOCK_DISCONNECT PIDGIN_STOCK_DISCONNECT
-#define GAIM_STOCK_DOWNLOAD PIDGIN_STOCK_DOWNLOAD
-#define GAIM_STOCK_EDIT PIDGIN_STOCK_EDIT
-#define GAIM_STOCK_FGCOLOR PIDGIN_STOCK_FGCOLOR
-#define GAIM_STOCK_FILE_CANCELED PIDGIN_STOCK_FILE_CANCELED
-#define GAIM_STOCK_FILE_DONE PIDGIN_STOCK_FILE_DONE
-#define GAIM_STOCK_FILE_TRANSFER PIDGIN_STOCK_FILE_TRANSFER
-#define GAIM_STOCK_IGNORE PIDGIN_STOCK_IGNORE
-#define GAIM_STOCK_IM "gaim-im" /* foo... */
-#define GAIM_STOCK_INVITE PIDGIN_STOCK_INVITE
-#define GAIM_STOCK_MODIFY PIDGIN_STOCK_MODIFY
-#define GAIM_STOCK_OPEN_MAIL PIDGIN_STOCK_OPEN_MAIL
-#define GAIM_STOCK_PAUSE PIDGIN_STOCK_PAUSE
-#define GAIM_STOCK_POUNCE PIDGIN_STOCK_POUNCE
-#define GAIM_STOCK_SIGN_OFF PIDGIN_STOCK_SIGN_OFF
-#define GAIM_STOCK_SIGN_ON PIDGIN_STOCK_SIGN_ON
-#define GAIM_STOCK_STATUS_OFFLINE PIDGIN_STOCK_STATUS_OFFLINE
-#define GAIM_STOCK_TEXT_NORMAL PIDGIN_STOCK_TEXT_NORMAL
-#define GAIM_STOCK_TYPED PIDGIN_STOCK_TYPED
-#define GAIM_STOCK_UPLOAD PIDGIN_STOCK_UPLOAD
-#define GAIM_TYPE_GTK_CELL_RENDERER_EXPANDER PIDGIN_TYPE_GTK_CELL_RENDERER_EXPANDER
-#define GAIM_TYPE_GTK_CELL_RENDERER_PROGRESS PIDGIN_TYPE_GTK_CELL_RENDERER_PROGRESS
-#define GAIM_UNSEEN_EVENT PIDGIN_UNSEEN_EVENT
-#define GAIM_UNSEEN_NICK PIDGIN_UNSEEN_NICK
-#define GAIM_UNSEEN_NO_LOG PIDGIN_UNSEEN_NO_LOG
-#define GAIM_UNSEEN_NONE PIDGIN_UNSEEN_NONE
-#define GaimUnseenState PidginUnseenState
-#define GAIM_UNSEEN_TEXT PIDGIN_UNSEEN_TEXT
-#define GAIM_WINDOW_ICONIFIED PIDGIN_WINDOW_ICONIFIED
-#define GTK_GAIM_IS_SCROLL_BOOK_CLASS PIDGIN_IS_SCROLL_BOOK_CLASS
-#define GTK_GAIM_IS_SCROLL_BOOK PIDGIN_IS_SCROLL_BOOK
-#define GTK_GAIM_IS_STATUS_BOX_CLASS PIDGIN_IS_STATUS_BOX_CLASS
-#define GTK_GAIM_IS_STATUS_BOX PIDGIN_IS_STATUS_BOX
-#define GTK_GAIM_SCROLL_BOOK_CLASS PIDGIN_SCROLL_BOOK_CLASS
-#define GTK_GAIM_SCROLL_BOOK_GET_CLASS PIDGIN_SCROLL_BOOK_GET_CLASS
-#define gtk_gaim_scroll_book_get_type pidgin_scroll_book_get_type
-#define gtk_gaim_scroll_book_new pidgin_scroll_book_new
-#define GTK_GAIM_SCROLL_BOOK PIDGIN_SCROLL_BOOK
-#define gtk_gaim_status_box_add pidgin_status_box_add
-#define gtk_gaim_status_box_add_separator pidgin_status_box_add_separator
-#define GTK_GAIM_STATUS_BOX_CLASS PIDGIN_STATUS_BOX_CLASS
-#define gtk_gaim_status_box_get_buddy_icon pidgin_status_box_get_buddy_icon
-#define GTK_GAIM_STATUS_BOX_GET_CLASS PIDGIN_STATUS_BOX_GET_CLASS
-#define gtk_gaim_status_box_get_message pidgin_status_box_get_message
-#define gtk_gaim_status_box_get_type pidgin_status_box_get_type
-#define GtkGaimStatusBoxItemType PidginStatusBoxItemType
-#define gtk_gaim_status_box_new pidgin_status_box_new
-#define gtk_gaim_status_box_new_with_account pidgin_status_box_new_with_account
-#define GTK_GAIM_STATUS_BOX_NUM_TYPES PIDGIN_STATUS_BOX_NUM_TYPES
-#define GtkGaimStatusBox PidginStatusBox
-#define GTK_GAIM_STATUS_BOX PIDGIN_STATUS_BOX
-#define gtk_gaim_status_box_pulse_connecting pidgin_status_box_pulse_connecting
-#define gtk_gaim_status_box_set_buddy_icon pidgin_status_box_set_buddy_icon
-#define gtk_gaim_status_box_set_connecting pidgin_status_box_set_connecting
-#define gtk_gaim_status_box_set_network_available pidgin_status_box_set_network_available
-#define GTK_GAIM_STATUS_BOX_TYPE_CUSTOM PIDGIN_STATUS_BOX_TYPE_CUSTOM
-#define GTK_GAIM_STATUS_BOX_TYPE_POPULAR PIDGIN_STATUS_BOX_TYPE_POPULAR
-#define GTK_GAIM_STATUS_BOX_TYPE_PRIMITIVE PIDGIN_STATUS_BOX_TYPE_PRIMITIVE
-#define GTK_GAIM_STATUS_BOX_TYPE_SAVED PIDGIN_STATUS_BOX_TYPE_SAVED
-#define GTK_GAIM_STATUS_BOX_TYPE_SEPARATOR PIDGIN_STATUS_BOX_TYPE_SEPARATOR
-#define GTK_GAIM_TYPE_SCROLL_BOOK PIDGIN_TYPE_SCROLL_BOOK
-#define GTK_GAIM_TYPE_STATUS_BOX PIDGIN_TYPE_STATUS_BOX
-
-#endif /* _GTKGAIM_COMPAT_H */
--- a/pidgin/gtkimhtml.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkimhtml.c	Sun Sep 11 04:19:01 2011 +0000
@@ -90,8 +90,7 @@
 	GtkTextTag *tag;
 };
 
-typedef struct _GtkIMHtmlProtocol
-{
+typedef struct {
 	char *name;
 	int length;
 
@@ -99,7 +98,8 @@
 	gboolean (*context_menu)(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu);
 } GtkIMHtmlProtocol;
 
-typedef struct _GtkIMHtmlFontDetail {
+/* The five elements contained in a FONT tag */
+typedef struct {
 	gushort size;
 	gchar *face;
 	gchar *fore;
@@ -3593,125 +3593,38 @@
 	gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &iter, 0, TRUE, 0, 0);
 }
 
-/* GtkIMHtmlScalable, gtk_imhtml_image, gtk_imhtml_hr */
-GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id)
-{
-	GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage));
-
-	GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale;
-	GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to;
-	GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_image_free;
-
-	im_image->pixbuf = img;
-	im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf));
-	im_image->width = gdk_pixbuf_get_width(img);
-	im_image->height = gdk_pixbuf_get_height(img);
-	im_image->mark = NULL;
-	im_image->filename = g_strdup(filename);
-	im_image->id = id;
-	im_image->filesel = NULL;
-
-	g_object_ref(img);
-	return GTK_IMHTML_SCALABLE(im_image);
-}
-
-static gboolean
-animate_image_cb(gpointer data)
-{
-	GtkIMHtmlImage *im_image;
-	int width, height;
-	int delay;
-
-	im_image = data;
-
-	/* Update the pointer to this GdkPixbuf frame of the animation */
-	if (gdk_pixbuf_animation_iter_advance(GTK_IMHTML_ANIMATION(im_image)->iter, NULL)) {
-		GdkPixbuf *pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
-		g_object_unref(G_OBJECT(im_image->pixbuf));
-		im_image->pixbuf = gdk_pixbuf_copy(pb);
-
-		/* Update the displayed GtkImage */
-		width = gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image));
-		height = gdk_pixbuf_get_height(gtk_image_get_pixbuf(im_image->image));
-		if (width > 0 && height > 0)
-		{
-			/* Need to scale the new frame to the same size as the old frame */
-			GdkPixbuf *tmp;
-			tmp = gdk_pixbuf_scale_simple(im_image->pixbuf, width, height, GDK_INTERP_BILINEAR);
-			gtk_image_set_from_pixbuf(im_image->image, tmp);
-			g_object_unref(G_OBJECT(tmp));
-		} else {
-			/* Display at full-size */
-			gtk_image_set_from_pixbuf(im_image->image, im_image->pixbuf);
-		}
-	}
-
-	delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
-	GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image);
-
-	return FALSE;
-}
-
-GtkIMHtmlScalable *gtk_imhtml_animation_new(GdkPixbufAnimation *anim, const gchar *filename, int id)
-{
-	GtkIMHtmlImage *im_image = (GtkIMHtmlImage *) g_new0(GtkIMHtmlAnimation, 1);
-
-	GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale;
-	GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to;
-	GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_animation_free;
-
-	GTK_IMHTML_ANIMATION(im_image)->anim = anim;
-	if (gdk_pixbuf_animation_is_static_image(anim)) {
-		im_image->pixbuf = gdk_pixbuf_animation_get_static_image(anim);
-		g_object_ref(im_image->pixbuf);
-	} else {
-		int delay;
-		GdkPixbuf *pb;
-		GTK_IMHTML_ANIMATION(im_image)->iter = gdk_pixbuf_animation_get_iter(anim, NULL);
-		pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
-		im_image->pixbuf = gdk_pixbuf_copy(pb);
-		delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
-		GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image);
-	}
-	im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf));
-	im_image->width = gdk_pixbuf_animation_get_width(anim);
-	im_image->height = gdk_pixbuf_animation_get_height(anim);
-	im_image->filename = g_strdup(filename);
-	im_image->id = id;
-
-	g_object_ref(anim);
-
-	return GTK_IMHTML_SCALABLE(im_image);
-}
-
-void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height)
-{
-	GtkIMHtmlImage *im_image = (GtkIMHtmlImage *)scale;
-
-	if (im_image->width > width || im_image->height > height) {
-		double ratio_w, ratio_h, ratio;
-		int new_h, new_w;
-		GdkPixbuf *new_image = NULL;
-
-		ratio_w = ((double)width - 2) / im_image->width;
-		ratio_h = ((double)height - 2) / im_image->height;
-
-		ratio = (ratio_w < ratio_h) ? ratio_w : ratio_h;
-
-		new_w = (int)(im_image->width * ratio);
-		new_h = (int)(im_image->height * ratio);
-
-		new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, new_w, new_h, GDK_INTERP_BILINEAR);
-		gtk_image_set_from_pixbuf(im_image->image, new_image);
-		g_object_unref(G_OBJECT(new_image));
-	} else if (gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)) != im_image->width) {
-		/* Enough space to show the full-size of the image. */
-		GdkPixbuf *new_image;
-
-		new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, im_image->width, im_image->height, GDK_INTERP_BILINEAR);
-		gtk_image_set_from_pixbuf(im_image->image, new_image);
-		g_object_unref(G_OBJECT(new_image));
-	}
+/**
+ * Destroys and frees a GTK+ IM/HTML scalable image.
+ *
+ * @param scale The GTK+ IM/HTML scalable.
+ */
+static void gtk_imhtml_image_free(GtkIMHtmlScalable *scale)
+{
+	GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale;
+
+	g_object_unref(image->pixbuf);
+	g_free(image->filename);
+	if (image->filesel)
+		gtk_widget_destroy(image->filesel);
+	g_free(scale);
+}
+
+/**
+ * Destroys and frees a GTK+ IM/HTML scalable animation.
+ *
+ * @param scale The GTK+ IM/HTML scalable.
+ */
+static void gtk_imhtml_animation_free(GtkIMHtmlScalable *scale)
+{
+	GtkIMHtmlAnimation *animation = (GtkIMHtmlAnimation *)scale;
+
+	if (animation->timer > 0)
+		g_source_remove(animation->timer);
+	if (animation->iter != NULL)
+		g_object_unref(animation->iter);
+	g_object_unref(animation->anim);
+
+	gtk_imhtml_image_free(scale);
 }
 
 static void
@@ -3918,55 +3831,51 @@
 
 }
 
-static gboolean gtk_imhtml_smiley_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlSmiley *smiley)
-{
-	GdkPixbufAnimation *anim = NULL;
-	GtkIMHtmlImageSave *save = NULL;
-	gboolean ret;
-
-	if (event->type != GDK_BUTTON_RELEASE || ((GdkEventButton*)event)->button != 3)
-		return FALSE;
-
-	anim = gtk_smiley_get_image(smiley);
-	if (!anim)
-		return FALSE;
-
-	save = g_new0(GtkIMHtmlImageSave, 1);
-	save->image = (GtkIMHtmlScalable *)gtk_imhtml_animation_new(anim, smiley->smile, 0);
-	save->data = smiley->data;        /* Do not need to memdup here, since the smiley is not
-	                                     destroyed before this GtkIMHtmlImageSave */
-	save->datasize = smiley->datasize;
-	ret = gtk_imhtml_image_clicked(w, event, save);
-	g_object_set_data_full(G_OBJECT(w), "image-data", save->image, (GDestroyNotify)gtk_imhtml_animation_free);
-	g_object_set_data_full(G_OBJECT(w), "image-save-data", save, (GDestroyNotify)g_free);
-	return ret;
-}
-
-void gtk_imhtml_image_free(GtkIMHtmlScalable *scale)
-{
-	GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale;
-
-	g_object_unref(image->pixbuf);
-	g_free(image->filename);
-	if (image->filesel)
-		gtk_widget_destroy(image->filesel);
-	g_free(scale);
-}
-
-void gtk_imhtml_animation_free(GtkIMHtmlScalable *scale)
-{
-	GtkIMHtmlAnimation *animation = (GtkIMHtmlAnimation *)scale;
-
-	if (animation->timer > 0)
-		g_source_remove(animation->timer);
-	if (animation->iter != NULL)
-		g_object_unref(animation->iter);
-	g_object_unref(animation->anim);
-
-	gtk_imhtml_image_free(scale);
-}
-
-void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter)
+/**
+ * Rescales a GTK+ IM/HTML scalable image to a given size.
+ *
+ * @param scale  The GTK+ IM/HTML scalable.
+ * @param width  The new width.
+ * @param height The new height.
+ */
+static void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height)
+{
+	GtkIMHtmlImage *im_image = (GtkIMHtmlImage *)scale;
+
+	if (im_image->width > width || im_image->height > height) {
+		double ratio_w, ratio_h, ratio;
+		int new_h, new_w;
+		GdkPixbuf *new_image = NULL;
+
+		ratio_w = ((double)width - 2) / im_image->width;
+		ratio_h = ((double)height - 2) / im_image->height;
+
+		ratio = (ratio_w < ratio_h) ? ratio_w : ratio_h;
+
+		new_w = (int)(im_image->width * ratio);
+		new_h = (int)(im_image->height * ratio);
+
+		new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, new_w, new_h, GDK_INTERP_BILINEAR);
+		gtk_image_set_from_pixbuf(im_image->image, new_image);
+		g_object_unref(G_OBJECT(new_image));
+	} else if (gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)) != im_image->width) {
+		/* Enough space to show the full-size of the image. */
+		GdkPixbuf *new_image;
+
+		new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, im_image->width, im_image->height, GDK_INTERP_BILINEAR);
+		gtk_image_set_from_pixbuf(im_image->image, new_image);
+		g_object_unref(G_OBJECT(new_image));
+	}
+}
+
+/**
+ * Adds a GTK+ IM/HTML scalable image to a given GTK+ IM/HTML at a given iter.
+ *
+ * @param scale  The GTK+ IM/HTML scalable.
+ * @param imhtml The GTK+ IM/HTML.
+ * @param iter   The GtkTextIter at which to add the scalable.
+ */
+static void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter)
 {
 	GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale;
 	GtkWidget *box = gtk_event_box_new();
@@ -3994,6 +3903,123 @@
 	g_object_set_data_full(G_OBJECT(box), "image-save-data", save, (GDestroyNotify)g_free);
 }
 
+/**
+ * Creates and returns a new GTK+ IM/HTML scalable object with an image.
+ *
+ * @param img      A GdkPixbuf of the image to add.
+ * @param filename The filename to associate with the image.
+ * @param id       The id to associate with the image.
+ *
+ * @return A new IM/HTML Scalable object with an image.
+ */
+static GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id)
+{
+	GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage));
+
+	GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale;
+	GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to;
+	GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_image_free;
+
+	im_image->pixbuf = img;
+	im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf));
+	im_image->width = gdk_pixbuf_get_width(img);
+	im_image->height = gdk_pixbuf_get_height(img);
+	im_image->mark = NULL;
+	im_image->filename = g_strdup(filename);
+	im_image->id = id;
+	im_image->filesel = NULL;
+
+	g_object_ref(img);
+	return GTK_IMHTML_SCALABLE(im_image);
+}
+
+static gboolean
+animate_image_cb(gpointer data)
+{
+	GtkIMHtmlImage *im_image;
+	int width, height;
+	int delay;
+
+	im_image = data;
+
+	/* Update the pointer to this GdkPixbuf frame of the animation */
+	if (gdk_pixbuf_animation_iter_advance(GTK_IMHTML_ANIMATION(im_image)->iter, NULL)) {
+		GdkPixbuf *pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
+		g_object_unref(G_OBJECT(im_image->pixbuf));
+		im_image->pixbuf = gdk_pixbuf_copy(pb);
+
+		/* Update the displayed GtkImage */
+		width = gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image));
+		height = gdk_pixbuf_get_height(gtk_image_get_pixbuf(im_image->image));
+		if (width > 0 && height > 0)
+		{
+			/* Need to scale the new frame to the same size as the old frame */
+			GdkPixbuf *tmp;
+			tmp = gdk_pixbuf_scale_simple(im_image->pixbuf, width, height, GDK_INTERP_BILINEAR);
+			gtk_image_set_from_pixbuf(im_image->image, tmp);
+			g_object_unref(G_OBJECT(tmp));
+		} else {
+			/* Display at full-size */
+			gtk_image_set_from_pixbuf(im_image->image, im_image->pixbuf);
+		}
+	}
+
+	delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
+	GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image);
+
+	return FALSE;
+}
+
+/**
+ * Creates and returns a new GTK+ IM/HTML scalable object with an
+ * animated image.
+ *
+ * @param img      A GdkPixbufAnimation of the image to add.
+ * @param filename The filename to associate with the image.
+ * @param id       The id to associate with the image.
+ *
+ * @return A new IM/HTML Scalable object with an image.
+ *
+ * @since 2.1.0
+ */
+/*
+ * TODO: All this animation code could be combined much better with
+ *       the image code.  It couldn't be done when it was written
+ *       because it requires breaking backward compatibility.  It
+ *       would be good to do it for 3.0.0.
+ */
+static GtkIMHtmlScalable *gtk_imhtml_animation_new(GdkPixbufAnimation *anim, const gchar *filename, int id)
+{
+	GtkIMHtmlImage *im_image = (GtkIMHtmlImage *) g_new0(GtkIMHtmlAnimation, 1);
+
+	GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale;
+	GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to;
+	GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_animation_free;
+
+	GTK_IMHTML_ANIMATION(im_image)->anim = anim;
+	if (gdk_pixbuf_animation_is_static_image(anim)) {
+		im_image->pixbuf = gdk_pixbuf_animation_get_static_image(anim);
+		g_object_ref(im_image->pixbuf);
+	} else {
+		int delay;
+		GdkPixbuf *pb;
+		GTK_IMHTML_ANIMATION(im_image)->iter = gdk_pixbuf_animation_get_iter(anim, NULL);
+		pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
+		im_image->pixbuf = gdk_pixbuf_copy(pb);
+		delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
+		GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image);
+	}
+	im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf));
+	im_image->width = gdk_pixbuf_animation_get_width(anim);
+	im_image->height = gdk_pixbuf_animation_get_height(anim);
+	im_image->filename = g_strdup(filename);
+	im_image->id = id;
+
+	g_object_ref(anim);
+
+	return GTK_IMHTML_SCALABLE(im_image);
+}
+
 GtkIMHtmlScalable *gtk_imhtml_hr_new()
 {
 	GtkIMHtmlHr *hr = g_malloc(sizeof(GtkIMHtmlHr));
@@ -4918,6 +4944,30 @@
 	}
 }
 
+static gboolean gtk_imhtml_smiley_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlSmiley *smiley)
+{
+	GdkPixbufAnimation *anim = NULL;
+	GtkIMHtmlImageSave *save = NULL;
+	gboolean ret;
+
+	if (event->type != GDK_BUTTON_RELEASE || ((GdkEventButton*)event)->button != 3)
+		return FALSE;
+
+	anim = gtk_smiley_get_image(smiley);
+	if (!anim)
+		return FALSE;
+
+	save = g_new0(GtkIMHtmlImageSave, 1);
+	save->image = (GtkIMHtmlScalable *)gtk_imhtml_animation_new(anim, smiley->smile, 0);
+	save->data = smiley->data;        /* Do not need to memdup here, since the smiley is not
+	                                     destroyed before this GtkIMHtmlImageSave */
+	save->datasize = smiley->datasize;
+	ret = gtk_imhtml_image_clicked(w, event, save);
+	g_object_set_data_full(G_OBJECT(w), "image-data", save->image, (GDestroyNotify)gtk_imhtml_animation_free);
+	g_object_set_data_full(G_OBJECT(w), "image-save-data", save, (GDestroyNotify)g_free);
+	return ret;
+}
+
 void gtk_imhtml_insert_smiley_at_iter(GtkIMHtml *imhtml, const char *sml, char *smiley, GtkTextIter *iter)
 {
 	GdkPixbuf *pixbuf = NULL;
@@ -5367,9 +5417,9 @@
 			tag = sl->data;
 			/** don't worry about non-printing tags ending */
 			if (tag_ends_here(tag, &iter, &next_iter) &&
-					strlen(tag_to_html_end(tag)) > 0 &&
-					strlen(tag_to_html_start(tag)) > 0) {
-
+					*tag_to_html_end(tag) &&
+					*tag_to_html_start(tag))
+			{
 				PidginTextTagData *tmp;
 				GQueue *r = g_queue_new();
 
--- a/pidgin/gtkimhtml.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkimhtml.h	Sun Sep 11 04:19:01 2011 +0000
@@ -50,9 +50,6 @@
 
 typedef struct _GtkIMHtml			GtkIMHtml;
 typedef struct _GtkIMHtmlClass		GtkIMHtmlClass;
-#if !(defined PIDGIN_DISABLE_DEPRECATED) && !(defined _PIDGIN_GTKIMHTML_C_)
-typedef struct _GtkIMHtmlFontDetail	GtkIMHtmlFontDetail;	/* The five elements contained in a FONT tag */
-#endif
 typedef struct _GtkSmileyTree		GtkSmileyTree;
 typedef struct _GtkIMHtmlSmiley		GtkIMHtmlSmiley;
 typedef struct _GtkIMHtmlScalable	GtkIMHtmlScalable;
@@ -135,16 +132,6 @@
 		GtkTextTag *link;
 	} edit;
 
-#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKIMHTML_C_)
-	/** @deprecated */
-	char *clipboard_text_string;
-	/** @deprecated */
-	char *clipboard_html_string;
-#else
-	char *depr1;
-	char *depr2;
-#endif
-
 	GSList *im_images;
 	GtkIMHtmlFuncs *funcs;
 	GtkSourceUndoManager *undo_manager;
@@ -164,20 +151,6 @@
 	GList *protocols; /* List of GtkIMHtmlProtocol's */
 };
 
-#if !(defined PIDGIN_DISABLE_DEPRECATED) && !(defined _PIDGIN_GTKIMHTML_C_)
-/** @deprecated as of 2.7.10 */
-struct _GtkIMHtmlFontDetail {
-	gushort size;
-	gchar *face;
-	gchar *fore;
-	gchar *back;
-	gchar *bg;
-	gchar *sml;
-	gboolean underline;
-	gshort bold;
-};
-#endif
-
 struct _GtkSmileyTree {
 	GString *values;
 	GtkSmileyTree **children;
@@ -443,73 +416,6 @@
 GtkIMHtmlScalable *gtk_imhtml_scalable_new(void);
 
 /**
- * Creates and returns a new GTK+ IM/HTML scalable object with an image.
- *
- * @param img      A GdkPixbuf of the image to add.
- * @param filename The filename to associate with the image.
- * @param id       The id to associate with the image.
- *
- * @return A new IM/HTML Scalable object with an image.
- */
-GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id);
-
-/**
- * Creates and returns a new GTK+ IM/HTML scalable object with an
- * animated image.
- *
- * @param img      A GdkPixbufAnimation of the image to add.
- * @param filename The filename to associate with the image.
- * @param id       The id to associate with the image.
- *
- * @return A new IM/HTML Scalable object with an image.
- *
- * @since 2.1.0
- */
-/*
- * TODO: All this animation code could be combined much better with
- *       the image code.  It couldn't be done when it was written
- *       because it requires breaking backward compatibility.  It
- *       would be good to do it for 3.0.0.
- */
-GtkIMHtmlScalable *gtk_imhtml_animation_new(GdkPixbufAnimation *img, const gchar *filename, int id);
-
-/**
- * Destroys and frees a GTK+ IM/HTML scalable image.
- *
- * @param scale The GTK+ IM/HTML scalable.
- */
-/* TODO: Is there any reason this isn't private? */
-void gtk_imhtml_image_free(GtkIMHtmlScalable *scale);
-
-/**
- * Destroys and frees a GTK+ IM/HTML scalable animation.
- *
- * @param scale The GTK+ IM/HTML scalable.
- */
-/* TODO: Is there any reason this isn't private? */
-void gtk_imhtml_animation_free(GtkIMHtmlScalable *scale);
-
-/**
- * Rescales a GTK+ IM/HTML scalable image to a given size.
- *
- * @param scale  The GTK+ IM/HTML scalable.
- * @param width  The new width.
- * @param height The new height.
- */
-/* TODO: Is there any reason this isn't private? */
-void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height);
-
-/**
- * Adds a GTK+ IM/HTML scalable image to a given GTK+ IM/HTML at a given iter.
- *
- * @param scale  The GTK+ IM/HTML scalable.
- * @param imhtml The GTK+ IM/HTML.
- * @param iter   The GtkTextIter at which to add the scalable.
- */
-/* TODO: Is there any reason this isn't private? */
-void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter);
-
-/**
  * Creates and returns an new GTK+ IM/HTML scalable with a horizontal rule.
  *
  * @return A new IM/HTML Scalable object with an image.
--- a/pidgin/gtkmain.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkmain.c	Sun Sep 11 04:19:01 2011 +0000
@@ -498,7 +498,6 @@
 	int opt;
 	gboolean gui_check;
 	gboolean debug_enabled;
-	gboolean migration_failed = FALSE;
 	GList *active_accounts;
 	struct stat st;
 
@@ -730,16 +729,6 @@
 
 	purple_debug_set_enabled(debug_enabled);
 
-	/* If we're using a custom configuration directory, we
-	 * do NOT want to migrate, or weird things will happen. */
-	if (opt_config_dir_arg == NULL)
-	{
-		if (!purple_core_migrate())
-		{
-			migration_failed = TRUE;
-		}
-	}
-
 	search_path = g_build_filename(purple_user_dir(), "gtkrc-2.0", NULL);
 	gtk_rc_add_default_file(search_path);
 	g_free(search_path);
@@ -765,37 +754,6 @@
 	winpidgin_init(hint);
 #endif
 
-	if (migration_failed)
-	{
-		char *old = g_strconcat(purple_home_dir(),
-		                        G_DIR_SEPARATOR_S ".gaim", NULL);
-		const char *text = _(
-			"%s encountered errors migrating your settings "
-			"from %s to %s. Please investigate and complete the "
-			"migration by hand. Please report this error at http://developer.pidgin.im");
-		GtkWidget *dialog;
-
-		dialog = gtk_message_dialog_new(NULL,
-		                                0,
-		                                GTK_MESSAGE_ERROR,
-		                                GTK_BUTTONS_CLOSE,
-		                                text, PIDGIN_NAME,
-		                                old, purple_user_dir());
-		g_free(old);
-
-		g_signal_connect_swapped(dialog, "response",
-		                         G_CALLBACK(gtk_main_quit), NULL);
-
-		gtk_widget_show_all(dialog);
-
-		gtk_main();
-
-#ifdef HAVE_SIGNAL_H
-		g_free(segfault_message);
-#endif
-		return 0;
-	}
-
 	purple_core_set_ui_ops(pidgin_core_get_ui_ops());
 	purple_eventloop_set_ui_ops(pidgin_eventloop_get_ui_ops());
 
--- a/pidgin/gtknotify.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtknotify.c	Sun Sep 11 04:19:01 2011 +0000
@@ -1035,6 +1035,10 @@
 
 		gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1,
 				column->title, renderer, "text", i, NULL);
+
+		if (!purple_notify_searchresult_column_is_visible(column))
+			gtk_tree_view_column_set_visible(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), i), FALSE);
+
 		i++;
 	}
 
--- a/pidgin/gtkprefs.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkprefs.c	Sun Sep 11 04:19:01 2011 +0000
@@ -2882,8 +2882,6 @@
 {
 	const char *str = NULL;
 
-	purple_prefs_rename("/gaim/gtk", PIDGIN_PREFS_ROOT);
-
 	/* Rename some old prefs */
 	purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_ims", "/purple/logging/log_ims");
 	purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_chats", "/purple/logging/log_chats");
@@ -2907,12 +2905,6 @@
 		purple_prefs_remove(PIDGIN_PREFS_ROOT "/browsers/command");
 	}
 
-	/* this string pref moved into the core, try to be friendly */
-	purple_prefs_rename(PIDGIN_PREFS_ROOT "/idle/reporting_method", "/purple/away/idle_reporting");
-	if ((str = purple_prefs_get_string("/purple/away/idle_reporting")) &&
-			strcmp(str, "gaim") == 0)
-		purple_prefs_set_string("/purple/away/idle_reporting", "purple");
-
 	/* Remove some no-longer-used prefs */
 	purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/auto_expand_contacts");
 	purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/button_style");
--- a/pidgin/gtkrequest.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkrequest.c	Sun Sep 11 04:19:01 2011 +0000
@@ -749,6 +749,7 @@
 req_entry_field_changed_cb(GtkWidget *entry, PurpleRequestField *field)
 {
 	PurpleRequestFieldGroup *group;
+	PurpleRequestFields *fields;
 	PidginRequestData *req_data;
 
 	if (purple_request_field_string_is_multiline(field))
@@ -771,10 +772,11 @@
 	}
 
 	group = purple_request_field_get_group(field);
-	req_data = (PidginRequestData *)group->fields_list->ui_data;
+	fields = purple_request_field_group_get_fields_list(group);
+	req_data = purple_request_fields_get_ui_data(fields);
 
 	gtk_widget_set_sensitive(req_data->ok_button,
-		purple_request_fields_all_required_filled(group->fields_list));
+		purple_request_fields_all_required_filled(fields));
 }
 
 static void
@@ -796,7 +798,7 @@
 		{
 			GtkWidget *optmenu = NULL;
 			PurpleRequestFieldGroup *group = purple_request_field_get_group(field);
-			GList *fields = group->fields;
+			GList *fields = purple_request_field_group_get_fields(group);
 
 			/* Ensure the account option menu is created (if the widget hasn't
 			 * been initialized already) for username auto-completion. */
@@ -857,6 +859,10 @@
 			gtk_text_buffer_set_text(buffer, value, -1);
 		}
 
+#if GTK_CHECK_VERSION(2,12,0)
+		gtk_widget_set_tooltip_text(textview, purple_request_field_get_tooltip(field));
+#endif
+
 		gtk_text_view_set_editable(GTK_TEXT_VIEW(textview),
 			purple_request_field_string_is_editable(field));
 
@@ -881,6 +887,10 @@
 		if (value != NULL)
 			gtk_entry_set_text(GTK_ENTRY(widget), value);
 
+#if GTK_CHECK_VERSION(2,12,0)
+		gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
 		if (purple_request_field_string_is_masked(field))
 		{
 			gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE);
@@ -921,6 +931,10 @@
 		gtk_entry_set_text(GTK_ENTRY(widget), buf);
 	}
 
+#if GTK_CHECK_VERSION(2,12,0)
+	gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
 	g_signal_connect(G_OBJECT(widget), "focus-out-event",
 					 G_CALLBACK(field_int_focus_out_cb), field);
 
@@ -935,6 +949,10 @@
 	widget = gtk_check_button_new_with_label(
 		purple_request_field_get_label(field));
 
+#if GTK_CHECK_VERSION(2,12,0)
+	gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
 		purple_request_field_bool_get_default_value(field));
 
@@ -965,6 +983,10 @@
 		gtk_combo_box_set_active(GTK_COMBO_BOX(widget),
 						purple_request_field_choice_get_default_value(field));
 
+#if GTK_CHECK_VERSION(2,12,0)
+		gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
 		g_signal_connect(G_OBJECT(widget), "changed",
 						 G_CALLBACK(field_choice_menu_cb), field);
 	}
@@ -982,6 +1004,10 @@
 
 		widget = box;
 
+#if GTK_CHECK_VERSION(2,12,0)
+		gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
 		for (l = labels, i = 0; l != NULL; l = l->next, i++)
 		{
 			const char *text = l->data;
@@ -1024,6 +1050,10 @@
 	g_object_unref(G_OBJECT(buf));
 	g_object_unref(G_OBJECT(scale));
 
+#if GTK_CHECK_VERSION(2,12,0)
+	gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
 	return widget;
 }
 
@@ -1039,6 +1069,10 @@
 		purple_request_field_account_get_filter(field),
 		field);
 
+#if GTK_CHECK_VERSION(2,12,0)
+	gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
 	return widget;
 }
 
@@ -1188,7 +1222,7 @@
 	data->user_data = user_data;
 	data->u.multifield.fields = fields;
 
-	fields->ui_data = data;
+	purple_request_fields_set_ui_data(fields, data);
 
 	data->cb_count = 2;
 	data->cbs = g_new0(GCallback, 2);
--- a/pidgin/gtkroomlist.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkroomlist.c	Sun Sep 11 04:19:01 2011 +0000
@@ -91,7 +91,7 @@
 		purple_timeout_remove(dialog->pg_update_to);
 
 	if (dialog->roomlist) {
-		PidginRoomlist *rl = dialog->roomlist->ui_data;
+		PidginRoomlist *rl = purple_roomlist_get_ui_data(dialog->roomlist);
 
 		if (dialog->pg_update_to > 0)
 			/* yes, that's right, unref it twice. */
@@ -115,7 +115,7 @@
 	dialog->account = account;
 
 	if (change && dialog->roomlist) {
-		PidginRoomlist *rl = dialog->roomlist->ui_data;
+		PidginRoomlist *rl = purple_roomlist_get_ui_data(dialog->roomlist);
 		if (rl->tree) {
 			gtk_widget_destroy(rl->tree);
 			rl->tree = NULL;
@@ -135,7 +135,7 @@
 		return;
 
 	if (dialog->roomlist != NULL) {
-		rl = dialog->roomlist->ui_data;
+		rl = purple_roomlist_get_ui_data(dialog->roomlist);
 		gtk_widget_destroy(rl->tree);
 		purple_roomlist_unref(dialog->roomlist);
 	}
@@ -144,7 +144,7 @@
 	if (!dialog->roomlist)
 		return;
 	purple_roomlist_ref(dialog->roomlist);
-	rl = dialog->roomlist->ui_data;
+	rl = purple_roomlist_get_ui_data(dialog->roomlist);
 	rl->dialog = dialog;
 
 	if (dialog->account_widget)
@@ -203,7 +203,7 @@
 		val.g_type = 0;
 		gtk_tree_model_get_value(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
 		room = g_value_get_pointer(&val);
-		if (!room || !(room->type & PURPLE_ROOMLIST_ROOMTYPE_ROOM)) {
+		if (!room || !(purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM)) {
 			gtk_widget_set_sensitive(dialog->join_button, FALSE);
 			gtk_widget_set_sensitive(dialog->add_button, FALSE);
 			return;
@@ -228,7 +228,8 @@
 static void do_add_room_cb(GtkWidget *w, struct _menu_cb_info *info)
 {
 	char *name;
-	PurpleConnection *gc = purple_account_get_connection(info->list->account);
+	PurpleAccount *account = purple_roomlist_get_account(info->list);
+	PurpleConnection *gc = purple_account_get_connection(account);
 	PurplePluginProtocolInfo *prpl_info = NULL;
 
 	if(gc != NULL)
@@ -237,9 +238,9 @@
 	if(prpl_info != NULL && prpl_info->roomlist_room_serialize)
 		name = prpl_info->roomlist_room_serialize(info->room);
 	else
-		name = g_strdup(info->room->name);
+		name = g_strdup(purple_roomlist_room_get_name(info->room));
 
-	purple_blist_request_add_chat(info->list->account, NULL, NULL, name);
+	purple_blist_request_add_chat(account, NULL, NULL, name);
 
 	g_free(name);
 }
@@ -247,7 +248,7 @@
 static void add_room_to_blist_cb(GtkButton *button, PidginRoomlistDialog *dialog)
 {
 	PurpleRoomlist *rl = dialog->roomlist;
-	PidginRoomlist *grl = rl->ui_data;
+	PidginRoomlist *grl = purple_roomlist_get_ui_data(rl);
 	struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "room-info");
 
 	if(info != NULL)
@@ -262,7 +263,7 @@
 static void join_button_cb(GtkButton *button, PidginRoomlistDialog *dialog)
 {
 	PurpleRoomlist *rl = dialog->roomlist;
-	PidginRoomlist *grl = rl->ui_data;
+	PidginRoomlist *grl = purple_roomlist_get_ui_data(rl);
 	struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "room-info");
 
 	if(info != NULL)
@@ -272,7 +273,7 @@
 static void row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *arg2,
                       PurpleRoomlist *list)
 {
-	PidginRoomlist *grl = list->ui_data;
+	PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
 	GtkTreeIter iter;
 	PurpleRoomlistRoom *room;
 	GValue val;
@@ -282,7 +283,7 @@
 	val.g_type = 0;
 	gtk_tree_model_get_value(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
 	room = g_value_get_pointer(&val);
-	if (!room || !(room->type & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
+	if (!room || !(purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
 		return;
 
 	info.list = list;
@@ -294,7 +295,7 @@
 static gboolean room_click_cb(GtkWidget *tv, GdkEventButton *event, PurpleRoomlist *list)
 {
 	GtkTreePath *path;
-	PidginRoomlist *grl = list->ui_data;
+	PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
 	GValue val;
 	PurpleRoomlistRoom *room;
 	GtkTreeIter iter;
@@ -313,7 +314,7 @@
 	gtk_tree_model_get_value (GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
 	room = g_value_get_pointer(&val);
 
-	if (!room || !(room->type & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
+	if (!room || !(purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
 		return FALSE;
 
 	info.list = list;
@@ -341,9 +342,9 @@
 	gtk_tree_model_get_value(gtk_tree_view_get_model(treeview), arg1, ROOM_COLUMN, &val);
 	category = g_value_get_pointer(&val);
 
-	if (!category->expanded_once) {
+	if (!purple_roomlist_room_get_expanded_once(category)) {
 		purple_roomlist_expand_category(list, category);
-		category->expanded_once = TRUE;
+		purple_roomlist_room_set_expanded_once(category, TRUE);
 	}
 }
 
@@ -354,7 +355,7 @@
 pidgin_roomlist_paint_tooltip(GtkWidget *widget, gpointer user_data)
 {
 	PurpleRoomlist *list = user_data;
-	PidginRoomlist *grl = list->ui_data;
+	PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
 	GtkStyle *style;
 	int current_height, max_width;
 	int max_text_width;
@@ -393,7 +394,7 @@
 
 static gboolean pidgin_roomlist_create_tip(PurpleRoomlist *list, GtkTreePath *path)
 {
-	PidginRoomlist *grl = list->ui_data;
+	PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
 	PurpleRoomlistRoom *room;
 	GtkTreeIter iter;
 	GValue val;
@@ -414,19 +415,23 @@
 	gtk_tree_model_get_value(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
 	room = g_value_get_pointer(&val);
 
-	if (!room || !(room->type & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
+	if (!room || !(purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
 		return FALSE;
 
 	tooltip_text = g_string_new("");
 	gtk_tree_model_get(GTK_TREE_MODEL(grl->model), &iter, NAME_COLUMN, &name, -1);
 
-	for (j = NUM_OF_COLUMNS, l = room->fields, k = list->fields; l && k; j++, l = l->next, k = k->next) {
+	for (j = NUM_OF_COLUMNS,
+				l = purple_roomlist_room_get_fields(room),
+				k = purple_roomlist_get_fields(list);
+			l && k; j++, l = l->next, k = k->next)
+	{
 		PurpleRoomlistField *f = k->data;
 		gchar *label;
-		if (f->hidden)
+		if (purple_roomlist_field_get_hidden(f))
 			continue;
-		label = g_markup_escape_text(f->label, -1);
-		switch (f->type) {
+		label = g_markup_escape_text(purple_roomlist_field_get_label(f), -1);
+		switch (purple_roomlist_field_get_type(f)) {
 			case PURPLE_ROOMLIST_FIELD_BOOL:
 				g_string_append_printf(tooltip_text, "%s<b>%s:</b> %s", first ? "" : "\n", label, l->data ? "True" : "False");
 				break;
@@ -478,7 +483,7 @@
 		gpointer data, int *w, int *h)
 {
 	PurpleRoomlist *list = data;
-	PidginRoomlist *grl = list->ui_data;
+	PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
 	grl->tipwindow = widget;
 	if (!pidgin_roomlist_create_tip(data, path))
 		return FALSE;
@@ -622,7 +627,7 @@
 {
 	PidginRoomlist *rl = g_new0(PidginRoomlist, 1);
 
-	list->ui_data = rl;
+	purple_roomlist_set_ui_data(list, rl);
 
 	rl->cats = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)gtk_tree_row_reference_free);
 
@@ -685,7 +690,7 @@
 
 static void pidgin_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
 {
-	PidginRoomlist *grl = list->ui_data;
+	PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
 	gint columns = NUM_OF_COLUMNS;
 	int j;
 	GtkTreeStore *model;
@@ -707,7 +712,7 @@
 	for (j = NUM_OF_COLUMNS, l = fields; l; l = l->next, j++) {
 		PurpleRoomlistField *f = l->data;
 
-		switch (f->type) {
+		switch (purple_roomlist_field_get_type(f)) {
 		case PURPLE_ROOMLIST_FIELD_BOOL:
 			types[j] = G_TYPE_BOOLEAN;
 			break;
@@ -749,18 +754,19 @@
 	for (j = NUM_OF_COLUMNS, l = fields; l; l = l->next, j++) {
 		PurpleRoomlistField *f = l->data;
 
-		if (f->hidden)
+		if (purple_roomlist_field_get_hidden(f))
 			continue;
 
 		renderer = gtk_cell_renderer_text_new();
-		column = gtk_tree_view_column_new_with_attributes(f->label, renderer,
-		                                                  "text", j, NULL);
+		column = gtk_tree_view_column_new_with_attributes(
+				purple_roomlist_field_get_label(f), renderer,
+				"text", j, NULL);
 		gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column),
 		                                GTK_TREE_VIEW_COLUMN_GROW_ONLY);
 		gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
 		gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), j);
 		gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
-		if (f->type == PURPLE_ROOMLIST_FIELD_INT) {
+		if (purple_roomlist_field_get_type(f) == PURPLE_ROOMLIST_FIELD_INT) {
 			gtk_tree_view_column_set_cell_data_func(column, renderer, int_cell_data_func,
 			                                        GINT_TO_POINTER(j), NULL);
 			gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), j, int_sort_func,
@@ -789,7 +795,7 @@
 static gboolean pidgin_progress_bar_pulse(gpointer data)
 {
 	PurpleRoomlist *list = data;
-	PidginRoomlist *rl = list->ui_data;
+	PidginRoomlist *rl = purple_roomlist_get_ui_data(list);
 
 	if (!rl || !rl->dialog || !rl->dialog->pg_needs_pulse) {
 		if (rl && rl->dialog)
@@ -805,7 +811,7 @@
 
 static void pidgin_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *room)
 {
-	PidginRoomlist *rl = list->ui_data;
+	PidginRoomlist *rl = purple_roomlist_get_ui_data(list);
 	GtkTreeRowReference *rr, *parentrr = NULL;
 	GtkTreePath *path;
 	GtkTreeIter iter, parent, child;
@@ -814,7 +820,7 @@
 	gboolean append = TRUE;
 
 	rl->total_rooms++;
-	if (room->type == PURPLE_ROOMLIST_ROOMTYPE_ROOM)
+	if (purple_roomlist_room_get_type(room) == PURPLE_ROOMLIST_ROOMTYPE_ROOM)
 		rl->num_rooms++;
 
 	if (rl->dialog) {
@@ -826,8 +832,8 @@
 			rl->dialog->pg_needs_pulse = TRUE;
 	}
 
-	if (room->parent) {
-		parentrr = g_hash_table_lookup(rl->cats, room->parent);
+	if (purple_roomlist_room_get_parent(room)) {
+		parentrr = g_hash_table_lookup(rl->cats, purple_roomlist_room_get_parent(room));
 		path = gtk_tree_row_reference_get_path(parentrr);
 		if (path) {
 			PurpleRoomlistRoom *tmproom = NULL;
@@ -848,24 +854,28 @@
 	else
 		iter = child;
 
-	if (room->type & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY)
+	if (purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY)
 		gtk_tree_store_append(rl->model, &child, &iter);
 
 	path = gtk_tree_model_get_path(GTK_TREE_MODEL(rl->model), &iter);
 
-	if (room->type & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY) {
+	if (purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY) {
 		rr = gtk_tree_row_reference_new(GTK_TREE_MODEL(rl->model), path);
 		g_hash_table_insert(rl->cats, room, rr);
 	}
 
 	gtk_tree_path_free(path);
 
-	gtk_tree_store_set(rl->model, &iter, NAME_COLUMN, room->name, -1);
+	gtk_tree_store_set(rl->model, &iter, NAME_COLUMN, purple_roomlist_room_get_name(room), -1);
 	gtk_tree_store_set(rl->model, &iter, ROOM_COLUMN, room, -1);
 
-	for (j = NUM_OF_COLUMNS, l = room->fields, k = list->fields; l && k; j++, l = l->next, k = k->next) {
+	for (j = NUM_OF_COLUMNS,
+				l = purple_roomlist_room_get_fields(room),
+				k = purple_roomlist_get_fields(list);
+			l && k; j++, l = l->next, k = k->next)
+	{
 		PurpleRoomlistField *f = k->data;
-		if (f->hidden)
+		if (purple_roomlist_field_get_hidden(f))
 			continue;
 		gtk_tree_store_set(rl->model, &iter, j, l->data, -1);
 	}
@@ -873,7 +883,7 @@
 
 static void pidgin_roomlist_in_progress(PurpleRoomlist *list, gboolean in_progress)
 {
-	PidginRoomlist *rl = list->ui_data;
+	PidginRoomlist *rl = purple_roomlist_get_ui_data(list);
 
 	if (!rl || !rl->dialog)
 		return;
@@ -895,7 +905,7 @@
 
 static void pidgin_roomlist_destroy(PurpleRoomlist *list)
 {
-	PidginRoomlist *rl = list->ui_data;
+	PidginRoomlist *rl = purple_roomlist_get_ui_data(list);
 
 	roomlists = g_list_remove(roomlists, list);
 
@@ -903,7 +913,7 @@
 
 	g_hash_table_destroy(rl->cats);
 	g_free(rl);
-	list->ui_data = NULL;
+	purple_roomlist_set_ui_data(list, NULL);
 }
 
 static PurpleRoomlistUiOps ops = {
--- a/pidgin/gtkutils.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkutils.c	Sun Sep 11 04:19:01 2011 +0000
@@ -922,24 +922,6 @@
 	return optmenu;
 }
 
-gboolean
-pidgin_check_if_dir(const char *path, GtkFileSelection *filesel)
-{
-	char *dirname = NULL;
-
-	if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
-		/* append a / if needed */
-		if (path[strlen(path) - 1] != G_DIR_SEPARATOR) {
-			dirname = g_strconcat(path, G_DIR_SEPARATOR_S, NULL);
-		}
-		gtk_file_selection_set_filename(filesel, (dirname != NULL) ? dirname : path);
-		g_free(dirname);
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
 void
 pidgin_setup_gtkspell(GtkTextView *textview)
 {
@@ -1002,7 +984,7 @@
 show_retrieveing_info(PurpleConnection *conn, const char *name)
 {
 	PurpleNotifyUserInfo *info = purple_notify_user_info_new();
-	purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving..."));
+	purple_notify_user_info_add_pair_plaintext(info, _("Information"), _("Retrieving..."));
 	purple_notify_userinfo(conn, name, info, NULL, NULL);
 	purple_notify_user_info_destroy(info);
 }
@@ -1308,7 +1290,7 @@
 
 	monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
 
-	push_in = FALSE;
+	*push_in = FALSE;
 
 	/*
 	 * The placement of popup menus horizontally works like this (with
@@ -1834,21 +1816,27 @@
                             gpointer object)
 {
 	GtkWidget *menuitem;
+	GList *list;
 
 	if (act == NULL) {
 		return pidgin_separator(menu);
 	}
 
-	if (act->children == NULL) {
-		menuitem = gtk_menu_item_new_with_mnemonic(act->label);
-
-		if (act->callback != NULL) {
+	list = purple_menu_action_get_children(act);
+	menuitem = gtk_menu_item_new_with_mnemonic(purple_menu_action_get_label(act));
+
+	if (list == NULL) {
+		PurpleCallback callback;
+
+		callback = purple_menu_action_get_callback(act);
+
+		if (callback != NULL) {
 			g_object_set_data(G_OBJECT(menuitem),
 							  "purplecallback",
-							  act->callback);
+							  callback);
 			g_object_set_data(G_OBJECT(menuitem),
 							  "purplecallbackdata",
-							  act->data);
+							  purple_menu_action_get_data(act));
 			g_signal_connect(G_OBJECT(menuitem), "activate",
 							 G_CALLBACK(menu_action_cb),
 							 object);
@@ -1862,7 +1850,6 @@
 		GtkWidget *submenu = NULL;
 		GtkAccelGroup *group;
 
-		menuitem = gtk_menu_item_new_with_mnemonic(act->label);
 		gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
 
 		submenu = gtk_menu_new();
@@ -1870,19 +1857,20 @@
 
 		group = gtk_menu_get_accel_group(GTK_MENU(menu));
 		if (group) {
-			char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path, act->label);
+			char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path,
+					purple_menu_action_get_label(act));
 			gtk_menu_set_accel_path(GTK_MENU(submenu), path);
 			g_free(path);
 			gtk_menu_set_accel_group(GTK_MENU(submenu), group);
 		}
 
-		for (l = act->children; l; l = l->next) {
+		for (l = list; l; l = l->next) {
 			PurpleMenuAction *act = (PurpleMenuAction *)l->data;
 
 			pidgin_append_menu_action(submenu, act, object);
 		}
-		g_list_free(act->children);
-		act->children = NULL;
+		g_list_free(list);
+		purple_menu_action_set_children(act, NULL);
 	}
 	purple_menu_action_free(act);
 	return menuitem;
@@ -2181,13 +2169,6 @@
 	}
 }
 
-void
-pidgin_setup_screenname_autocomplete(GtkWidget *entry, GtkWidget *accountopt, gboolean all) {
-	pidgin_setup_screenname_autocomplete_with_filter(entry, accountopt, pidgin_screenname_autocomplete_default_filter, GINT_TO_POINTER(all));
-}
-
-
-
 void pidgin_set_cursor(GtkWidget *widget, GdkCursorType cursor_type)
 {
 	GdkCursor *cursor;
@@ -2533,21 +2514,6 @@
 	return NULL;
 }
 
-void pidgin_set_custom_buddy_icon(PurpleAccount *account, const char *who, const char *filename)
-{
-	PurpleBuddy *buddy;
-	PurpleContact *contact;
-
-	buddy = purple_find_buddy(account, who);
-	if (!buddy) {
-		purple_debug_info("custom-icon", "You can only set custom icon for someone in your buddylist.\n");
-		return;
-	}
-
-	contact = purple_buddy_get_contact(buddy);
-	purple_buddy_icons_node_set_custom_icon_from_file((PurpleBlistNode*)contact, filename);
-}
-
 char *pidgin_make_pretty_arrows(const char *str)
 {
 	char *ret;
--- a/pidgin/gtkutils.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkutils.h	Sun Sep 11 04:19:01 2011 +0000
@@ -384,39 +384,6 @@
 gboolean pidgin_screenname_autocomplete_default_filter(const PidginBuddyCompletionEntry *completion_entry, gpointer all_accounts);
 
 /**
- * Add autocompletion of screenames to an entry.
- *
- * @deprecated
- *   For new code, use the equivalent:
- *   #pidgin_setup_screenname_autocomplete_with_filter(@a entry, @a optmenu,
- *   #pidgin_screenname_autocomplete_default_filter, <tt>GINT_TO_POINTER(@a
- *   all)</tt>)
- *
- * @param entry     The GtkEntry on which to setup autocomplete.
- * @param optmenu   A menu for accounts, returned by
- *                  pidgin_account_option_menu_new().  If @a optmenu is not @c
- *                  NULL, it'll be updated when a username is chosen from the
- *                  autocomplete list.
- * @param all       Whether to include usernames from disconnected accounts.
- */
-void pidgin_setup_screenname_autocomplete(GtkWidget *entry, GtkWidget *optmenu, gboolean all);
-
-/**
- * Check if the given path is a directory or not.  If it is, then modify
- * the given GtkFileSelection dialog so that it displays the given path.
- * If the given path is not a directory, then do nothing.
- *
- * @param path    The path entered in the file selection window by the user.
- * @param filesel The file selection window.
- *
- * @return TRUE if given path is a directory, FALSE otherwise.
- * @deprecated Pidgin no longer uses GtkFileSelection internally. It has also
- *             been deprecated by GTK+. Use GtkFileChooser instead and ignore
- *             this function.
- */
-gboolean pidgin_check_if_dir(const char *path, GtkFileSelection *filesel);
-
-/**
  * Sets up GtkSpell for the given GtkTextView, reporting errors
  * if encountered.
  *
@@ -661,19 +628,6 @@
  */
 gpointer pidgin_convert_buddy_icon(PurplePlugin *plugin, const char *path, size_t *len);
 
-#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKUTILS_C_)
-/**
- * Set or unset a custom buddyicon for a user.
- *
- * @param account   The account the user belongs to.
- * @param who       The name of the user.
- * @param filename  The path of the custom icon. If this is @c NULL, then any
- *                  previously set custom buddy icon for the user is removed.
- * @deprecated See purple_buddy_icons_node_set_custom_icon_from_file()
- */
-void pidgin_set_custom_buddy_icon(PurpleAccount *account, const char *who, const char *filename);
-#endif
-
 /**
  * Converts "->" and "<-" in strings to Unicode arrow characters, for use in referencing
  * menu items.
--- a/pidgin/gtkwhiteboard.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/gtkwhiteboard.c	Sun Sep 11 04:19:01 2011 +0000
@@ -125,7 +125,7 @@
 	PidginWhiteboard *gtkwb = g_new0(PidginWhiteboard, 1);
 
 	gtkwb->wb = wb;
-	wb->ui_data = gtkwb;
+	purple_whiteboard_set_ui_data(wb, gtkwb);
 
 	/* Get dimensions (default?) for the whiteboard canvas */
 	if (!purple_whiteboard_get_dimensions(wb, &gtkwb->width, &gtkwb->height))
@@ -145,11 +145,11 @@
 	/* Try and set window title as the name of the buddy, else just use their
 	 * username
 	 */
-	buddy = purple_find_buddy(wb->account, wb->who);
+	buddy = purple_find_buddy(purple_whiteboard_get_account(wb), purple_whiteboard_get_who(wb));
 
-	window = pidgin_create_window(buddy != NULL ? purple_buddy_get_contact_alias(buddy) : wb->who, 0, NULL, FALSE);
+	window = pidgin_create_window(buddy != NULL ? purple_buddy_get_contact_alias(buddy) : purple_whiteboard_get_who(wb), 0, NULL, FALSE);
 	gtkwb->window = window;
-	gtk_widget_set_name(window, wb->who);
+	gtk_widget_set_name(window, purple_whiteboard_get_who(wb));
 
 	g_signal_connect(G_OBJECT(window), "delete_event",
 					 G_CALLBACK(whiteboard_close_cb), gtkwb);
@@ -274,7 +274,7 @@
 	GtkWidget *colour_dialog;
 
 	g_return_if_fail(wb != NULL);
-	gtkwb = wb->ui_data;
+	gtkwb = purple_whiteboard_get_ui_data(wb);
 	g_return_if_fail(gtkwb != NULL);
 
 	/* TODO Ask if user wants to save picture before the session is closed */
@@ -301,7 +301,7 @@
 		gtkwb->window = NULL;
 	}
 	g_free(gtkwb);
-	wb->ui_data = NULL;
+	purple_whiteboard_set_ui_data(wb, NULL);
 }
 
 static gboolean whiteboard_close_cb(GtkWidget *widget, GdkEvent *event, PidginWhiteboard *gtkwb)
@@ -406,7 +406,7 @@
 	GdkPixmap *pixmap = gtkwb->pixmap;
 
 	PurpleWhiteboard *wb = gtkwb->wb;
-	GList *draw_list = wb->draw_list;
+	GList *draw_list = purple_whiteboard_get_draw_list(wb);
 
 	if(BrushState != BRUSH_STATE_UP)
 	{
@@ -441,7 +441,7 @@
 											 gtkwb->brush_color, gtkwb->brush_size);
 	}
 
-	wb->draw_list = draw_list;
+	purple_whiteboard_set_draw_list(wb, draw_list);
 
 	return TRUE;
 }
@@ -459,7 +459,7 @@
 	GdkPixmap *pixmap = gtkwb->pixmap;
 
 	PurpleWhiteboard *wb = gtkwb->wb;
-	GList *draw_list = wb->draw_list;
+	GList *draw_list = purple_whiteboard_get_draw_list(wb);
 
 	if(event->is_hint)
 		gdk_window_get_pointer(event->window, &x, &y, &state);
@@ -528,7 +528,7 @@
 		LastY = y;
 	}
 
-	wb->draw_list = draw_list;
+	purple_whiteboard_set_draw_list(wb, draw_list);
 
 	return TRUE;
 }
@@ -539,7 +539,7 @@
 	GdkPixmap *pixmap = gtkwb->pixmap;
 
 	PurpleWhiteboard *wb = gtkwb->wb;
-	GList *draw_list = wb->draw_list;
+	GList *draw_list = purple_whiteboard_get_draw_list(wb);
 
 	if((BrushState != BRUSH_STATE_DOWN) && (BrushState != BRUSH_STATE_MOTION))
 	{
@@ -583,7 +583,7 @@
 		if(draw_list)
 			purple_whiteboard_draw_list_destroy(draw_list);
 
-		wb->draw_list = NULL;
+		purple_whiteboard_set_draw_list(wb, NULL);
 	}
 
 	return TRUE;
@@ -591,7 +591,7 @@
 
 static void pidgin_whiteboard_draw_brush_point(PurpleWhiteboard *wb, int x, int y, int color, int size)
 {
-	PidginWhiteboard *gtkwb = wb->ui_data;
+	PidginWhiteboard *gtkwb = purple_whiteboard_get_ui_data(wb);
 	GtkWidget *widget = gtkwb->drawing_area;
 	GdkPixmap *pixmap = gtkwb->pixmap;
 
@@ -684,7 +684,7 @@
 
 static void pidgin_whiteboard_set_dimensions(PurpleWhiteboard *wb, int width, int height)
 {
-	PidginWhiteboard *gtkwb = wb->ui_data;
+	PidginWhiteboard *gtkwb = purple_whiteboard_get_ui_data(wb);
 
 	gtkwb->width = width;
 	gtkwb->height = height;
@@ -692,7 +692,7 @@
 
 static void pidgin_whiteboard_set_brush(PurpleWhiteboard *wb, int size, int color)
 {
-	PidginWhiteboard *gtkwb = wb->ui_data;
+	PidginWhiteboard *gtkwb = purple_whiteboard_get_ui_data(wb);
 
 	gtkwb->brush_size = size;
 	gtkwb->brush_color = color;
@@ -700,7 +700,7 @@
 
 static void pidgin_whiteboard_clear(PurpleWhiteboard *wb)
 {
-	PidginWhiteboard *gtkwb = wb->ui_data;
+	PidginWhiteboard *gtkwb = purple_whiteboard_get_ui_data(wb);
 	GdkPixmap *pixmap = gtkwb->pixmap;
 	GtkWidget *drawing_area = gtkwb->drawing_area;
 	cairo_t *cr = g_object_get_data(G_OBJECT(pixmap), "cairo-context");
--- a/pidgin/pidgin-2-uninstalled.pc.in	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-abs_srcdir=@abs_srcdir@
-abs_builddir=@abs_builddir@
-
-abs_top_srcdir=@abs_top_srcdir@
-abs_top_builddir=@abs_top_builddir@
-
-plugindir=${libdir}/pidgin
-
-Name: Pidgin
-Description: Pidgin is a GTK2-based instant messenger application.
-Version: @VERSION@
-Requires: gtk+-2.0 purple
-Cflags: -I${abs_top_srcdir}
--- a/pidgin/pidgin-2.pc.in	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-plugindir=${libdir}/pidgin
-
-Name: Pidgin
-Description: Pidgin is a GTK2-based instant messenger application.
-Version: @VERSION@
-Requires: gtk+-2.0 purple
-Cflags: -I${includedir}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidgin-3-uninstalled.pc.in	Sun Sep 11 04:19:01 2011 +0000
@@ -0,0 +1,21 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@datarootdir@
+datadir=@datadir@
+sysconfdir=@sysconfdir@
+
+abs_srcdir=@abs_srcdir@
+abs_builddir=@abs_builddir@
+
+abs_top_srcdir=@abs_top_srcdir@
+abs_top_builddir=@abs_top_builddir@
+
+plugindir=${libdir}/pidgin
+
+Name: Pidgin
+Description: Pidgin is a GTK2-based instant messenger application.
+Version: @VERSION@
+Requires: gtk+-2.0 purple-3
+Cflags: -I${abs_top_srcdir}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidgin-3.pc.in	Sun Sep 11 04:19:01 2011 +0000
@@ -0,0 +1,15 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@datarootdir@
+datadir=@datadir@
+sysconfdir=@sysconfdir@
+
+plugindir=${libdir}/pidgin
+
+Name: Pidgin
+Description: Pidgin is a GTK2-based instant messenger application.
+Version: @VERSION@
+Requires: gtk+-2.0 purple-3
+Cflags: -I${includedir}
--- a/pidgin/pidgin-uninstalled.pc.in	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-abs_srcdir=@abs_srcdir@
-abs_builddir=@abs_builddir@
-
-plugindir=${libdir}/pidgin
-
-Name: Pidgin
-Description: Pidgin is a GTK2-based instant messenger application.
-Version: @VERSION@
-Requires: gtk+-2.0 purple
-Cflags: -I${abs_srcdir}
--- a/pidgin/pidgin.pc.in	Sun Sep 11 04:18:46 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-plugindir=${libdir}/pidgin
-
-Name: Pidgin
-Description: Pidgin is a GTK2-based instant messenger application.
-Version: @VERSION@
-Requires: gtk+-2.0 purple
-Cflags: -I${includedir}/pidgin
-
--- a/pidgin/plugins/perl/common/GtkBlist.xs	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/plugins/perl/common/GtkBlist.xs	Sun Sep 11 04:19:01 2011 +0000
@@ -69,8 +69,3 @@
 
 void
 pidgin_blist_joinchat_show()
-
-void
-pidgin_blist_update_account_error_state(account, message)
-	Purple::Account account
-	const char * message
--- a/pidgin/plugins/perl/common/GtkDialogs.xs	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/plugins/perl/common/GtkDialogs.xs	Sun Sep 11 04:19:01 2011 +0000
@@ -24,10 +24,6 @@
 pidgin_dialogs_log()
 
 void
-pidgin_dialogs_alias_contact(contact)
-	Purple::BuddyList::Contact contact
-
-void
 pidgin_dialogs_alias_buddy(buddy)
 	Purple::BuddyList::Buddy buddy
 
--- a/pidgin/plugins/perl/common/GtkIMHtml.xs	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/plugins/perl/common/GtkIMHtml.xs	Sun Sep 11 04:19:01 2011 +0000
@@ -77,26 +77,6 @@
 	Gtk::TextIter end
 */
 
-/* This can't work at the moment since I don't have a typemap for Gdk::Pixbuf.
- * I thought about using the one from libgtk2-perl but wasn't sure how to go
- * about doing that.
-Pidgin::IMHtml::Scalable
-gtk_imhtml_image_new(img, filename, id)
-	Gdk::Pixbuf img
-	const gchar * filename
-	int id
-*/
-
-/* This can't work at the moment since I don't have a typemap for Gtk::Widget.
- * I thought about using the one from libgtk2-perl but wasn't sure how to go
- * about doing that.
-void
-gtk_imhtml_image_add_to(scale, imhtml, iter)
-	Pidgin::IMHtml::Scalable scale
-	Pidgin::IMHtml imhtml
-	Gtk::TextIter iter
-*/
-
 /* This can't work at the moment since I don't have a typemap for Gtk::Widget.
  * I thought about using the one from libgtk2-perl but wasn't sure how to go
  * about doing that.
@@ -323,19 +303,6 @@
 	}
 	XPUSHs(sv_2mortal(newRV_noinc((SV *)lines)));
 
-MODULE = Pidgin::IMHtml  PACKAGE = Pidgin::IMHtml::Scalable  PREFIX = gtk_imhtml_image_
-PROTOTYPES: ENABLE
-
-void
-gtk_imhtml_image_free(scale)
-	Pidgin::IMHtml::Scalable scale
-
-void
-gtk_imhtml_image_scale(scale, width, height)
-	Pidgin::IMHtml::Scalable scale
-	int width
-	int height
-
 MODULE = Pidgin::IMHtml  PACKAGE = Pidgin::IMHtml::Hr  PREFIX = gtk_imhtml_hr_
 PROTOTYPES: ENABLE
 
--- a/pidgin/plugins/relnot.c	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/plugins/relnot.c	Sun Sep 11 04:19:01 2011 +0000
@@ -152,7 +152,7 @@
 				url,
 				host);
 
-		purple_util_fetch_url_request_len(url, TRUE, NULL, FALSE,
+		purple_util_fetch_url_request_len(NULL, url, TRUE, NULL, FALSE,
 			request, TRUE, -1, version_fetch_cb, NULL);
 
 		g_free(request);
--- a/pidgin/win32/untar.h	Sun Sep 11 04:18:46 2011 +0000
+++ b/pidgin/win32/untar.h	Sun Sep 11 04:19:01 2011 +0000
@@ -12,7 +12,7 @@
 extern "C" {
 #endif /* __cplusplus */
 
-typedef enum _untar_opt {
+typedef enum {
 	UNTAR_LISTING =      (1 << 0),
 	UNTAR_QUIET =        (1 << 1),
 	UNTAR_VERBOSE =      (1 << 2),
--- a/po/POTFILES.in	Sun Sep 11 04:18:46 2011 +0000
+++ b/po/POTFILES.in	Sun Sep 11 04:19:01 2011 +0000
@@ -160,14 +160,6 @@
 libpurple/protocols/silc/silc.c
 libpurple/protocols/silc/util.c
 libpurple/protocols/silc/wb.c
-libpurple/protocols/silc10/buddy.c
-libpurple/protocols/silc10/chat.c
-libpurple/protocols/silc10/ft.c
-libpurple/protocols/silc10/ops.c
-libpurple/protocols/silc10/pk.c
-libpurple/protocols/silc10/silc.c
-libpurple/protocols/silc10/util.c
-libpurple/protocols/silc10/wb.c
 libpurple/protocols/simple/simple.c
 libpurple/protocols/yahoo/libyahoo.c
 libpurple/protocols/yahoo/libyahoojp.c