# HG changeset patch
# Node ID b6402d0d7a9f
# Parent  413cde086275
diff --git a/finch/gntaccount.c b/finch/gntaccount.c
--- a/finch/gntaccount.c
+++ b/finch/gntaccount.c
@@ -736,9 +736,9 @@ account_list_key_pressed_cb(GntWidget *w
 {
 	GntTree *tree = GNT_TREE(widget);
 	PurpleAccountManager *manager = NULL;
+	GListModel *manager_model = NULL;
 	PurpleAccount *account = gnt_tree_get_selection_data(tree);
 	int move, pos, count;
-	GList *accounts;
 
 	if (!account)
 		return FALSE;
@@ -755,20 +755,28 @@ account_list_key_pressed_cb(GntWidget *w
 	}
 
 	manager = purple_account_manager_get_default();
-	accounts = purple_account_manager_get_all(manager);
-	count = g_list_length(accounts);
-	pos = g_list_index(accounts, account);
-	pos = (move + pos + count + 1) % (count + 1);
-	if(pos >= 0) {
-		purple_account_manager_reorder(manager, account, pos);
+	manager_model = G_LIST_MODEL(manager);
+
+	count = g_list_model_get_n_items(manager_model);
+	for(pos = 0; pos < count; pos++) {
+		PurpleAccount *acct = g_list_model_get_item(manager_model, pos);
+		if(account == acct) {
+			pos = (move + pos + count + 1) % (count + 1);
+			purple_account_manager_reorder(manager, account, pos);
+			g_object_unref(acct);
+			break;
+		}
+		g_object_unref(acct);
 	}
 
 	/* I don't like this, but recreating the entire list seems to be
 	 * the easiest way of doing it */
 	gnt_tree_remove_all(tree);
-	accounts = purple_account_manager_get_all(manager);
-	for (; accounts; accounts = accounts->next)
-		account_add(accounts->data);
+	for(pos = 0; pos < count; pos++) {
+		PurpleAccount *account = g_list_model_get_item(manager_model, pos);
+		account_add(account);
+		g_object_unref(account);
+	}
 	gnt_tree_set_selected(tree, account);
 
 	return TRUE;
@@ -784,8 +792,8 @@ reset_accounts_win(GntWidget *widget, gp
 void
 finch_accounts_show_all(void)
 {
-	PurpleAccountManager *manager = NULL;
-	GList *iter;
+	GListModel *manager_model = NULL;
+	guint n_items = 0;
 	GntWidget *box, *button;
 
 	if (accounts.window) {
@@ -808,12 +816,12 @@ finch_accounts_show_all(void)
 	accounts.tree = gnt_tree_new_with_columns(2);
 	gnt_widget_set_has_border(accounts.tree, FALSE);
 
-	manager = purple_account_manager_get_default();
-	iter = purple_account_manager_get_all(manager);
-
-	for(; iter; iter = iter->next) {
-		PurpleAccount *account = iter->data;
+	manager_model = purple_account_manager_get_default_as_model();
+	n_items = g_list_model_get_n_items(manager_model);
+	for(guint index = 0; index < n_items; index++) {
+		PurpleAccount *account = g_list_model_get_item(manager_model, index);
 		account_add(account);
+		g_object_unref(account);
 	}
 
 	g_signal_connect(G_OBJECT(accounts.tree), "toggled", G_CALLBACK(account_toggled), NULL);
@@ -894,10 +902,12 @@ void
 finch_accounts_init(void)
 {
 	PurpleAccountManager *manager = NULL;
+	GListModel *manager_model = NULL;
 	gpointer account_handle = NULL;
-	GList *iter;
+	guint n_items = 0;
 
 	manager = purple_account_manager_get_default();
+	manager_model = G_LIST_MODEL(manager);
 	account_handle = purple_accounts_get_handle();
 
 	g_signal_connect(manager, "added", G_CALLBACK(account_added_callback),
@@ -911,14 +921,26 @@ finch_accounts_init(void)
 			finch_accounts_get_handle(),
 			G_CALLBACK(account_abled_cb), GINT_TO_POINTER(TRUE));
 
-	iter = purple_account_manager_get_all(manager);
-	if (iter) {
-		for (; iter; iter = iter->next) {
-			if (purple_account_get_enabled(iter->data))
+	n_items = g_list_model_get_n_items(manager_model);
+	if(n_items != 0) {
+		gboolean has_enabled_account = FALSE;
+
+		for(guint index = 0; index < n_items; index++) {
+			PurpleAccount *account = NULL;
+			account = g_list_model_get_item(manager_model, index);
+
+			if(purple_account_get_enabled(account)) {
+				has_enabled_account = TRUE;
+				g_object_unref(account);
 				break;
+			}
+
+			g_object_unref(account);
 		}
-		if (!iter)
+
+		if(!has_enabled_account) {
 			finch_accounts_show_all();
+		}
 	} else {
 		edit_account(NULL);
 		finch_accounts_show_all();
diff --git a/finch/gntrequest.c b/finch/gntrequest.c
--- a/finch/gntrequest.c
+++ b/finch/gntrequest.c
@@ -514,12 +514,22 @@ create_list_field(PurpleRequestField *fi
 	return ret;
 }
 
+static void
+add_account_to_combo(GntWidget *combo, PurpleAccount *account) {
+	char *text = NULL;
+
+	text = g_strdup_printf("%s (%s)",
+	                       purple_account_get_username(account),
+	                       purple_account_get_protocol_name(account));
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), account, text);
+	g_free(text);
+}
+
 static GntWidget*
 create_account_field(PurpleRequestField *field)
 {
 	gboolean all;
 	PurpleAccount *def;
-	GList *list;
 	GntWidget *combo = gnt_combo_box_new();
 
 	all = purple_request_field_account_get_show_all(field);
@@ -529,29 +539,37 @@ create_account_field(PurpleRequestField 
 	}
 
 	if(all) {
-		PurpleAccountManager *manager = purple_account_manager_get_default();
-		list = purple_account_manager_get_all(manager);
+		GListModel *manager_model = NULL;
+		guint n_items = 0;
+
+		manager_model = purple_account_manager_get_default_as_model();
+		n_items = g_list_model_get_n_items(manager_model);
+		for(guint index = 0; index < n_items; index++) {
+			PurpleAccount *account;
+
+			account = g_list_model_get_item(manager_model, index);
+			add_account_to_combo(combo, account);
+
+			if(account == def) {
+				gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), account);
+			}
+
+			g_object_unref(account);
+		}
 	} else {
-		list = purple_connections_get_all();
+		GList *list = purple_connections_get_all();
+		for(; list; list = list->next) {
+			PurpleAccount *account = NULL;
+
+			account = purple_connection_get_account(list->data);
+			add_account_to_combo(combo, account);
+
+			if(account == def) {
+				gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), account);
+			}
+		}
 	}
 
-	for(; list; list = list->next) {
-		PurpleAccount *account;
-		char *text;
-
-		if (all)
-			account = list->data;
-		else
-			account = purple_connection_get_account(list->data);
-
-		text = g_strdup_printf("%s (%s)",
-				purple_account_get_username(account),
-				purple_account_get_protocol_name(account));
-		gnt_combo_box_add_data(GNT_COMBO_BOX(combo), account, text);
-		g_free(text);
-		if (account == def)
-			gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), account);
-	}
 	gnt_widget_set_size(combo, 20, 3); /* ew */
 	return combo;
 }
diff --git a/finch/gntstatus.c b/finch/gntstatus.c
--- a/finch/gntstatus.c
+++ b/finch/gntstatus.c
@@ -491,12 +491,12 @@ popup_substatus(GntTree *tree, const cha
 
 void finch_savedstatus_edit(PurpleSavedStatus *saved)
 {
-	PurpleAccountManager *manager = NULL;
+	GListModel *manager_model = NULL;
 	EditStatus *edit;
 	GntWidget *window, *box, *button, *entry, *combo, *label, *tree;
 	PurpleStatusPrimitive prims[] = {PURPLE_STATUS_AVAILABLE, PURPLE_STATUS_AWAY,
 		PURPLE_STATUS_INVISIBLE, PURPLE_STATUS_OFFLINE, PURPLE_STATUS_UNSET}, current;
-	GList *iter;
+	guint n_items = 0;
 	int i;
 
 	if (saved)
@@ -567,10 +567,12 @@ void finch_savedstatus_edit(PurpleSavedS
 	gnt_tree_set_col_width(GNT_TREE(tree), 1, 10);
 	gnt_tree_set_col_width(GNT_TREE(tree), 2, 30);
 
-	manager = purple_account_manager_get_default();
-	iter = purple_account_manager_get_all(manager);
-	for(; iter; iter = iter->next) {
-		add_substatus(edit, iter->data);
+	manager_model = purple_account_manager_get_default_as_model();
+	n_items = g_list_model_get_n_items(manager_model);
+	for(guint index = 0; index < n_items; index++) {
+		PurpleAccount *account = g_list_model_get_item(manager_model, index);
+		add_substatus(edit, account);
+		g_object_unref(account);
 	}
 
 	g_signal_connect(G_OBJECT(tree), "key_pressed", G_CALLBACK(popup_substatus), edit);
diff --git a/libpurple/buddylist.c b/libpurple/buddylist.c
--- a/libpurple/buddylist.c
+++ b/libpurple/buddylist.c
@@ -361,10 +361,10 @@ accountprivacy_to_xmlnode(PurpleAccount 
 
 static PurpleXmlNode *
 blist_to_xmlnode(void) {
-	PurpleAccountManager *manager = purple_account_manager_get_default();
+	GListModel *manager_model = NULL;
+	guint n_items = 0;
 	PurpleXmlNode *node, *child, *grandchild;
 	PurpleBlistNode *gnode;
-	GList *cur;
 	const gchar *localized_default;
 
 	node = purple_xmlnode_new("purple");
@@ -394,11 +394,13 @@ blist_to_xmlnode(void) {
 
 	/* Write privacy settings */
 	child = purple_xmlnode_new_child(node, "privacy");
-	for(cur = purple_account_manager_get_all(manager); cur != NULL;
-	    cur = cur->next)
-	{
-		grandchild = accountprivacy_to_xmlnode(cur->data);
+	manager_model = purple_account_manager_get_default_as_model();
+	n_items = g_list_model_get_n_items(manager_model);
+	for(guint index = 0; index < n_items; index++) {
+		PurpleAccount *account = g_list_model_get_item(manager_model, index);
+		grandchild = accountprivacy_to_xmlnode(account);
 		purple_xmlnode_insert_child(child, grandchild);
+		g_object_unref(account);
 	}
 
 	return node;
@@ -745,18 +747,21 @@ purple_blist_set_ui(GType type)
 void
 purple_blist_boot(void)
 {
-	PurpleAccountManager *manager = NULL;
+	GListModel *manager_model = NULL;
 	PurpleBuddyList *gbl = g_object_new(buddy_list_type, NULL);
-	GList *l;
+	guint n_items = 0;
 
 	buddies_cache = g_hash_table_new_full(g_direct_hash, g_direct_equal,
 					 NULL, (GDestroyNotify)g_hash_table_destroy);
 
 	groups_cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
 
-	manager = purple_account_manager_get_default();
-	for(l = purple_account_manager_get_all(manager); l != NULL; l = l->next) {
-		purple_blist_buddies_cache_add_account(PURPLE_ACCOUNT(l->data));
+	manager_model = purple_account_manager_get_default_as_model();
+	n_items = g_list_model_get_n_items(manager_model);
+	for(guint index = 0; index < n_items; index++) {
+		PurpleAccount *account = g_list_model_get_item(manager_model, index);
+		purple_blist_buddies_cache_add_account(account);
+		g_object_unref(account);
 	}
 
 	purplebuddylist = gbl;
diff --git a/libpurple/purpleaccountmanager.h b/libpurple/purpleaccountmanager.h
--- a/libpurple/purpleaccountmanager.h
+++ b/libpurple/purpleaccountmanager.h
@@ -66,6 +66,17 @@ typedef void (*PurpleAccountManagerForea
 PurpleAccountManager *purple_account_manager_get_default(void);
 
 /**
+ * purple_account_manager_get_default_as_model:
+ *
+ * Gets the default account manager for libpurple as a list model.
+ *
+ * Returns: (transfer none): The default account manager for libpurple.
+ *
+ * Since: 3.0.0
+ */
+GListModel *purple_account_manager_get_default_as_model(void);
+
+/**
  * purple_account_manager_add:
  * @manager: The account manager instance.
  * @account: (transfer full): The account to add.
@@ -100,19 +111,6 @@ void purple_account_manager_remove(Purpl
 void purple_account_manager_reorder(PurpleAccountManager *manager, PurpleAccount *account, guint new_index);
 
 /**
- * purple_account_manager_get_all:
- * @manager: The account manager instance.
- *
- * Gets the list of all accounts.
- *
- * Returns: (transfer none) (element-type PurpleAccount): The list of all
- *          accounts.
- *
- * Since: 3.0.0
- */
-GList *purple_account_manager_get_all(PurpleAccountManager *manager);
-
-/**
  * purple_account_manager_get_enabled:
  * @manager: The account manager instance.
  *
diff --git a/libpurple/purpleaccountmanager.c b/libpurple/purpleaccountmanager.c
--- a/libpurple/purpleaccountmanager.c
+++ b/libpurple/purpleaccountmanager.c
@@ -33,23 +33,60 @@ static guint signals[N_SIGNALS] = {0, };
 struct _PurpleAccountManager {
 	GObject parent;
 
-	GList *accounts;
+	GPtrArray *accounts;
 };
 
 static PurpleAccountManager *default_manager = NULL;
 
-G_DEFINE_TYPE(PurpleAccountManager, purple_account_manager, G_TYPE_OBJECT)
+/******************************************************************************
+ * GListModel Implementation
+ *****************************************************************************/
+static GType
+purple_account_get_item_type(G_GNUC_UNUSED GListModel *list) {
+	return PURPLE_TYPE_ACCOUNT;
+}
+
+static guint
+purple_account_get_n_items(GListModel *list) {
+	PurpleAccountManager *manager = PURPLE_ACCOUNT_MANAGER(list);
+
+	return manager->accounts->len;
+}
+
+static gpointer
+purple_account_get_item(GListModel *list, guint position) {
+	PurpleAccountManager *manager = PURPLE_ACCOUNT_MANAGER(list);
+	PurpleAccount *account = NULL;
+
+	if(position < manager->accounts->len) {
+		account = g_ptr_array_index(manager->accounts, position);
+		g_object_ref(account);
+	}
+
+	return account;
+}
+
+static void
+purple_account_manager_list_model_init(GListModelInterface *iface) {
+	iface->get_item_type = purple_account_get_item_type;
+	iface->get_n_items = purple_account_get_n_items;
+	iface->get_item = purple_account_get_item;
+}
 
 /******************************************************************************
  * GObject Implementation
  *****************************************************************************/
+G_DEFINE_TYPE_EXTENDED(PurpleAccountManager, purple_account_manager,
+                       G_TYPE_OBJECT, 0,
+                       G_IMPLEMENT_INTERFACE(G_TYPE_LIST_MODEL,
+                                             purple_account_manager_list_model_init))
+
 static void
 purple_account_manager_finalize(GObject *obj) {
 	PurpleAccountManager *manager = PURPLE_ACCOUNT_MANAGER(obj);
-	GList *l = NULL;
 
-	for(l = manager->accounts; l != NULL; l = l->next) {
-		g_object_unref(l->data);
+	if(manager->accounts != NULL) {
+		g_ptr_array_free(manager->accounts, TRUE);
 	}
 
 	G_OBJECT_CLASS(purple_account_manager_parent_class)->finalize(obj);
@@ -57,6 +94,7 @@ purple_account_manager_finalize(GObject 
 
 static void
 purple_account_manager_init(PurpleAccountManager *manager) {
+	manager->accounts = g_ptr_array_new_full(0, (GDestroyNotify)g_object_unref);
 }
 
 static void
@@ -131,6 +169,11 @@ purple_account_manager_get_default(void)
 	return default_manager;
 }
 
+GListModel *
+purple_account_manager_get_default_as_model(void) {
+	return G_LIST_MODEL(default_manager);
+}
+
 void
 purple_account_manager_add(PurpleAccountManager *manager,
                            PurpleAccount *account)
@@ -139,7 +182,7 @@ purple_account_manager_add(PurpleAccount
 	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
 
 	/* If the manager already knows about the account, we do nothing. */
-	if(g_list_find(manager->accounts, account) != NULL) {
+	if(g_ptr_array_find(manager->accounts, account, NULL)) {
 		return;
 	}
 
@@ -148,21 +191,27 @@ purple_account_manager_add(PurpleAccount
 	 * interfaces and the most likely to have configuration issues as it's a
 	 * new account.
 	 */
-	manager->accounts = g_list_prepend(manager->accounts, account);
+	g_ptr_array_insert(manager->accounts, 0, account);
 
 	purple_accounts_schedule_save();
 
 	g_signal_emit(manager, signals[SIG_ADDED], 0, account);
+	g_list_model_items_changed(G_LIST_MODEL(manager), 0, 0, 1);
 }
 
 void
 purple_account_manager_remove(PurpleAccountManager *manager,
                               PurpleAccount *account)
 {
+	guint index = 0;
+
 	g_return_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager));
 	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
 
-	manager->accounts = g_list_remove(manager->accounts, account);
+	if(g_ptr_array_find(manager->accounts, account, &index)) {
+		g_ptr_array_steal_index(manager->accounts, index);
+		g_list_model_items_changed(G_LIST_MODEL(manager), index, 1, 0);
+	}
 
 	purple_accounts_schedule_save();
 
@@ -175,20 +224,13 @@ purple_account_manager_remove(PurpleAcco
 }
 
 GList *
-purple_account_manager_get_all(PurpleAccountManager *manager) {
-	g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
-
-	return manager->accounts;
-}
-
-GList *
 purple_account_manager_get_enabled(PurpleAccountManager *manager) {
-	GList *enabled = NULL, *l = NULL;
+	GList *enabled = NULL;
 
 	g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
 
-	for(l = manager->accounts; l != NULL; l = l->next) {
-		PurpleAccount *account = PURPLE_ACCOUNT(l->data);
+	for(guint index = 0; index < manager->accounts->len; index++) {
+		PurpleAccount *account = g_ptr_array_index(manager->accounts, index);
 
 		if(purple_account_get_enabled(account)) {
 			enabled = g_list_append(enabled, account);
@@ -200,12 +242,12 @@ purple_account_manager_get_enabled(Purpl
 
 GList *
 purple_account_manager_get_disabled(PurpleAccountManager *manager) {
-	GList *disabled = NULL, *l = NULL;
+	GList *disabled = NULL;
 
 	g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
 
-	for(l = manager->accounts; l != NULL; l = l->next) {
-		PurpleAccount *account = l->data;
+	for(guint index = 0; index < manager->accounts->len; index++) {
+		PurpleAccount *account = g_ptr_array_index(manager->accounts, index);
 
 		if(!purple_account_get_enabled(account)) {
 			disabled = g_list_append(disabled, account);
@@ -220,42 +262,31 @@ purple_account_manager_reorder(PurpleAcc
                                PurpleAccount *account,
                                guint new_index)
 {
-	GList *l = NULL;
-	gboolean found = FALSE;
 	guint index = 0;
 
 	g_return_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager));
 	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
 
-	/* Iterate over the known accounts until we have found a matching account
-	 * or exhausted the list. For each iteration increment idx.
-	 */
-	for(l = manager->accounts; l != NULL; l = l->next, index++) {
-		if(PURPLE_ACCOUNT(l->data) == account) {
-			manager->accounts = g_list_delete_link(manager->accounts, l);
-
-			found = TRUE;
+	if(g_ptr_array_find(manager->accounts, account, &index)) {
+		g_ptr_array_steal_index(manager->accounts, index);
+		g_list_model_items_changed(G_LIST_MODEL(manager), index, 1, 0);
 
-			/* If new_index is greater than the current index, we need to
-			 * decrement new_index by 1 to account for the move as we'll be
-			 * inserting into a list with one less item.
-			 */
-			if(new_index > index) {
-				new_index--;
-			}
-
-			break;
+		/* If new_index is greater than the current index, we need to
+		 * decrement new_index by 1 to account for the move as we'll be
+		 * inserting into a list with one less item.
+		 */
+		if(new_index > index) {
+			new_index--;
 		}
-	}
-
-	if(!found) {
+	} else {
 		g_critical("Unregistered account (%s) found during reorder!",
 		           purple_account_get_username(account));
 		return;
 	}
 
 	/* Insert the account into its new position. */
-	manager->accounts = g_list_insert(manager->accounts, account, new_index);
+	g_ptr_array_insert(manager->accounts, new_index, account);
+	g_list_model_items_changed(G_LIST_MODEL(manager), new_index, 0, 1);
 
 	purple_accounts_schedule_save();
 }
@@ -264,13 +295,11 @@ PurpleAccount *
 purple_account_manager_find_by_id(PurpleAccountManager *manager,
                                   const gchar *id)
 {
-	GList *l = NULL;
-
 	g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
 	g_return_val_if_fail(id != NULL, NULL);
 
-	for(l = manager->accounts; l != NULL; l = l->next) {
-		PurpleAccount *account = PURPLE_ACCOUNT(l->data);
+	for(guint index = 0; index < manager->accounts->len; index++) {
+		PurpleAccount *account = g_ptr_array_index(manager->accounts, index);
 
 		if(purple_strequal(purple_account_get_id(account), id)) {
 			return account;
@@ -284,14 +313,12 @@ PurpleAccount *
 purple_account_manager_find(PurpleAccountManager *manager,
                             const gchar *username, const gchar *protocol_id)
 {
-	GList *l;
-
 	g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
 	g_return_val_if_fail(username != NULL, NULL);
 	g_return_val_if_fail(protocol_id != NULL, NULL);
 
-	for(l = manager->accounts; l != NULL; l = l->next) {
-		PurpleAccount *account = PURPLE_ACCOUNT(l->data);
+	for(guint index = 0; index < manager->accounts->len; index++) {
+		PurpleAccount *account = g_ptr_array_index(manager->accounts, index);
 		gchar *normalized = NULL;
 		const gchar *existing_protocol_id = NULL;
 		const gchar *existing_username = NULL;
@@ -323,17 +350,15 @@ PurpleAccount *
 purple_account_manager_find_custom(PurpleAccountManager *manager,
                                    GEqualFunc func, gconstpointer data)
 {
-	GList *l;
+	guint index = 0;
 
 	g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
 	g_return_val_if_fail(func != NULL, NULL);
 
-	for(l = manager->accounts; l != NULL; l = l->next) {
-		PurpleAccount *account = PURPLE_ACCOUNT(l->data);
+	if(g_ptr_array_find_with_equal_func(manager->accounts, data, func, &index)) {
+		PurpleAccount *account = g_ptr_array_index(manager->accounts, index);
 
-		if(func(account, data)) {
-			return account;
-		}
+		return account;
 	}
 
 	return NULL;
@@ -344,12 +369,11 @@ purple_account_manager_foreach(PurpleAcc
                                PurpleAccountManagerForeachFunc callback,
                                gpointer data)
 {
-	GList *l = NULL;
-
 	g_return_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager));
 	g_return_if_fail(callback != NULL);
 
-	for(l = manager->accounts; l != NULL; l = l->next) {
-		callback(PURPLE_ACCOUNT(l->data), data);
+	for(guint index = 0; index < manager->accounts->len; index++) {
+		PurpleAccount *account = g_ptr_array_index(manager->accounts, index);
+		callback(account, data);
 	}
 }
diff --git a/libpurple/tests/test_account_manager.c b/libpurple/tests/test_account_manager.c
--- a/libpurple/tests/test_account_manager.c
+++ b/libpurple/tests/test_account_manager.c
@@ -59,7 +59,6 @@ static void
 test_purple_account_manager_add_remove(void) {
 	PurpleAccount *account = NULL;
 	PurpleAccountManager *manager = NULL;
-	GList *accounts = NULL;
 	gboolean signal_called = FALSE;
 
 	account = purple_account_new("test", "test");
@@ -72,15 +71,13 @@ test_purple_account_manager_add_remove(v
 	                 G_CALLBACK(test_purple_account_manager_signal_called),
 	                 &signal_called);
 
-	accounts = purple_account_manager_get_all(manager);
-	g_assert_true(g_list_length(accounts) == 0);
+	g_assert_cmpuint(g_list_model_get_n_items(G_LIST_MODEL(manager)), ==, 0);
 
 	/* Add the account and verify that it was added and that the signal was
 	 * emitted.
 	 */
 	purple_account_manager_add(manager, account);
-	accounts = purple_account_manager_get_all(manager);
-	g_assert_true(g_list_length(accounts) == 1);
+	g_assert_cmpuint(g_list_model_get_n_items(G_LIST_MODEL(manager)), ==, 1);
 	g_assert_true(signal_called);
 
 	signal_called = FALSE;
@@ -89,8 +86,7 @@ test_purple_account_manager_add_remove(v
 	 * was emitted.
 	 */
 	purple_account_manager_remove(manager, account);
-	accounts = purple_account_manager_get_all(manager);
-	g_assert_true(g_list_length(accounts) == 0);
+	g_assert_cmpuint(g_list_model_get_n_items(G_LIST_MODEL(manager)), ==, 0);
 	g_assert_true(signal_called);
 
 	/* Cleanup */
diff --git a/libpurple/util.c b/libpurple/util.c
--- a/libpurple/util.c
+++ b/libpurple/util.c
@@ -933,19 +933,27 @@ purple_escape_filename(const char *str)
 
 void purple_util_set_current_song(const char *title, const char *artist, const char *album)
 {
-	PurpleAccountManager *manager = purple_account_manager_get_default();
-	GList *list = purple_account_manager_get_all(manager);
-	for (; list; list = list->next) {
+	GListModel *manager_model = NULL;
+	guint n_items = 0;
+
+	manager_model = purple_account_manager_get_default_as_model();
+	n_items = g_list_model_get_n_items(manager_model);
+	for(guint index = 0; index < n_items; index++) {
+		PurpleAccount *account = g_list_model_get_item(manager_model, index);
 		PurplePresence *presence;
 		PurpleStatus *tune;
-		PurpleAccount *account = list->data;
-		if (!purple_account_get_enabled(account))
+
+		if (!purple_account_get_enabled(account)) {
+			g_object_unref(account);
 			continue;
+		}
 
 		presence = purple_account_get_presence(account);
 		tune = purple_presence_get_status(presence, "tune");
-		if (!tune)
+		if (!tune) {
+			g_object_unref(account);
 			continue;
+		}
 		if (title) {
 			GHashTable *attributes = g_hash_table_new(g_str_hash, g_str_equal);
 
@@ -962,6 +970,8 @@ void purple_util_set_current_song(const 
 		} else {
 			purple_status_set_active(tune, FALSE);
 		}
+
+		g_object_unref(account);
 	}
 }
 
diff --git a/pidgin/pidginmooddialog.c b/pidgin/pidginmooddialog.c
--- a/pidgin/pidginmooddialog.c
+++ b/pidgin/pidginmooddialog.c
@@ -95,12 +95,15 @@ pidgin_mood_dialog_edit_cb(PurpleConnect
 
 		update_status_with_mood(account, mood, text);
 	} else {
-		PurpleAccountManager *manager = purple_account_manager_get_default();
-		GList *accounts = purple_account_manager_get_all(manager);
+		GListModel *manager_model = NULL;
+		guint n_items = 0;
 
-		for (; accounts ; accounts = g_list_delete_link(accounts, accounts)) {
-			PurpleAccount *account = (PurpleAccount *) accounts->data;
+		manager_model = purple_account_manager_get_default_as_model();
+		n_items = g_list_model_get_n_items(manager_model);
+		for(guint index = 0; index < n_items; index++) {
+			PurpleAccount *account = NULL;
 
+			account = g_list_model_get_item(manager_model, index);
 			connection = purple_account_get_connection(account);
 			if(PURPLE_IS_CONNECTION(connection)) {
 				PurpleConnectionFlags flags;
@@ -110,6 +113,8 @@ pidgin_mood_dialog_edit_cb(PurpleConnect
 					update_status_with_mood(account, mood, NULL);
 				}
 			}
+
+			g_object_unref(account);
 		}
 	}
 }
