gobjectification: 44719c56: Hide group members, but became a big ove...

aluink at soc.pidgin.im aluink at soc.pidgin.im
Sun Aug 9 14:35:40 EDT 2009


-----------------------------------------------------------------
Revision: 44719c562fcb5f2b7ef36a039542fc39a184b76f
Ancestor: b92015e0f6052ff5c302d3f6daf4aecdaf400027
Author: aluink at soc.pidgin.im
Date: 2009-08-09T18:29:35
Branch: im.pidgin.gobjectification
URL: http://d.pidgin.im/viewmtn/revision/info/44719c562fcb5f2b7ef36a039542fc39a184b76f

Modified files:
        libpurple/account.c libpurple/blist-node.c
        libpurple/blist-node.h libpurple/blist.c libpurple/blist.h
        libpurple/contact.c libpurple/group.c libpurple/group.h
        libpurple/protocols/bonjour/bonjour.c
        libpurple/protocols/bonjour/buddy.c
        libpurple/protocols/gg/buddylist.c
        libpurple/protocols/jabber/google.c
        libpurple/protocols/jabber/roster.c
        libpurple/protocols/msn/contact.c
        libpurple/protocols/msn/dialog.c
        libpurple/protocols/msn/msn.c
        libpurple/protocols/msn/session.c
        libpurple/protocols/msn/sync.c
        libpurple/protocols/msn/user.c
        libpurple/protocols/myspace/myspace.c
        libpurple/protocols/novell/novell.c
        libpurple/protocols/oscar/oscar.c
        libpurple/protocols/qq/buddy_opt.c
        libpurple/protocols/qq/group_internal.c
        libpurple/protocols/simple/simple.c
        libpurple/protocols/yahoo/libymsg.c
        libpurple/protocols/zephyr/zephyr.c

ChangeLog: 

Hide group members, but became a big overhaul

-------------- next part --------------
============================================================
--- libpurple/account.c	b1cd1680782788831fa28a823080428f219c88b4
+++ libpurple/account.c	f46903ff98a63ffe9f3ea7bbaa88c38dc50f4243
@@ -2632,7 +2632,7 @@ purple_accounts_delete(PurpleAccount *ac
 						PurpleBuddy *b = (PurpleBuddy *)bnode;
 
 						if (purple_buddy_get_account(b) == account)
-							purple_blist_remove_buddy(b);
+							purple_blist_node_remove(PURPLE_BLIST_NODE(b));
 					}
 					bnode = bnode_next;
 				}
@@ -2640,7 +2640,7 @@ purple_accounts_delete(PurpleAccount *ac
 				PurpleChat *c = (PurpleChat *)cnode;
 
 				if (purple_chat_get_account(c) == account)
-					purple_blist_remove_chat(c);
+					purple_blist_node_remove(PURPLE_BLIST_NODE(c));
 			}
 			cnode = cnode_next;
 		}
============================================================
--- libpurple/blist-node.c	b5601df7bc90f43af5682b6483c38fb6bda9afd9
+++ libpurple/blist-node.c	5aa7e2504fd38020dbfd728cfb5e91c433928ba9
@@ -98,6 +98,27 @@ static PurpleBlistNode *get_next_node(Pu
 	return get_next_node(node->parent, FALSE);
 }
 
+void
+purple_blist_node_save(PurpleBlistNode *node)
+{
+	PurpleBlistNode *tmp;
+	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+
+	g_return_if_fail(PURPLE_IS_BLIST_NODE(node));
+
+	if (ops && ops->save_node) {
+		ops->save_node(node);
+		for (tmp = node->child; tmp; tmp = tmp->next)
+			ops->save_node(tmp);
+	}
+
+	if (ops && ops->update) {
+		ops->update(node);
+		for (tmp = node->child; tmp; tmp = tmp->next)
+			ops->update(tmp);
+	}
+}
+
 PurpleBlistNode *purple_blist_node_next_online(PurpleBlistNode *node, gboolean offline)
 {
 	PurpleBlistNode *ret = node;
@@ -686,13 +707,20 @@ purple_blist_node_class_init(PurpleBlist
 	klass->is_online = NULL;
 
 	purple_signal_register( purple_blist_node_handle(),
-													"group-removed",
+													"node-removed",
 													purple_marshal_VOID__POINTER,
 													NULL,
 													1,
-													purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_BLIST_GROUP));
+													purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_BLIST_NODE));
 
 	purple_signal_register( purple_blist_node_handle(),
+													"node-renamed",
+													purple_marshal_VOID__POINTER_POINTER, /* old_name, new_name */
+													NULL,
+													2,
+													purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_TYPE_CHAR));
+
+	purple_signal_register( purple_blist_node_handle(),
 													"node-updated",
 													purple_marshal_VOID__POINTER,
 													NULL,
============================================================
--- libpurple/blist-node.h	6f284bac12500e34ddaea23db760f0eeb3a88883
+++ libpurple/blist-node.h	d82169908c865459768f14a165f22531d65fee6c
@@ -168,6 +168,13 @@ gboolean purple_blist_node_contains(Purp
 gboolean purple_blist_node_contains(PurpleBlistNode *parent, PurpleBlistNode *node);
 
 /**
+ * Save a blist node and its children
+ *
+ * @param node the node to save
+ */
+void purple_blist_node_save(PurpleBlistNode *node);
+
+/**
  * Add a node as the first child of a given node.
  *
  * @param parent The parent node
============================================================
--- libpurple/blist.c	095008a8c6d966806343154287726bfd47653246
+++ libpurple/blist.c	a5edb0f5ebc0032afd306a59f7ed343e0348c66f
@@ -328,8 +328,7 @@ parse_group(xmlnode *groupnode)
 		name = _("Buddies");
 
 	group = purple_group_new(name);
-	purple_blist_add_group(group,
-	purple_blist_node_first_child(PURPLE_BLIST_NODE(PURPLE_BLIST)));
+	purple_blist_node_add_child(PURPLE_BLIST_NODE(group), PURPLE_BLIST_NODE(PURPLE_BLIST));
 
 	for (cnode = groupnode->child; cnode; cnode = cnode->next) {
 		if (cnode->type != XMLNODE_TYPE_TAG)
@@ -480,19 +479,21 @@ void purple_blist_rename_group(PurpleGro
 	gchar *new_name;
 	GList *moved_buddies = NULL;
 	GSList *accts;
+	char *tmp, *tmp2 = NULL, *tmp3 = NULL;
 
 	g_return_if_fail(source != NULL);
 	g_return_if_fail(name != NULL);
 
 	new_name = purple_utf8_strip_unprintables(name);
 
-	if (*new_name == '\0' || purple_strequal(new_name, source->name)) {
+	if (*new_name == '\0' || purple_strequal(new_name, tmp = purple_group_get_name(source))) {
 		g_free(new_name);
 		return;
 	}
+	g_free(tmp);
 
 	dest = purple_find_group(new_name);
-	if (dest != NULL && purple_utf8_strcasecmp(source->name, dest->name) != 0) {
+	if (dest != NULL && purple_utf8_strcasecmp(tmp3 = purple_group_get_name(source), tmp2 = purple_group_get_name(dest)) != 0) {
 		/* We're merging two groups */
 		PurpleBlistNode *prev, *child, *next;
 
@@ -510,7 +511,7 @@ void purple_blist_rename_group(PurpleGro
 			next = child->next;
 			if (PURPLE_IS_CONTACT(child)) {
 				PurpleBlistNode *bnode;
-				purple_blist_add_contact(PURPLE_CONTACT(child), dest, prev);
+				purple_blist_node_add_sibling(PURPLE_BLIST_NODE(child), prev);
 				for (bnode = child->child; bnode != NULL; bnode = bnode->next) {
 					purple_blist_add_buddy((PurpleBuddy *)bnode, PURPLE_CONTACT(child),
 							NULL, bnode->prev);
@@ -522,13 +523,14 @@ void purple_blist_rename_group(PurpleGro
 				prev = child;
 			} else {
 				purple_debug(PURPLE_DEBUG_ERROR, "blist",
-						"Unknown child type in group %s\n", source->name);
+						"Unknown child type in group %s\n", tmp = purple_group_get_name(source));
+				g_free(tmp);
 			}
 			child = next;
 		}
 
 		/* Make a copy of the old group name and then delete the old group */
-		old_name = g_strdup(source->name);
+		old_name = purple_group_get_name(source);
 		purple_blist_node_remove(PURPLE_BLIST_NODE(source));
 		source = dest;
 		g_free(new_name);
@@ -539,8 +541,8 @@ void purple_blist_rename_group(PurpleGro
 		/* A simple rename */
 		moved_buddies = purple_group_get_buddies(source);
 
-		old_name = source->name;
-		source->name = new_name;
+		old_name = purple_group_get_name(source);
+		purple_group_set_name(source, new_name);
 
 		key = g_utf8_collate_key(old_name, -1);
 		g_hash_table_remove(list->groups_cache, key);
@@ -549,6 +551,10 @@ void purple_blist_rename_group(PurpleGro
 		key = g_utf8_collate_key(new_name, -1);
 		g_hash_table_insert(list->groups_cache, key, source);
 	}
+	if(tmp2){
+		g_free(tmp2);
+		g_free(tmp3);
+	}
 
 	/* Save our changes */
 	if (ops && ops->save_node)
@@ -560,7 +566,7 @@ void purple_blist_rename_group(PurpleGro
 
 	/* Notify all PRPLs */
 	/* TODO: Is this condition needed?  Seems like it would always be TRUE */
-	if(old_name && !purple_strequal(source->name, old_name)) {
+	if(old_name && !purple_strequal(tmp = purple_group_get_name(source), old_name)) {
 		for (accts = purple_group_get_accounts(source); accts; accts = g_slist_remove(accts, accts->data)) {
 			PurpleAccount *account = accts->data;
 			PurpleConnection *gc = NULL;
@@ -605,6 +611,7 @@ void purple_blist_rename_group(PurpleGro
 			g_list_free(buddies);
 		}
 	}
+	g_free(tmp);
 	g_list_free(moved_buddies);
 	g_free(old_name);
 }
@@ -613,7 +620,8 @@ void purple_blist_rename_group(PurpleGro
  * TODO: Maybe remove the call to this from server.c and call it
  * from oscar.c and toc.c instead?
  */
-void purple_blist_rename_buddy(PurpleBuddy *buddy, const char *name)
+static void
+purple_blist_rename_buddy(PurpleBuddy *buddy, const char *name)
 {
 	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
 	PurpleBuddyList *list = PURPLE_BLIST;
@@ -651,358 +659,89 @@ void purple_blist_rename_buddy(PurpleBud
 		ops->update(PURPLE_BLIST_NODE(buddy));
 }
 
-void purple_blist_add_contact(PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node)
+static void
+purple_blist_node_renamed(PurpleBlistNode *node, const char *old_name, const char *new_name)
 {
-	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-	PurpleGroup *g;
-	PurpleBuddyList *list = PURPLE_BLIST;
-	PurpleBlistNode *lnode = PURPLE_BLIST_NODE(list);
-	PurpleBlistNode *gnode, *cnode, *bnode;
-
-	g_return_if_fail(contact != NULL);
-	g_return_if_fail(PURPLE_IS_CONTACT(PURPLE_BLIST_NODE(contact)));
-
-	if (PURPLE_BLIST_NODE(contact) == node)
-		return;
-
-	if (node && (PURPLE_IS_CONTACT(node) ||
-				PURPLE_IS_CHAT(node)))
-		g = PURPLE_GROUP(node->parent);
-	else if (group)
-		g = group;
-	else {
-		g = purple_find_group(_("Buddies"));
-		if (g == NULL) {
-			g = purple_group_new(_("Buddies"));
-			purple_blist_add_group(g,
-					purple_blist_node_first_child(lnode));
-		}
-	}
-
-	gnode = PURPLE_BLIST_NODE(g);
-	cnode = PURPLE_BLIST_NODE(contact);
-
-	/* If node is already in the list somewhere */	
-	if (cnode->parent) {
-		purple_blist_node_remove(cnode);
-		/* If node is in the group already */
-		if (purple_blist_node_contains(gnode, cnode)) {
-			bnode = cnode->child;
-			/* Iterate the buddies of the contact */
-			while (bnode) {
-				PurpleBlistNode *next_bnode = bnode->next;
-				PurpleBuddy *b = (PurpleBuddy*)bnode;
-				GHashTable *account_buddies;
-
-
-				/* Remove the buddy from the buddies and buddies_cache HTs */
-				struct _purple_hbuddy *hb, *hb2;
-
-				hb = g_new(struct _purple_hbuddy, 1);
-				hb->name = g_strdup(purple_normalize(purple_buddy_get_account(b), purple_buddy_get_name(b)));
-				hb->account = purple_buddy_get_account(b);
-				hb->group = cnode->parent;
-
-				g_hash_table_remove(list->buddies, hb);
-
-				account_buddies = g_hash_table_lookup(list->buddies_cache, purple_buddy_get_account(b));
-				g_hash_table_remove(account_buddies, hb);
-
-				/* If buddy isn't in the group, then add it to the caches with the new group */
-				if (!purple_find_buddy_in_group(purple_buddy_get_account(b), purple_buddy_get_name(b), g)) {
-					hb->group = gnode;
-					g_hash_table_replace(list->buddies, hb, b);
-
-					hb2 = g_new(struct _purple_hbuddy, 1);
-					hb2->name = g_strdup(hb->name);
-					hb2->account = purple_buddy_get_account(b);
-					hb2->group = gnode;
-
-					g_hash_table_replace(account_buddies, hb2, b);
-
-					if (purple_account_get_connection(purple_buddy_get_account(b)))
-						serv_move_buddy(b, PURPLE_GROUP(cnode->parent), g);
-				} else {
-					/* If it's already in the group, then we don't move it there,
-					 * we just remove it from the contact.*/
-					gboolean empty_contact = FALSE;
-
-					/* this buddy already exists in the group, so we're
-					 * gonna delete it instead */
-					g_free(hb->name);
-					g_free(hb);
-					if (purple_account_get_connection(purple_buddy_get_account(b)))
-						purple_account_remove_buddy(purple_buddy_get_account(b), b, PURPLE_GROUP(cnode->parent));
-
-					/* Since we removed it from the contact, the cnode might be empty */
-					if (!cnode->child->next)
-						empty_contact = TRUE;
-					purple_blist_remove_buddy(b);
-
-					/** in purple_blist_remove_buddy(), if the last buddy in a
-					 * contact is removed, the contact is cleaned up and
-					 * g_free'd, so we mustn't try to reference bnode->next */
-					/* If the contact is empty, it's deleted, and thus there's nothing to move */
-					if (empty_contact)
-						return;
-				}
-				bnode = next_bnode;
-			}
-		}
-
-		/*purple_group_remove_contact_count(PURPLE_GROUP(cnode->parent), contact);*/
-		PURPLE_GROUP(cnode->parent)->totalsize--;
-
-		if (ops && ops->remove)
-			ops->remove(cnode);
-
-		if (ops && ops->remove_node)
-			ops->remove_node(cnode);
-	}
-
-	/*purple_group_add_contact(g,contact,node);*/
-
-	if (ops && ops->save_node)
-	{
-		if (cnode->child)
-			ops->save_node(cnode);
-		for (bnode = cnode->child; bnode; bnode = bnode->next)
-			ops->save_node(bnode);
-	}
-
-
-	if (ops && ops->update)
-	{
-		if (cnode->child)
-			ops->update(cnode);
-
-		for (bnode = cnode->child; bnode; bnode = bnode->next)
-			ops->update(bnode);
-	}
+	
 }
 
-/**
- * Return the group this node is contained in, or the node itself if the node is a group.
- *
- * @param node The node to search
- * @return The group containing the node, or the node itself if the node is a group
- */
-static PurpleGroup *
-purple_blist_get_containing_group(PurpleBlistNode *node)
+static void
+purple_blist_add_group_prep(PurpleBlistNode *gnode)
 {
-	g_return_val_if_fail(node, NULL);
-	do {
-		if(PURPLE_IS_GROUP(node))
-			return PURPLE_GROUP(node);
-		node = node->parent;
-	} while(node);
-	return NULL;
-}
-
-void purple_blist_add_group(PurpleGroup *group, PurpleBlistNode *node)
-{
 	PurpleBlistUiOps *ops;
-	PurpleBlistNode *gnode = PURPLE_BLIST_NODE(group);
+	PurpleGroup *group;
 	PurpleBuddyList *list = PURPLE_BLIST;
 	gchar *key;
+	gchar *name;
 
-	g_return_if_fail(group != NULL);
-	g_return_if_fail(PURPLE_IS_GROUP(PURPLE_BLIST_NODE(group)));
+	g_return_if_fail(PURPLE_IS_GROUP(gnode));
 
+	group = PURPLE_GROUP(gnode);
+	name = purple_group_get_name(group);
+
 	ops = purple_blist_get_ui_ops();
 
-	/* if we're moving to overtop of ourselves, do nothing */
-	if (gnode == node)
-		return;
-
-	if (purple_find_group(group->name)) {
+	if (purple_find_group(name)) {
 		/* This is just being moved */
+		/* It would be nice to have the client worry 
+		 * about this case, but we'll leave it in for now */
 
 		if (ops && ops->remove)
 			ops->remove(PURPLE_BLIST_NODE(group));
 
 		purple_blist_node_remove(gnode);
-	} else {
-		key = g_utf8_collate_key(group->name, -1);
-		g_hash_table_insert(list->groups_cache, key, group);
 	}
-
-	if (node) {
-		node = PURPLE_BLIST_NODE(purple_blist_get_containing_group(node));
-		purple_blist_node_add_sibling(gnode, node);
-	} else {
-		purple_blist_node_add_child(PURPLE_BLIST_NODE(list), gnode);
-	}
-
-	if (ops && ops->save_node) {
-		ops->save_node(gnode);
-		for (node = gnode->child; node; node = node->next)
-			ops->save_node(node);
-	}
-
-	if (ops && ops->update) {
-		ops->update(gnode);
-		for (node = gnode->child; node; node = node->next)
-			ops->update(node);
-	}
-
-	purple_signal_emit(purple_blist_get_handle(), "blist-node-added",
-			gnode);
+	key = g_utf8_collate_key(name, -1);
+	g_hash_table_insert(list->groups_cache, key, group);
+	g_free(name);
+	g_free(key);
 }
 
-void purple_blist_remove_contact(PurpleContact *contact)
+static void
+purple_blist_add_group_sibling(PurpleBlistNode *gnode, PurpleBlistNode *node)
 {
-	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-	PurpleBlistNode *node, *gnode;
-
-	g_return_if_fail(contact != NULL);
-
-	node = PURPLE_BLIST_NODE(contact);
-	gnode = node->parent;
-
-	if (node->child) {
-		/*
-		 * If this contact has children then remove them.  When the last
-		 * buddy is removed from the contact, the contact is automatically
-		 * deleted.
-		 */
-		while (node->child->next) {
-			purple_blist_remove_buddy((PurpleBuddy*)node->child);
-		}
-		/*
-		 * Remove the last buddy and trigger the deletion of the contact.
-		 * It would probably be cleaner if contact-deletion was done after
-		 * a timeout?  Or if it had to be done manually, like below?
-		 */
-		purple_blist_remove_buddy((PurpleBuddy*)node->child);
-	} else {
-		/* Remove the node from its parent */
-		purple_blist_node_remove(node);
-
-		/* Update the UI */
-		if (ops && ops->remove)
-			ops->remove(node);
-
-		if (ops && ops->remove_node)
-			ops->remove_node(node);
-
-		purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
-				PURPLE_BLIST_NODE(contact));
-
-		/* Delete the node */
-		purple_contact_destroy(contact);
-	}
+	purple_blist_add_group_prep(gnode);
+	parent_class->add_sibling(gnode, node);
+	purple_blist_node_save(gnode);
+	purple_signal_emit(purple_blist_get_handle(), "blist-node-added", gnode);
 }
 
-void purple_blist_remove_buddy(PurpleBuddy *buddy)
+static void
+purple_blist_add_group_child(PurpleBlistNode *parent, PurpleBlistNode *gnode)
 {
-	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-	PurpleBlistNode *node, *cnode, *gnode;
-	PurpleBuddyList *list = PURPLE_BLIST;
-	struct _purple_hbuddy hb;
-	GHashTable *account_buddies;
-
-	g_return_if_fail(buddy != NULL);
-
-	node = PURPLE_BLIST_NODE(buddy);
-	cnode = purple_blist_node_parent(node);
-	gnode = purple_blist_node_parent(cnode);
-
-	purple_blist_node_remove(node);
-	
-	/* Remove this buddy from the buddies hash table */
-	hb.name = g_strdup(purple_normalize(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy)));
-	hb.account = purple_buddy_get_account(buddy);
-	hb.group = gnode;
-	g_hash_table_remove(list->buddies, &hb);
-
-	account_buddies = g_hash_table_lookup(list->buddies_cache, purple_buddy_get_account(buddy));
-	g_hash_table_remove(account_buddies, &hb);
-
-	/* Update the UI */
-	if (ops && ops->remove)
-		ops->remove(node);
-
-	if (ops && ops->remove_node)
-		ops->remove_node(node);
-
-	/* Signal that the buddy has been removed before freeing the memory for it */
-	purple_signal_emit(purple_blist_get_handle(), "buddy-removed", buddy);
-
-	purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
-			PURPLE_BLIST_NODE(buddy));
-
-	purple_buddy_destroy(buddy);
+	purple_blist_add_group_prep(gnode);
+	parent_class->add_child(parent, gnode);
+	purple_blist_node_save(gnode);
+	purple_signal_emit(purple_blist_get_handle(), "blist-node-added",	gnode);
 }
 
-void purple_blist_remove_chat(PurpleChat *chat)
-{
-	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-	PurpleBlistNode *node, *gnode;
-	PurpleGroup *group;
-	PurpleAccount *account;
-
-	g_return_if_fail(chat != NULL);
-
-	node = PURPLE_BLIST_NODE(chat);
-	gnode = node->parent;
-	group = PURPLE_GROUP(gnode);
-
-	if (gnode != NULL)
-	{
-		/* Remove the node from its parent */
-		purple_blist_node_remove(node);
-
-		/* Adjust size counts */
-		account = purple_chat_get_account(chat);
-		if (purple_account_is_connected(account)) {
-			group->online--;
-			group->currentsize--;
-		}
-		group->totalsize--;
-
-	}
-
-	/* Update the UI */
-	if (ops && ops->remove)
-		ops->remove(node);
-
-	if (ops && ops->remove_node)
-		ops->remove_node(node);
-
-	purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
-			PURPLE_BLIST_NODE(chat));
-
-	/* Delete the node */
-	purple_chat_destroy(chat);
-}
-
 static void
-purple_blist_remove_group(PurpleGroup *group)
+purple_blist_remove_group(PurpleBlistNode *gnode)
 {
 	PurpleBuddyList *list = PURPLE_BLIST;
 	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-	PurpleBlistNode *node;
+	PurpleGroup *group;
 	GList *l;
 	gchar *key;
+	gchar *tmp;
 
-	g_return_if_fail(group != NULL);
+	g_return_if_fail(PURPLE_IS_GROUP(gnode));
 
-	node = PURPLE_BLIST_NODE(group);
+	group = PURPLE_GROUP(gnode);
 
-	if (purple_blist_node_is_empty(PURPLE_BLIST_NODE(group)))
-		return;
-
-	key = g_utf8_collate_key(group->name, -1);
+	key = g_utf8_collate_key(tmp = purple_group_get_name(group), -1);
 	g_hash_table_remove(list->groups_cache, key);
 	g_free(key);
+	g_free(tmp);
 
+	parent_class->remove(gnode);
+
 	/* Update the UI */
 	if (ops && ops->remove)
-		ops->remove(node);
+		ops->remove(gnode);
 
 	if (ops && ops->remove_node)
-		ops->remove_node(node);
+		ops->remove_node(gnode);
 
 	purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
 			PURPLE_BLIST_NODE(group));
@@ -1103,6 +842,7 @@ void purple_blist_add_account(PurpleAcco
 	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
 	PurpleBlistNode *gnode, *cnode, *bnode;
 	PurpleBuddyList *list = PURPLE_BLIST;
+	PurpleGroup *group;
 
 	/* There are long/nasty lines in this function, and it's sibling remove, 
 	 * for now until we can do most of this with signals */
@@ -1114,6 +854,7 @@ void purple_blist_add_account(PurpleAcco
 	for (; gnode; gnode = gnode->next) {
 		if (!PURPLE_IS_GROUP(gnode))
 			continue;
+		group = PURPLE_GROUP(gnode);
 		for (cnode = gnode->child; cnode; cnode = cnode->next) {
 			if (PURPLE_IS_CONTACT(cnode)) {
 				gboolean recompute = FALSE;
@@ -1124,7 +865,7 @@ void purple_blist_add_account(PurpleAcco
 							purple_contact_set_currentsize(PURPLE_CONTACT(cnode), 
 								purple_contact_get_currentsize(PURPLE_CONTACT(cnode))+1);
 							if (purple_contact_get_currentsize(PURPLE_CONTACT(cnode)) == 1)
-								PURPLE_GROUP(gnode)->currentsize++;
+								purple_group_set_currentsize(group, purple_group_get_size(group, FALSE)+1);
 							ops->update(bnode);
 						}
 					}
@@ -1135,8 +876,8 @@ void purple_blist_add_account(PurpleAcco
 					}
 			} else if (PURPLE_IS_CHAT(cnode) &&
 					purple_chat_get_account(PURPLE_CHAT(cnode)) == account) {
-				PURPLE_GROUP(gnode)->online++;
-				PURPLE_GROUP(gnode)->currentsize++;
+				purple_group_set_online(group, purple_group_get_online(group)+1);
+				purple_group_set_currentsize(group, purple_group_get_size(group, FALSE)+1);
 				ops->update(cnode);
 			}
 		}
@@ -1181,7 +922,7 @@ void purple_blist_remove_account(PurpleA
 							purple_contact_set_currentsize(contact,
 								purple_contact_get_currentsize(contact)-1);
 							if (purple_contact_get_online(contact) == 0)
-								group->online--;
+								purple_group_set_online(group, purple_group_get_online(group)-1);
 
 							purple_blist_node_set_int(&buddy->node,
 													"last_seen", time(NULL));
@@ -1190,7 +931,7 @@ void purple_blist_remove_account(PurpleA
 						purple_contact_set_currentsize(contact,
 							purple_contact_get_currentsize(contact)-1);
 						if (purple_contact_get_currentsize(contact) == 0)
-							group->currentsize--;
+							purple_group_set_currentsize(group, purple_group_get_size(group, FALSE)-1);
 
 						if (!g_list_find(list, presence))
 							list = g_list_prepend(list, presence);
@@ -1214,8 +955,8 @@ void purple_blist_remove_account(PurpleA
 				chat = (PurpleChat *)cnode;
 
 				if(purple_chat_get_account(chat) == account) {
-					group->currentsize--;
-					group->online--;
+					purple_group_set_currentsize(group, purple_group_get_size(group, FALSE)-1);
+					purple_group_set_online(group, purple_group_get_online(group)-1);
 
 					if (ops && ops->remove)
 						ops->remove(cnode);
@@ -1253,6 +994,7 @@ void purple_blist_add_chat(PurpleChat *c
 	PurpleBlistNode *cnode = PURPLE_BLIST_NODE(chat);
 	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
 	PurpleBuddyList *list = PURPLE_BLIST;
+	gchar *tmp;
 
 	g_return_if_fail(chat != NULL);
 	g_return_if_fail(PURPLE_IS_CHAT(PURPLE_BLIST_NODE(chat)));
@@ -1262,10 +1004,10 @@ void purple_blist_add_chat(PurpleChat *c
 			group = purple_group_new(_("Chats"));
 
 		/* Add group to blist if isn't already on it. Fixes #2752. */
-		if (!purple_find_group(group->name)) {
-			purple_blist_add_group(group,
-					purple_blist_node_first_child(PURPLE_BLIST_NODE(list)));
+		if (!purple_find_group(tmp = purple_group_get_name(group))) {
+			purple_blist_node_add_child(PURPLE_BLIST_NODE(group), PURPLE_BLIST_NODE(list));
 		}
+		g_free(tmp);
 	} else {
 		group = PURPLE_GROUP(node->parent);
 	}
@@ -1297,11 +1039,11 @@ void purple_blist_add_chat(PurpleChat *c
 		cnode->prev = node;
 		cnode->parent = node->parent;
 		node->next = cnode;
-		(PURPLE_GROUP(node->parent))->totalsize++;
-		if (purple_account_is_connected(purple_chat_get_account(chat))) {
+		/* (PURPLE_GROUP(node->parent))->totalsize++; */
+	/*	if (purple_account_is_connected(purple_chat_get_account(chat))) {
 			(PURPLE_GROUP(node->parent))->online++;
 			(PURPLE_GROUP(node->parent))->currentsize++;
-		}
+		}*/
 	} else {
 		if ((PURPLE_BLIST_NODE(group))->child)
 			(PURPLE_BLIST_NODE(group))->child->prev = cnode;
@@ -1309,11 +1051,11 @@ void purple_blist_add_chat(PurpleChat *c
 		cnode->prev = NULL;
 		(PURPLE_BLIST_NODE(group))->child = cnode;
 		cnode->parent = PURPLE_BLIST_NODE(group);
-		group->totalsize++;
+		/*group->totalsize++;
 		if (purple_account_is_connected(purple_chat_get_account(chat))) {
 			group->online++;
 			group->currentsize++;
-		}
+		}*/
 	}
 
 	if (ops && ops->save_node)
@@ -1335,6 +1077,7 @@ void purple_blist_add_buddy(PurpleBuddy 
 	struct _purple_hbuddy *hb, *hb2;
 	GHashTable *account_buddies;
 	PurpleBuddyList *list = PURPLE_BLIST;
+	gchar *tmp;
 
 	g_return_if_fail(buddy != NULL);
 	g_return_if_fail(PURPLE_IS_BUDDY(PURPLE_BLIST_NODE(buddy)));
@@ -1358,13 +1101,13 @@ void purple_blist_add_buddy(PurpleBuddy 
 		if (g == NULL)
 			g = purple_group_new(_("Buddies"));
 		/* Add group to blist if isn't already on it. Fixes #2752. */
-		if (!purple_find_group(g->name)) {
-			purple_blist_add_group(g,
-					purple_blist_node_first_child(PURPLE_BLIST_NODE(list)));
+		if (!purple_find_group(tmp = purple_group_get_name(g))) {
+			purple_blist_node_add_child(PURPLE_BLIST_NODE(g),PURPLE_BLIST_NODE(list));
 		}
+		g_free(tmp);
 		c = purple_contact_new();
-		purple_blist_add_contact(c, g,
-				purple_blist_get_last_child(PURPLE_BLIST_NODE(g)));
+		purple_blist_node_add_sibling(PURPLE_BLIST_NODE(c),
+									 	purple_blist_get_last_child(PURPLE_BLIST_NODE(g)));
 	}
 
 	cnode = PURPLE_BLIST_NODE(c);
@@ -1412,7 +1155,7 @@ void purple_blist_add_buddy(PurpleBuddy 
 		}
 
 		if (!bnode->parent->child) {
-			purple_blist_remove_contact((PurpleContact*)bnode->parent);
+			purple_blist_node_remove(purple_blist_node_parent(bnode));
 		} else {
 			purple_contact_invalidate_priority_buddy((PurpleContact*)bnode->parent);
 			if (ops && ops->update)
@@ -1684,43 +1427,6 @@ purple_blist_uninit(void)
 	purple_signals_unregister_by_instance(purple_blist_get_handle());
 };
 
-static void
-purple_blist_remove_node(PurpleBlistNode *node)
-{
-	PurpleGroup *group;
-
-	g_return_if_fail(node);
-	parent_class->remove(node);
-	
-	group = PURPLE_GROUP(node);
-}
-
-static void
-purple_blist_add_sibling(PurpleBlistNode *child, PurpleBlistNode *location)
-{
-	PurpleGroup *group;
-	PurpleGroup *ref_group;
-
-	g_return_if_fail(child);
-	g_return_if_fail(location);
-	parent_class->add_sibling(child, location);
-
-	group = PURPLE_GROUP(child);
-	ref_group = PURPLE_GROUP(location);
-}
-
-static void
-purple_blist_add_child(PurpleBlistNode *parent, PurpleBlistNode *child)
-{
-	PurpleGroup *group;
-
-	g_return_if_fail(parent);
-	g_return_if_fail(child);
-	parent_class->add_child(parent, child);
-
- 	group	= PURPLE_GROUP(child);
-}
-
 /******************/
 /*  GObject Code  */
 /******************/
@@ -1746,9 +1452,9 @@ purple_blist_class_init(PurpleBuddyListC
 
 
 	parent_class = PURPLE_BLIST_NODE_CLASS(klass);
-	parent_class->remove = purple_blist_remove_node;
-	parent_class->add_sibling = purple_blist_add_sibling;
-	parent_class->add_child = purple_blist_add_child;
+	parent_class->remove = purple_blist_remove_group;
+	parent_class->add_sibling = purple_blist_add_group_sibling;
+	parent_class->add_child = purple_blist_add_group_child;
 
 	parent_class = g_type_class_peek_parent(klass);
 	obj_class->finalize = purple_blist_finalize;
@@ -1866,6 +1572,12 @@ purple_blist_instance_init(GTypeInstance
 	gbl->groups_cache = g_hash_table_new_full(g_str_hash, g_str_equal,
 					 (GDestroyNotify)g_free, NULL);
 
+	purple_signal_connect(purple_blist_node_get_handle(), "node-renamed", /* What to connect to */
+		instance, /* Object receiving the signal */
+		PURPLE_CALLBACK(purple_blist_node_renamed), /* Callback function */
+		instance /* Data to pass to the callback function */
+	);
+
 	gbl->save_timer = 0;
 	gbl->blist_loaded = FALSE;
 
============================================================
--- libpurple/blist.h	d99eb684af9d4347a1c60c2acbea26dc9ea737db
+++ libpurple/blist.h	b9239d35cd23485b947558429925d2793132d236
@@ -248,14 +248,6 @@ void purple_blist_update_buddy_icon(Purp
 #endif
 
 /**
- * Renames a buddy in the buddy list.
- *
- * @param buddy  The buddy whose name will be changed.
- * @param name   The new name of the buddy.
- */
-void purple_blist_rename_buddy(PurpleBuddy *buddy, const char *name);
-
-/**
  * Aliases a contact in the buddy list.
  *
  * @param contact The contact whose alias will be changed.
@@ -315,57 +307,6 @@ void purple_blist_add_buddy(PurpleBuddy 
 void purple_blist_add_buddy(PurpleBuddy *buddy, PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node);
 
 /**
- * Adds a new group to the buddy list.
- *
- * The new group will be inserted after node or prepended to the list if
- * node is NULL.
- *
- * @param group  The group
- * @param node   The insertion point
- */
-void purple_blist_add_group(PurpleGroup *group, PurpleBlistNode *node);
-
-/**
- * Adds a new contact to the buddy list.
- *
- * The new contact will be inserted after insert or prepended to the list if
- * node is NULL.
- *
- * @param contact The contact
- * @param group   The group to add the contact to
- * @param node    The insertion point
- */
-void purple_blist_add_contact(PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node);
-
-/**
- * Removes a buddy from the buddy list and frees the memory allocated to it.
- * This doesn't actually try to remove the buddy from the server list.
- *
- * @param buddy   The buddy to be removed
- *
- * @see purple_account_remove_buddy
- */
-void purple_blist_remove_buddy(PurpleBuddy *buddy);
-
-/**
- * Removes a contact, and any buddies it contains, and frees the memory
- * allocated to it. This calls purple_blist_remove_buddy and therefore
- * doesn't remove the buddies from the server list.
- *
- * @param contact The contact to be removed
- *
- * @see purple_blist_remove_buddy
- */
-void purple_blist_remove_contact(PurpleContact *contact);
-
-/**
- * Removes a chat from the buddy list and frees the memory allocated to it.
- *
- * @param chat   The chat to be removed
- */
-void purple_blist_remove_chat(PurpleChat *chat);
-
-/**
  * Finds the buddy struct given a name and an account
  *
  * @param account The account this buddy belongs to
============================================================
--- libpurple/contact.c	7829c4b6ea110aeb0218b14552efa2674fcc71a5
+++ libpurple/contact.c	dd47d7fdd45a6aae9c132fce1be88575839b9d7d
@@ -86,7 +86,7 @@ parse_contact(PurpleGroup *group, xmlnod
 	xmlnode *x;
 	const char *alias;
 
-	purple_blist_add_contact(contact, group,
+	purple_blist_node_add_sibling(PURPLE_BLIST_NODE(contact),
 			purple_blist_get_last_child(PURPLE_BLIST_NODE(group)));
 
 	if ((alias = xmlnode_get_attrib(cnode, "alias"))) {
@@ -104,7 +104,7 @@ parse_contact(PurpleGroup *group, xmlnod
 
 	/* if the contact is empty, don't keep it around.  it causes problems */
 	if (!(PURPLE_BLIST_NODE(contact))->child)
-		purple_blist_remove_contact(contact);
+		purple_blist_node_remove(PURPLE_BLIST_NODE(contact));
 }
 
 void
@@ -285,14 +285,14 @@ purple_contact_buddy_status_update(Purpl
 
 	if (purple_status_is_online(status) &&
 		!purple_status_is_online(old_status)) {
-
-		if (++(priv->online) == 1)
-			PURPLE_GROUP(contact->node.parent)->online++;
+#warning: broken, fix with signals
+		/* if (++(priv->online) == 1)
+			PURPLE_GROUP(contact->node.parent)->online++;*/
 	} else if (!purple_status_is_online(status) &&
 				purple_status_is_online(old_status)) {
 
-		if (--(priv->online) == 0)
-			PURPLE_GROUP(contact->node.parent)->online--;
+		/*if (--(priv->online) == 0)
+			PURPLE_GROUP(contact->node.parent)->online--;*/
 	}
 }
 
============================================================
--- libpurple/group.c	f6ed937d8e00158a9d5fb43cafad49ee34a65066
+++ libpurple/group.c	151bb38b0aa4a4190d955f24b0adb1bf62a5db22
@@ -31,19 +31,31 @@
 #include "signals.h"
 #include "xmlnode.h"
 
+#define PURPLE_GROUP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PURPLE_GROUP_TYPE, PurpleGroupPrivate))
+
 static PurpleBlistNodeClass *parent_class = NULL;
 
+struct _PurpleGroupPrivate {
+	char *name;                            /**< The name of this group. */
+	int totalsize;			       /**< The number of chats and contacts in this group */
+	int currentsize;		       /**< The number of chats and contacts in this group corresponding to online accounts */
+	int online;			       /**< The number of chats and contacts in this group who are currently online */
+};
+
 xmlnode *
 group_to_xmlnode(PurpleBlistNode *gnode)
 {
 	xmlnode *node, *child;
 	PurpleGroup *group;
 	PurpleBlistNode *cnode;
+	PurpleGroupPrivate *priv;
+	g_return_val_if_fail(PURPLE_IS_GROUP(gnode), NULL);
+	priv = PURPLE_GROUP_GET_PRIVATE(gnode);
 
 	group = PURPLE_GROUP(gnode);
 
 	node = xmlnode_new("group");
-	xmlnode_set_attrib(node, "name", group->name);
+	xmlnode_set_attrib(node, "name", priv->name);
 
 	/* Write settings */
 	g_hash_table_foreach(purple_blist_node_get_settings(PURPLE_BLIST_NODE(group)), value_to_xmlnode, node);
@@ -97,22 +109,24 @@ purple_group_child_updated(PurpleGroup *
 {
 	PurpleChat *chat;
 	PurpleContact *contact;
+	PurpleGroupPrivate *priv;
+	g_return_if_fail(PURPLE_IS_GROUP(group));
+	g_return_if_fail(PURPLE_IS_CONTACT(child) || PURPLE_IS_CHAT(child));
+	priv = PURPLE_GROUP_GET_PRIVATE(group);
 
-	g_return_if_fail(group);
-	g_return_if_fail(child);
 	
 	if(PURPLE_IS_CHAT(child)){
 		chat = PURPLE_CHAT(child);
 		if (purple_account_is_connected(purple_chat_get_account(chat))) {
-			group->online++;
-			group->currentsize++;
+			priv->online++;
+			priv->currentsize++;
 		}
 	} else if(PURPLE_IS_CONTACT(child)){
 		contact = PURPLE_CONTACT(child);
 		if(purple_contact_get_online(contact) > 0)
-			group->online++;
+			priv->online++;
 		if(purple_contact_get_currentsize(contact) == 1)/* Just came online */
-			group->currentsize++;
+			priv->currentsize++;
 	} else {
 		g_warn_if_reached();
 	}
@@ -124,9 +138,15 @@ purple_group_add_child_helper(PurpleGrou
 
 	PurpleChat *chat;
 	PurpleContact *contact;
-
+	PurpleGroupPrivate *priv;
 	g_return_if_fail(PURPLE_IS_GROUP(group));
+	g_return_if_fail(PURPLE_IS_CONTACT(child));
+	priv = PURPLE_GROUP_GET_PRIVATE(group);
 
+#warning: gotta be a better way than doing this over and over
+	/* Maybe when the group is created, then the children just have to emit it.
+	 * Then how will the group know if this is a child it's worried about or not?
+	 */
 	purple_signal_connect(purple_blist_node_get_handle(), "node-updated", /* What to connect to */
 		group, /* Object receiving the signal */
 		PURPLE_CALLBACK(purple_group_child_updated), /* Callback function */
@@ -136,36 +156,32 @@ purple_group_add_child_helper(PurpleGrou
 	if(PURPLE_IS_CHAT(child)){
 		chat = PURPLE_CHAT(child);
 		if (purple_account_is_connected(purple_chat_get_account(chat))) {
-			group->online++;
-			group->currentsize++;
+			priv->online++;
+			priv->currentsize++;
 		}
 	} else if(PURPLE_IS_CONTACT(child)){
 		contact = PURPLE_CONTACT(child);
 		if(purple_contact_get_online(contact) > 0)
-			group->online++;
+			priv->online++;
 		if(purple_contact_get_currentsize(contact) > 0)
-			group->currentsize++;
+			priv->currentsize++;
 	} else {
 		#warning: is this an ok case?
 		g_warn_if_reached();
 	}
-	group->totalsize++;
+	priv->totalsize++;
 
 	#warning Is this schedule save necessary?
 	purple_blist_schedule_save();
 	purple_signal_emit(purple_blist_node_get_handle(), "node-added", child);
-	purple_signal_connect(purple_blist_node_get_handle(), "node-updated", /* What to connect to */
-		group, /* Object receiving the signal */
-		PURPLE_CALLBACK(purple_group_child_updated), /* Callback function */
-		group /* Data to pass to the callback function */
-	);
 
 }
 
 static void
 purple_group_add_sibling(PurpleBlistNode *node, PurpleBlistNode *location)
 {
-	g_return_if_fail(node);
+	g_return_if_fail(PURPLE_IS_CONTACT(node) || PURPLE_IS_CHAT(node));
+	g_return_if_fail(PURPLE_IS_CONTACT(location) || PURPLE_IS_CHAT(location));
 	g_return_if_fail(PURPLE_IS_GROUP(purple_blist_node_parent(location)));
 	
 	purple_group_add_child_helper(PURPLE_GROUP(purple_blist_node_parent(location)), node);
@@ -187,31 +203,31 @@ purple_group_remove_node(PurpleBlistNode
 static void
 purple_group_remove_node(PurpleBlistNode *child)
 {
-	PurpleGroup *group;
 	PurpleContact *contact;
 	PurpleChat *chat;
+	PurpleGroupPrivate *priv;
+	g_return_if_fail(PURPLE_IS_CONTACT(child) || PURPLE_IS_CHAT(child));
+	g_return_if_fail(PURPLE_IS_GROUP(purple_blist_node_parent(child)));
 
-	g_return_if_fail(child);
-	g_return_if_fail(purple_blist_node_parent(child));
-	group = PURPLE_GROUP(child->parent);
+	priv = PURPLE_GROUP_GET_PRIVATE(purple_blist_node_parent(child));
 
 	if(PURPLE_IS_CHAT(child)){
 		chat = PURPLE_CHAT(child);
 		if (purple_account_is_connected(purple_chat_get_account(chat))) {
-			group->online--;
-			group->currentsize--;
+			priv->online--;
+			priv->currentsize--;
 		}
 	} else if(PURPLE_IS_CONTACT(child)){
 		contact = PURPLE_CONTACT(child);
 		if(purple_contact_get_online(contact) > 0)
-			group->online--;
+			priv->online--;
 		if(purple_contact_get_currentsize(contact) > 0)
-			group->currentsize--;
+			priv->currentsize--;
 	} else {
 		#warning: Is this an ok case?
 		g_warn_if_reached();
 	}
-	group->totalsize--;
+	priv->totalsize--;
 
 	parent_class->remove(child);
 
@@ -228,29 +244,51 @@ purple_group_destroy(PurpleGroup *group)
 	g_object_unref(G_OBJECT(group));
 }
 
-const char *purple_group_get_name(PurpleGroup *group)
+char *
+purple_group_get_name(const PurpleGroup *group)
 {
-	g_return_val_if_fail(group != NULL, NULL);
+	PurpleGroupPrivate *priv;
+	g_return_val_if_fail(PURPLE_IS_GROUP(group), NULL);
+	priv = PURPLE_GROUP_GET_PRIVATE(group);
 
-	return group->name;
+	return strdup(priv->name);
 }
 
-int purple_blist_get_group_size(PurpleGroup *group, gboolean offline)
+int purple_group_get_size(const PurpleGroup *group, gboolean offline)
 {
-	if (!group)
-		return 0;
+	PurpleGroupPrivate *priv;
+	g_return_val_if_fail(PURPLE_IS_GROUP(group), 0);
+	priv = PURPLE_GROUP_GET_PRIVATE(group);
 
-	return offline ? group->totalsize : group->currentsize;
+	return offline ? priv->totalsize : priv->currentsize;
 }
 
-int purple_blist_get_group_online_count(PurpleGroup *group)
+void 
+purple_group_set_online(PurpleGroup *group, int online)
 {
-	if (!group)
-		return 0;
+	PurpleGroupPrivate *priv;
+	g_return_if_fail(PURPLE_IS_GROUP(group));
+	priv = PURPLE_GROUP_GET_PRIVATE(group);
+	priv->online = online;
+}
 
-	return group->online;
+int purple_group_get_online(const PurpleGroup *group)
+{
+	PurpleGroupPrivate *priv;
+	g_return_val_if_fail(PURPLE_IS_GROUP(group), 0);
+	priv = PURPLE_GROUP_GET_PRIVATE(group);
+	return priv->online;
 }
 
+void 
+purple_group_set_currentsize(PurpleGroup *group, int currentsize)
+{
+	PurpleGroupPrivate *priv;
+	g_return_if_fail(PURPLE_IS_GROUP(group));
+	priv = PURPLE_GROUP_GET_PRIVATE(group);
+	priv->currentsize = currentsize;
+}
+
 GList *purple_group_get_buddies(PurpleGroup *group)
 {
 	GList *buddies = NULL;
@@ -269,11 +307,13 @@ GList *purple_group_get_buddies(PurpleGr
 	return buddies;
 }
 
-static void
+void
 purple_group_set_name(PurpleGroup *group, const char *name)
 {
+	PurpleGroupPrivate *priv;
 	g_return_if_fail(group != NULL);
-	group->name = purple_utf8_strip_unprintables(name);
+	priv = PURPLE_GROUP_GET_PRIVATE(group);
+	priv->name = purple_utf8_strip_unprintables(name);
 }
 
 /******************/
@@ -308,9 +348,11 @@ purple_group_finalize(GObject *object)
 static void
 purple_group_finalize(GObject *object)
 {
+	PurpleGroupPrivate *priv;
 	PurpleGroup *group = PURPLE_GROUP(object);
 	purple_signals_disconnect_by_handle(group);
-	g_free(group->name);
+	priv = PURPLE_GROUP_GET_PRIVATE(group);
+	g_free(priv->name);
 	PURPLE_DBUS_UNREGISTER_POINTER(group);
 	G_OBJECT_CLASS(parent_class)->finalize(object);
 }
@@ -333,10 +375,10 @@ purple_group_get_property(GObject *obj, 
 purple_group_get_property(GObject *obj, guint param_id, GValue *value,
 		GParamSpec *pspec)
 {
-	PurpleGroup *group = PURPLE_GROUP(obj);
+	PurpleGroupPrivate *priv = PURPLE_GROUP_GET_PRIVATE(obj);
 	switch(param_id){
 		case PROP_NAME:
-			g_value_set_string(value, purple_group_get_name(group));
+			g_value_set_string(value, priv->name);
 			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -369,12 +411,13 @@ purple_group_init(GTypeInstance *instanc
 static void
 purple_group_init(GTypeInstance *instance, gpointer class)
 {
+	PurpleGroupPrivate *priv = PURPLE_GROUP_GET_PRIVATE(instance);
 	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
 	PurpleGroup *group = PURPLE_GROUP(instance);
 
-	group->totalsize = 0;
-	group->currentsize = 0;
-	group->online = 0;
+	priv->totalsize = 0;
+	priv->currentsize = 0;
+	priv->online = 0;
 
 	if (ops && ops->new_node)
 		ops->new_node(PURPLE_BLIST_NODE(group));
============================================================
--- libpurple/group.h	b27a1d09dead92ca0dbdcfc1e8e99fc8af5668e6
+++ libpurple/group.h	17fba2a72df6431b96ad600e38928c31501b7d5c
@@ -31,6 +31,7 @@ typedef struct _PurpleGroup PurpleGroup;
 
 /** @copydoc _PurpleGroup */
 typedef struct _PurpleGroup PurpleGroup;
+typedef struct _PurpleGroupPrivate PurpleGroupPrivate;
 typedef struct _PurpleGroupClass PurpleGroupClass;
 
 #include "buddy.h"
@@ -45,22 +46,17 @@ typedef struct _PurpleGroupClass PurpleG
 #define PURPLE_IS_GROUP_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), PURPLE_GROUP_TYPE))
 #define PURPLE_GET_GROUP_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), PURPLE_GROUP_TYPE, PurpleGroupClass))
 
-#if !(defined PURPLE_HIDE_STRUCTS) || (defined _PURPLE_GROUP_C_)
 /**
  * A group.  This contains everything Purple will ever need to know about a group.
  */
 struct _PurpleGroup {
 	PurpleBlistNode node;                    /**< The node that this group inherits from */
-	char *name;                            /**< The name of this group. */
-	int totalsize;			       /**< The number of chats and contacts in this group */
-	int currentsize;		       /**< The number of chats and contacts in this group corresponding to online accounts */
-	int online;			       /**< The number of chats and contacts in this group who are currently online */
+	PurpleGroupPrivate *priv;
 };
 
 struct _PurpleGroupClass {
 	PurpleBlistNodeClass parent;
 };
-#endif
 
 /**
  * Creates a new group
@@ -101,13 +97,21 @@ gboolean purple_group_on_account(PurpleG
 gboolean purple_group_on_account(PurpleGroup *g, PurpleAccount *account);
 
 /**
+ * Set the name of this group
+ *
+ * @param group the group
+ * @param name the name to set it to
+ */
+void purple_group_set_name(PurpleGroup *group, const char *name);
+
+/**
  * Returns the name of a group.
  *
  * @param group The group.
  *
- * @return The name of the group.
+ * @return The a copy of the group name, caller is responsible for freeing it
  */
-const char *purple_group_get_name(PurpleGroup *group);
+char *purple_group_get_name(const PurpleGroup *group);
 
 /**
  * Determines the total size of a group
@@ -116,16 +120,20 @@ const char *purple_group_get_name(Purple
  * @param offline Count buddies in offline accounts
  * @return The number of buddies in the group
  */
-int purple_blist_get_group_size(PurpleGroup *group, gboolean offline);
+int purple_group_get_size(const PurpleGroup *group, gboolean offline);
 
+void purple_group_set_online(PurpleGroup *group, int online);
+
 /**
  * Determines the number of online buddies in a group
  *
  * @param group The group
  * @return The number of online buddies in the group, or 0 if the group is NULL
  */
-int purple_blist_get_group_online_count(PurpleGroup *group);
+int purple_group_get_online(const PurpleGroup *group);
 
+void purple_group_set_currentsize(PurpleGroup *group, int currentsize);
+
 /**
  * Update the counts based on a changed online/offline status of a contact
  *
============================================================
--- libpurple/protocols/bonjour/bonjour.c	463ad4832be3b7ed01efb2945adb6165fc0822b2
+++ libpurple/protocols/bonjour/bonjour.c	1334f183a54bdcdfaf2e1b3d9e8e8b938427d651
@@ -72,7 +72,7 @@ bonjour_removeallfromlocal(PurpleConnect
 				continue;
 			purple_prpl_got_user_status(account, purple_buddy_get_name(buddy), "offline", NULL);
 			purple_account_remove_buddy(account, buddy, NULL);
-			purple_blist_remove_buddy(buddy);
+			purple_blist_node_remove(PURPLE_BLIST_NODE(buddy));
 		}
 	}
 
@@ -255,7 +255,7 @@ bonjour_fake_add_buddy(PurpleConnection 
 	/* I suppose we could alert the user here, but it seems unnecessary. */
 
 	/* If this causes problems, it can be moved to an idle callback */
-	purple_blist_remove_buddy(buddy);
+	purple_blist_node_remove(PURPLE_BLIST_NODE(buddy));
 }
 
 
============================================================
--- libpurple/protocols/bonjour/buddy.c	652683463d0330f64605fbe08e06deb8f0fb6644
+++ libpurple/protocols/bonjour/buddy.c	0b363785163f652f863e430704c14826377d8e84
@@ -144,7 +144,7 @@ bonjour_buddy_add_to_purple(BonjourBuddy
 	group = purple_find_group(BONJOUR_GROUP_NAME); /* Use the buddy's domain, instead? */
 	if (group == NULL) {
 		group = purple_group_new(BONJOUR_GROUP_NAME);
-		purple_blist_add_group(group, NULL);
+		purple_blist_node_add_child(PURPLE_BLIST_NODE(group), purple_blist_get_root());
 	}
 
 	/* Make sure the buddy exists in our buddy list */
@@ -214,7 +214,7 @@ void bonjour_buddy_signed_off(PurpleBudd
 		purple_buddy_set_protocol_data(pb, NULL);
 	} else {
 		purple_account_remove_buddy(purple_buddy_get_account(pb), pb, NULL);
-		purple_blist_remove_buddy(pb);
+		purple_blist_node_remove(PURPLE_BLIST_NODE(pb));
 	}
 }
 
============================================================
--- libpurple/protocols/gg/buddylist.c	ad276922185c2ef0195b68a89687409e947bbcdd
+++ libpurple/protocols/gg/buddylist.c	a033293df04fc87a3cc71e252928e8c032a2bc49
@@ -139,7 +139,7 @@ void ggp_buddylist_load(PurpleConnection
 
 		if (!(group = purple_find_group(g))) {
 			group = purple_group_new(g);
-			purple_blist_add_group(group, NULL);
+			purple_blist_node_add_child(PURPLE_BLIST_NODE(group), purple_blist_get_root());
 		}
 
 		purple_blist_add_buddy(buddy, NULL, group, NULL);
============================================================
--- libpurple/protocols/jabber/google.c	faa6ff868271118d8c4924c6ef593ba885879384
+++ libpurple/protocols/jabber/google.c	fd065cf05b6ed602d0710d75f2a3ed21c6725e44
@@ -1026,7 +1026,7 @@ gboolean jabber_google_roster_incoming(J
 			                  jid_norm);
 
 		for ( ; buddies; buddies = g_slist_delete_link(buddies, buddies)) {
-			purple_blist_remove_buddy(buddies->data);
+			purple_blist_node_remove(PURPLE_BLIST_NODE(buddies->data));
 		}
 
 		g_free(jid_norm);
============================================================
--- libpurple/protocols/jabber/roster.c	e042e18d2140a5bdd5f6b919ed72d7e56aa6fc3a
+++ libpurple/protocols/jabber/roster.c	2f8f3ef5b166d6fc688689f134ee267c453e0215
@@ -60,7 +60,7 @@ static void remove_purple_buddies(Jabber
 	buddies = purple_find_buddies(purple_connection_get_account(js->gc), jid);
 
 	for(l = buddies; l; l = l->next)
-		purple_blist_remove_buddy(l->data);
+		purple_blist_node_remove(PURPLE_BLIST_NODE(l->data));
 
 	g_slist_free(buddies);
 }
@@ -156,7 +156,7 @@ static void add_purple_buddy_to_groups(J
 
 		if(!g) {
 			g = purple_group_new(groups->data);
-			purple_blist_add_group(g, NULL);
+			purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 		}
 
 		purple_blist_add_buddy(b, NULL, g, NULL);
@@ -176,7 +176,7 @@ static void add_purple_buddy_to_groups(J
 	 * server */
 	while (pool) {
 		PurpleBuddy *b = pool->data;
-		purple_blist_remove_buddy(b);
+		purple_blist_node_remove(PURPLE_BLIST_NODE(b));
 		pool = g_slist_delete_link(pool, pool);
 	}
 
============================================================
--- libpurple/protocols/msn/contact.c	4b30dee0c1ceabc92a85a2c8d662be77dd33af4c
+++ libpurple/protocols/msn/contact.c	43d2725993b163639ba8e7fc5ee48e257b44bace
@@ -592,7 +592,7 @@ msn_parse_addressbook_groups(MsnSession 
 		purple_debug_info("msn", "AB group_id: %s, name: %s\n", group_id, group_name ? group_name : "(null)");
 		if ((purple_find_group(group_name)) == NULL) {
 			PurpleGroup *g = purple_group_new(group_name);
-			purple_blist_add_group(g, NULL);
+			purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 		}
 		g_free(group_id);
 		g_free(group_name);
@@ -867,7 +867,7 @@ msn_parse_addressbook(MsnSession *sessio
 					  MSN_INDIVIDUALS_GROUP_ID, MSN_INDIVIDUALS_GROUP_NAME);
 	if ((purple_find_group(MSN_INDIVIDUALS_GROUP_NAME)) == NULL){
 		PurpleGroup *g = purple_group_new(MSN_INDIVIDUALS_GROUP_NAME);
-		purple_blist_add_group(g, NULL);
+		purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 	}
 
 	/*add a default No group to set up the no group Membership*/
@@ -875,7 +875,7 @@ msn_parse_addressbook(MsnSession *sessio
 	purple_debug_misc("msn", "AB group_id:%s name:%s\n", MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME);
 	if ((purple_find_group(MSN_NON_IM_GROUP_NAME)) == NULL) {
 		PurpleGroup *g = purple_group_new(MSN_NON_IM_GROUP_NAME);
-		purple_blist_add_group(g, NULL);
+		purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 	}
 
 	/*Process contact List*/
@@ -998,7 +998,7 @@ msn_add_contact_read_cb(MsnSoapMessage *
 			g_free(str);
 			msn_userlist_rem_buddy(userlist, state->who);
 			if (buddy != NULL)
-				purple_blist_remove_buddy(buddy);
+				purple_blist_node_remove(PURPLE_BLIST_NODE(buddy));
 
 		} else {
 			/* We don't know how to respond to this faultcode, so log it */
@@ -1106,7 +1106,7 @@ msn_add_contact_to_group_read_cb(MsnSoap
 			g_free(str);
 			msn_userlist_rem_buddy(userlist, state->who);
 			if (buddy != NULL)
-				purple_blist_remove_buddy(buddy);
+				purple_blist_node_remove(PURPLE_BLIST_NODE(buddy));
 
 		} else {
 			/* We don't know how to respond to this faultcode, so log it */
============================================================
--- libpurple/protocols/msn/dialog.c	ecb4903ab6b140526199a2544fdc54d964009f3e
+++ libpurple/protocols/msn/dialog.c	3438d58523793fce69cb27f7ceedb58e47c8f7f9
@@ -52,7 +52,7 @@ msn_complete_sync_issue(MsnAddRemData *d
 		buddy = purple_find_buddy(purple_connection_get_account(data->gc), data->who);
 
 	if (buddy != NULL)
-		purple_blist_remove_buddy(buddy);
+		purple_blist_node_remove(PURPLE_BLIST_NODE(buddy));
 }
 
 
============================================================
--- libpurple/protocols/msn/msn.c	09d6b123b11906d2c5e61d5d93d66ad6b9e9f2a5
+++ libpurple/protocols/msn/msn.c	1fd6bdbe0d0a8be07c5c9ade1646700d775d6423
@@ -1425,7 +1425,7 @@ add_pending_buddy(MsnSession *session,
 		g_free(buf);
 
 		/* Remove from local list */
-		purple_blist_remove_buddy(buddy);
+		purple_blist_node_remove(PURPLE_BLIST_NODE(buddy));
 		msn_user_destroy(user);
 	}
 	g_free(group);
@@ -1494,7 +1494,7 @@ cancel_auth_request(MsnAddReqData *data,
 cancel_auth_request(MsnAddReqData *data, char *msg)
 {
 	/* Remove from local list */
-	purple_blist_remove_buddy(data->buddy);
+	purple_blist_node_remove(PURPLE_BLIST_NODE(data->buddy));
 	
 	g_free(data);
 }
@@ -1515,7 +1515,7 @@ msn_add_buddy(PurpleConnection *gc, Purp
 		g_free(buf);
 
 		/* Remove from local list */
-		purple_blist_remove_buddy(buddy);
+		purple_blist_node_remove(PURPLE_BLIST_NODE(buddy));
 
 		return;
 	}
============================================================
--- libpurple/protocols/msn/session.c	f5c88b67a5858e8d16997c919d22ef4c31793d9e
+++ libpurple/protocols/msn/session.c	7a6e162ec791a0999af62cb5b785bec426ba3df2
@@ -307,7 +307,7 @@ msn_session_sync_users(MsnSession *sessi
 	}
 
 	if (to_remove != NULL) {
-		g_list_foreach(to_remove, (GFunc)purple_blist_remove_buddy, NULL);
+		g_list_foreach(to_remove, (GFunc)purple_blist_node_remove, NULL);
 		g_list_free(to_remove);
 	}
 }
============================================================
--- libpurple/protocols/msn/sync.c	fdf87d75c9c155d01b33b104a0092a263e124e68
+++ libpurple/protocols/msn/sync.c	c9e9a8255c13f028958770b786cff49f5437edb8
@@ -116,7 +116,7 @@ lsg_cmd(MsnCmdProc *cmdproc, MsnCommand 
 	if ((purple_find_group(name)) == NULL)
 	{
 		PurpleGroup *g = purple_group_new(name);
-		purple_blist_add_group(g, NULL);
+		purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 	}
 }
 
============================================================
--- libpurple/protocols/msn/user.c	3adb418b0e1f662a96a84267255cfc31b4cd80ea
+++ libpurple/protocols/msn/user.c	30a55c9eec17fd7e3147a9f96b75ca00ab9fce07
@@ -288,7 +288,7 @@ msn_user_add_group_id(MsnUser *user, con
 	if ((group_id == NULL) && (g == NULL))
 	{
 		g = purple_group_new(group_name);
-		purple_blist_add_group(g, NULL);
+		purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 	}
 
 	b = purple_find_buddy_in_group(account, passport, g);
============================================================
--- libpurple/protocols/myspace/myspace.c	f0c2ff6fd2a8901b10c342d68e2d260610008568
+++ libpurple/protocols/myspace/myspace.c	461e7b41d326f7f6c59120a9125f8dbd2976fb89
@@ -1038,7 +1038,7 @@ msim_add_contact_from_server_cb(MsimSess
 	if (!group) {
 		group = purple_group_new(group_name);
 		/* Add group to beginning. See #2752. */
-		purple_blist_add_group(group, NULL);
+		purple_blist_node_add_child(PURPLE_BLIST_NODE(group), purple_blist_get_root());
 	}
 	g_free(group_name);
 
============================================================
--- libpurple/protocols/novell/novell.c	6fa5f9421b421f395b1eb6cb1384ff7a2f49dc41
+++ libpurple/protocols/novell/novell.c	6c69599f85aa7e69e878d286b791a6f5f8586bf6
@@ -289,7 +289,7 @@ _get_details_resp_setup_buddy(NMUser * u
 		nm_contact_set_user_record(contact, user_record);
 
 		/* Set the display id */
-		purple_blist_rename_buddy(buddy,
+		purple_buddy_set_name(buddy,
 								nm_user_record_get_display_id(user_record));
 
 		alias = purple_buddy_get_alias(buddy);
@@ -1269,7 +1269,7 @@ _remove_purple_buddies(NMUser *user)
 
 	if (rem_list) {
 		for (l = rem_list; l; l = l->next) {
-			purple_blist_remove_buddy(l->data);
+			purple_blist_node_remove(PURPLE_BLIST_NODE(l->data));
 		}
 		g_slist_free(rem_list);
 	}
@@ -1301,7 +1301,7 @@ _add_contacts_to_purple_blist(NMUser * u
 	group = purple_find_group(fname);
 	if (group == NULL) {
 		group = purple_group_new(fname);
-		purple_blist_add_group(group, NULL);
+		purple_blist_node_add_child(PURPLE_BLIST_NODE(group), purple_blist_get_root());
 	}
 
 	/* Get each contact for this folder */
@@ -2571,7 +2571,7 @@ novell_add_buddy(PurpleConnection * gc, 
 	if (alias && strcmp(alias, bname))
 		nm_contact_set_display_name(contact, alias);
 
-	purple_blist_remove_buddy(buddy);
+	purple_blist_node_remove(PURPLE_BLIST_NODE(buddy));
 	buddy = NULL;
 
 	gname = purple_group_get_name(group);
============================================================
--- libpurple/protocols/oscar/oscar.c	e5ddb9eb349805ca2811a921bd3806853f649fce
+++ libpurple/protocols/oscar/oscar.c	b28bf3f32a37cf66c541e4e5a93be18d6b9dc8f3
@@ -4951,7 +4951,7 @@ oscar_add_buddy(PurpleConnection *gc, Pu
 		g_free(buf);
 
 		/* Remove from local list */
-		purple_blist_remove_buddy(buddy);
+		purple_blist_node_remove(PURPLE_BLIST_NODE(buddy));
 
 		return;
 	}
@@ -5204,7 +5204,7 @@ static int purple_ssi_parselist(OscarDat
 		while (cur != NULL) {
 			b = cur->data;
 			cur = g_slist_remove(cur, b);
-			purple_blist_remove_buddy(b);
+			purple_blist_node_remove(PURPLE_BLIST_NODE(b));
 		}
 
 		/* Permit list */
@@ -5274,7 +5274,7 @@ static int purple_ssi_parselist(OscarDat
 					g = purple_find_group(gname_utf8 ? gname_utf8 : _("Orphans"));
 					if (g == NULL) {
 						g = purple_group_new(gname_utf8 ? gname_utf8 : _("Orphans"));
-						purple_blist_add_group(g, NULL);
+						purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 					}
 
 					alias = aim_ssi_getalias(od->ssi.local, gname, curitem->name);
@@ -5337,7 +5337,7 @@ static int purple_ssi_parselist(OscarDat
 
 				if (gname_utf8 != NULL && purple_find_group(gname_utf8) == NULL) {
 					g = purple_group_new(gname_utf8);
-					purple_blist_add_group(g, NULL);
+					purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 				}
 				g_free(gname_utf8);
 			} break;
@@ -5517,7 +5517,7 @@ purple_ssi_parseaddmod(OscarData *od, Fl
 
 		if (!(g = purple_find_group(gname_utf8 ? gname_utf8 : _("Orphans")))) {
 			g = purple_group_new(gname_utf8 ? gname_utf8 : _("Orphans"));
-			purple_blist_add_group(g, NULL);
+			purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 		}
 
 		purple_debug_info("oscar",
@@ -6266,7 +6266,7 @@ static void oscar_buddycb_edit_comment(P
 
 	data = g_new(struct name_data, 1);
 
-	comment = aim_ssi_getcomment(od->ssi.local, g->name, purple_buddy_get_name(buddy));
+	comment = aim_ssi_getcomment(od->ssi.local, purple_group_get_name(g), purple_buddy_get_name(buddy));
 	comment_utf8 = comment ? oscar_utf8_try_convert(purple_connection_get_account(gc), comment) : NULL;
 
 	data->gc = gc;
============================================================
--- libpurple/protocols/qq/buddy_opt.c	23c45494a5afd3717d65b3163f97154033c11d92
+++ libpurple/protocols/qq/buddy_opt.c	97c33097617153e2684bc866b2e9044a990e7e94
@@ -81,7 +81,7 @@ PurpleGroup *qq_group_find_or_new(const 
 	g = purple_find_group(group_name);
 	if (g == NULL) {
 		g = purple_group_new(group_name);
-		purple_blist_add_group(g, NULL);
+		purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 		purple_debug_warning("QQ", "Add new group: %s\n", group_name);
 	}
 
@@ -174,7 +174,7 @@ static void qq_buddy_free(PurpleBuddy *b
 		qq_buddy_data_free(bd);
 	}
 	purple_object_set_protocol_data(PURPLE_OBJECT(buddy), NULL);
-	purple_blist_remove_buddy(buddy);
+	purple_blist_node_remove(PURPLE_BLIST_NODE(buddy));
 }
 
 PurpleBuddy *qq_buddy_find(PurpleConnection *gc, guint32 uid)
============================================================
--- libpurple/protocols/qq/group_internal.c	807f08e0a7313de3bfdb5619817c44d7dbad53fc
+++ libpurple/protocols/qq/group_internal.c	2bc8fa9272a5d74d686d1c47d72915a3e373f83c
@@ -205,7 +205,7 @@ void qq_room_remove(PurpleConnection *gc
 
 	g_return_if_fail (chat != NULL);
 
-	purple_blist_remove_chat(chat);
+	purple_blist_node_remove(PURPLE_BLIST_NODE(chat));
 }
 
 /* find a qq_buddy_data by uid, called by im.c */
============================================================
--- libpurple/protocols/simple/simple.c	5772ac9f65a148259f396e7384d2fda2faffdf55
+++ libpurple/protocols/simple/simple.c	8d32011a17329b793021622d5e169500a48f3afa
@@ -199,7 +199,7 @@ static void simple_add_buddy(PurpleConne
 	const char *name = purple_buddy_get_name(buddy);
 	if(strncmp(name, "sip:", 4)) {
 		gchar *buf = g_strdup_printf("sip:%s", name);
-		purple_blist_rename_buddy(buddy, buf);
+		purple_buddy_set_name(buddy, buf);
 		g_free(buf);
 	}
 	if(!g_hash_table_lookup(sip->buddies, name)) {
============================================================
--- libpurple/protocols/yahoo/libymsg.c	deeda0808c1dee3f4ba1e07b16f33c0aa77d3830
+++ libpurple/protocols/yahoo/libymsg.c	5fb7ac7b058cb32109f99fa5f9d4fbafc5f86d2b
@@ -407,7 +407,7 @@ static void yahoo_do_group_check(PurpleA
 			"Uhoh, %s isn't on the list (or not in this group), adding him to group %s.\n", name, group);
 		if (!(g = purple_find_group(group))) {
 			g = purple_group_new(group);
-			purple_blist_add_group(g, NULL);
+			purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 		}
 		b = purple_buddy_new(account, name, NULL);
 		purple_blist_add_buddy(b, NULL, g, NULL);
@@ -433,7 +433,7 @@ static void yahoo_do_group_cleanup(gpoin
 		g = purple_buddy_get_group(b);
 		purple_debug_misc("yahoo", "Deleting Buddy %s from group %s.\n", name,
 				purple_group_get_name(g));
-		purple_blist_remove_buddy(b);
+		purple_blist_node_remove(PURPLE_BLIST_NODE(b));
 	}
 }
 
@@ -522,7 +522,7 @@ static void yahoo_process_list_15(Purple
 					if (!(b = purple_find_buddy(account, norm_bud))) {
 						if (!(g = purple_find_group(yd->current_list15_grp))) {
 							g = purple_group_new(yd->current_list15_grp);
-							purple_blist_add_group(g, NULL);
+							purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 						}
 						b = purple_buddy_new(account, norm_bud, NULL);
 						purple_blist_add_buddy(b, NULL, g, NULL);
@@ -679,7 +679,7 @@ static void yahoo_process_list(PurpleCon
 				if (!(b = purple_find_buddy(account, norm_bud))) {
 					if (!(g = purple_find_group(grp))) {
 						g = purple_group_new(grp);
-						purple_blist_add_group(g, NULL);
+						purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 					}
 					b = purple_buddy_new(account, norm_bud, NULL);
 					purple_blist_add_buddy(b, NULL, g, NULL);
@@ -1945,7 +1945,7 @@ static void ignore_buddy(PurpleBuddy *bu
 
 	purple_debug_info("yahoo", "blist: Removing '%s' from buddy list.\n", name);
 	purple_account_remove_buddy(account, buddy, group);
-	purple_blist_remove_buddy(buddy);
+	purple_blist_node_remove(PURPLE_BLIST_NODE(buddy));
 
 	serv_add_deny(purple_account_get_connection(account), name);
 
============================================================
--- libpurple/protocols/zephyr/zephyr.c	8adcbaec770255ac6ca7f8bef96d27763c1dbbdd
+++ libpurple/protocols/zephyr/zephyr.c	0b74e5dbc48b97cc48fcd4aad627667c7faa2a90
@@ -1506,7 +1506,7 @@ static void process_anyone(PurpleConnect
 
 	if (!(g = purple_find_group(_("Anyone")))) {
 		g = purple_group_new(_("Anyone"));
-		purple_blist_add_group(g, NULL);
+		purple_blist_node_add_child(PURPLE_BLIST_NODE(g), purple_blist_get_root());
 	}
 
 	filename = g_strconcat(purple_home_dir(), "/.anyone", NULL);


More information about the Commits mailing list