# HG changeset patch
# Node ID a996a32145354ea927fb0a7c1f50f49e661c64e5
# Parent  a99e622e89ee475668d8f568bced961a07a00ffb
diff --git a/libpurple/purpleaccount.c b/libpurple/purpleaccount.c
--- a/libpurple/purpleaccount.c
+++ b/libpurple/purpleaccount.c
@@ -1790,3 +1790,22 @@
 	G_UNLOCK(setting_notify_lock);
 }
 
+int
+purple_account_compare(PurpleAccount *a, PurpleAccount *b) {
+	if (a != NULL && b == NULL) {
+		return -1;
+	}
+	if (a == NULL && b != NULL) {
+		return 1;
+	}
+	if (a == NULL && b == NULL) {
+		return 0;
+	}
+
+	return g_strcmp0(a->id, b->id);
+}
+
+gboolean
+purple_account_equal(PurpleAccount *a, PurpleAccount *b) {
+	return purple_account_compare(a, b) == 0;
+}
diff --git a/libpurple/purpleaccount.h b/libpurple/purpleaccount.h
--- a/libpurple/purpleaccount.h
+++ b/libpurple/purpleaccount.h
@@ -665,6 +665,35 @@
 PURPLE_AVAILABLE_IN_3_0
 void purple_account_thaw_notify_settings(PurpleAccount *account);
 
+/**
+ * purple_account_compare:
+ * @a: (nullable): the first instance
+ * @b: (nullable): the second instance
+ *
+ * Compares accounts @a and @b.
+ *
+ * Returns: less than 0 if @a should be sorted before @b, 0 if they should be
+ *          sorted equally, and greater than 0 if @a should be sorted after @b.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+int purple_account_compare(PurpleAccount *a, PurpleAccount *b);
+
+/**
+ * purple_account_equal:
+ * @a: (nullable): the first instance
+ * @b: (nullable): the second instance
+ *
+ * Checks two [class@Account] objects for equality.
+ *
+ * Returns: true if @a and @b are equal; false otherwise.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+gboolean purple_account_equal(PurpleAccount *a, PurpleAccount *b);
+
 G_END_DECLS
 
 #endif /* PURPLE_ACCOUNT_H */
diff --git a/libpurple/tests/test_account.c b/libpurple/tests/test_account.c
--- a/libpurple/tests/test_account.c
+++ b/libpurple/tests/test_account.c
@@ -221,6 +221,115 @@
 	g_assert_finalize_object(account);
 }
 
+static void
+test_purple_account_compare_not_null__null(void) {
+	PurpleAccount *account = NULL;
+
+	account = purple_account_new("test", "test");
+
+	g_assert_cmpint(purple_account_compare(account, NULL), <, 0);
+
+	g_assert_finalize_object(account);
+}
+
+static void
+test_purple_account_compare_null__not_null(void) {
+	PurpleAccount *account = NULL;
+
+	account = purple_account_new("test", "test");
+
+	g_assert_cmpint(purple_account_compare(NULL, account), >, 0);
+
+	g_assert_finalize_object(account);
+}
+
+static void
+test_purple_account_compare_null__null(void) {
+	g_assert_cmpint(purple_account_compare(NULL, NULL), ==, 0);
+}
+
+static void
+test_purple_account_compare_not_null__not_null(void) {
+	PurpleAccount *account_a = NULL;
+	PurpleAccount *account_b = NULL;
+
+	account_a = g_object_new(
+		PURPLE_TYPE_ACCOUNT,
+		"id", "id_a",
+		"username", "test_a",
+		"protocol-id", "test",
+		"enabled", FALSE,
+		NULL);
+	account_b = g_object_new(
+		PURPLE_TYPE_ACCOUNT,
+		"id", "id_b",
+		"username", "test_b",
+		"protocol-id", "test",
+		"enabled", FALSE,
+		NULL);
+
+	g_assert_cmpint(purple_account_compare(account_a, account_b), <, 0);
+	g_assert_cmpint(purple_account_compare(account_b, account_a), >, 0);
+	g_assert_cmpint(purple_account_compare(account_a, account_a), ==, 0);
+
+	g_assert_finalize_object(account_a);
+	g_assert_finalize_object(account_b);
+}
+
+static void
+test_purple_account_equal_not_null__null(void) {
+	PurpleAccount *account = NULL;
+
+	account = purple_account_new("test", "test");
+
+	g_assert_false(purple_account_equal(account, NULL));
+
+	g_assert_finalize_object(account);
+}
+
+static void
+test_purple_account_equal_null__not_null(void) {
+	PurpleAccount *account = NULL;
+
+	account = purple_account_new("test", "test");
+
+	g_assert_false(purple_account_equal(NULL, account));
+
+	g_assert_finalize_object(account);
+}
+
+static void
+test_purple_account_equal_null__null(void) {
+	g_assert_true(purple_account_equal(NULL, NULL));
+}
+
+static void
+test_purple_account_equal_not_null__not_null(void) {
+	PurpleAccount *account_a = NULL;
+	PurpleAccount *account_b = NULL;
+
+	account_a = g_object_new(
+		PURPLE_TYPE_ACCOUNT,
+		"id", "id_a",
+		"username", "test_a",
+		"protocol-id", "test",
+		"enabled", FALSE,
+		NULL);
+	account_b = g_object_new(
+		PURPLE_TYPE_ACCOUNT,
+		"id", "id_b",
+		"username", "test_b",
+		"protocol-id", "test",
+		"enabled", FALSE,
+		NULL);
+
+	g_assert_false(purple_account_equal(account_a, account_b));
+	g_assert_true(purple_account_equal(account_a, account_a));
+
+	g_assert_finalize_object(account_a);
+	g_assert_finalize_object(account_b);
+}
+
 /******************************************************************************
  * Main
  *****************************************************************************/
@@ -235,5 +344,23 @@
 	g_test_add_func("/account/properties", test_purple_account_properties);
 	g_test_add_func("/account/error", test_purple_account_error);
 
+	g_test_add_func("/account/compare/not_null__null",
+	                test_purple_account_compare_not_null__null);
+	g_test_add_func("/account/compare/null__not_null",
+	                test_purple_account_compare_null__not_null);
+	g_test_add_func("/account/compare/null__null",
+	                test_purple_account_compare_null__null);
+	g_test_add_func("/account/compare/not_null__not_null",
+	                test_purple_account_compare_not_null__not_null);
+
+	g_test_add_func("/account/equal/not_null__null",
+	                test_purple_account_equal_not_null__null);
+	g_test_add_func("/account/equal/null__not_null",
+	                test_purple_account_equal_null__not_null);
+	g_test_add_func("/account/equal/null__null",
+	                test_purple_account_equal_null__null);
+	g_test_add_func("/account/equal/not_null__not_null",
+	                test_purple_account_equal_not_null__not_null);
+
 	return g_test_run();
 }
