Backed out the previous 4 changesets. GSignals do not seem feasible with pidgin's architecture using any method. soc.2013.gobjectification.plugins

Fri, 11 Oct 2013 01:26:38 +0530

author
Ankit Vani <a@nevitus.org>
date
Fri, 11 Oct 2013 01:26:38 +0530
branch
soc.2013.gobjectification.plugins
changeset 36868
1aca7f52f1ef
parent 36867
92c196849837
child 36869
14e76c7b2eeb

Backed out the previous 4 changesets. GSignals do not seem feasible with pidgin's architecture using any method.
I think we should keep using purple signals for class events and use gsignals for instance events.

ChangeLog.API file | annotate | diff | comparison | revisions
libpurple/Makefile.am file | annotate | diff | comparison | revisions
libpurple/Makefile.mingw file | annotate | diff | comparison | revisions
libpurple/account-manager.c file | annotate | diff | comparison | revisions
libpurple/account-manager.h file | annotate | diff | comparison | revisions
libpurple/account.c file | annotate | diff | comparison | revisions
libpurple/accounts.c file | annotate | diff | comparison | revisions
libpurple/accounts.h file | annotate | diff | comparison | revisions
libpurple/connection.c file | annotate | diff | comparison | revisions
libpurple/dbus-useful.c file | annotate | diff | comparison | revisions
libpurple/internal.h file | annotate | diff | comparison | revisions
libpurple/plugins/perl/common/module.h file | annotate | diff | comparison | revisions
libpurple/protocols.c file | annotate | diff | comparison | revisions
libpurple/purple.h.in file | annotate | diff | comparison | revisions
libpurple/server.c file | annotate | diff | comparison | revisions
libpurple/server.h file | annotate | diff | comparison | revisions
libpurple/status.c file | annotate | diff | comparison | revisions
pidgin/gtkaccount.h file | annotate | diff | comparison | revisions
--- a/ChangeLog.API	Thu Oct 10 23:53:58 2013 +0530
+++ b/ChangeLog.API	Fri Oct 11 01:26:38 2013 +0530
@@ -173,7 +173,7 @@
 
 		Changed:
 		* account.h has been split into account.h (PurpleAccount GObject) and
-		  account-manager.h (PurpleAccountManager GObject)
+		  accounts.h (Accounts subsystem)
 		* blist.h has been split into buddylist.h (PurpleBuddyList and
 		  subsystem), blistnode.h (PurpleBlistNode and PurpleCountingNode
 		  GObjects), blistnodetypes (Buddy, Chat, Contact, Group GObjects)
--- a/libpurple/Makefile.am	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/Makefile.am	Fri Oct 11 01:26:38 2013 +0530
@@ -47,7 +47,7 @@
 
 purple_coresources = \
 	account.c \
-	account-manager.c \
+	accounts.c \
 	accountopt.c \
 	blistnode.c \
 	blistnodetypes.c \
@@ -133,7 +133,7 @@
 
 purple_coreheaders = \
 	account.h \
-	account-manager.h \
+	accounts.h \
 	accountopt.h \
 	blistnode.h \
 	blistnodetypes.h \
@@ -269,7 +269,7 @@
 dbus_sources  = dbus-server.c dbus-useful.c
 dbus_headers  = dbus-server.h dbus-bindings.h dbus-purple.h dbus-useful.h dbus-define-api.h dbus-types.h
 
-dbus_exported = dbus-useful.h dbus-define-api.h account.h account-manager.h blistnode.h \
+dbus_exported = dbus-useful.h dbus-define-api.h account.h accounts.h blistnode.h \
                 blistnodetypes.h buddylist.h buddyicon.h connection.h conversation.h \
                 conversationtypes.h conversations.h core.h xfer.h log.h notify.h \
                 prefs.h presence.h roomlist.h savedstatuses.h smiley.h status.h \
--- a/libpurple/Makefile.mingw	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/Makefile.mingw	Fri Oct 11 01:26:38 2013 +0530
@@ -63,7 +63,7 @@
 C_SRC =	\
 			$(BUILT_SRC) \
 			account.c \
-			account-manager.c \
+			accounts.c \
 			accountopt.c \
 			blistnode.c \
 			blistnodetypes.c \
--- a/libpurple/account-manager.c	Thu Oct 10 23:53:58 2013 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1250 +0,0 @@
-/**
- * @file account-manager.c Account Manager API
- * @ingroup core
- */
-
-/* purple
- *
- * Purple 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
- */
-#include "internal.h"
-#include "account-manager.h"
-#include "core.h"
-#include "dbus-maybe.h"
-#include "debug.h"
-#include "enums.h"
-#include "network.h"
-#include "pounce.h"
-
-#define PURPLE_ACCOUNT_MANAGER_GET_PRIVATE(obj) \
-	(G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_ACCOUNT_MANAGER, PurpleAccountManagerPrivate))
-
-/** @copydoc _PurpleAccountManagerPrivate */
-typedef struct _PurpleAccountManagerPrivate  PurpleAccountManagerPrivate;
-
-/** Private data of an account manager */
-struct _PurpleAccountManagerPrivate {
-	PurpleAccountUiOps *account_ui_ops;
-
-	GList   *accounts;
-	guint    save_timer;
-	gboolean accounts_loaded;
-};
-
-static PurpleAccountManager        *account_manager = NULL;
-static PurpleAccountManagerPrivate *priv            = NULL;
-
-static GObjectClass *parent_class = NULL;
-
-/* Account Manager property enums */
-enum
-{
-	PROP_0,
-	PROP_UI_OPS,
-	PROP_LAST
-};
-
-/* Account Manager signal enums */
-enum
-{
-	SIG_ACC_CONNECTING,
-	SIG_ACC_DISABLED,
-	SIG_ACC_ENABLED,
-	SIG_ACC_SETTING_INFO,
-	SIG_ACC_SET_INFO,
-	SIG_ACC_CREATED,
-	SIG_ACC_DESTROYING,
-	SIG_ACC_ADDED,
-	SIG_ACC_REMOVED,
-	SIG_ACC_STATUS_CHANGED,
-	SIG_ACC_ACTIONS_CHANGED,
-	SIG_ACC_ALIAS_CHANGED,
-	SIG_ACC_AUTH_REQUESTED,
-	SIG_ACC_AUTH_DENIED,
-	SIG_ACC_AUTH_GRANTED,
-	SIG_ACC_ERROR_CHANGED,
-	SIG_ACC_SIGNED_ON,
-	SIG_ACC_SIGNED_OFF,
-	SIG_ACC_CONNECTION_ERROR,
-	SIG_LAST
-};
-static guint signals[SIG_LAST] = { 0 };
-
-void _purple_account_set_current_error(PurpleAccount *account,
-		PurpleConnectionErrorInfo *new_err);
-
-/*********************************************************************
- * Writing to disk                                                   *
- *********************************************************************/
-static PurpleXmlNode *
-accounts_to_xmlnode(void)
-{
-	PurpleXmlNode *node, *child;
-	GList *cur;
-
-	node = purple_xmlnode_new("account");
-	purple_xmlnode_set_attrib(node, "version", "1.0");
-
-	for (cur = purple_accounts_get_all(); cur != NULL; cur = cur->next)
-	{
-		child = purple_account_to_xmlnode(cur->data);
-		purple_xmlnode_insert_child(node, child);
-	}
-
-	return node;
-}
-
-static void
-sync_accounts(void)
-{
-	PurpleXmlNode *node;
-	char *data;
-
-	g_return_if_fail(priv != NULL);
-
-	if (!priv->accounts_loaded)
-	{
-		purple_debug_error("account", "Attempted to save accounts before "
-						 "they were read!\n");
-		return;
-	}
-
-	node = accounts_to_xmlnode();
-	data = purple_xmlnode_to_formatted_str(node, NULL);
-	purple_util_write_data_to_file("accounts.xml", data, -1);
-	g_free(data);
-	purple_xmlnode_free(node);
-}
-
-static gboolean
-save_cb(gpointer data)
-{
-	g_return_val_if_fail(priv != NULL, FALSE);
-
-	sync_accounts();
-	priv->save_timer = 0;
-	return FALSE;
-}
-
-void
-purple_accounts_schedule_save(void)
-{
-	g_return_if_fail(priv != NULL);
-
-	if (priv->save_timer == 0)
-		priv->save_timer = purple_timeout_add_seconds(5, save_cb, NULL);
-}
-
-/*********************************************************************
- * Reading from disk                                                 *
- *********************************************************************/
-static void
-migrate_yahoo_japan(PurpleAccount *account)
-{
-	/* detect a Yahoo! JAPAN account that existed prior to 2.6.0 and convert it
-	 * to use the new yahoojp protocol.  Also remove the account-specific settings
-	 * we no longer need */
-
-	if(purple_strequal(purple_account_get_protocol_id(account), "yahoo")) {
-		if(purple_account_get_bool(account, "yahoojp", FALSE)) {
-			const char *serverjp = purple_account_get_string(account, "serverjp", NULL);
-			const char *xferjp_host = purple_account_get_string(account, "xferjp_host", NULL);
-
-			g_return_if_fail(serverjp != NULL);
-			g_return_if_fail(xferjp_host != NULL);
-
-			purple_account_set_string(account, "server", serverjp);
-			purple_account_set_string(account, "xfer_host", xferjp_host);
-
-			purple_account_set_protocol_id(account, "yahoojp");
-		}
-
-		/* these should always be nuked */
-		purple_account_remove_setting(account, "yahoojp");
-		purple_account_remove_setting(account, "serverjp");
-		purple_account_remove_setting(account, "xferjp_host");
-
-	}
-}
-
-static void
-migrate_icq_server(PurpleAccount *account)
-{
-	/* Migrate the login server setting for ICQ accounts.  See
-	 * 'mtn log --last 1 --no-graph --from b6d7712e90b68610df3bd2d8cbaf46d94c8b3794'
-	 * for details on the change. */
-
-	if(purple_strequal(purple_account_get_protocol_id(account), "icq")) {
-		const char *tmp = purple_account_get_string(account, "server", NULL);
-
-		/* Non-secure server */
-		if(purple_strequal(tmp,	"login.messaging.aol.com") ||
-				purple_strequal(tmp, "login.oscar.aol.com"))
-			purple_account_set_string(account, "server", "login.icq.com");
-
-		/* Secure server */
-		if(purple_strequal(tmp, "slogin.oscar.aol.com"))
-			purple_account_set_string(account, "server", "slogin.icq.com");
-	}
-}
-
-static void
-migrate_xmpp_encryption(PurpleAccount *account)
-{
-	/* When this is removed, nuke the "old_ssl" and "require_tls" settings */
-	if (g_str_equal(purple_account_get_protocol_id(account), "jabber")) {
-		const char *sec = purple_account_get_string(account, "connection_security", "");
-
-		if (g_str_equal("", sec)) {
-			const char *val = "require_tls";
-			if (purple_account_get_bool(account, "old_ssl", FALSE))
-				val = "old_ssl";
-			else if (!purple_account_get_bool(account, "require_tls", TRUE))
-				val = "opportunistic_tls";
-
-			purple_account_set_string(account, "connection_security", val);
-		}
-	}
-}
-
-static void
-parse_settings(PurpleXmlNode *node, PurpleAccount *account)
-{
-	const char *ui;
-	PurpleXmlNode *child;
-
-	/* Get the UI string, if these are UI settings */
-	ui = purple_xmlnode_get_attrib(node, "ui");
-
-	/* Read settings, one by one */
-	for (child = purple_xmlnode_get_child(node, "setting"); child != NULL;
-			child = purple_xmlnode_get_next_twin(child))
-	{
-		const char *name, *str_type;
-		PurplePrefType type;
-		char *data;
-
-		name = purple_xmlnode_get_attrib(child, "name");
-		if (name == NULL)
-			/* Ignore this setting */
-			continue;
-
-		str_type = purple_xmlnode_get_attrib(child, "type");
-		if (str_type == NULL)
-			/* Ignore this setting */
-			continue;
-
-		if (purple_strequal(str_type, "string"))
-			type = PURPLE_PREF_STRING;
-		else if (purple_strequal(str_type, "int"))
-			type = PURPLE_PREF_INT;
-		else if (purple_strequal(str_type, "bool"))
-			type = PURPLE_PREF_BOOLEAN;
-		else
-			/* Ignore this setting */
-			continue;
-
-		data = purple_xmlnode_get_data(child);
-		if (data == NULL)
-			/* Ignore this setting */
-			continue;
-
-		if (ui == NULL)
-		{
-			if (type == PURPLE_PREF_STRING)
-				purple_account_set_string(account, name, data);
-			else if (type == PURPLE_PREF_INT)
-				purple_account_set_int(account, name, atoi(data));
-			else if (type == PURPLE_PREF_BOOLEAN)
-				purple_account_set_bool(account, name,
-									  (*data == '0' ? FALSE : TRUE));
-		} else {
-			if (type == PURPLE_PREF_STRING)
-				purple_account_set_ui_string(account, ui, name, data);
-			else if (type == PURPLE_PREF_INT)
-				purple_account_set_ui_int(account, ui, name, atoi(data));
-			else if (type == PURPLE_PREF_BOOLEAN)
-				purple_account_set_ui_bool(account, ui, name,
-										 (*data == '0' ? FALSE : TRUE));
-		}
-
-		g_free(data);
-	}
-
-	/* we do this here because we need access to account settings to determine
-	 * if we can/should migrate an old Yahoo! JAPAN account */
-	migrate_yahoo_japan(account);
-	/* we do this here because we need access to account settings to determine
-	 * if we can/should migrate an ICQ account's server setting */
-	migrate_icq_server(account);
-	/* we do this here because we need to do it before the user views the
-	 * Edit Account dialog. */
-	migrate_xmpp_encryption(account);
-}
-
-static GList *
-parse_status_attrs(PurpleXmlNode *node, PurpleStatus *status)
-{
-	GList *list = NULL;
-	PurpleXmlNode *child;
-	GValue *attr_value;
-
-	for (child = purple_xmlnode_get_child(node, "attribute"); child != NULL;
-			child = purple_xmlnode_get_next_twin(child))
-	{
-		const char *id = purple_xmlnode_get_attrib(child, "id");
-		const char *value = purple_xmlnode_get_attrib(child, "value");
-
-		if (!id || !*id || !value || !*value)
-			continue;
-
-		attr_value = purple_status_get_attr_value(status, id);
-		if (!attr_value)
-			continue;
-
-		list = g_list_append(list, (char *)id);
-
-		switch (G_VALUE_TYPE(attr_value))
-		{
-			case G_TYPE_STRING:
-				list = g_list_append(list, (char *)value);
-				break;
-			case G_TYPE_INT:
-			case G_TYPE_BOOLEAN:
-			{
-				int v;
-				if (sscanf(value, "%d", &v) == 1)
-					list = g_list_append(list, GINT_TO_POINTER(v));
-				else
-					list = g_list_remove(list, id);
-				break;
-			}
-			default:
-				break;
-		}
-	}
-
-	return list;
-}
-
-static void
-parse_status(PurpleXmlNode *node, PurpleAccount *account)
-{
-	gboolean active = FALSE;
-	const char *data;
-	const char *type;
-	PurpleXmlNode *child;
-	GList *attrs = NULL;
-
-	/* Get the active/inactive state */
-	data = purple_xmlnode_get_attrib(node, "active");
-	if (data == NULL)
-		return;
-	if (g_ascii_strcasecmp(data, "true") == 0)
-		active = TRUE;
-	else if (g_ascii_strcasecmp(data, "false") == 0)
-		active = FALSE;
-	else
-		return;
-
-	/* Get the type of the status */
-	type = purple_xmlnode_get_attrib(node, "type");
-	if (type == NULL)
-		return;
-
-	/* Read attributes into a GList */
-	child = purple_xmlnode_get_child(node, "attributes");
-	if (child != NULL)
-	{
-		attrs = parse_status_attrs(child,
-						purple_account_get_status(account, type));
-	}
-
-	purple_account_set_status_list(account, type, active, attrs);
-
-	g_list_free(attrs);
-}
-
-static void
-parse_statuses(PurpleXmlNode *node, PurpleAccount *account)
-{
-	PurpleXmlNode *child;
-
-	for (child = purple_xmlnode_get_child(node, "status"); child != NULL;
-			child = purple_xmlnode_get_next_twin(child))
-	{
-		parse_status(child, account);
-	}
-}
-
-static void
-parse_proxy_info(PurpleXmlNode *node, PurpleAccount *account)
-{
-	PurpleProxyInfo *proxy_info;
-	PurpleXmlNode *child;
-	char *data;
-
-	proxy_info = purple_proxy_info_new();
-
-	/* Use the global proxy settings, by default */
-	purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
-
-	/* Read proxy type */
-	child = purple_xmlnode_get_child(node, "type");
-	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
-	{
-		if (purple_strequal(data, "global"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
-		else if (purple_strequal(data, "none"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_NONE);
-		else if (purple_strequal(data, "http"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_HTTP);
-		else if (purple_strequal(data, "socks4"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS4);
-		else if (purple_strequal(data, "socks5"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS5);
-		else if (purple_strequal(data, "tor"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_TOR);
-		else if (purple_strequal(data, "envvar"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_ENVVAR);
-		else
-		{
-			purple_debug_error("account", "Invalid proxy type found when "
-							 "loading account information for %s\n",
-							 purple_account_get_username(account));
-		}
-		g_free(data);
-	}
-
-	/* Read proxy host */
-	child = purple_xmlnode_get_child(node, "host");
-	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
-	{
-		purple_proxy_info_set_host(proxy_info, data);
-		g_free(data);
-	}
-
-	/* Read proxy port */
-	child = purple_xmlnode_get_child(node, "port");
-	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
-	{
-		purple_proxy_info_set_port(proxy_info, atoi(data));
-		g_free(data);
-	}
-
-	/* Read proxy username */
-	child = purple_xmlnode_get_child(node, "username");
-	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
-	{
-		purple_proxy_info_set_username(proxy_info, data);
-		g_free(data);
-	}
-
-	/* Read proxy password */
-	child = purple_xmlnode_get_child(node, "password");
-	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
-	{
-		purple_proxy_info_set_password(proxy_info, data);
-		g_free(data);
-	}
-
-	/* If there are no values set then proxy_info NULL */
-	if ((purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) &&
-		(purple_proxy_info_get_host(proxy_info) == NULL) &&
-		(purple_proxy_info_get_port(proxy_info) == 0) &&
-		(purple_proxy_info_get_username(proxy_info) == NULL) &&
-		(purple_proxy_info_get_password(proxy_info) == NULL))
-	{
-		purple_proxy_info_destroy(proxy_info);
-		return;
-	}
-
-	purple_account_set_proxy_info(account, proxy_info);
-}
-
-static void
-parse_current_error(PurpleXmlNode *node, PurpleAccount *account)
-{
-	guint type;
-	char *type_str = NULL, *description = NULL;
-	PurpleXmlNode *child;
-	PurpleConnectionErrorInfo *current_error = NULL;
-
-	child = purple_xmlnode_get_child(node, "type");
-	if (child == NULL || (type_str = purple_xmlnode_get_data(child)) == NULL)
-		return;
-	type = atoi(type_str);
-	g_free(type_str);
-
-	if (type > PURPLE_CONNECTION_ERROR_OTHER_ERROR)
-	{
-		purple_debug_error("account",
-			"Invalid PurpleConnectionError value %d found when "
-			"loading account information for %s\n",
-			type, purple_account_get_username(account));
-		type = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
-	}
-
-	child = purple_xmlnode_get_child(node, "description");
-	if (child)
-		description = purple_xmlnode_get_data(child);
-	if (description == NULL)
-		description = g_strdup("");
-
-	current_error = g_new0(PurpleConnectionErrorInfo, 1);
-	PURPLE_DBUS_REGISTER_POINTER(current_error, PurpleConnectionErrorInfo);
-	current_error->type = type;
-	current_error->description = description;
-
-	_purple_account_set_current_error(account, current_error);
-}
-
-static PurpleAccount *
-parse_account(PurpleXmlNode *node)
-{
-	PurpleAccount *ret;
-	PurpleXmlNode *child;
-	char *protocol_id = NULL;
-	char *name = NULL;
-	char *data;
-
-	child = purple_xmlnode_get_child(node, "protocol");
-	if (child != NULL)
-		protocol_id = purple_xmlnode_get_data(child);
-
-	child = purple_xmlnode_get_child(node, "name");
-	if (child != NULL)
-		name = purple_xmlnode_get_data(child);
-	if (name == NULL)
-	{
-		/* Do we really need to do this? */
-		child = purple_xmlnode_get_child(node, "username");
-		if (child != NULL)
-			name = purple_xmlnode_get_data(child);
-	}
-
-	if ((protocol_id == NULL) || (name == NULL))
-	{
-		g_free(protocol_id);
-		g_free(name);
-		return NULL;
-	}
-
-	ret = purple_account_new(name, protocol_id);
-	g_free(name);
-	g_free(protocol_id);
-
-	/* Read the alias */
-	child = purple_xmlnode_get_child(node, "alias");
-	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
-	{
-		if (*data != '\0')
-			purple_account_set_private_alias(ret, data);
-		g_free(data);
-	}
-
-	/* Read the statuses */
-	child = purple_xmlnode_get_child(node, "statuses");
-	if (child != NULL)
-	{
-		parse_statuses(child, ret);
-	}
-
-	/* Read the userinfo */
-	child = purple_xmlnode_get_child(node, "userinfo");
-	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
-	{
-		purple_account_set_user_info(ret, data);
-		g_free(data);
-	}
-
-	/* Read an old buddyicon */
-	child = purple_xmlnode_get_child(node, "buddyicon");
-	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
-	{
-		const char *dirname = purple_buddy_icons_get_cache_dir();
-		char *filename = g_build_filename(dirname, data, NULL);
-		gchar *contents;
-		gsize len;
-
-		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);
-	}
-
-	/* Read settings (both core and UI) */
-	for (child = purple_xmlnode_get_child(node, "settings"); child != NULL;
-			child = purple_xmlnode_get_next_twin(child))
-	{
-		parse_settings(child, ret);
-	}
-
-	/* Read proxy */
-	child = purple_xmlnode_get_child(node, "proxy");
-	if (child != NULL)
-	{
-		parse_proxy_info(child, ret);
-	}
-
-	/* Read current error */
-	child = purple_xmlnode_get_child(node, "current_error");
-	if (child != NULL)
-	{
-		parse_current_error(child, ret);
-	}
-
-	/* Read the password */
-	child = purple_xmlnode_get_child(node, "password");
-	if (child != NULL)
-	{
-		const char *keyring_id = purple_xmlnode_get_attrib(child, "keyring_id");
-		const char *mode = purple_xmlnode_get_attrib(child, "mode");
-		gboolean result;
-
-		data = purple_xmlnode_get_data(child);
-		result = purple_keyring_import_password(ret, keyring_id, mode, data, NULL);
-
-		if (result == TRUE || purple_keyring_get_inuse() == NULL) {
-			purple_account_set_remember_password(ret, TRUE);
-		} else {
-			purple_debug_error("account", "Failed to import password.\n");
-		} 
-		purple_str_wipe(data);
-	}
-
-	return ret;
-}
-
-static void
-load_accounts(void)
-{
-	PurpleXmlNode *node, *child;
-
-	g_return_if_fail(priv != NULL);
-
-	priv->accounts_loaded = TRUE;
-
-	node = purple_util_read_xml_from_file("accounts.xml", _("accounts"));
-
-	if (node == NULL)
-		return;
-
-	for (child = purple_xmlnode_get_child(node, "account"); child != NULL;
-			child = purple_xmlnode_get_next_twin(child))
-	{
-		PurpleAccount *new_acct;
-		new_acct = parse_account(child);
-		purple_accounts_add(new_acct);
-	}
-
-	purple_xmlnode_free(node);
-
-	_purple_buddy_icons_account_loaded_cb();
-}
-
-void
-purple_accounts_add(PurpleAccount *account)
-{
-	g_return_if_fail(priv != NULL);
-	g_return_if_fail(account != NULL);
-
-	if (g_list_find(priv->accounts, account) != NULL)
-		return;
-
-	priv->accounts = g_list_append(priv->accounts, account);
-
-	purple_accounts_schedule_save();
-
-	g_signal_emit(account_manager, signals[SIG_ACC_ADDED], 0, account);
-}
-
-void
-purple_accounts_remove(PurpleAccount *account)
-{
-	g_return_if_fail(priv != NULL);
-	g_return_if_fail(account != NULL);
-
-	priv->accounts = g_list_remove(priv->accounts, account);
-
-	purple_accounts_schedule_save();
-
-	/* Clearing the error ensures that account-error-changed is emitted,
-	 * which is the end of the guarantee that the the error's pointer is
-	 * valid.
-	 */
-	purple_account_clear_current_error(account);
-	g_signal_emit(account_manager, signals[SIG_ACC_REMOVED], 0, account);
-}
-
-static void
-purple_accounts_delete_set(PurpleAccount *account, GError *error, gpointer data)
-{
-	g_object_unref(G_OBJECT(account));
-}
-
-void
-purple_accounts_delete(PurpleAccount *account)
-{
-	PurpleBlistNode *gnode, *cnode, *bnode;
-	GList *iter;
-
-	g_return_if_fail(account != NULL);
-
-	/*
-	 * Disable the account before blowing it out of the water.
-	 * Conceptually it probably makes more sense to disable the
-	 * account for all UIs rather than the just the current UI,
-	 * but it doesn't really matter.
-	 */
-	purple_account_set_enabled(account, purple_core_get_ui(), FALSE);
-
-	purple_notify_close_with_handle(account);
-	purple_request_close_with_handle(account);
-
-	purple_accounts_remove(account);
-
-	/* Remove this account's buddies */
-	for (gnode = purple_blist_get_root();
-	     gnode != NULL;
-		 gnode = purple_blist_node_get_sibling_next(gnode))
-	{
-		if (!PURPLE_IS_GROUP(gnode))
-			continue;
-
-		cnode = purple_blist_node_get_first_child(gnode);
-		while (cnode) {
-			PurpleBlistNode *cnode_next = purple_blist_node_get_sibling_next(cnode);
-
-			if(PURPLE_IS_CONTACT(cnode)) {
-				bnode = purple_blist_node_get_first_child(cnode);
-				while (bnode) {
-					PurpleBlistNode *bnode_next = purple_blist_node_get_sibling_next(bnode);
-
-					if (PURPLE_IS_BUDDY(bnode)) {
-						PurpleBuddy *b = (PurpleBuddy *)bnode;
-
-						if (purple_buddy_get_account(b) == account)
-							purple_blist_remove_buddy(b);
-					}
-					bnode = bnode_next;
-				}
-			} else if (PURPLE_IS_CHAT(cnode)) {
-				PurpleChat *c = (PurpleChat *)cnode;
-
-				if (purple_chat_get_account(c) == account)
-					purple_blist_remove_chat(c);
-			}
-			cnode = cnode_next;
-		}
-	}
-
-	/* Remove any open conversation for this account */
-	for (iter = purple_conversations_get_all(); iter; ) {
-		PurpleConversation *conv = iter->data;
-		iter = iter->next;
-		if (purple_conversation_get_account(conv) == account)
-			g_object_unref(conv);
-	}
-
-	/* Remove this account's pounces */
-	purple_pounce_destroy_all_by_account(account);
-
-	/* This will cause the deletion of an old buddy icon. */
-	purple_buddy_icons_set_account_icon(account, NULL, 0);
-
-	/* This is async because we do not want the
-	 * account being overwritten before we are done.
-	 */
-	purple_keyring_set_password(account, NULL,
-		purple_accounts_delete_set, NULL);
-}
-
-void
-purple_accounts_reorder(PurpleAccount *account, guint new_index)
-{
-	gint index;
-	GList *l;
-
-	g_return_if_fail(priv != NULL);
-	g_return_if_fail(account != NULL);
-	g_return_if_fail(new_index <= g_list_length(priv->accounts));
-
-	index = g_list_index(priv->accounts, account);
-
-	if (index < 0) {
-		purple_debug_error("account",
-				   "Unregistered account (%s) discovered during reorder!\n",
-				   purple_account_get_username(account));
-		return;
-	}
-
-	l = g_list_nth(priv->accounts, index);
-
-	if (new_index > (guint)index)
-		new_index--;
-
-	/* Remove the old one. */
-	priv->accounts = g_list_delete_link(priv->accounts, l);
-
-	/* Insert it where it should go. */
-	priv->accounts = g_list_insert(priv->accounts, account, new_index);
-
-	purple_accounts_schedule_save();
-}
-
-GList *
-purple_accounts_get_all(void)
-{
-	g_return_val_if_fail(priv != NULL, NULL);
-
-	return priv->accounts;
-}
-
-GList *
-purple_accounts_get_all_active(void)
-{
-	GList *list = NULL;
-	GList *all = purple_accounts_get_all();
-
-	while (all != NULL) {
-		PurpleAccount *account = all->data;
-
-		if (purple_account_get_enabled(account, purple_core_get_ui()))
-			list = g_list_append(list, account);
-
-		all = all->next;
-	}
-
-	return list;
-}
-
-PurpleAccount *
-purple_accounts_find(const char *name, const char *protocol_id)
-{
-	PurpleAccount *account = NULL;
-	GList *l;
-	char *who;
-
-	g_return_val_if_fail(name != NULL, NULL);
-	g_return_val_if_fail(protocol_id != NULL, NULL);
-
-	for (l = purple_accounts_get_all(); l != NULL; l = l->next) {
-		account = (PurpleAccount *)l->data;
-
-		if (!purple_strequal(purple_account_get_protocol_id(account), protocol_id))
-			continue;
-
-		who = g_strdup(purple_normalize(account, name));
-		if (purple_strequal(purple_normalize(account, purple_account_get_username(account)), who)) {
-			g_free(who);
-			return account;
-		}
-		g_free(who);
-	}
-
-	return NULL;
-}
-
-void
-purple_accounts_restore_current_statuses()
-{
-	GList *l;
-	PurpleAccount *account;
-
-	/* If we're not connected to the Internet right now, we bail on this */
-	if (!purple_network_is_available())
-	{
-		purple_debug_warning("account", "Network not connected; skipping reconnect\n");
-		return;
-	}
-
-	for (l = purple_accounts_get_all(); l != NULL; l = l->next)
-	{
-		account = (PurpleAccount *)l->data;
-
-		if (purple_account_get_enabled(account, purple_core_get_ui()) &&
-			(purple_presence_is_online(purple_account_get_presence(account))))
-		{
-			purple_account_connect(account);
-		}
-	}
-}
-
-void
-purple_accounts_set_ui_ops(PurpleAccountUiOps *ops)
-{
-	g_return_if_fail(priv != NULL);
-
-	priv->account_ui_ops = ops;
-
-	g_object_notify(G_OBJECT(account_manager), "ui-ops");
-}
-
-PurpleAccountUiOps *
-purple_accounts_get_ui_ops(void)
-{
-	g_return_val_if_fail(priv != NULL, FALSE);
-
-	return priv->account_ui_ops;
-}
-
-static void
-signed_on_cb(PurpleConnection *gc,
-             gpointer unused)
-{
-	PurpleAccount *account;
-
-	g_return_if_fail(account_manager != NULL);
-
-	account = purple_connection_get_account(gc);
-	purple_account_clear_current_error(account);
-
-	g_signal_emit(account_manager, signals[SIG_ACC_SIGNED_ON], 0, account);
-}
-
-static void
-signed_off_cb(PurpleConnection *gc,
-              gpointer unused)
-{
-	PurpleAccount *account;
-
-	g_return_if_fail(account_manager != NULL);
-
-	account = purple_connection_get_account(gc);
-
-	g_signal_emit(account_manager, signals[SIG_ACC_SIGNED_OFF], 0, account);
-}
-
-static void
-connection_error_cb(PurpleConnection *gc,
-                    PurpleConnectionError type,
-                    const gchar *description,
-                    gpointer unused)
-{
-	PurpleAccount *account;
-	PurpleConnectionErrorInfo *err;
-
-	g_return_if_fail(account_manager != NULL);
-
-	account = purple_connection_get_account(gc);
-
-	g_return_if_fail(account != NULL);
-
-	err = g_new0(PurpleConnectionErrorInfo, 1);
-	PURPLE_DBUS_REGISTER_POINTER(err, PurpleConnectionErrorInfo);
-
-	err->type = type;
-	err->description = g_strdup(description);
-
-	_purple_account_set_current_error(account, err);
-
-	g_signal_emit(account_manager, signals[SIG_ACC_CONNECTION_ERROR], 0,
-	                   account, type, description);
-}
-
-static void
-password_migration_cb(PurpleAccount *account)
-{
-	/* account may be NULL (means: all) */
-
-	purple_accounts_schedule_save();
-}
-
-PurpleAccountManager *
-purple_account_manager_get_instance(void)
-{
-	g_return_val_if_fail(account_manager != NULL, NULL);
-
-	return account_manager;
-}
-
-/**************************************************************************
- * GObject code
- **************************************************************************/
-
-/* Set method for GObject properties */
-static void
-purple_account_manager_set_property(GObject *obj, guint param_id,
-		const GValue *value, GParamSpec *pspec)
-{
-	switch (param_id) {
-		case PROP_UI_OPS:
-			purple_accounts_set_ui_ops(g_value_get_pointer(value));
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-			break;
-	}
-}
-
-/* Get method for GObject properties */
-static void
-purple_account_manager_get_property(GObject *obj, guint param_id, GValue *value,
-		GParamSpec *pspec)
-{
-	switch (param_id) {
-		case PROP_UI_OPS:
-			g_value_set_pointer(value, purple_accounts_get_ui_ops());
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-			break;
-	}
-}
-
-/* GObject dispose function */
-static void
-purple_account_manager_dispose(GObject *object)
-{
-	if (priv->save_timer != 0)
-	{
-		purple_timeout_remove(priv->save_timer);
-		priv->save_timer = 0;
-		sync_accounts();
-	}
-
-	for (; priv->accounts; priv->accounts = g_list_delete_link(priv->accounts, priv->accounts))
-		g_object_unref(G_OBJECT(priv->accounts->data));
-
-	G_OBJECT_CLASS(parent_class)->dispose(object);
-}
-
-static gboolean
-purple_account_request_response_accumulator(GSignalInvocationHint *ihint,
-		GValue *return_accu, const GValue *handler_return, gpointer data)
-{
-	PurpleAccountRequestResponse response;
-
-	response = g_value_get_enum(handler_return);
-	g_value_set_enum(return_accu, response);
-
-	if (response == PURPLE_ACCOUNT_RESPONSE_PASS)
-		return TRUE;
-
-	return FALSE;
-}
-
-/* Class initializer function */
-static void purple_account_manager_class_init(PurpleAccountManagerClass *klass)
-{
-	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-
-	parent_class = g_type_class_peek_parent(klass);
-
-	obj_class->dispose = purple_account_manager_dispose;
-
-	/* Setup properties */
-	obj_class->get_property = purple_account_manager_get_property;
-	obj_class->set_property = purple_account_manager_set_property;
-
-	g_object_class_install_property(obj_class, PROP_UI_OPS,
-			g_param_spec_pointer("ui-ops", _("UI Ops"),
-				_("UI Operations structure for accounts."),
-				G_PARAM_READWRITE)
-			);
-
-	signals[SIG_ACC_CONNECTING] =
-		g_signal_new("account-connecting", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT, G_TYPE_NONE, 1,
-		             PURPLE_TYPE_ACCOUNT);
-
-	signals[SIG_ACC_DISABLED] =
-		g_signal_new("account-disabled", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT, G_TYPE_NONE, 1,
-		             PURPLE_TYPE_ACCOUNT);
-
-	signals[SIG_ACC_ENABLED]
-		g_signal_new("account-enabled", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT, G_TYPE_NONE, 1,
-		             PURPLE_TYPE_ACCOUNT);
-
-	signals[SIG_ACC_SETTING_INFO]
-		g_signal_new("account-setting-info", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2,
-		             PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
-
-	signals[SIG_ACC_SET_INFO]
-		g_signal_new("account-set-info", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2,
-		             PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
-
-	signals[SIG_ACC_CREATED]
-		g_signal_new("account-created", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT, G_TYPE_NONE, 1,
-		             PURPLE_TYPE_ACCOUNT);
-
-	signals[SIG_ACC_DESTROYING]
-		g_signal_new("account-destroying", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT, G_TYPE_NONE, 1,
-		             PURPLE_TYPE_ACCOUNT);
-
-	signals[SIG_ACC_ADDED]
-		g_signal_new("account-added", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT, G_TYPE_NONE, 1,
-		             PURPLE_TYPE_ACCOUNT);
-
-	signals[SIG_ACC_REMOVED]
-		g_signal_new("account-removed", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT, G_TYPE_NONE, 1,
-		             PURPLE_TYPE_ACCOUNT);
-
-	signals[SIG_ACC_STATUS_CHANGED]
-		g_signal_new("account-status-changed", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT_OBJECT_OBJECT, G_TYPE_NONE, 3,
-		             PURPLE_TYPE_ACCOUNT, PURPLE_TYPE_STATUS,
-		             PURPLE_TYPE_STATUS);
-
-	signals[SIG_ACC_ACTIONS_CHANGED]
-		g_signal_new("account-actions-changed", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT, G_TYPE_NONE, 1,
-		             PURPLE_TYPE_ACCOUNT);
-
-	signals[SIG_ACC_ALIAS_CHANGED]
-		g_signal_new("account-alias-changed", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2,
-		             PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
-
-	signals[SIG_ACC_AUTH_REQUESTED]
-		g_signal_new("account-authorization-requested",
-		             G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_ACTION, 0,
-		             purple_account_request_response_accumulator, NULL,
-		             purple_smarshal_ENUM__OBJECT_STRING_STRING_STRING,
-		             PURPLE_TYPE_ACCOUNT_REQUEST_RESPONSE, 4,
-		             PURPLE_TYPE_ACCOUNT, G_TYPE_STRING, G_TYPE_STRING,
-		             G_TYPE_STRING);
-
-	signals[SIG_ACC_AUTH_DENIED]
-		g_signal_new("account-authorization-denied", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT_STRING_STRING, G_TYPE_NONE, 3,
-		             PURPLE_TYPE_ACCOUNT, G_TYPE_STRING, G_TYPE_STRING);
-
-	signals[SIG_ACC_AUTH_GRANTED]
-		g_signal_new("account-authorization-granted", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT_STRING_STRING, G_TYPE_NONE, 3,
-		             PURPLE_TYPE_ACCOUNT, G_TYPE_STRING, G_TYPE_STRING);
-
-	signals[SIG_ACC_ERROR_CHANGED]
-		g_signal_new("account-error-changed", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT_ENUM_ENUM, G_TYPE_NONE, 3,
-		             PURPLE_TYPE_ACCOUNT, PURPLE_TYPE_CONNECTION_ERROR_INFO,
-		             PURPLE_TYPE_CONNECTION_ERROR_INFO);
-
-	signals[SIG_ACC_SIGNED_ON]
-		g_signal_new("account-signed-on", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT, G_TYPE_NONE, 1,
-		             PURPLE_TYPE_ACCOUNT);
-
-	signals[SIG_ACC_SIGNED_OFF]
-		g_signal_new("account-signed-off", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT, G_TYPE_NONE, 1,
-		             PURPLE_TYPE_ACCOUNT);
-
-	signals[SIG_ACC_CONNECTION_ERROR]
-		g_signal_new("account-connection-error", G_OBJECT_CLASS_TYPE(klass),
-		             G_SIGNAL_ACTION, 0, NULL, NULL,
-		             purple_smarshal_VOID__OBJECT_ENUM_STRING, G_TYPE_NONE, 3,
-		             PURPLE_TYPE_ACCOUNT, PURPLE_TYPE_CONNECTION_ERROR,
-		             G_TYPE_STRING);
-
-	g_type_class_add_private(klass, sizeof(PurpleAccountManagerPrivate));
-}
-
-GType
-purple_account_manager_get_type(void)
-{
-	static GType type = 0;
-
-	if(type == 0) {
-		static const GTypeInfo info = {
-			sizeof(PurpleAccountManagerClass),
-			NULL,
-			NULL,
-			(GClassInitFunc)purple_account_manager_class_init,
-			NULL,
-			NULL,
-			sizeof(PurpleAccountManager),
-			0,
-			NULL,
-			NULL,
-		};
-
-		type = g_type_register_static(G_TYPE_OBJECT,
-				"PurpleAccountManager",
-				&info, 0);
-	}
-
-	return type;
-}
-
-static void
-manager_destroyed_cb(gpointer data, GObject *obj_was)
-{
-	priv            = NULL;
-	account_manager = NULL;
-}
-
-void purple_accounts_init(void)
-{
-	if (!account_manager) {
-		void *conn_handle = purple_connections_get_handle();
-
-		account_manager = g_object_new(PURPLE_TYPE_ACCOUNT_MANAGER, NULL);
-
-		g_return_if_fail(account_manager != NULL);
-
-		g_object_weak_ref(G_OBJECT(account_manager), manager_destroyed_cb, NULL);
-
-		purple_signal_connect(conn_handle, "signed-on", handle,
-			                  PURPLE_CALLBACK(signed_on_cb), NULL);
-		purple_signal_connect(conn_handle, "signed-off", handle,
-			                  PURPLE_CALLBACK(signed_off_cb), NULL);
-		purple_signal_connect(conn_handle, "connection-error", handle,
-			                  PURPLE_CALLBACK(connection_error_cb), NULL);
-		purple_signal_connect(purple_keyring_get_handle(), "password-migration", handle,
-			                  PURPLE_CALLBACK(password_migration_cb), NULL);
-
-		load_accounts();
-	}
-}
-
-void purple_accounts_uninit(void)
-{
-	g_object_unref(account_manager);
-}
--- a/libpurple/account-manager.h	Thu Oct 10 23:53:58 2013 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,279 +0,0 @@
-/**
- * @file account-manager.h Account Manager API
- * @ingroup core
- */
-
-/* purple
- *
- * Purple 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 _PURPLE_ACCOUNT_MANAGER_H_
-#define _PURPLE_ACCOUNT_MANAGER_H_
-
-#define PURPLE_TYPE_ACCOUNT_MANAGER             (purple_account_manager_get_type())
-#define PURPLE_ACCOUNT_MANAGER(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_ACCOUNT_MANAGER, PurpleAccountManager))
-#define PURPLE_ACCOUNT_MANAGER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_ACCOUNT_MANAGER, PurpleAccountManagerClass))
-#define PURPLE_IS_ACCOUNT_MANAGER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_ACCOUNT_MANAGER))
-#define PURPLE_IS_ACCOUNT_MANAGER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_ACCOUNT_MANAGER))
-#define PURPLE_ACCOUNT_MANAGER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_ACCOUNT_MANAGER, PurpleAccountManagerClass))
-
-/** @copydoc _PurpleAccountManager */
-typedef struct _PurpleAccountManager       PurpleAccountManager;
-/** @copydoc _PurpleAccountManagerClass */
-typedef struct _PurpleAccountManagerClass  PurpleAccountManagerClass;
-
-#define PURPLE_TYPE_ACCOUNT_UI_OPS  (purple_account_ui_ops_get_type())
-
-/** @copydoc _PurpleAccountUiOps */
-typedef struct _PurpleAccountUiOps  PurpleAccountUiOps;
-
-#include "account.h"
-#include "status.h"
-
-/**
- * Structure representing an account manager.
- */
-struct _PurpleAccountManager
-{
-	/*< private >*/
-	GObject gparent;
-};
-
-/**
- * The base class for all #PurpleAccountManager's.
- */
-struct _PurpleAccountManagerClass {
-	/*< private >*/
-	GObjectClass parent_class;
-
-	void (*_purple_reserved1)(void);
-	void (*_purple_reserved2)(void);
-	void (*_purple_reserved3)(void);
-	void (*_purple_reserved4)(void);
-};
-
-/**  Account UI operations, used to notify the user of status changes and when
- *   buddies add this account to their buddy lists.
- */
-struct _PurpleAccountUiOps
-{
-	/** A buddy who is already on this account's buddy list added this account
-	 *  to their buddy list.
-	 */
-	void (*notify_added)(PurpleAccount *account,
-	                     const char *remote_user,
-	                     const char *id,
-	                     const char *alias,
-	                     const char *message);
-
-	/** This account's status changed. */
-	void (*status_changed)(PurpleAccount *account,
-	                       PurpleStatus *status);
-
-	/** Someone we don't have on our list added us; prompt to add them. */
-	void (*request_add)(PurpleAccount *account,
-	                    const char *remote_user,
-	                    const char *id,
-	                    const char *alias,
-	                    const char *message);
-
-	/** Prompt for authorization when someone adds this account to their buddy
-	 * list.  To authorize them to see this account's presence, call \a
-	 * authorize_cb (\a message, \a user_data); otherwise call
-	 * \a deny_cb (\a message, \a user_data);
-	 * @return a UI-specific handle, as passed to #close_account_request.
-	 */
-	void *(*request_authorize)(PurpleAccount *account,
-	                           const char *remote_user,
-	                           const char *id,
-	                           const char *alias,
-	                           const char *message,
-	                           gboolean on_list,
-	                           PurpleAccountRequestAuthorizationCb authorize_cb,
-	                           PurpleAccountRequestAuthorizationCb deny_cb,
-	                           void *user_data);
-
-	/** Close a pending request for authorization.  \a ui_handle is a handle
-	 *  as returned by #request_authorize.
-	 */
-	void (*close_account_request)(void *ui_handle);
-
-	void (*permit_added)(PurpleAccount *account, const char *name);
-	void (*permit_removed)(PurpleAccount *account, const char *name);
-	void (*deny_added)(PurpleAccount *account, const char *name);
-	void (*deny_removed)(PurpleAccount *account, const char *name);
-
-	void (*_purple_reserved1)(void);
-	void (*_purple_reserved2)(void);
-	void (*_purple_reserved3)(void);
-	void (*_purple_reserved4)(void);
-};
-
-G_BEGIN_DECLS
-
-/**************************************************************************/
-/** @name Accounts API                                                    */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Adds an account to the list of accounts.
- *
- * @param account The account.
- */
-void purple_accounts_add(PurpleAccount *account);
-
-/**
- * Removes an account from the list of accounts.
- *
- * @param account The account.
- */
-void purple_accounts_remove(PurpleAccount *account);
-
-/**
- * Deletes an account.
- *
- * This will remove any buddies from the buddy list that belong to this
- * account, buddy pounces that belong to this account, and will also
- * destroy @a account.
- *
- * @param account The account.
- */
-void purple_accounts_delete(PurpleAccount *account);
-
-/**
- * Reorders an account.
- *
- * @param account   The account to reorder.
- * @param new_index The new index for the account.
- */
-void purple_accounts_reorder(PurpleAccount *account, guint new_index);
-
-/**
- * Returns a list of all accounts.
- *
- * @constreturn A list of all accounts.
- */
-GList *purple_accounts_get_all(void);
-
-/**
- * Returns a list of all enabled accounts
- *
- * @return A list of all enabled accounts. The list is owned
- *         by the caller, and must be g_list_free()d to avoid
- *         leaking the nodes.
- */
-GList *purple_accounts_get_all_active(void);
-
-/**
- * Finds an account with the specified name and protocol id.
- *
- * @param name     The account username.
- * @param protocol The account protocol ID.
- *
- * @return The account, if found, or @c FALSE otherwise.
- */
-PurpleAccount *purple_accounts_find(const char *name, const char *protocol);
-
-/**
- * This is called by the core after all subsystems and what
- * not have been initialized.  It sets all enabled accounts
- * to their startup status by signing them on, setting them
- * away, etc.
- *
- * You probably shouldn't call this unless you really know
- * what you're doing.
- */
-void purple_accounts_restore_current_statuses(void);
-
-/**
- * Schedules saving of accounts
- */
-void purple_accounts_schedule_save(void);
-
-/*@}*/
-
-
-/**************************************************************************/
-/** @name UI Registration Functions                                       */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Returns the GType for the PurpleAccountUiOps boxed structure.
- */
-GType purple_account_ui_ops_get_type(void);
-
-/**
- * Sets the UI operations structure to be used for accounts.
- *
- * @param ops The UI operations structure.
- */
-void purple_accounts_set_ui_ops(PurpleAccountUiOps *ops);
-
-/**
- * Returns the UI operations structure used for accounts.
- *
- * @return The UI operations structure in use.
- */
-PurpleAccountUiOps *purple_accounts_get_ui_ops(void);
-
-/*@}*/
-
-
-/**************************************************************************/
-/** @name Account Manager API                                             */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Returns the GType for the AccountManager object.
- */
-GType purple_account_manager_get_type(void);
-
-/**
- * Returns the account manager instance
- *
- * @return The account manager instance if initialized, else @c NULL.
- */
-PurpleAccountManager *purple_account_manager_get_instance(void);
-
-/*@}*/
-
-
-/**************************************************************************/
-/** @name Accounts Subsystem                                              */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Initializes the accounts subsystem.
- */
-void purple_accounts_init(void);
-
-/**
- * Uninitializes the accounts subsystem.
- */
-void purple_accounts_uninit(void);
-
-/*@}*/
-
-G_END_DECLS
-
-#endif /* _PURPLE_ACCOUNT_MANAGER_H_ */
--- a/libpurple/account.c	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/account.c	Fri Oct 11 01:26:38 2013 +0530
@@ -24,7 +24,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 #include "internal.h"
-#include "account-manager.h"
+#include "accounts.h"
 #include "core.h"
 #include "dbus-maybe.h"
 #include "debug.h"
@@ -510,7 +510,7 @@
 	if (info->auth_cb != NULL)
 		info->auth_cb(message, info->userdata);
 
-	g_signal_emit_by_name(purple_account_manager_get_instance(),
+	purple_signal_emit(purple_accounts_get_handle(),
 			"account-authorization-granted", info->account, info->user, message);
 
 	purple_account_request_info_unref(info);
@@ -526,7 +526,7 @@
 	if (info->deny_cb != NULL)
 		info->deny_cb(message, info->userdata);
 
-	g_signal_emit_by_name(purple_account_manager_get_instance(),
+	purple_signal_emit(purple_accounts_get_handle(),
 			"account-authorization-denied", info->account, info->user, message);
 
 	purple_account_request_info_unref(info);
@@ -539,7 +539,7 @@
 {
 	PurpleAccountUiOps *ui_ops;
 	PurpleAccountRequestInfo *info;
-	PurpleAccountRequestResponse response;
+	int plugin_return;
 	char *response = NULL;
 
 	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
@@ -547,11 +547,14 @@
 
 	ui_ops = purple_accounts_get_ui_ops();
 
-	g_signal_emit_by_name(purple_account_manager_get_instance(),
-				"account-authorization-requested", account, remote_user,
-				message, &response, &response);
-
-	switch (response)
+	plugin_return = GPOINTER_TO_INT(
+			purple_signal_emit_return_1(
+				purple_accounts_get_handle(),
+				"account-authorization-requested",
+				account, remote_user, message, &response
+			));
+
+	switch (plugin_return)
 	{
 		case PURPLE_ACCOUNT_RESPONSE_IGNORE:
 			g_free(response);
@@ -734,8 +737,6 @@
 	g_free(priv->username);
 	priv->username = g_strdup(username);
 
-	g_object_notify(G_OBJECT(account), "username");
-
 	purple_accounts_schedule_save();
 
 	/* if the name changes, we should re-write the buddy list
@@ -794,7 +795,7 @@
 		char *old = priv->alias;
 
 		priv->alias = g_strdup(alias);
-		g_signal_emit_by_name(purple_account_manager_get_instance(), "account-alias-changed",
+		purple_signal_emit(purple_accounts_get_handle(), "account-alias-changed",
 						 account, old);
 		g_free(old);
 
@@ -814,8 +815,6 @@
 	g_free(priv->user_info);
 	priv->user_info = g_strdup(user_info);
 
-	g_object_notify(G_OBJECT(account), "userinfo");
-
 	purple_accounts_schedule_save();
 }
 
@@ -830,8 +829,6 @@
 	g_free(priv->buddy_icon_path);
 	priv->buddy_icon_path = g_strdup(path);
 
-	g_object_notify(G_OBJECT(account), "buddy-icon-path");
-
 	purple_accounts_schedule_save();
 }
 
@@ -872,8 +869,6 @@
 	priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
 	priv->remember_pass = value;
 
-	g_object_notify(G_OBJECT(account), "remember-password");
-
 	purple_accounts_schedule_save();
 }
 
@@ -883,8 +878,6 @@
 	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
 
 	purple_account_set_bool(account, "check-mail", value);
-
-	g_object_notify(G_OBJECT(account), "check-mail");
 }
 
 void
@@ -904,9 +897,9 @@
 	gc = purple_account_get_connection(account);
 
 	if(was_enabled && !value)
-		g_signal_emit_by_name(purple_account_manager_get_instance(), "account-disabled", account);
+		purple_signal_emit(purple_accounts_get_handle(), "account-disabled", account);
 	else if(!was_enabled && value)
-		g_signal_emit_by_name(purple_account_manager_get_instance(), "account-enabled", account);
+		purple_signal_emit(purple_accounts_get_handle(), "account-enabled", account);
 
 	if ((gc != NULL) && (_purple_connection_wants_to_die(gc)))
 		wants_to_die = TRUE;
@@ -2393,7 +2386,7 @@
 
 	priv->current_error = new_err;
 
-	g_signal_emit_by_name(purple_account_manager_get_instance(),
+	purple_signal_emit(purple_accounts_get_handle(),
 	                   "account-error-changed",
 	                   account, old_err, new_err);
 	purple_accounts_schedule_save();
@@ -2777,6 +2770,17 @@
  * GObject Code *
  ****************/
 
+/* GObject Property names */
+#define PROP_USERNAME_S           "username"
+#define PROP_PRIVATE_ALIAS_S      "private-alias"
+#define PROP_ENABLED_S            "enabled"
+#define PROP_CONNECTION_S         "connection"
+#define PROP_PROTOCOL_ID_S        "protocol-id"
+#define PROP_USER_INFO_S          "userinfo"
+#define PROP_BUDDY_ICON_PATH_S    "buddy-icon-path"
+#define PROP_REMEMBER_PASSWORD_S  "remember-password"
+#define PROP_CHECK_MAIL_S         "check-mail"
+
 /* Set method for GObject properties */
 static void
 purple_account_set_property(GObject *obj, guint param_id, const GValue *value,
@@ -2895,11 +2899,11 @@
 	parent_class->constructed(object);
 
 	g_object_get(object,
-			"username",    &username,
-			"protocol-id", &protocol_id,
+			PROP_USERNAME_S,    &username,
+			PROP_PROTOCOL_ID_S, &protocol_id,
 			NULL);
 
-	g_signal_emit_by_name(purple_account_manager_get_instance(), "account-created",
+	purple_signal_emit(purple_accounts_get_handle(), "account-created",
 			account);
 
 	protocol = purple_protocols_find(protocol_id);
@@ -2952,7 +2956,7 @@
 	PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
 
 	purple_debug_info("account", "Destroying account %p\n", account);
-	g_signal_emit_by_name(purple_account_manager_get_instance(), "account-destroying",
+	purple_signal_emit(purple_accounts_get_handle(), "account-destroying",
 						account);
 
 	for (l = purple_conversations_get_all(); l != NULL; l = l->next)
@@ -3019,55 +3023,55 @@
 	obj_class->set_property = purple_account_set_property;
 
 	g_object_class_install_property(obj_class, PROP_USERNAME,
-			g_param_spec_string("username", _("Username"),
+			g_param_spec_string(PROP_USERNAME_S, _("Username"),
 				_("The username for the account."), NULL,
 				G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
 			);
 
 	g_object_class_install_property(obj_class, PROP_PRIVATE_ALIAS,
-			g_param_spec_string("private-alias", _("Private Alias"),
+			g_param_spec_string(PROP_PRIVATE_ALIAS_S, _("Private Alias"),
 				_("The private alias for the account."), NULL,
 				G_PARAM_READWRITE)
 			);
 
 	g_object_class_install_property(obj_class, PROP_USER_INFO,
-			g_param_spec_string("userinfo", _("User information"),
+			g_param_spec_string(PROP_USER_INFO_S, _("User information"),
 				_("Detailed user information for the account."), NULL,
 				G_PARAM_READWRITE)
 			);
 
 	g_object_class_install_property(obj_class, PROP_BUDDY_ICON_PATH,
-			g_param_spec_string("buddy-icon-path", _("Buddy icon path"),
+			g_param_spec_string(PROP_BUDDY_ICON_PATH_S, _("Buddy icon path"),
 				_("Path to the buddyicon for the account."), NULL,
 				G_PARAM_READWRITE)
 			);
 
 	g_object_class_install_property(obj_class, PROP_ENABLED,
-			g_param_spec_boolean("enabled", _("Enabled"),
+			g_param_spec_boolean(PROP_ENABLED_S, _("Enabled"),
 				_("Whether the account is enabled or not."), FALSE,
 				G_PARAM_READWRITE)
 			);
 
 	g_object_class_install_property(obj_class, PROP_REMEMBER_PASSWORD,
-			g_param_spec_boolean("remember-password", _("Remember password"),
+			g_param_spec_boolean(PROP_REMEMBER_PASSWORD_S, _("Remember password"),
 				_("Whether to remember and store the password for this account."), FALSE,
 				G_PARAM_READWRITE)
 			);
 
 	g_object_class_install_property(obj_class, PROP_CHECK_MAIL,
-			g_param_spec_boolean("check-mail", _("Check mail"),
+			g_param_spec_boolean(PROP_CHECK_MAIL_S, _("Check mail"),
 				_("Whether to check mails for this account."), FALSE,
 				G_PARAM_READWRITE)
 			);
 
 	g_object_class_install_property(obj_class, PROP_CONNECTION,
-			g_param_spec_object("connection", _("Connection"),
+			g_param_spec_object(PROP_CONNECTION_S, _("Connection"),
 				_("The connection for the account."), PURPLE_TYPE_CONNECTION,
 				G_PARAM_READWRITE)
 			);
 
 	g_object_class_install_property(obj_class, PROP_PROTOCOL_ID,
-			g_param_spec_string("protocol-id", _("Protocol ID"),
+			g_param_spec_string(PROP_PROTOCOL_ID_S, _("Protocol ID"),
 				_("ID of the protocol that is responsible for the account."), NULL,
 				G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
 			);
@@ -3116,8 +3120,8 @@
 		return account;
 
 	account = g_object_new(PURPLE_TYPE_ACCOUNT,
-					"username",    username,
-					"protocol-id", protocol_id,
+					PROP_USERNAME_S,    username,
+					PROP_PROTOCOL_ID_S, protocol_id,
 					NULL);
 
 	return account;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/accounts.c	Fri Oct 11 01:26:38 2013 +0530
@@ -0,0 +1,1022 @@
+/**
+ * @file accounts.c Accounts API
+ * @ingroup core
+ */
+
+/* purple
+ *
+ * Purple 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
+ */
+#include "internal.h"
+#include "accounts.h"
+#include "core.h"
+#include "dbus-maybe.h"
+#include "debug.h"
+#include "enums.h"
+#include "network.h"
+#include "pounce.h"
+
+static PurpleAccountUiOps *account_ui_ops = NULL;
+
+static GList   *accounts = NULL;
+static guint    save_timer = 0;
+static gboolean accounts_loaded = FALSE;
+
+void _purple_account_set_current_error(PurpleAccount *account,
+		PurpleConnectionErrorInfo *new_err);
+
+/*********************************************************************
+ * Writing to disk                                                   *
+ *********************************************************************/
+static PurpleXmlNode *
+accounts_to_xmlnode(void)
+{
+	PurpleXmlNode *node, *child;
+	GList *cur;
+
+	node = purple_xmlnode_new("account");
+	purple_xmlnode_set_attrib(node, "version", "1.0");
+
+	for (cur = purple_accounts_get_all(); cur != NULL; cur = cur->next)
+	{
+		child = purple_account_to_xmlnode(cur->data);
+		purple_xmlnode_insert_child(node, child);
+	}
+
+	return node;
+}
+
+static void
+sync_accounts(void)
+{
+	PurpleXmlNode *node;
+	char *data;
+
+	if (!accounts_loaded)
+	{
+		purple_debug_error("account", "Attempted to save accounts before "
+						 "they were read!\n");
+		return;
+	}
+
+	node = accounts_to_xmlnode();
+	data = purple_xmlnode_to_formatted_str(node, NULL);
+	purple_util_write_data_to_file("accounts.xml", data, -1);
+	g_free(data);
+	purple_xmlnode_free(node);
+}
+
+static gboolean
+save_cb(gpointer data)
+{
+	sync_accounts();
+	save_timer = 0;
+	return FALSE;
+}
+
+void
+purple_accounts_schedule_save(void)
+{
+	if (save_timer == 0)
+		save_timer = purple_timeout_add_seconds(5, save_cb, NULL);
+}
+
+/*********************************************************************
+ * Reading from disk                                                 *
+ *********************************************************************/
+static void
+migrate_yahoo_japan(PurpleAccount *account)
+{
+	/* detect a Yahoo! JAPAN account that existed prior to 2.6.0 and convert it
+	 * to use the new yahoojp protocol.  Also remove the account-specific settings
+	 * we no longer need */
+
+	if(purple_strequal(purple_account_get_protocol_id(account), "yahoo")) {
+		if(purple_account_get_bool(account, "yahoojp", FALSE)) {
+			const char *serverjp = purple_account_get_string(account, "serverjp", NULL);
+			const char *xferjp_host = purple_account_get_string(account, "xferjp_host", NULL);
+
+			g_return_if_fail(serverjp != NULL);
+			g_return_if_fail(xferjp_host != NULL);
+
+			purple_account_set_string(account, "server", serverjp);
+			purple_account_set_string(account, "xfer_host", xferjp_host);
+
+			purple_account_set_protocol_id(account, "yahoojp");
+		}
+
+		/* these should always be nuked */
+		purple_account_remove_setting(account, "yahoojp");
+		purple_account_remove_setting(account, "serverjp");
+		purple_account_remove_setting(account, "xferjp_host");
+
+	}
+}
+
+static void
+migrate_icq_server(PurpleAccount *account)
+{
+	/* Migrate the login server setting for ICQ accounts.  See
+	 * 'mtn log --last 1 --no-graph --from b6d7712e90b68610df3bd2d8cbaf46d94c8b3794'
+	 * for details on the change. */
+
+	if(purple_strequal(purple_account_get_protocol_id(account), "icq")) {
+		const char *tmp = purple_account_get_string(account, "server", NULL);
+
+		/* Non-secure server */
+		if(purple_strequal(tmp,	"login.messaging.aol.com") ||
+				purple_strequal(tmp, "login.oscar.aol.com"))
+			purple_account_set_string(account, "server", "login.icq.com");
+
+		/* Secure server */
+		if(purple_strequal(tmp, "slogin.oscar.aol.com"))
+			purple_account_set_string(account, "server", "slogin.icq.com");
+	}
+}
+
+static void
+migrate_xmpp_encryption(PurpleAccount *account)
+{
+	/* When this is removed, nuke the "old_ssl" and "require_tls" settings */
+	if (g_str_equal(purple_account_get_protocol_id(account), "jabber")) {
+		const char *sec = purple_account_get_string(account, "connection_security", "");
+
+		if (g_str_equal("", sec)) {
+			const char *val = "require_tls";
+			if (purple_account_get_bool(account, "old_ssl", FALSE))
+				val = "old_ssl";
+			else if (!purple_account_get_bool(account, "require_tls", TRUE))
+				val = "opportunistic_tls";
+
+			purple_account_set_string(account, "connection_security", val);
+		}
+	}
+}
+
+static void
+parse_settings(PurpleXmlNode *node, PurpleAccount *account)
+{
+	const char *ui;
+	PurpleXmlNode *child;
+
+	/* Get the UI string, if these are UI settings */
+	ui = purple_xmlnode_get_attrib(node, "ui");
+
+	/* Read settings, one by one */
+	for (child = purple_xmlnode_get_child(node, "setting"); child != NULL;
+			child = purple_xmlnode_get_next_twin(child))
+	{
+		const char *name, *str_type;
+		PurplePrefType type;
+		char *data;
+
+		name = purple_xmlnode_get_attrib(child, "name");
+		if (name == NULL)
+			/* Ignore this setting */
+			continue;
+
+		str_type = purple_xmlnode_get_attrib(child, "type");
+		if (str_type == NULL)
+			/* Ignore this setting */
+			continue;
+
+		if (purple_strequal(str_type, "string"))
+			type = PURPLE_PREF_STRING;
+		else if (purple_strequal(str_type, "int"))
+			type = PURPLE_PREF_INT;
+		else if (purple_strequal(str_type, "bool"))
+			type = PURPLE_PREF_BOOLEAN;
+		else
+			/* Ignore this setting */
+			continue;
+
+		data = purple_xmlnode_get_data(child);
+		if (data == NULL)
+			/* Ignore this setting */
+			continue;
+
+		if (ui == NULL)
+		{
+			if (type == PURPLE_PREF_STRING)
+				purple_account_set_string(account, name, data);
+			else if (type == PURPLE_PREF_INT)
+				purple_account_set_int(account, name, atoi(data));
+			else if (type == PURPLE_PREF_BOOLEAN)
+				purple_account_set_bool(account, name,
+									  (*data == '0' ? FALSE : TRUE));
+		} else {
+			if (type == PURPLE_PREF_STRING)
+				purple_account_set_ui_string(account, ui, name, data);
+			else if (type == PURPLE_PREF_INT)
+				purple_account_set_ui_int(account, ui, name, atoi(data));
+			else if (type == PURPLE_PREF_BOOLEAN)
+				purple_account_set_ui_bool(account, ui, name,
+										 (*data == '0' ? FALSE : TRUE));
+		}
+
+		g_free(data);
+	}
+
+	/* we do this here because we need access to account settings to determine
+	 * if we can/should migrate an old Yahoo! JAPAN account */
+	migrate_yahoo_japan(account);
+	/* we do this here because we need access to account settings to determine
+	 * if we can/should migrate an ICQ account's server setting */
+	migrate_icq_server(account);
+	/* we do this here because we need to do it before the user views the
+	 * Edit Account dialog. */
+	migrate_xmpp_encryption(account);
+}
+
+static GList *
+parse_status_attrs(PurpleXmlNode *node, PurpleStatus *status)
+{
+	GList *list = NULL;
+	PurpleXmlNode *child;
+	GValue *attr_value;
+
+	for (child = purple_xmlnode_get_child(node, "attribute"); child != NULL;
+			child = purple_xmlnode_get_next_twin(child))
+	{
+		const char *id = purple_xmlnode_get_attrib(child, "id");
+		const char *value = purple_xmlnode_get_attrib(child, "value");
+
+		if (!id || !*id || !value || !*value)
+			continue;
+
+		attr_value = purple_status_get_attr_value(status, id);
+		if (!attr_value)
+			continue;
+
+		list = g_list_append(list, (char *)id);
+
+		switch (G_VALUE_TYPE(attr_value))
+		{
+			case G_TYPE_STRING:
+				list = g_list_append(list, (char *)value);
+				break;
+			case G_TYPE_INT:
+			case G_TYPE_BOOLEAN:
+			{
+				int v;
+				if (sscanf(value, "%d", &v) == 1)
+					list = g_list_append(list, GINT_TO_POINTER(v));
+				else
+					list = g_list_remove(list, id);
+				break;
+			}
+			default:
+				break;
+		}
+	}
+
+	return list;
+}
+
+static void
+parse_status(PurpleXmlNode *node, PurpleAccount *account)
+{
+	gboolean active = FALSE;
+	const char *data;
+	const char *type;
+	PurpleXmlNode *child;
+	GList *attrs = NULL;
+
+	/* Get the active/inactive state */
+	data = purple_xmlnode_get_attrib(node, "active");
+	if (data == NULL)
+		return;
+	if (g_ascii_strcasecmp(data, "true") == 0)
+		active = TRUE;
+	else if (g_ascii_strcasecmp(data, "false") == 0)
+		active = FALSE;
+	else
+		return;
+
+	/* Get the type of the status */
+	type = purple_xmlnode_get_attrib(node, "type");
+	if (type == NULL)
+		return;
+
+	/* Read attributes into a GList */
+	child = purple_xmlnode_get_child(node, "attributes");
+	if (child != NULL)
+	{
+		attrs = parse_status_attrs(child,
+						purple_account_get_status(account, type));
+	}
+
+	purple_account_set_status_list(account, type, active, attrs);
+
+	g_list_free(attrs);
+}
+
+static void
+parse_statuses(PurpleXmlNode *node, PurpleAccount *account)
+{
+	PurpleXmlNode *child;
+
+	for (child = purple_xmlnode_get_child(node, "status"); child != NULL;
+			child = purple_xmlnode_get_next_twin(child))
+	{
+		parse_status(child, account);
+	}
+}
+
+static void
+parse_proxy_info(PurpleXmlNode *node, PurpleAccount *account)
+{
+	PurpleProxyInfo *proxy_info;
+	PurpleXmlNode *child;
+	char *data;
+
+	proxy_info = purple_proxy_info_new();
+
+	/* Use the global proxy settings, by default */
+	purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
+
+	/* Read proxy type */
+	child = purple_xmlnode_get_child(node, "type");
+	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
+	{
+		if (purple_strequal(data, "global"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
+		else if (purple_strequal(data, "none"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_NONE);
+		else if (purple_strequal(data, "http"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_HTTP);
+		else if (purple_strequal(data, "socks4"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS4);
+		else if (purple_strequal(data, "socks5"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS5);
+		else if (purple_strequal(data, "tor"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_TOR);
+		else if (purple_strequal(data, "envvar"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_ENVVAR);
+		else
+		{
+			purple_debug_error("account", "Invalid proxy type found when "
+							 "loading account information for %s\n",
+							 purple_account_get_username(account));
+		}
+		g_free(data);
+	}
+
+	/* Read proxy host */
+	child = purple_xmlnode_get_child(node, "host");
+	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
+	{
+		purple_proxy_info_set_host(proxy_info, data);
+		g_free(data);
+	}
+
+	/* Read proxy port */
+	child = purple_xmlnode_get_child(node, "port");
+	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
+	{
+		purple_proxy_info_set_port(proxy_info, atoi(data));
+		g_free(data);
+	}
+
+	/* Read proxy username */
+	child = purple_xmlnode_get_child(node, "username");
+	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
+	{
+		purple_proxy_info_set_username(proxy_info, data);
+		g_free(data);
+	}
+
+	/* Read proxy password */
+	child = purple_xmlnode_get_child(node, "password");
+	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
+	{
+		purple_proxy_info_set_password(proxy_info, data);
+		g_free(data);
+	}
+
+	/* If there are no values set then proxy_info NULL */
+	if ((purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) &&
+		(purple_proxy_info_get_host(proxy_info) == NULL) &&
+		(purple_proxy_info_get_port(proxy_info) == 0) &&
+		(purple_proxy_info_get_username(proxy_info) == NULL) &&
+		(purple_proxy_info_get_password(proxy_info) == NULL))
+	{
+		purple_proxy_info_destroy(proxy_info);
+		return;
+	}
+
+	purple_account_set_proxy_info(account, proxy_info);
+}
+
+static void
+parse_current_error(PurpleXmlNode *node, PurpleAccount *account)
+{
+	guint type;
+	char *type_str = NULL, *description = NULL;
+	PurpleXmlNode *child;
+	PurpleConnectionErrorInfo *current_error = NULL;
+
+	child = purple_xmlnode_get_child(node, "type");
+	if (child == NULL || (type_str = purple_xmlnode_get_data(child)) == NULL)
+		return;
+	type = atoi(type_str);
+	g_free(type_str);
+
+	if (type > PURPLE_CONNECTION_ERROR_OTHER_ERROR)
+	{
+		purple_debug_error("account",
+			"Invalid PurpleConnectionError value %d found when "
+			"loading account information for %s\n",
+			type, purple_account_get_username(account));
+		type = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
+	}
+
+	child = purple_xmlnode_get_child(node, "description");
+	if (child)
+		description = purple_xmlnode_get_data(child);
+	if (description == NULL)
+		description = g_strdup("");
+
+	current_error = g_new0(PurpleConnectionErrorInfo, 1);
+	PURPLE_DBUS_REGISTER_POINTER(current_error, PurpleConnectionErrorInfo);
+	current_error->type = type;
+	current_error->description = description;
+
+	_purple_account_set_current_error(account, current_error);
+}
+
+static PurpleAccount *
+parse_account(PurpleXmlNode *node)
+{
+	PurpleAccount *ret;
+	PurpleXmlNode *child;
+	char *protocol_id = NULL;
+	char *name = NULL;
+	char *data;
+
+	child = purple_xmlnode_get_child(node, "protocol");
+	if (child != NULL)
+		protocol_id = purple_xmlnode_get_data(child);
+
+	child = purple_xmlnode_get_child(node, "name");
+	if (child != NULL)
+		name = purple_xmlnode_get_data(child);
+	if (name == NULL)
+	{
+		/* Do we really need to do this? */
+		child = purple_xmlnode_get_child(node, "username");
+		if (child != NULL)
+			name = purple_xmlnode_get_data(child);
+	}
+
+	if ((protocol_id == NULL) || (name == NULL))
+	{
+		g_free(protocol_id);
+		g_free(name);
+		return NULL;
+	}
+
+	ret = purple_account_new(name, protocol_id);
+	g_free(name);
+	g_free(protocol_id);
+
+	/* Read the alias */
+	child = purple_xmlnode_get_child(node, "alias");
+	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
+	{
+		if (*data != '\0')
+			purple_account_set_private_alias(ret, data);
+		g_free(data);
+	}
+
+	/* Read the statuses */
+	child = purple_xmlnode_get_child(node, "statuses");
+	if (child != NULL)
+	{
+		parse_statuses(child, ret);
+	}
+
+	/* Read the userinfo */
+	child = purple_xmlnode_get_child(node, "userinfo");
+	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
+	{
+		purple_account_set_user_info(ret, data);
+		g_free(data);
+	}
+
+	/* Read an old buddyicon */
+	child = purple_xmlnode_get_child(node, "buddyicon");
+	if ((child != NULL) && ((data = purple_xmlnode_get_data(child)) != NULL))
+	{
+		const char *dirname = purple_buddy_icons_get_cache_dir();
+		char *filename = g_build_filename(dirname, data, NULL);
+		gchar *contents;
+		gsize len;
+
+		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);
+	}
+
+	/* Read settings (both core and UI) */
+	for (child = purple_xmlnode_get_child(node, "settings"); child != NULL;
+			child = purple_xmlnode_get_next_twin(child))
+	{
+		parse_settings(child, ret);
+	}
+
+	/* Read proxy */
+	child = purple_xmlnode_get_child(node, "proxy");
+	if (child != NULL)
+	{
+		parse_proxy_info(child, ret);
+	}
+
+	/* Read current error */
+	child = purple_xmlnode_get_child(node, "current_error");
+	if (child != NULL)
+	{
+		parse_current_error(child, ret);
+	}
+
+	/* Read the password */
+	child = purple_xmlnode_get_child(node, "password");
+	if (child != NULL)
+	{
+		const char *keyring_id = purple_xmlnode_get_attrib(child, "keyring_id");
+		const char *mode = purple_xmlnode_get_attrib(child, "mode");
+		gboolean result;
+
+		data = purple_xmlnode_get_data(child);
+		result = purple_keyring_import_password(ret, keyring_id, mode, data, NULL);
+
+		if (result == TRUE || purple_keyring_get_inuse() == NULL) {
+			purple_account_set_remember_password(ret, TRUE);
+		} else {
+			purple_debug_error("account", "Failed to import password.\n");
+		} 
+		purple_str_wipe(data);
+	}
+
+	return ret;
+}
+
+static void
+load_accounts(void)
+{
+	PurpleXmlNode *node, *child;
+
+	accounts_loaded = TRUE;
+
+	node = purple_util_read_xml_from_file("accounts.xml", _("accounts"));
+
+	if (node == NULL)
+		return;
+
+	for (child = purple_xmlnode_get_child(node, "account"); child != NULL;
+			child = purple_xmlnode_get_next_twin(child))
+	{
+		PurpleAccount *new_acct;
+		new_acct = parse_account(child);
+		purple_accounts_add(new_acct);
+	}
+
+	purple_xmlnode_free(node);
+
+	_purple_buddy_icons_account_loaded_cb();
+}
+
+void
+purple_accounts_add(PurpleAccount *account)
+{
+	g_return_if_fail(account != NULL);
+
+	if (g_list_find(accounts, account) != NULL)
+		return;
+
+	accounts = g_list_append(accounts, account);
+
+	purple_accounts_schedule_save();
+
+	purple_signal_emit(purple_accounts_get_handle(), "account-added", account);
+}
+
+void
+purple_accounts_remove(PurpleAccount *account)
+{
+	g_return_if_fail(account != NULL);
+
+	accounts = g_list_remove(accounts, account);
+
+	purple_accounts_schedule_save();
+
+	/* Clearing the error ensures that account-error-changed is emitted,
+	 * which is the end of the guarantee that the the error's pointer is
+	 * valid.
+	 */
+	purple_account_clear_current_error(account);
+	purple_signal_emit(purple_accounts_get_handle(), "account-removed", account);
+}
+
+static void
+purple_accounts_delete_set(PurpleAccount *account, GError *error, gpointer data)
+{
+	g_object_unref(G_OBJECT(account));
+}
+
+void
+purple_accounts_delete(PurpleAccount *account)
+{
+	PurpleBlistNode *gnode, *cnode, *bnode;
+	GList *iter;
+
+	g_return_if_fail(account != NULL);
+
+	/*
+	 * Disable the account before blowing it out of the water.
+	 * Conceptually it probably makes more sense to disable the
+	 * account for all UIs rather than the just the current UI,
+	 * but it doesn't really matter.
+	 */
+	purple_account_set_enabled(account, purple_core_get_ui(), FALSE);
+
+	purple_notify_close_with_handle(account);
+	purple_request_close_with_handle(account);
+
+	purple_accounts_remove(account);
+
+	/* Remove this account's buddies */
+	for (gnode = purple_blist_get_root();
+	     gnode != NULL;
+		 gnode = purple_blist_node_get_sibling_next(gnode))
+	{
+		if (!PURPLE_IS_GROUP(gnode))
+			continue;
+
+		cnode = purple_blist_node_get_first_child(gnode);
+		while (cnode) {
+			PurpleBlistNode *cnode_next = purple_blist_node_get_sibling_next(cnode);
+
+			if(PURPLE_IS_CONTACT(cnode)) {
+				bnode = purple_blist_node_get_first_child(cnode);
+				while (bnode) {
+					PurpleBlistNode *bnode_next = purple_blist_node_get_sibling_next(bnode);
+
+					if (PURPLE_IS_BUDDY(bnode)) {
+						PurpleBuddy *b = (PurpleBuddy *)bnode;
+
+						if (purple_buddy_get_account(b) == account)
+							purple_blist_remove_buddy(b);
+					}
+					bnode = bnode_next;
+				}
+			} else if (PURPLE_IS_CHAT(cnode)) {
+				PurpleChat *c = (PurpleChat *)cnode;
+
+				if (purple_chat_get_account(c) == account)
+					purple_blist_remove_chat(c);
+			}
+			cnode = cnode_next;
+		}
+	}
+
+	/* Remove any open conversation for this account */
+	for (iter = purple_conversations_get_all(); iter; ) {
+		PurpleConversation *conv = iter->data;
+		iter = iter->next;
+		if (purple_conversation_get_account(conv) == account)
+			g_object_unref(conv);
+	}
+
+	/* Remove this account's pounces */
+	purple_pounce_destroy_all_by_account(account);
+
+	/* This will cause the deletion of an old buddy icon. */
+	purple_buddy_icons_set_account_icon(account, NULL, 0);
+
+	/* This is async because we do not want the
+	 * account being overwritten before we are done.
+	 */
+	purple_keyring_set_password(account, NULL,
+		purple_accounts_delete_set, NULL);
+}
+
+void
+purple_accounts_reorder(PurpleAccount *account, guint new_index)
+{
+	gint index;
+	GList *l;
+
+	g_return_if_fail(account != NULL);
+	g_return_if_fail(new_index <= g_list_length(accounts));
+
+	index = g_list_index(accounts, account);
+
+	if (index < 0) {
+		purple_debug_error("account",
+				   "Unregistered account (%s) discovered during reorder!\n",
+				   purple_account_get_username(account));
+		return;
+	}
+
+	l = g_list_nth(accounts, index);
+
+	if (new_index > (guint)index)
+		new_index--;
+
+	/* Remove the old one. */
+	accounts = g_list_delete_link(accounts, l);
+
+	/* Insert it where it should go. */
+	accounts = g_list_insert(accounts, account, new_index);
+
+	purple_accounts_schedule_save();
+}
+
+GList *
+purple_accounts_get_all(void)
+{
+	return accounts;
+}
+
+GList *
+purple_accounts_get_all_active(void)
+{
+	GList *list = NULL;
+	GList *all = purple_accounts_get_all();
+
+	while (all != NULL) {
+		PurpleAccount *account = all->data;
+
+		if (purple_account_get_enabled(account, purple_core_get_ui()))
+			list = g_list_append(list, account);
+
+		all = all->next;
+	}
+
+	return list;
+}
+
+PurpleAccount *
+purple_accounts_find(const char *name, const char *protocol_id)
+{
+	PurpleAccount *account = NULL;
+	GList *l;
+	char *who;
+
+	g_return_val_if_fail(name != NULL, NULL);
+	g_return_val_if_fail(protocol_id != NULL, NULL);
+
+	for (l = purple_accounts_get_all(); l != NULL; l = l->next) {
+		account = (PurpleAccount *)l->data;
+
+		if (!purple_strequal(purple_account_get_protocol_id(account), protocol_id))
+			continue;
+
+		who = g_strdup(purple_normalize(account, name));
+		if (purple_strequal(purple_normalize(account, purple_account_get_username(account)), who)) {
+			g_free(who);
+			return account;
+		}
+		g_free(who);
+	}
+
+	return NULL;
+}
+
+void
+purple_accounts_restore_current_statuses()
+{
+	GList *l;
+	PurpleAccount *account;
+
+	/* If we're not connected to the Internet right now, we bail on this */
+	if (!purple_network_is_available())
+	{
+		purple_debug_warning("account", "Network not connected; skipping reconnect\n");
+		return;
+	}
+
+	for (l = purple_accounts_get_all(); l != NULL; l = l->next)
+	{
+		account = (PurpleAccount *)l->data;
+
+		if (purple_account_get_enabled(account, purple_core_get_ui()) &&
+			(purple_presence_is_online(purple_account_get_presence(account))))
+		{
+			purple_account_connect(account);
+		}
+	}
+}
+
+void
+purple_accounts_set_ui_ops(PurpleAccountUiOps *ops)
+{
+	account_ui_ops = ops;
+}
+
+PurpleAccountUiOps *
+purple_accounts_get_ui_ops(void)
+{
+	return account_ui_ops;
+}
+
+void *
+purple_accounts_get_handle(void)
+{
+	static int handle;
+
+	return &handle;
+}
+
+static void
+signed_on_cb(PurpleConnection *gc,
+             gpointer unused)
+{
+	PurpleAccount *account = purple_connection_get_account(gc);
+	purple_account_clear_current_error(account);
+
+	purple_signal_emit(purple_accounts_get_handle(), "account-signed-on",
+	                   account);
+}
+
+static void
+signed_off_cb(PurpleConnection *gc,
+              gpointer unused)
+{
+	PurpleAccount *account = purple_connection_get_account(gc);
+
+	purple_signal_emit(purple_accounts_get_handle(), "account-signed-off",
+	                   account);
+}
+
+static void
+connection_error_cb(PurpleConnection *gc,
+                    PurpleConnectionError type,
+                    const gchar *description,
+                    gpointer unused)
+{
+	PurpleAccount *account;
+	PurpleConnectionErrorInfo *err;
+
+	account = purple_connection_get_account(gc);
+
+	g_return_if_fail(account != NULL);
+
+	err = g_new0(PurpleConnectionErrorInfo, 1);
+	PURPLE_DBUS_REGISTER_POINTER(err, PurpleConnectionErrorInfo);
+
+	err->type = type;
+	err->description = g_strdup(description);
+
+	_purple_account_set_current_error(account, err);
+
+	purple_signal_emit(purple_accounts_get_handle(), "account-connection-error",
+	                   account, type, description);
+}
+
+static void
+password_migration_cb(PurpleAccount *account)
+{
+	/* account may be NULL (means: all) */
+
+	purple_accounts_schedule_save();
+}
+
+void
+purple_accounts_init(void)
+{
+	void *handle = purple_accounts_get_handle();
+	void *conn_handle = purple_connections_get_handle();
+
+	purple_signal_register(handle, "account-connecting",
+						 purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+						 PURPLE_TYPE_ACCOUNT);
+
+	purple_signal_register(handle, "account-disabled",
+						 purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+						 PURPLE_TYPE_ACCOUNT);
+
+	purple_signal_register(handle, "account-enabled",
+						 purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+						 PURPLE_TYPE_ACCOUNT);
+
+	purple_signal_register(handle, "account-setting-info",
+						 purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+						 PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
+
+	purple_signal_register(handle, "account-set-info",
+						 purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+						 PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
+
+	purple_signal_register(handle, "account-created",
+						 purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+						 PURPLE_TYPE_ACCOUNT);
+
+	purple_signal_register(handle, "account-destroying",
+						 purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+						 PURPLE_TYPE_ACCOUNT);
+
+	purple_signal_register(handle, "account-added",
+						 purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+						 PURPLE_TYPE_ACCOUNT);
+
+	purple_signal_register(handle, "account-removed",
+						 purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+						 PURPLE_TYPE_ACCOUNT);
+
+	purple_signal_register(handle, "account-status-changed",
+						 purple_marshal_VOID__POINTER_POINTER_POINTER,
+						 G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT,
+						 PURPLE_TYPE_STATUS, PURPLE_TYPE_STATUS);
+
+	purple_signal_register(handle, "account-actions-changed",
+						 purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+						 PURPLE_TYPE_ACCOUNT);
+
+	purple_signal_register(handle, "account-alias-changed",
+						 purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+						 PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
+
+	purple_signal_register(handle, "account-authorization-requested",
+						purple_marshal_INT__POINTER_POINTER_POINTER,
+						G_TYPE_INT, 4, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+						G_TYPE_STRING, G_TYPE_STRING);
+
+	purple_signal_register(handle, "account-authorization-denied",
+						purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 3,
+						PURPLE_TYPE_ACCOUNT, G_TYPE_STRING, G_TYPE_STRING);
+
+	purple_signal_register(handle, "account-authorization-granted",
+						purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 3,
+						PURPLE_TYPE_ACCOUNT, G_TYPE_STRING, G_TYPE_STRING);
+
+	purple_signal_register(handle, "account-error-changed",
+	                       purple_marshal_VOID__POINTER_POINTER_POINTER,
+	                       G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT,
+	                       PURPLE_TYPE_CONNECTION_ERROR_INFO,
+	                       PURPLE_TYPE_CONNECTION_ERROR_INFO);
+
+	purple_signal_register(handle, "account-signed-on",
+	                       purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+	                       PURPLE_TYPE_ACCOUNT);
+
+	purple_signal_register(handle, "account-signed-off",
+	                       purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+	                       PURPLE_TYPE_ACCOUNT);
+
+	purple_signal_register(handle, "account-connection-error",
+	                       purple_marshal_VOID__POINTER_INT_POINTER,
+	                       G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT,
+	                       PURPLE_TYPE_CONNECTION_ERROR, G_TYPE_STRING);
+
+	purple_signal_connect(conn_handle, "signed-on", handle,
+	                      PURPLE_CALLBACK(signed_on_cb), NULL);
+	purple_signal_connect(conn_handle, "signed-off", handle,
+	                      PURPLE_CALLBACK(signed_off_cb), NULL);
+	purple_signal_connect(conn_handle, "connection-error", handle,
+	                      PURPLE_CALLBACK(connection_error_cb), NULL);
+	purple_signal_connect(purple_keyring_get_handle(), "password-migration", handle,
+	                      PURPLE_CALLBACK(password_migration_cb), NULL);
+
+	load_accounts();
+
+}
+
+void
+purple_accounts_uninit(void)
+{
+	gpointer handle = purple_accounts_get_handle();
+	if (save_timer != 0)
+	{
+		purple_timeout_remove(save_timer);
+		save_timer = 0;
+		sync_accounts();
+	}
+
+	for (; accounts; accounts = g_list_delete_link(accounts, accounts))
+		g_object_unref(G_OBJECT(accounts->data));
+
+	purple_signals_disconnect_by_handle(handle);
+	purple_signals_unregister_by_instance(handle);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/accounts.h	Fri Oct 11 01:26:38 2013 +0530
@@ -0,0 +1,225 @@
+/**
+ * @file accounts.h Accounts API
+ * @ingroup core
+ * @see @ref account-signals
+ */
+
+/* purple
+ *
+ * Purple 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 _PURPLE_ACCOUNTS_H_
+#define _PURPLE_ACCOUNTS_H_
+
+#include "account.h"
+#include "status.h"
+
+/** @copydoc _PurpleAccountUiOps */
+typedef struct _PurpleAccountUiOps  PurpleAccountUiOps;
+
+/**  Account UI operations, used to notify the user of status changes and when
+ *   buddies add this account to their buddy lists.
+ */
+struct _PurpleAccountUiOps
+{
+	/** A buddy who is already on this account's buddy list added this account
+	 *  to their buddy list.
+	 */
+	void (*notify_added)(PurpleAccount *account,
+	                     const char *remote_user,
+	                     const char *id,
+	                     const char *alias,
+	                     const char *message);
+
+	/** This account's status changed. */
+	void (*status_changed)(PurpleAccount *account,
+	                       PurpleStatus *status);
+
+	/** Someone we don't have on our list added us; prompt to add them. */
+	void (*request_add)(PurpleAccount *account,
+	                    const char *remote_user,
+	                    const char *id,
+	                    const char *alias,
+	                    const char *message);
+
+	/** Prompt for authorization when someone adds this account to their buddy
+	 * list.  To authorize them to see this account's presence, call \a
+	 * authorize_cb (\a message, \a user_data); otherwise call
+	 * \a deny_cb (\a message, \a user_data);
+	 * @return a UI-specific handle, as passed to #close_account_request.
+	 */
+	void *(*request_authorize)(PurpleAccount *account,
+	                           const char *remote_user,
+	                           const char *id,
+	                           const char *alias,
+	                           const char *message,
+	                           gboolean on_list,
+	                           PurpleAccountRequestAuthorizationCb authorize_cb,
+	                           PurpleAccountRequestAuthorizationCb deny_cb,
+	                           void *user_data);
+
+	/** Close a pending request for authorization.  \a ui_handle is a handle
+	 *  as returned by #request_authorize.
+	 */
+	void (*close_account_request)(void *ui_handle);
+
+	void (*permit_added)(PurpleAccount *account, const char *name);
+	void (*permit_removed)(PurpleAccount *account, const char *name);
+	void (*deny_added)(PurpleAccount *account, const char *name);
+	void (*deny_removed)(PurpleAccount *account, const char *name);
+
+	void (*_purple_reserved1)(void);
+	void (*_purple_reserved2)(void);
+	void (*_purple_reserved3)(void);
+	void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+/**************************************************************************/
+/** @name Accounts API                                                    */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Adds an account to the list of accounts.
+ *
+ * @param account The account.
+ */
+void purple_accounts_add(PurpleAccount *account);
+
+/**
+ * Removes an account from the list of accounts.
+ *
+ * @param account The account.
+ */
+void purple_accounts_remove(PurpleAccount *account);
+
+/**
+ * Deletes an account.
+ *
+ * This will remove any buddies from the buddy list that belong to this
+ * account, buddy pounces that belong to this account, and will also
+ * destroy @a account.
+ *
+ * @param account The account.
+ */
+void purple_accounts_delete(PurpleAccount *account);
+
+/**
+ * Reorders an account.
+ *
+ * @param account   The account to reorder.
+ * @param new_index The new index for the account.
+ */
+void purple_accounts_reorder(PurpleAccount *account, guint new_index);
+
+/**
+ * Returns a list of all accounts.
+ *
+ * @constreturn A list of all accounts.
+ */
+GList *purple_accounts_get_all(void);
+
+/**
+ * Returns a list of all enabled accounts
+ *
+ * @return A list of all enabled accounts. The list is owned
+ *         by the caller, and must be g_list_free()d to avoid
+ *         leaking the nodes.
+ */
+GList *purple_accounts_get_all_active(void);
+
+/**
+ * Finds an account with the specified name and protocol id.
+ *
+ * @param name     The account username.
+ * @param protocol The account protocol ID.
+ *
+ * @return The account, if found, or @c FALSE otherwise.
+ */
+PurpleAccount *purple_accounts_find(const char *name, const char *protocol);
+
+/**
+ * This is called by the core after all subsystems and what
+ * not have been initialized.  It sets all enabled accounts
+ * to their startup status by signing them on, setting them
+ * away, etc.
+ *
+ * You probably shouldn't call this unless you really know
+ * what you're doing.
+ */
+void purple_accounts_restore_current_statuses(void);
+
+/*@}*/
+
+
+/**************************************************************************/
+/** @name UI Registration Functions                                       */
+/**************************************************************************/
+/*@{*/
+/**
+ * Sets the UI operations structure to be used for accounts.
+ *
+ * @param ops The UI operations structure.
+ */
+void purple_accounts_set_ui_ops(PurpleAccountUiOps *ops);
+
+/**
+ * Returns the UI operations structure used for accounts.
+ *
+ * @return The UI operations structure in use.
+ */
+PurpleAccountUiOps *purple_accounts_get_ui_ops(void);
+
+/*@}*/
+
+
+/**************************************************************************/
+/** @name Accounts Subsystem                                              */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the accounts subsystem handle.
+ *
+ * @return The accounts subsystem handle.
+ */
+void *purple_accounts_get_handle(void);
+
+/**
+ * Initializes the accounts subsystem.
+ */
+void purple_accounts_init(void);
+
+/**
+ * Uninitializes the accounts subsystem.
+ */
+void purple_accounts_uninit(void);
+
+/**
+ * Schedules saving of accounts
+ */
+void purple_accounts_schedule_save(void);
+
+/*@}*/
+
+G_END_DECLS
+
+#endif /* _PURPLE_ACCOUNTS_H_ */
--- a/libpurple/connection.c	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/connection.c	Fri Oct 11 01:26:38 2013 +0530
@@ -908,9 +908,7 @@
 	{
 		purple_debug_info("connection", "Connecting. gc = %p\n", gc);
 
-		g_signal_emit_by_name(purple_account_manager_get_instance(),
-				"account-connecting", account);
-
+		purple_signal_emit(purple_accounts_get_handle(), "account-connecting", account);
 		purple_protocol_class_login(protocol, account);
 	}
 }
--- a/libpurple/dbus-useful.c	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/dbus-useful.c	Fri Oct 11 01:26:38 2013 +0530
@@ -2,7 +2,7 @@
 #include <glib.h>
 
 #include "dbus-useful.h"
-#include "account-manager.h"
+#include "accounts.h"
 #include "conversation.h"
 #include "util.h"
 
--- a/libpurple/internal.h	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/internal.h	Fri Oct 11 01:26:38 2013 +0530
@@ -154,7 +154,7 @@
 
 /* INTERNAL FUNCTIONS */
 
-#include "account-manager.h"
+#include "accounts.h"
 #include "connection.h"
 
 /* This is for the accounts code to notify the buddy icon code that
--- a/libpurple/plugins/perl/common/module.h	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/plugins/perl/common/module.h	Fri Oct 11 01:26:38 2013 +0530
@@ -19,7 +19,7 @@
 
 #include "../perl-common.h"
 
-#include "account-manager.h"
+#include "accounts.h"
 #include "accountopt.h"
 #include "buddylist.h"
 #include "buddyicon.h"
--- a/libpurple/protocols.c	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/protocols.c	Fri Oct 11 01:26:38 2013 +0530
@@ -264,8 +264,8 @@
 	g_return_if_fail(account != NULL);
 	g_return_if_fail(purple_account_is_connected(account));
 
-	g_signal_emit_by_name(purple_account_manager_get_instance(),
-	                      "account-actions-changed", account);
+	purple_signal_emit(purple_accounts_get_handle(), "account-actions-changed",
+	                   account);
 }
 
 void
@@ -456,8 +456,8 @@
 
 	do_protocol_change_account_status(account, old_status, new_status);
 
-	g_signal_emit_by_name(purple_account_manager_get_instance(),
-					"account-status-changed", account, old_status, new_status);
+	purple_signal_emit(purple_accounts_get_handle(), "account-status-changed",
+					account, old_status, new_status);
 }
 
 GList *
--- a/libpurple/purple.h.in	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/purple.h.in	Fri Oct 11 01:26:38 2013 +0530
@@ -44,7 +44,7 @@
 
 @PLUGINS_DEFINE@
 
-#include <account-manager.h>
+#include <accounts.h>
 #include <accountopt.h>
 #include <buddylist.h>
 #include <buddyicon.h>
--- a/libpurple/server.c	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/server.c	Fri Oct 11 01:26:38 2013 +0530
@@ -178,12 +178,13 @@
 		if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER_IFACE, set_info)) {
 			account = purple_connection_get_account(gc);
 
-			g_signal_emit_by_name(purple_account_manager_get_instance(),
-					"account-setting-info", account, info);
+			if (purple_signal_emit_return_1(purple_accounts_get_handle(),
+					"account-setting-info", account, info))
+				return;
 
 			purple_protocol_server_iface_set_info(protocol, gc, info);
 
-			g_signal_emit_by_name(purple_account_manager_get_instance(),
+			purple_signal_emit(purple_accounts_get_handle(),
 					"account-set-info", account, info);
 		}
 	}
--- a/libpurple/server.h	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/server.h	Fri Oct 11 01:26:38 2013 +0530
@@ -26,7 +26,7 @@
 #ifndef _PURPLE_SERVER_H_
 #define _PURPLE_SERVER_H_
 
-#include "account-manager.h"
+#include "accounts.h"
 #include "conversations.h"
 #include "protocols.h"
 
--- a/libpurple/status.c	Thu Oct 10 23:53:58 2013 +0530
+++ b/libpurple/status.c	Fri Oct 11 01:26:38 2013 +0530
@@ -671,7 +671,7 @@
 /*
  * This used to parse the va_list directly, but now it creates a GList
  * and passes it to purple_status_set_active_with_attrs_list().  That
- * function was created because account.c needs to pass a GList of
+ * function was created because accounts.c needs to pass a GList of
  * attributes to the status API.
  */
 void
--- a/pidgin/gtkaccount.h	Thu Oct 10 23:53:58 2013 +0530
+++ b/pidgin/gtkaccount.h	Fri Oct 11 01:26:38 2013 +0530
@@ -27,7 +27,7 @@
 #ifndef _PIDGINACCOUNT_H_
 #define _PIDGINACCOUNT_H_
 
-#include "account-manager.h"
+#include "accounts.h"
 
 typedef enum
 {

mercurial