diff --git a/libpurple/protocols/bonjour/bonjour.h b/libpurple/protocols/bonjour/bonjour.h
deleted file mode 100644
--- a/libpurple/protocols/bonjour/bonjour.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file bonjour.h The Purple interface to mDNS and peer to peer XMPP.
- *
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- *
- */
-
-#ifndef PURPLE_BONJOUR_BONJOUR_H
-#define PURPLE_BONJOUR_BONJOUR_H
-
-#include <gmodule.h>
-
-#include <purple.h>
-
-#include "mdns_common.h"
-#include "xmpp.h"
-
-#define BONJOUR_GROUP_NAME (bonjour_get_group_name())
-#define BONJOUR_PROTOCOL_NAME "bonjour"
-
-#define BONJOUR_STATUS_ID_OFFLINE   "offline"
-#define BONJOUR_STATUS_ID_AVAILABLE "available"
-#define BONJOUR_STATUS_ID_AWAY      "away"
-
-#define BONJOUR_DEFAULT_PORT 5298
-
-#define BONJOUR_DOMAIN (g_quark_from_static_string("bonjour"))
-
-#define BONJOUR_TYPE_PROTOCOL (bonjour_protocol_get_type())
-
-G_MODULE_EXPORT
-G_DECLARE_FINAL_TYPE(BonjourProtocol, bonjour_protocol, BONJOUR, PROTOCOL,
-                     PurpleProtocol)
-
-typedef struct
-{
-	BonjourDnsSd *dns_sd_data;
-	BonjourXMPP *xmpp_data;
-	GSList *xfer_lists;
-	gchar *jid;
-} BonjourData;
-
-/**
- *  This will always be username@machinename
- */
-const char *bonjour_get_jid(PurpleAccount *account);
-
-const gchar *bonjour_get_group_name(void);
-
-#endif /* PURPLE_BONJOUR_BONJOUR_H */
# HG changeset patch
# Node ID 12dcbd792fa3
# Parent  6d41b29637ef
diff --git a/libpurple/protocols/bonjour/bonjour.c b/libpurple/protocols/bonjour/bonjour.c
deleted file mode 100644
--- a/libpurple/protocols/bonjour/bonjour.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- * purple - Bonjour Protocol Plugin
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- */
-
-#include <glib/gi18n-lib.h>
-
-#include <glib.h>
-#ifndef _WIN32
-#include <pwd.h>
-#else
-#define UNICODE
-#include <winsock2.h>
-#include <windows.h>
-#include <lm.h>
-#endif
-
-#include <gplugin.h>
-#include <gplugin-native.h>
-
-#include <purple.h>
-
-#include "bonjour.h"
-#include "mdns_common.h"
-#include "buddy.h"
-#include "bonjour_ft.h"
-#include "xmpp.h"
-
-struct _BonjourProtocol {
-	PurpleProtocol parent;
-};
-
-static PurpleProtocol *my_protocol = NULL;
-
-static char *default_firstname;
-static char *default_lastname;
-
-const char *
-bonjour_get_jid(PurpleAccount *account)
-{
-	PurpleConnection *conn = purple_account_get_connection(account);
-	BonjourData *bd = purple_connection_get_protocol_data(conn);
-	return bd->jid;
-}
-
-const gchar *
-bonjour_get_group_name(void) {
-	return _("Bonjour");
-}
-
-static void
-bonjour_removeallfromlocal(PurpleConnection *conn, PurpleGroup *bonjour_group)
-{
-	PurpleAccount *account = purple_connection_get_account(conn);
-	PurpleBlistNode *cnode, *cnodenext, *bnode, *bnodenext;
-	PurpleBuddy *buddy;
-
-	if (bonjour_group == NULL)
-		return;
-
-	/* Go through and remove all buddies that belong to this account */
-	for (cnode = purple_blist_node_get_first_child((PurpleBlistNode *) bonjour_group); cnode; cnode = cnodenext) {
-		cnodenext = purple_blist_node_get_sibling_next(cnode);
-		if (!PURPLE_IS_META_CONTACT(cnode))
-			continue;
-		for (bnode = purple_blist_node_get_first_child(cnode); bnode; bnode = bnodenext) {
-			bnodenext = purple_blist_node_get_sibling_next(bnode);
-			if (!PURPLE_IS_BUDDY(bnode))
-				continue;
-			buddy = (PurpleBuddy *) bnode;
-			if (purple_buddy_get_account(buddy) != account)
-				continue;
-			purple_account_remove_buddy(account, buddy, NULL);
-			purple_blist_remove_buddy(buddy);
-		}
-	}
-
-}
-
-static void
-bonjour_login(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleAccount *account) {
-	PurpleConnection *gc = purple_account_get_connection(account);
-	BonjourData *bd;
-	PurpleStatus *status;
-	PurplePresence *presence;
-
-	if (!mdns_available()) {
-		purple_connection_error(gc,
-				PURPLE_CONNECTION_ERROR_OTHER_ERROR,
-				_("Unable to find Apple's \"Bonjour for Windows\" toolkit, see "
-				  "https://developer.pidgin.im/BonjourWindows for more information."));
-		return;
-	}
-
-	purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_HTML |
-		PURPLE_CONNECTION_FLAG_NO_IMAGES);
-	bd = g_new0(BonjourData, 1);
-	purple_connection_set_protocol_data(gc, bd);
-
-	/* Start waiting for xmpp connections (iChat style) */
-	bd->xmpp_data = g_new0(BonjourXMPP, 1);
-	bd->xmpp_data->port = purple_account_get_int(account, "port", BONJOUR_DEFAULT_PORT);
-	bd->xmpp_data->account = account;
-
-	if (bonjour_xmpp_start(bd->xmpp_data) == -1) {
-		/* Send a message about the connection error */
-		purple_connection_error (gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Unable to listen for incoming IM connections"));
-		return;
-	}
-
-	/* Connect to the mDNS daemon looking for buddies in the LAN */
-	bd->dns_sd_data = bonjour_dns_sd_new();
-	bd->dns_sd_data->first = g_strdup(purple_account_get_string(account, "first", default_firstname));
-	bd->dns_sd_data->last = g_strdup(purple_account_get_string(account, "last", default_lastname));
-	bd->dns_sd_data->port_p2pj = bd->xmpp_data->port;
-	/* Not engaged in AV conference */
-	bd->dns_sd_data->vc = g_strdup("!");
-
-	status = purple_account_get_active_status(account);
-	presence = purple_account_get_presence(account);
-	if (purple_presence_is_available(presence))
-		bd->dns_sd_data->status = g_strdup("avail");
-	else if (purple_presence_is_idle(presence))
-		bd->dns_sd_data->status = g_strdup("away");
-	else
-		bd->dns_sd_data->status = g_strdup("dnd");
-	bd->dns_sd_data->msg = g_strdup(purple_status_get_attr_string(status, "message"));
-
-	bd->dns_sd_data->account = account;
-	if (!bonjour_dns_sd_start(bd->dns_sd_data))
-	{
-		purple_connection_error (gc,
-			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-			_("Unable to establish connection with the local mDNS server.  Is it running?"));
-		return;
-	}
-
-	bonjour_dns_sd_update_buddy_icon(bd->dns_sd_data);
-
-	/* Show the buddy list by telling Purple we have already connected */
-	purple_connection_set_state(gc, PURPLE_CONNECTION_STATE_CONNECTED);
-}
-
-static void
-bonjour_close(G_GNUC_UNUSED PurpleProtocol *protocol,
-              PurpleConnection *connection)
-{
-	PurpleGroup *bonjour_group;
-	BonjourData *bd = purple_connection_get_protocol_data(connection);
-
-	bonjour_group = purple_blist_find_group(BONJOUR_GROUP_NAME);
-
-	/* Remove all the bonjour buddies */
-	bonjour_removeallfromlocal(connection, bonjour_group);
-
-	/* Stop looking for buddies in the LAN */
-	if (bd != NULL && bd->dns_sd_data != NULL)
-	{
-		bonjour_dns_sd_stop(bd->dns_sd_data);
-		bonjour_dns_sd_free(bd->dns_sd_data);
-	}
-
-	if (bd != NULL && bd->xmpp_data != NULL)
-	{
-		/* Stop waiting for conversations */
-		bonjour_xmpp_stop(bd->xmpp_data);
-		g_free(bd->xmpp_data);
-	}
-
-	/* Delete the bonjour group
-	 * (purple_blist_remove_group will bail out if the group isn't empty)
-	 */
-	if (bonjour_group != NULL)
-		purple_blist_remove_group(bonjour_group);
-
-	/* Cancel any file transfers */
-	while (bd != NULL && bd->xfer_lists) {
-		purple_xfer_cancel_local(bd->xfer_lists->data);
-	}
-
-	if (bd != NULL)
-		g_free(bd->jid);
-	g_free(bd);
-	purple_connection_set_protocol_data(connection, NULL);
-}
-
-static GList *
-bonjour_protocol_get_account_options(G_GNUC_UNUSED PurpleProtocol *protocol) {
-	PurpleAccountOption *option;
-	GList *opts = NULL;
-
-	/* Creating the options for the protocol */
-	option = purple_account_option_int_new(_("Local Port"), "port",
-	                                       BONJOUR_DEFAULT_PORT);
-	opts = g_list_append(opts, option);
-
-	option = purple_account_option_string_new(_("First name"), "first",
-	                                          default_firstname);
-	opts = g_list_append(opts, option);
-
-	option = purple_account_option_string_new(_("Last name"), "last",
-	                                          default_lastname);
-	opts = g_list_append(opts, option);
-
-	option = purple_account_option_string_new(_("Email"), "email", "");
-	opts = g_list_append(opts, option);
-
-	option = purple_account_option_string_new(_("AIM Account"), "AIM", "");
-	opts = g_list_append(opts, option);
-
-	option = purple_account_option_string_new(_("XMPP Account"), "jid", "");
-	opts = g_list_append(opts, option);
-
-	return opts;
-}
-
-static PurpleBuddyIconSpec *
-bonjour_protocol_get_buddy_icon_spec(G_GNUC_UNUSED PurpleProtocol *protocol) {
-	return purple_buddy_icon_spec_new("png,gif,jpeg",
-	                                  0, 0, 96, 96, 65535,
-	                                  PURPLE_ICON_SCALE_DISPLAY);
-}
-
-static void
-bonjour_conversation_send_message_async(PurpleProtocolConversation *protocol,
-                                        PurpleConversation *conversation,
-                                        PurpleMessage *message,
-                                        GCancellable *cancellable,
-                                        GAsyncReadyCallback callback,
-                                        gpointer data)
-{
-	GTask *task = NULL;
-	const char *target = NULL;
-
-	task = g_task_new(protocol, cancellable, callback, data);
-
-	target = purple_conversation_get_name(conversation);
-	if(purple_strempty(target)) {
-		target = purple_message_get_recipient(message);
-	}
-
-	if(purple_message_is_empty(message) || purple_strempty(target)) {
-		g_task_return_boolean(task, TRUE);
-	} else {
-		BonjourData *bd = NULL;
-		PurpleAccount *account = NULL;
-		PurpleConnection *connection = NULL;
-		int result = 0;
-
-		account = purple_conversation_get_account(conversation);
-		connection = purple_account_get_connection(account);
-		bd = purple_connection_get_protocol_data(connection);
-
-		result = bonjour_xmpp_send_message(bd->xmpp_data, target,
-		                                   purple_message_get_contents(message));
-
-		purple_conversation_write_message(conversation, message);
-
-		if(result >= 0) {
-			g_task_return_boolean(task, TRUE);
-		} else {
-			g_task_return_new_error(task, BONJOUR_DOMAIN, 0, "unknown error");
-		}
-	}
-
-	g_clear_object(&task);
-}
-
-static gboolean
-bonjour_conversation_send_message_finish(G_GNUC_UNUSED PurpleProtocolConversation *protocol,
-                                         GAsyncResult *result,
-                                         GError **error)
-{
-	return g_task_propagate_boolean(G_TASK(result), error);
-}
-
-static void
-bonjour_set_status(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                   PurpleAccount *account, PurpleStatus *status)
-{
-	PurpleConnection *gc;
-	BonjourData *bd;
-	PurplePresence *presence;
-	const char *message, *bonjour_status;
-	gchar *stripped;
-
-	gc = purple_account_get_connection(account);
-	bd = purple_connection_get_protocol_data(gc);
-	presence = purple_account_get_presence(account);
-
-	message = purple_status_get_attr_string(status, "message");
-	if (message == NULL)
-		message = "";
-	stripped = purple_markup_strip_html(message);
-
-	/*
-	 * The three possible status for Bonjour are
-	 *   -available ("avail")
-	 *   -idle ("away")
-	 *   -away ("dnd")
-	 * Each of them can have an optional message.
-	 */
-	if (purple_presence_is_available(presence))
-		bonjour_status = "avail";
-	else if (purple_presence_is_idle(presence))
-		bonjour_status = "away";
-	else
-		bonjour_status = "dnd";
-
-	bonjour_dns_sd_send_status(bd->dns_sd_data, bonjour_status, stripped);
-	g_free(stripped);
-}
-
-/*
- * The add_buddy callback removes the buddy from the local list.
- * Bonjour manages buddies for you, and adding someone locally by
- * hand is stupid.  Perhaps we should change libpurple not to allow adding
- * if there is no add_buddy callback.
- */
-static void
-bonjour_fake_add_buddy(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                       G_GNUC_UNUSED PurpleConnection *connection,
-                       PurpleBuddy *buddy,
-                       G_GNUC_UNUSED PurpleGroup *group,
-                       G_GNUC_UNUSED const gchar *message)
-{
-	purple_debug_error("bonjour", "Buddy '%s' manually added; removing.  "
-				      "Bonjour buddies must be discovered and not manually added.\n",
-			   purple_buddy_get_name(buddy));
-
-	/* 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);
-}
-
-
-static void
-bonjour_remove_buddy(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                     G_GNUC_UNUSED PurpleConnection *connection,
-                     PurpleBuddy *buddy,
-                     G_GNUC_UNUSED PurpleGroup *group)
-{
-	BonjourBuddy *bb = purple_buddy_get_protocol_data(buddy);
-	if (bb) {
-		bonjour_buddy_delete(bb);
-		purple_buddy_set_protocol_data(buddy, NULL);
-	}
-}
-
-static GList *
-bonjour_status_types(G_GNUC_UNUSED PurpleProtocol *protocol,
-                     PurpleAccount *account)
-{
-	GList *status_types = NULL;
-	PurpleStatusType *type;
-
-	g_return_val_if_fail(account != NULL, NULL);
-
-	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
-										   BONJOUR_STATUS_ID_AVAILABLE,
-										   NULL, TRUE, TRUE, FALSE,
-										   "message", _("Message"),
-										   purple_value_new(G_TYPE_STRING), NULL);
-	status_types = g_list_append(status_types, type);
-
-	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
-										   BONJOUR_STATUS_ID_AWAY,
-										   NULL, TRUE, TRUE, FALSE,
-										   "message", _("Message"),
-										   purple_value_new(G_TYPE_STRING), NULL);
-	status_types = g_list_append(status_types, type);
-
-	type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE,
-									 BONJOUR_STATUS_ID_OFFLINE,
-									 NULL, TRUE, TRUE, FALSE);
-	status_types = g_list_append(status_types, type);
-
-	return status_types;
-}
-
-static void
-bonjour_convo_closed(G_GNUC_UNUSED PurpleProtocolClient *client,
-                     PurpleConnection *connection, const char *who)
-{
-	PurpleAccount *account = NULL;
-	PurpleContact *contact = NULL;
-	PurpleContactManager *manager = NULL;
-	BonjourBuddy *bb;
-
-	account = purple_connection_get_account(connection);
-	manager = purple_contact_manager_get_default();
-	contact = purple_contact_manager_find_with_username(manager, account, who);
-
-	if(!PURPLE_IS_CONTACT(contact) ||
-	   (bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy")) == NULL)
-	{
-		/*
-		 * This buddy is not in our buddy list, and therefore does not really
-		 * exist, so we won't have any data about them.
-		 */
-		g_clear_object(&contact);
-
-		return;
-	}
-
-	bonjour_xmpp_close_conversation(bb->conversation);
-	bb->conversation = NULL;
-	g_clear_object(&contact);
-}
-
-static void
-bonjour_set_buddy_icon(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                       PurpleConnection *conn,
-                       G_GNUC_UNUSED PurpleImage *img)
-{
-	BonjourData *bd = purple_connection_get_protocol_data(conn);
-	bonjour_dns_sd_update_buddy_icon(bd->dns_sd_data);
-}
-
-static void
-bonjour_do_group_change(PurpleBuddy *buddy, const char *new_group)
-{
-	if (buddy == NULL)
-		return;
-
-	/* If we're moving them out of the bonjour group, make them persistent */
-	if (purple_strequal(new_group, BONJOUR_GROUP_NAME))
-		purple_blist_node_set_transient(PURPLE_BLIST_NODE(buddy), TRUE);
-	else
-		purple_blist_node_set_transient(PURPLE_BLIST_NODE(buddy),
-				!purple_blist_node_is_transient(PURPLE_BLIST_NODE(buddy)));
-
-}
-
-static void
-bonjour_group_buddy(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                    PurpleConnection *connection, const char *who,
-                    G_GNUC_UNUSED const char *old_group, const char *new_group)
-{
-	PurpleBuddy *buddy = purple_blist_find_buddy(purple_connection_get_account(connection), who);
-
-	bonjour_do_group_change(buddy, new_group);
-}
-
-static void
-bonjour_rename_group(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                     G_GNUC_UNUSED PurpleConnection *connection,
-                     G_GNUC_UNUSED const char *old_name, PurpleGroup *group,
-                     GList *moved_buddies)
-{
-	const gchar *new_group;
-
-	new_group = purple_group_get_name(group);
-
-	g_list_foreach(moved_buddies, (GFunc)bonjour_do_group_change, (gpointer)new_group);
-}
-
-static gboolean
-bonjour_can_receive_file(G_GNUC_UNUSED PurpleProtocolXfer *prplxfer,
-                         PurpleConnection *connection, const char *who)
-{
-	PurpleAccount *account = NULL;
-	PurpleContact *contact = NULL;
-	PurpleContactManager *manager = NULL;
-	gboolean ret = FALSE;
-
-	account = purple_connection_get_account(connection);
-	manager = purple_contact_manager_get_default();
-	contact = purple_contact_manager_find_with_username(manager, account, who);
-
-	if(PURPLE_IS_CONTACT(contact)) {
-		BonjourBuddy *bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-
-		ret = (bb != NULL);
-	}
-
-	g_clear_object(&contact);
-
-	return ret;
-}
-
-static gssize
-bonjour_get_max_message_size(G_GNUC_UNUSED PurpleProtocolClient *client,
-                             G_GNUC_UNUSED PurpleConversation *conv)
-{
-	return -1; /* 5MB successfully tested. */
-}
-
-#ifdef WIN32
-static void
-_set_default_name_cb(G_GNUC_UNUSED GObject *source, GAsyncResult *result,
-                     G_GNUC_UNUSED gpointer data)
-{
-	gchar *fullname = NULL;
-	const char *splitpoint;
-	GError *error = NULL;
-
-	fullname = g_task_propagate_pointer(G_TASK(result), &error);
-	if (fullname == NULL) {
-		purple_debug_info("bonjour",
-		                  "Unable to look up First and Last name or Username "
-		                  "from system (%s); using defaults.",
-		                  error ? error->message : "unknown reason");
-		g_clear_error(&error);
-		return;
-	}
-
-	g_free(default_firstname);
-	g_free(default_lastname);
-
-	/* Split the real name into a first and last name */
-	splitpoint = strchr(fullname, ' ');
-	if (splitpoint != NULL) {
-		default_firstname = g_strndup(fullname, splitpoint - fullname);
-		default_lastname = g_strdup(&splitpoint[1]);
-	} else {
-		default_firstname = g_strdup(fullname);
-		default_lastname = g_strdup("");
-	}
-	g_free(fullname);
-}
-
-static void
-_win32_name_lookup_thread(GTask *task, G_GNUC_UNUSED gpointer source,
-                          G_GNUC_UNUSED gpointer data,
-                          G_GNUC_UNUSED GCancellable *cancellable)
-{
-	gchar *fullname = NULL;
-	wchar_t username[UNLEN + 1];
-	DWORD dwLenUsername = UNLEN + 1;
-
-	GetUserNameW((LPWSTR) &username, &dwLenUsername);
-
-	if (*username != '\0') {
-		LPBYTE servername = NULL;
-		LPBYTE info = NULL;
-
-		NetGetDCName(NULL, NULL, &servername);
-
-		/* purple_debug_info("bonjour", "Looking up the full name from the %s.\n", (servername ? "domain controller" : "local machine")); */
-
-		if (NetUserGetInfo((LPCWSTR) servername, username, 10, &info) == NERR_Success
-				&& info != NULL && ((LPUSER_INFO_10) info)->usri10_full_name != NULL
-				&& *(((LPUSER_INFO_10) info)->usri10_full_name) != '\0') {
-			fullname = g_utf16_to_utf8(
-				((LPUSER_INFO_10) info)->usri10_full_name,
-				-1, NULL, NULL, NULL);
-		}
-		/* Fall back to the local machine if we didn't get the full name from the domain controller */
-		else if (servername != NULL) {
-			/* purple_debug_info("bonjour", "Looking up the full name from the local machine"); */
-
-			if (info != NULL) NetApiBufferFree(info);
-			info = NULL;
-
-			if (NetUserGetInfo(NULL, username, 10, &info) == NERR_Success
-					&& info != NULL && ((LPUSER_INFO_10) info)->usri10_full_name != NULL
-					&& *(((LPUSER_INFO_10) info)->usri10_full_name) != '\0') {
-				fullname = g_utf16_to_utf8(
-					((LPUSER_INFO_10) info)->usri10_full_name,
-					-1, NULL, NULL, NULL);
-			}
-		}
-
-		if (info != NULL) NetApiBufferFree(info);
-		if (servername != NULL) NetApiBufferFree(servername);
-
-		if (!fullname)
-			fullname = g_utf16_to_utf8(username, -1, NULL, NULL, NULL);
-	}
-
-	g_task_return_pointer(task, fullname, g_free);
-}
-#endif
-
-static void
-initialize_default_account_values(void)
-{
-#ifndef _WIN32
-	struct passwd *info;
-#else
-	GTask *lookup;
-#endif
-	const char *fullname = NULL, *splitpoint, *tmp;
-	gchar *conv = NULL;
-
-#ifndef _WIN32
-	/* Try to figure out the user's real name */
-	info = getpwuid(getuid());
-	if ((info != NULL) && (info->pw_gecos != NULL) && (info->pw_gecos[0] != '\0'))
-		fullname = info->pw_gecos;
-	else if ((info != NULL) && (info->pw_name != NULL) && (info->pw_name[0] != '\0'))
-		fullname = info->pw_name;
-	else if (((fullname = getlogin()) != NULL) && (fullname[0] == '\0'))
-		fullname = NULL;
-#else
-	/* The Win32 username lookup functions are synchronous so we do it in a thread */
-	lookup = g_task_new(my_protocol, NULL, _set_default_name_cb, NULL);
-	g_task_run_in_thread(lookup, _win32_name_lookup_thread);
-	g_object_unref(lookup);
-#endif
-
-	/* Make sure fullname is valid UTF-8.  If not, try to convert it. */
-	if (fullname != NULL && !g_utf8_validate(fullname, -1, NULL)) {
-		fullname = conv = g_locale_to_utf8(fullname, -1, NULL, NULL, NULL);
-		if (conv == NULL || *conv == '\0')
-			fullname = NULL;
-	}
-
-	if (fullname == NULL)
-		fullname = _("Purple Person");
-
-	/* Split the real name into a first and last name */
-	splitpoint = strchr(fullname, ' ');
-	if (splitpoint != NULL) {
-		default_firstname = g_strndup(fullname, splitpoint - fullname);
-		tmp = &splitpoint[1];
-
-		/* The last name may be followed by a comma and additional data.
-		 * Only use the last name itself.
-		 */
-		splitpoint = strchr(tmp, ',');
-		if (splitpoint != NULL)
-			default_lastname = g_strndup(tmp, splitpoint - tmp);
-		else
-			default_lastname = g_strdup(tmp);
-	} else {
-		default_firstname = g_strdup(fullname);
-		default_lastname = g_strdup("");
-	}
-
-	g_free(conv);
-}
-
-static void
-bonjour_protocol_init(G_GNUC_UNUSED BonjourProtocol *self)
-{
-}
-
-static void
-bonjour_protocol_class_init(BonjourProtocolClass *klass)
-{
-	PurpleProtocolClass *protocol_class = PURPLE_PROTOCOL_CLASS(klass);
-
-	protocol_class->login = bonjour_login;
-	protocol_class->close = bonjour_close;
-	protocol_class->status_types = bonjour_status_types;
-
-	protocol_class->get_account_options = bonjour_protocol_get_account_options;
-	protocol_class->get_buddy_icon_spec = bonjour_protocol_get_buddy_icon_spec;
-}
-
-static void
-bonjour_protocol_class_finalize(G_GNUC_UNUSED BonjourProtocolClass *klass)
-{
-}
-
-static void
-bonjour_protocol_client_iface_init(PurpleProtocolClientInterface *client_iface)
-{
-	client_iface->convo_closed         = bonjour_convo_closed;
-	client_iface->get_max_message_size = bonjour_get_max_message_size;
-}
-
-static void
-bonjour_protocol_server_iface_init(PurpleProtocolServerInterface *server_iface)
-{
-	server_iface->add_buddy      = bonjour_fake_add_buddy;
-	server_iface->remove_buddy   = bonjour_remove_buddy;
-	server_iface->group_buddy    = bonjour_group_buddy;
-	server_iface->rename_group   = bonjour_rename_group;
-	server_iface->set_buddy_icon = bonjour_set_buddy_icon;
-	server_iface->set_status     = bonjour_set_status;
-}
-
-static void
-bonjour_protocol_conversation_iface_init(PurpleProtocolConversationInterface *iface)
-{
-	iface->send_message_async = bonjour_conversation_send_message_async;
-	iface->send_message_finish = bonjour_conversation_send_message_finish;
-}
-
-static void
-bonjour_protocol_xfer_iface_init(PurpleProtocolXferInterface *xfer_iface)
-{
-	xfer_iface->can_receive = bonjour_can_receive_file;
-	xfer_iface->send_file   = bonjour_send_file;
-	xfer_iface->new_xfer    = bonjour_new_xfer;
-}
-
-G_DEFINE_DYNAMIC_TYPE_EXTENDED(
-	BonjourProtocol,
-	bonjour_protocol,
-	PURPLE_TYPE_PROTOCOL,
-	G_TYPE_FLAG_FINAL,
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_CLIENT,
-	                              bonjour_protocol_client_iface_init)
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_SERVER,
-	                              bonjour_protocol_server_iface_init)
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_CONVERSATION,
-	                              bonjour_protocol_conversation_iface_init)
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_XFER,
-	                              bonjour_protocol_xfer_iface_init))
-
-static PurpleProtocol *
-bonjour_protocol_new(void) {
-	return g_object_new(
-		BONJOUR_TYPE_PROTOCOL,
-		"id", "prpl-bonjour",
-		"name", "Bonjour (Deprecated)",
-		"description", _("Bonjour is a serverless protocol for local "
-		                 "networks."),
-		"icon-name", "im-bonjour",
-		"icon-resource-path", "/im/pidgin/libpurple/bonjour/icons",
-		"options", OPT_PROTO_NO_PASSWORD,
-		NULL);
-}
-
-static GPluginPluginInfo *
-bonjour_query(G_GNUC_UNUSED GError **error)
-{
-	return purple_plugin_info_new(
-		"id",           "prpl-bonjour",
-		"name",         "Bonjour Protocol",
-		"version",      DISPLAY_VERSION,
-		"category",     N_("Protocol"),
-		"summary",      N_("Bonjour Protocol Plugin"),
-		"description",  N_("Bonjour Protocol Plugin"),
-		"website",      PURPLE_WEBSITE,
-		"abi-version",  PURPLE_ABI_VERSION,
-		"flags",        PURPLE_PLUGIN_INFO_FLAGS_INTERNAL |
-		                PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD,
-		NULL
-	);
-}
-
-static gboolean
-bonjour_load(GPluginPlugin *plugin, GError **error)
-{
-	PurpleProtocolManager *manager = purple_protocol_manager_get_default();
-
-	bonjour_protocol_register_type(G_TYPE_MODULE(plugin));
-
-	xep_xfer_register(G_TYPE_MODULE(plugin));
-
-	my_protocol = bonjour_protocol_new();
-	if(!purple_protocol_manager_register(manager, my_protocol, error)) {
-		g_clear_object(&my_protocol);
-
-		return FALSE;
-	}
-
-	initialize_default_account_values();
-
-	return TRUE;
-}
-
-static gboolean
-bonjour_unload(G_GNUC_UNUSED GPluginPlugin *plugin,
-               G_GNUC_UNUSED gboolean shutdown, GError **error)
-{
-	PurpleProtocolManager *manager = purple_protocol_manager_get_default();
-
-	if(!purple_protocol_manager_unregister(manager, my_protocol, error)) {
-		return FALSE;
-	}
-
-	g_clear_object(&my_protocol);
-
-	g_free(default_firstname);
-	g_free(default_lastname);
-
-	return TRUE;
-}
-
-GPLUGIN_NATIVE_PLUGIN_DECLARE(bonjour)
diff --git a/libpurple/protocols/bonjour/bonjour_ft.h b/libpurple/protocols/bonjour/bonjour_ft.h
deleted file mode 100644
--- a/libpurple/protocols/bonjour/bonjour_ft.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * purple - Bonjour Protocol Plugin
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA
- */
-#ifndef PURPLE_BONJOUR_BONJOUR_FT_H
-#define PURPLE_BONJOUR_BONJOUR_FT_H
-
-#include <purple.h>
-
-G_BEGIN_DECLS
-
-#define XEP_TYPE_XFER (xep_xfer_get_type())
-G_DECLARE_FINAL_TYPE(XepXfer, xep_xfer, XEP, XFER, PurpleXfer);
-
-typedef enum {
-	XEP_BYTESTREAMS = 1,
-	XEP_IBB = 2,
-	XEP_UNKNOWN = 4
-} XepSiMode;
-
-/**
- * Create a new PurpleXfer
- *
- * @param gc The PurpleConnection handle.
- * @param who Who will we be sending it to?
- */
-PurpleXfer *bonjour_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who);
-
-/**
- * Send a file.
- *
- * @param gc The PurpleConnection handle.
- * @param who Who are we sending it to?
- * @param file What file? If NULL, user will choose after this call.
- */
-void bonjour_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who, const char *file);
-
-void xep_si_parse(PurpleConnection *pc, PurpleXmlNode *packet, PurpleContact *contact);
-void xep_bytestreams_parse(PurpleConnection *pc, PurpleXmlNode *packet, PurpleContact *contact);
-
-void xep_xfer_register(GTypeModule *module);
-
-G_END_DECLS
-
-#endif /* PURPLE_BONJOUR_BONJOUR_FT_H */
diff --git a/libpurple/protocols/bonjour/bonjour_ft.c b/libpurple/protocols/bonjour/bonjour_ft.c
deleted file mode 100644
--- a/libpurple/protocols/bonjour/bonjour_ft.c
+++ /dev/null
@@ -1,1228 +0,0 @@
-/*
- * purple - Bonjour Protocol Plugin
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA
- */
-
-#include <purpleconfig.h>
-
-#include <sys/types.h>
-
-#include <purple.h>
-
-#include "bonjour.h"
-#include "bonjour_ft.h"
-
-static void
-bonjour_bytestreams_init(PurpleXfer *xfer);
-static void
-bonjour_bytestreams_connect(PurpleXfer *xfer);
-static void
-bonjour_xfer_init(PurpleXfer *xfer);
-static void
-bonjour_xfer_receive(PurpleConnection *pc, const char *id, const char *sid, const char *from,
-		     goffset filesize, const char *filename, int option);
-
-/* Look for specific xfer handle */
-static unsigned int next_id = 0;
-
-struct _XepXfer
-{
-	PurpleXfer parent;
-
-	GCancellable *cancellable;
-	void *data;
-	char *filename;
-	int filesize;
-	char *iq_id;
-	char *sid;
-	char *recv_id;
-	char *buddy_ip;
-	int mode;
-	GSocketClient *client;
-	GSocketService *service;
-	GSocketConnection *conn;
-	char rx_buf[0x500];
-	char tx_buf[0x500];
-	char *jid;
-	char *proxy_host;
-	int proxy_port;
-	PurpleXmlNode *streamhost;
-	PurpleContact *contact;
-};
-
-G_DEFINE_DYNAMIC_TYPE_EXTENDED(XepXfer, xep_xfer, PURPLE_TYPE_XFER,
-                               G_TYPE_FLAG_FINAL, {})
-
-static void
-xep_ft_si_reject(BonjourData *bd, const char *id, const char *to, const char *error_code, const char *error_type)
-{
-	PurpleXmlNode *error_node;
-	XepIq *iq;
-
-	g_return_if_fail(error_code != NULL);
-	g_return_if_fail(error_type != NULL);
-
-	if(!to || !id) {
-		purple_debug_info("bonjour", "xep file transfer stream initialization error.\n");
-		return;
-	}
-
-	iq = xep_iq_new(bd, XEP_IQ_ERROR, to, bonjour_get_jid(bd->xmpp_data->account), id);
-	if(iq == NULL)
-		return;
-
-	error_node = purple_xmlnode_new_child(iq->node, "error");
-	purple_xmlnode_set_attrib(error_node, "code", error_code);
-	purple_xmlnode_set_attrib(error_node, "type", error_type);
-
-	/* TODO: Make this better */
-	if (purple_strequal(error_code, "403")) {
-		PurpleXmlNode *tmp_node = purple_xmlnode_new_child(error_node, "forbidden");
-		purple_xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
-
-		tmp_node = purple_xmlnode_new_child(error_node, "text");
-		purple_xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
-		purple_xmlnode_insert_data(tmp_node, "Offer Declined", -1);
-	} else if (purple_strequal(error_code, "404")) {
-		PurpleXmlNode *tmp_node = purple_xmlnode_new_child(error_node, "item-not-found");
-		purple_xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
-	}
-
-	xep_iq_send_and_free(iq);
-}
-
-static void bonjour_xfer_cancel_send(PurpleXfer *xfer)
-{
-	XepXfer *xf = XEP_XFER(xfer);
-
-	purple_debug_info("bonjour", "Bonjour-xfer-cancel-send.\n");
-	g_cancellable_cancel(xf->cancellable);
-}
-
-static void bonjour_xfer_request_denied(PurpleXfer *xfer)
-{
-	XepXfer *xf = XEP_XFER(xfer);
-
-	purple_debug_info("bonjour", "Bonjour-xfer-request-denied.\n");
-
-	if(xf) {
-		xep_ft_si_reject(xf->data, xf->sid, purple_xfer_get_remote_user(xfer), "403", "cancel");
-	}
-}
-
-static void bonjour_xfer_cancel_recv(PurpleXfer *xfer)
-{
-	XepXfer *xf = XEP_XFER(xfer);
-
-	purple_debug_info("bonjour", "Bonjour-xfer-cancel-recv.\n");
-	g_cancellable_cancel(xf->cancellable);
-}
-
-static void bonjour_xfer_end(PurpleXfer *xfer)
-{
-	purple_debug_info("bonjour", "Bonjour-xfer-end for xfer %p", xfer);
-
-	/* We can't allow the server side to close the connection until the client is complete,
-	 * otherwise there is a RST resulting in an error on the client side */
-	if (purple_xfer_get_xfer_type(xfer) == PURPLE_XFER_TYPE_SEND && purple_xfer_is_completed(xfer)) {
-		XepXfer *xf = XEP_XFER(xfer);
-		g_io_stream_close_async(G_IO_STREAM(xf->conn), G_PRIORITY_DEFAULT, xf->cancellable, NULL, NULL);
-		purple_xfer_set_fd(xfer, -1);
-	}
-}
-
-static PurpleXfer*
-bonjour_si_xfer_find(BonjourData *bd, const char *sid, const char *from)
-{
-	GSList *xfers;
-	PurpleXfer *xfer;
-	XepXfer *xf;
-
-	if(!sid || !from || !bd)
-		return NULL;
-
-	purple_debug_info("bonjour", "Look for sid=%s from=%s xferlists.\n",
-			  sid, from);
-
-	for(xfers = bd->xfer_lists; xfers; xfers = xfers->next) {
-		xfer = xfers->data;
-		if(xfer == NULL)
-			break;
-		xf = XEP_XFER(xfer);
-		if(xf == NULL)
-			break;
-		if(xf->sid && purple_xfer_get_remote_user(xfer) && purple_strequal(xf->sid, sid) &&
-				purple_strequal(purple_xfer_get_remote_user(xfer), from))
-			return xfer;
-	}
-
-	purple_debug_info("bonjour", "Look for xfer list fail\n");
-
-	return NULL;
-}
-
-static void
-xep_ft_si_offer(PurpleXfer *xfer, const gchar *to)
-{
-	PurpleXmlNode *si_node, *feature, *field, *file, *x;
-	XepIq *iq;
-	XepXfer *xf = XEP_XFER(xfer);
-	BonjourData *bd = NULL;
-	char buf[32];
-
-	if(!xf)
-		return;
-
-	bd = xf->data;
-	if(!bd)
-		return;
-
-	purple_debug_info("bonjour", "xep file transfer stream initialization offer-id=%d.\n", next_id);
-
-	/* Assign stream id. */
-	g_free(xf->iq_id);
-	xf->iq_id = g_strdup_printf("%u", next_id++);
-	iq = xep_iq_new(xf->data, XEP_IQ_SET, to, bonjour_get_jid(bd->xmpp_data->account), xf->iq_id);
-	if(iq == NULL)
-		return;
-
-	/*Construct Stream initialization offer message.*/
-	si_node = purple_xmlnode_new_child(iq->node, "si");
-	purple_xmlnode_set_namespace(si_node, "http://jabber.org/protocol/si");
-	purple_xmlnode_set_attrib(si_node, "profile", "http://jabber.org/protocol/si/profile/file-transfer");
-	g_free(xf->sid);
-	xf->sid = g_strdup(xf->iq_id);
-	purple_xmlnode_set_attrib(si_node, "id", xf->sid);
-
-	file = purple_xmlnode_new_child(si_node, "file");
-	purple_xmlnode_set_namespace(file, "http://jabber.org/protocol/si/profile/file-transfer");
-	purple_xmlnode_set_attrib(file, "name", purple_xfer_get_filename(xfer));
-	g_snprintf(buf, sizeof(buf), "%" G_GOFFSET_FORMAT, purple_xfer_get_size(xfer));
-	purple_xmlnode_set_attrib(file, "size", buf);
-
-	feature = purple_xmlnode_new_child(si_node, "feature");
-	purple_xmlnode_set_namespace(feature, "http://jabber.org/protocol/feature-neg");
-
-	x = purple_xmlnode_new_child(feature, "x");
-	purple_xmlnode_set_namespace(x, "jabber:x:data");
-	purple_xmlnode_set_attrib(x, "type", "form");
-
-	field = purple_xmlnode_new_child(x, "field");
-	purple_xmlnode_set_attrib(field, "var", "stream-method");
-	purple_xmlnode_set_attrib(field, "type", "list-single");
-
-	if (xf->mode & XEP_BYTESTREAMS) {
-		PurpleXmlNode *option = purple_xmlnode_new_child(field, "option");
-		PurpleXmlNode *value = purple_xmlnode_new_child(option, "value");
-		purple_xmlnode_insert_data(value, "http://jabber.org/protocol/bytestreams", -1);
-	}
-	if (xf->mode & XEP_IBB) {
-		PurpleXmlNode *option = purple_xmlnode_new_child(field, "option");
-		PurpleXmlNode *value = purple_xmlnode_new_child(option, "value");
-		purple_xmlnode_insert_data(value, "http://jabber.org/protocol/ibb", -1);
-	}
-
-	xep_iq_send_and_free(iq);
-}
-
-static void
-xep_ft_si_result(PurpleXfer *xfer, const char *to)
-{
-	PurpleXmlNode *si_node, *feature, *field, *value, *x;
-	XepIq *iq;
-	XepXfer *xf;
-	BonjourData *bd;
-
-	if(!to || !xfer)
-		return;
-	xf = XEP_XFER(xfer);
-
-	bd = xf->data;
-
-	purple_debug_info("bonjour", "xep file transfer stream initialization result.\n");
-	iq = xep_iq_new(bd, XEP_IQ_RESULT, to, bonjour_get_jid(bd->xmpp_data->account), xf->iq_id);
-	if(iq == NULL)
-		return;
-
-	si_node = purple_xmlnode_new_child(iq->node, "si");
-	purple_xmlnode_set_namespace(si_node, "http://jabber.org/protocol/si");
-	/*purple_xmlnode_set_attrib(si_node, "profile", "http://jabber.org/protocol/si/profile/file-transfer");*/
-
-	feature = purple_xmlnode_new_child(si_node, "feature");
-	purple_xmlnode_set_namespace(feature, "http://jabber.org/protocol/feature-neg");
-
-	x = purple_xmlnode_new_child(feature, "x");
-	purple_xmlnode_set_namespace(x, "jabber:x:data");
-	purple_xmlnode_set_attrib(x, "type", "submit");
-
-	field = purple_xmlnode_new_child(x, "field");
-	purple_xmlnode_set_attrib(field, "var", "stream-method");
-
-	value = purple_xmlnode_new_child(field, "value");
-	purple_xmlnode_insert_data(value, "http://jabber.org/protocol/bytestreams", -1);
-
-	xep_iq_send_and_free(iq);
-}
-
-/**
- * Frees the whole tree of an xml node
- *
- * First determines the root of the xml tree and then frees the whole tree
- * from there.
- *
- * @param node	The node to free the tree from
- */
-static void
-purple_xmlnode_free_tree(PurpleXmlNode *node)
-{
-	g_return_if_fail(node != NULL);
-
-	while(purple_xmlnode_get_parent(node))
-		node = purple_xmlnode_get_parent(node);
-
-	purple_xmlnode_free(node);
-}
-
-PurpleXfer *
-bonjour_new_xfer(G_GNUC_UNUSED PurpleProtocolXfer *prplxfer,
-                 PurpleConnection *gc, const char *who)
-{
-	PurpleXfer *xfer;
-	XepXfer *xep_xfer;
-	BonjourData *bd;
-
-	if(who == NULL || gc == NULL)
-		return NULL;
-
-	purple_debug_info("bonjour", "Bonjour-new-xfer to %s.\n", who);
-	bd = purple_connection_get_protocol_data(gc);
-	if(bd == NULL)
-		return NULL;
-
-	/* Build the file transfer handle */
-	xep_xfer = g_object_new(
-		XEP_TYPE_XFER,
-		"account", purple_connection_get_account(gc),
-		"type", PURPLE_XFER_TYPE_SEND,
-		"remote-user", who,
-		NULL
-	);
-	xfer = PURPLE_XFER(xep_xfer);
-	xep_xfer->data = bd;
-
-	purple_debug_info("bonjour", "Bonjour-new-xfer bd=%p data=%p.\n", bd, xep_xfer->data);
-
-	/* We don't support IBB yet */
-	/*xep_xfer->mode = XEP_BYTESTREAMS | XEP_IBB;*/
-	xep_xfer->mode = XEP_BYTESTREAMS;
-	xep_xfer->sid = NULL;
-
-	bd->xfer_lists = g_slist_append(bd->xfer_lists, xfer);
-
-	return xfer;
-}
-
-void
-bonjour_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who, const char *file)
-{
-	PurpleXfer *xfer;
-
-	g_return_if_fail(gc != NULL);
-	g_return_if_fail(who != NULL);
-
-	purple_debug_info("bonjour", "Bonjour-send-file to=%s.\n", who);
-
-	xfer = bonjour_new_xfer(prplxfer, gc, who);
-
-	if (file)
-		purple_xfer_request_accepted(xfer, file);
-	else
-		purple_xfer_request(xfer);
-
-}
-
-static void
-bonjour_xfer_init(PurpleXfer *xfer)
-{
-	PurpleContact *contact = NULL;
-	PurpleContactManager *manager = NULL;
-	BonjourBuddy *bb;
-	XepXfer *xf;
-
-	xf = XEP_XFER(xfer);
-
-	purple_debug_info("bonjour", "Bonjour-xfer-init.\n");
-
-	manager = purple_contact_manager_get_default();
-	contact = purple_contact_manager_find_with_username(manager,
-	                                                    purple_xfer_get_account(xfer),
-	                                                    purple_xfer_get_remote_user(xfer));
-
-	/* this buddy is offline. */
-	if(!PURPLE_IS_CONTACT(contact) ||
-	   (bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy")) == NULL)
-	{
-		g_clear_object(&contact);
-
-		return;
-	}
-
-	/* Assume it is the first IP. We could do something like keep track of which one is in use or something. */
-	if (bb->ips)
-		xf->buddy_ip = g_strdup(bb->ips->data);
-	if (purple_xfer_get_xfer_type(xfer) == PURPLE_XFER_TYPE_SEND) {
-		/* initiate file transfer, send SI offer. */
-		purple_debug_info("bonjour", "Bonjour xfer type is PURPLE_XFER_TYPE_SEND.\n");
-		xep_ft_si_offer(xfer, purple_xfer_get_remote_user(xfer));
-	} else {
-		/* accept file transfer request, send SI result. */
-		xep_ft_si_result(xfer, purple_xfer_get_remote_user(xfer));
-		purple_debug_info("bonjour", "Bonjour xfer type is PURPLE_XFER_TYPE_RECEIVE.\n");
-	}
-
-	g_clear_object(&contact);
-}
-
-void
-xep_si_parse(PurpleConnection *pc, PurpleXmlNode *packet,
-             PurpleContact *contact)
-{
-	const char *type, *id;
-	BonjourData *bd;
-	PurpleXfer *xfer;
-	const gchar *name = NULL;
-
-	g_return_if_fail(pc != NULL);
-	g_return_if_fail(packet != NULL);
-	g_return_if_fail(PURPLE_IS_CONTACT(contact));
-
-	bd = purple_connection_get_protocol_data(pc);
-	if(bd == NULL) {
-		return;
-	}
-
-	purple_debug_info("bonjour", "xep-si-parse.\n");
-
-	name = purple_contact_info_get_username(PURPLE_CONTACT_INFO(contact));
-
-	type = purple_xmlnode_get_attrib(packet, "type");
-	id = purple_xmlnode_get_attrib(packet, "id");
-	if(!type)
-		return;
-
-	if(purple_strequal(type, "set")) {
-		PurpleXmlNode *si;
-		gboolean parsed_receive = FALSE;
-
-		si = purple_xmlnode_get_child(packet, "si");
-
-		purple_debug_info("bonjour", "si offer Message type - SET.\n");
-		if (si) {
-			const char *profile;
-
-			profile = purple_xmlnode_get_attrib(si, "profile");
-
-			if (purple_strequal(profile, "http://jabber.org/protocol/si/profile/file-transfer")) {
-				const char *filename = NULL, *filesize_str = NULL;
-				goffset filesize = 0;
-				PurpleXmlNode *file;
-
-				const char *sid = purple_xmlnode_get_attrib(si, "id");
-
-				if ((file = purple_xmlnode_get_child(si, "file"))) {
-					filename = purple_xmlnode_get_attrib(file, "name");
-					if((filesize_str = purple_xmlnode_get_attrib(file, "size")))
-						filesize = g_ascii_strtoll(filesize_str, NULL, 10);
-				}
-
-				/* TODO: Make sure that it is advertising a bytestreams transfer */
-
-				if (filename) {
-					bonjour_xfer_receive(pc, id, sid, name, filesize, filename, XEP_BYTESTREAMS);
-
-					parsed_receive = TRUE;
-				}
-			}
-		}
-
-		if (!parsed_receive) {
-			BonjourData *bd = purple_connection_get_protocol_data(pc);
-
-			purple_debug_info("bonjour", "rejecting unrecognized si SET offer.\n");
-			xep_ft_si_reject(bd, id, name, "403", "cancel");
-			/*TODO: Send Cancel (501) */
-		}
-	} else if(purple_strequal(type, "result")) {
-		purple_debug_info("bonjour", "si offer Message type - RESULT.\n");
-
-		xfer = bonjour_si_xfer_find(bd, id, name);
-
-		if(xfer == NULL) {
-			BonjourData *bd = purple_connection_get_protocol_data(pc);
-			purple_debug_info("bonjour", "xfer find fail.\n");
-			xep_ft_si_reject(bd, id, name, "403", "cancel");
-		} else
-			bonjour_bytestreams_init(xfer);
-
-	} else if(purple_strequal(type, "error")) {
-		purple_debug_info("bonjour", "si offer Message type - ERROR.\n");
-
-		xfer = bonjour_si_xfer_find(bd, id, name);
-
-		if(xfer == NULL)
-			purple_debug_info("bonjour", "xfer find fail.\n");
-		else
-			purple_xfer_cancel_remote(xfer);
-	} else
-		purple_debug_info("bonjour", "si offer Message type - Unknown-%s.\n", type);
-}
-
-/**
- * Will compare a host with a buddy_ip.
- *
- * Additionally to a common 'purple_strequal(host, buddy_ip)', it will also return TRUE
- * if 'host' is a link local IPv6 address without an appended interface
- * identifier and 'buddy_ip' string is "host" + "%iface".
- *
- * Note: This may theoretically result in the attempt to connect to the wrong
- * host, because we do not know for sure which interface the according link
- * local IPv6 address might relate to and RFC4862 for instance only ensures the
- * uniqueness of this address on a given link. So we could possibly have two
- * distinct buddies with the same ipv6 link local address on two distinct
- * interfaces. Unfortunately XEP-0065 does not seem to specify how to deal with
- * link local ip addresses properly...
- * However, in practice the possibility for such a conflict is relatively low
- * (2011 - might be different in the future though?).
- *
- * @param host		ipv4 or ipv6 address string
- * @param buddy_ip	ipv4 or ipv6 address string
- * @return		TRUE if they match, FALSE otherwise
- */
-static gboolean
-xep_cmp_addr(const char *host, const char *buddy_ip)
-{
-	GInetAddress *addr = NULL;
-
-	addr = g_inet_address_new_from_string(host);
-	if (addr != NULL &&
-	    g_inet_address_get_family(addr) == G_SOCKET_FAMILY_IPV6 &&
-	    g_inet_address_get_is_link_local(addr)) {
-		g_clear_object(&addr);
-
-		if (strlen(buddy_ip) <= strlen(host) || buddy_ip[strlen(host)] != '%') {
-			return FALSE;
-		}
-
-		return !strncmp(host, buddy_ip, strlen(host));
-	} else {
-		g_clear_object(&addr);
-		return purple_strequal(host, buddy_ip);
-	}
-}
-
-static inline gint
-xep_addr_differ(const char *buddy_ip, const char *host)
-{
-	return !xep_cmp_addr(host, buddy_ip);
-}
-
-/**
- * Create and insert an identical twin
- *
- * Creates a copy of the specified node and inserts it right after
- * this original node.
- *
- * @param node	The node to clone
- * @return	A pointer to the new, cloned twin if successful
- *		or NULL otherwise.
- */
-static PurpleXmlNode *
-purple_xmlnode_insert_twin_copy(PurpleXmlNode *node) {
-	PurpleXmlNode *copy;
-
-	g_return_val_if_fail(node != NULL, NULL);
-
-	copy = purple_xmlnode_copy(node);
-	g_return_val_if_fail(copy != NULL, NULL);
-
-	copy->next = node->next;
-	node->next = copy;
-
-	return copy;
-}
-
-/**
- * Tries to append an interface scope to an IPv6 link local address.
- *
- * If the given address is a link local IPv6 address (with no
- * interface scope) then we try to determine all fitting interfaces
- * from our Bonjour IP address list.
- *
- * For any such found matches we insert a copy of our current xml
- * streamhost entry right after this streamhost entry and append
- * the determined interface to the host address of this copy.
- *
- * @param cur_streamhost	The XML streamhost node we examine
- * @param host	The host address to examine in text form
- * @param pb	Buddy to get the list of link local IPv6 addresses
- *		and their interface from
- * @return	Returns TRUE if the specified 'host' address is a
- *		link local IPv6 address with no interface scope.
- *		Otherwise returns FALSE.
- */
-static gboolean
-add_ipv6_link_local_ifaces(PurpleXmlNode *cur_streamhost, const char *host,
-                           PurpleContact *contact)
-{
-	PurpleXmlNode *new_streamhost = NULL;
-	GInetAddress *addr;
-	BonjourBuddy *bb;
-	GSList *ip_elem;
-
-	addr = g_inet_address_new_from_string(host);
-	if (addr == NULL ||
-	    g_inet_address_get_family(addr) != G_SOCKET_FAMILY_IPV6 ||
-	    !g_inet_address_get_is_link_local(addr) ||
-	    strchr(host, '%'))
-	{
-		g_clear_object(&addr);
-		return FALSE;
-	}
-	g_clear_object(&addr);
-
-	bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-
-	for (ip_elem = bb->ips;
-	     (ip_elem = g_slist_find_custom(ip_elem, host, (GCompareFunc)&xep_addr_differ));
-	     ip_elem = ip_elem->next) {
-		purple_debug_info("bonjour", "Inserting an PurpleXmlNode twin copy for %s with new host address %s\n",
-				  host, (char*)ip_elem->data);
-		new_streamhost = purple_xmlnode_insert_twin_copy(cur_streamhost);
-		purple_xmlnode_set_attrib(new_streamhost, "host", ip_elem->data);
-	}
-
-	if (!new_streamhost)
-		purple_debug_info("bonjour", "No interface for this IPv6 link local address found: %s\n",
-				  host);
-
-	return TRUE;
-}
-
-static gboolean
-__xep_bytestreams_parse(PurpleContact *contact, PurpleXfer *xfer,
-                        PurpleXmlNode *streamhost, const char *iq_id)
-{
-	char *tmp_iq_id;
-	const char *jid, *host, *port;
-	int portnum;
-	XepXfer *xf = XEP_XFER(xfer);
-
-	for(; streamhost; streamhost = purple_xmlnode_get_next_twin(streamhost)) {
-		if(!(jid = purple_xmlnode_get_attrib(streamhost, "jid")) ||
-		   !(host = purple_xmlnode_get_attrib(streamhost, "host")) ||
-		   !(port = purple_xmlnode_get_attrib(streamhost, "port")) ||
-		   !(portnum = atoi(port))) {
-			purple_debug_info("bonjour", "bytestream offer Message parse error.\n");
-			continue;
-		}
-
-		/* skip IPv6 link local addresses with no interface scope
-		 * (but try to add a new one with an interface scope then) */
-		if(add_ipv6_link_local_ifaces(streamhost, host, contact))
-			continue;
-
-		tmp_iq_id = g_strdup(iq_id);
-		g_free(xf->iq_id);
-		g_free(xf->jid);
-		g_free(xf->proxy_host);
-
-		xf->iq_id = tmp_iq_id;
-		xf->jid = g_strdup(jid);
-		xf->proxy_host = g_strdup(host);
-		xf->proxy_port = portnum;
-		xf->streamhost = streamhost;
-		xf->contact = contact;
-		purple_debug_info("bonjour", "bytestream offer parse"
-				  "jid=%s host=%s port=%d.\n", jid, host, portnum);
-		bonjour_bytestreams_connect(xfer);
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-void
-xep_bytestreams_parse(PurpleConnection *pc, PurpleXmlNode *packet,
-                      PurpleContact *contact)
-{
-	const char *type, *from, *iq_id, *sid;
-	PurpleXmlNode *query, *streamhost;
-	BonjourData *bd;
-	PurpleXfer *xfer;
-
-	g_return_if_fail(pc != NULL);
-	g_return_if_fail(packet != NULL);
-	g_return_if_fail(PURPLE_IS_CONTACT(contact));
-
-	bd = purple_connection_get_protocol_data(pc);
-	if(bd == NULL) {
-		return;
-	}
-
-	purple_debug_info("bonjour", "xep-bytestreams-parse.\n");
-
-	type = purple_xmlnode_get_attrib(packet, "type");
-	from = purple_contact_info_get_username(PURPLE_CONTACT_INFO(contact));
-	query = purple_xmlnode_get_child(packet,"query");
-	if(!type)
-		return;
-
-	query = purple_xmlnode_copy(query);
-	if (!query)
-		return;
-
-	if(!purple_strequal(type, "set")) {
-		purple_debug_info("bonjour", "bytestream offer Message type - Unknown-%s.\n", type);
-		return;
-	}
-
-	purple_debug_info("bonjour", "bytestream offer Message type - SET.\n");
-
-	iq_id = purple_xmlnode_get_attrib(packet, "id");
-
-	sid = purple_xmlnode_get_attrib(query, "sid");
-	xfer = bonjour_si_xfer_find(bd, sid, from);
-	streamhost = purple_xmlnode_get_child(query, "streamhost");
-
-	if(xfer && streamhost && __xep_bytestreams_parse(contact, xfer, streamhost, iq_id))
-		return; /* success */
-
-	purple_debug_error("bonjour", "Didn't find an acceptable streamhost.\n");
-
-	if (iq_id && xfer != NULL)
-		xep_ft_si_reject(bd, iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel");
-}
-
-static void
-bonjour_xfer_receive(PurpleConnection *pc, const char *id, const char *sid,
-                     const char *from, goffset filesize, const char *filename,
-                     G_GNUC_UNUSED int option)
-{
-	PurpleXfer *xfer;
-	XepXfer *xf;
-	BonjourData *bd;
-
-	if(pc == NULL || id == NULL || from == NULL)
-		return;
-
-	bd = purple_connection_get_protocol_data(pc);
-	if(bd == NULL)
-		return;
-
-	purple_debug_info("bonjour", "bonjour-xfer-receive.\n");
-
-	/* Build the file transfer handle */
-	xf = g_object_new(
-		XEP_TYPE_XFER,
-		"account", purple_connection_get_account(pc),
-		"type", PURPLE_XFER_TYPE_RECEIVE,
-		"remote-user", from,
-		NULL
-	);
-
-	xfer = PURPLE_XFER(xf);
-
-	xf->data = bd;
-	purple_xfer_set_filename(xfer, filename);
-	xf->iq_id = g_strdup(id);
-	xf->sid = g_strdup(sid);
-
-	if(filesize > 0)
-		purple_xfer_set_size(xfer, filesize);
-
-	bd->xfer_lists = g_slist_append(bd->xfer_lists, xfer);
-
-	purple_xfer_request(xfer);
-}
-
-static void
-bonjour_sock5_request_cb(GObject *source, GAsyncResult *result,
-                         gpointer user_data)
-{
-	PurpleXfer *xfer = PURPLE_XFER(user_data);
-	XepXfer *xf = XEP_XFER(xfer);
-	gsize bytes_written = 0;
-	GError *error = NULL;
-	GSocket *sock = NULL;
-	gint fd = -1;
-
-	purple_debug_info("bonjour", "bonjour_sock5_request_cb");
-
-	if (!g_output_stream_write_all_finish(G_OUTPUT_STREAM(source), result,
-	                                      &bytes_written, &error)) {
-		if (error->code != G_IO_ERROR_CANCELLED) {
-			purple_xfer_cancel_remote(xfer);
-		}
-		g_clear_error(&error);
-		return;
-	}
-
-	sock = g_socket_connection_get_socket(xf->conn);
-	fd = g_socket_get_fd(sock);
-	purple_debug_info("bonjour", "Accepted SOCKS5 ft connection - fd=%d", fd);
-
-	_purple_network_set_common_socket_flags(fd);
-	purple_xfer_start(xfer, fd, NULL, -1);
-}
-
-static void
-bonjour_sock5_read_connect_cb(GObject *source, GAsyncResult *result,
-                              gpointer user_data)
-{
-	PurpleXfer *xfer = PURPLE_XFER(user_data);
-	XepXfer *xf = XEP_XFER(xfer);
-	GOutputStream *output = NULL;
-	gsize bytes_read = 0;
-	GError *error = NULL;
-
-	purple_debug_info("bonjour", "bonjour_sock5_request_state4_cb");
-
-	if (!g_input_stream_read_all_finish(G_INPUT_STREAM(source), result,
-	                                    &bytes_read, &error)) {
-		if (error->code != G_IO_ERROR_CANCELLED) {
-			purple_xfer_cancel_remote(xfer);
-		}
-		g_clear_error(&error);
-		return;
-	}
-
-	xf->tx_buf[0] = 0x05;
-	xf->tx_buf[1] = 0x00;
-	xf->tx_buf[2] = 0x00;
-	xf->tx_buf[3] = 0x03;
-	xf->tx_buf[4] = strlen(xf->buddy_ip);
-	memcpy(xf->tx_buf + 5, xf->buddy_ip, strlen(xf->buddy_ip));
-	xf->tx_buf[5 + strlen(xf->buddy_ip)] = 0x00;
-	xf->tx_buf[6 + strlen(xf->buddy_ip)] = 0x00;
-	output = g_io_stream_get_output_stream(G_IO_STREAM(xf->conn));
-	g_output_stream_write_all_async(
-	        output, xf->tx_buf, 7 + strlen(xf->buddy_ip), G_PRIORITY_DEFAULT,
-	        xf->cancellable, bonjour_sock5_request_cb, xfer);
-}
-
-static void
-bonjour_sock5_write_server_method_cb(GObject *source, GAsyncResult *result,
-                                     gpointer user_data)
-{
-	PurpleXfer *xfer = PURPLE_XFER(user_data);
-	XepXfer *xf = XEP_XFER(xfer);
-	GInputStream *input = NULL;
-	gsize bytes_written = 0;
-	GError *error = NULL;
-
-	purple_debug_info("bonjour", "bonjour_sock5_request_state3_cb");
-
-	if (!g_output_stream_write_all_finish(G_OUTPUT_STREAM(source), result,
-	                                      &bytes_written, &error)) {
-		if (error->code != G_IO_ERROR_CANCELLED) {
-			purple_xfer_cancel_remote(xfer);
-		}
-		g_clear_error(&error);
-		return;
-	}
-
-	input = g_io_stream_get_input_stream(G_IO_STREAM(xf->conn));
-	g_input_stream_read_all_async(input, xf->rx_buf, 20, G_PRIORITY_DEFAULT,
-	                              xf->cancellable,
-	                              bonjour_sock5_read_connect_cb, xfer);
-}
-
-static void
-bonjour_sock5_read_client_version_cb(GObject *source, GAsyncResult *result,
-                                     gpointer user_data)
-{
-	PurpleXfer *xfer = PURPLE_XFER(user_data);
-	XepXfer *xf = XEP_XFER(xfer);
-	GOutputStream *output = NULL;
-	gsize bytes_read = 0;
-	GError *error = NULL;
-
-	purple_debug_info("bonjour", "bonjour_sock5_read_client_version_cb");
-
-	if (!g_input_stream_read_all_finish(G_INPUT_STREAM(source), result,
-	                                    &bytes_read, &error)) {
-		if (error->code != G_IO_ERROR_CANCELLED) {
-			purple_xfer_cancel_remote(xfer);
-		}
-		g_clear_error(&error);
-		return;
-	}
-
-	xf->tx_buf[0] = 0x05;
-	xf->tx_buf[1] = 0x00;
-	output = g_io_stream_get_output_stream(G_IO_STREAM(xf->conn));
-	g_output_stream_write_all_async(output, xf->tx_buf, 2, G_PRIORITY_DEFAULT,
-	                                xf->cancellable,
-	                                bonjour_sock5_write_server_method_cb, xfer);
-}
-
-static void
-bonjour_sock5_incoming_cb(G_GNUC_UNUSED GSocketService *service,
-                          GSocketConnection *connection, GObject *source_object,
-                          G_GNUC_UNUSED gpointer data)
-{
-	PurpleXfer *xfer = PURPLE_XFER(source_object);
-	XepXfer *xf = XEP_XFER(xfer);
-	GInputStream *input = NULL;
-
-	if (xf == NULL) {
-		return;
-	}
-
-	purple_debug_info("bonjour", "bonjour_sock5_incoming_cb");
-
-	xf->conn = g_object_ref(connection);
-	g_socket_service_stop(xf->service);
-	g_clear_object(&xf->service);
-
-	purple_debug_info("bonjour", "Accepted SOCKS5 ft connection");
-	input = g_io_stream_get_input_stream(G_IO_STREAM(xf->conn));
-
-	g_input_stream_read_all_async(input, xf->rx_buf, 3, G_PRIORITY_DEFAULT,
-	                              xf->cancellable,
-	                              bonjour_sock5_read_client_version_cb, xfer);
-}
-
-static void
-bonjour_bytestreams_init(PurpleXfer *xfer)
-{
-	XepXfer *xf;
-	XepIq *iq;
-	PurpleXmlNode *query, *streamhost;
-	guint16 port;
-	gchar *port_str;
-	GList *local_ips;
-	BonjourData *bd;
-	GError *error = NULL;
-
-	if (xfer == NULL) {
-		return;
-	}
-
-	purple_debug_info("bonjour", "Bonjour-bytestreams-init.\n");
-	xf = XEP_XFER(xfer);
-
-	xf->service = g_socket_service_new();
-	port = purple_socket_listener_add_any_inet_port(
-	        G_SOCKET_LISTENER(xf->service), G_OBJECT(xfer), &error);
-	if (port == 0) {
-		purple_debug_error("bonjour",
-		                   "Unable to open port for file transfer: %s",
-		                   error->message);
-		purple_xfer_cancel_local(xfer);
-		g_error_free(error);
-		return;
-	}
-
-	g_signal_connect(xf->service, "incoming",
-	                 G_CALLBACK(bonjour_sock5_incoming_cb), NULL);
-
-	bd = xf->data;
-
-	iq = xep_iq_new(bd, XEP_IQ_SET, purple_xfer_get_remote_user(xfer), bonjour_get_jid(bd->xmpp_data->account), xf->sid);
-
-	query = purple_xmlnode_new_child(iq->node, "query");
-	purple_xmlnode_set_namespace(query, "http://jabber.org/protocol/bytestreams");
-	purple_xmlnode_set_attrib(query, "sid", xf->sid);
-	purple_xmlnode_set_attrib(query, "mode", "tcp");
-
-	purple_xfer_set_local_port(xfer, port);
-
-	#pragma message("Need to figure out how to get the local ip addresses")
-	local_ips = NULL;
-
-	port_str = g_strdup_printf("%hu", port);
-	while(local_ips) {
-		streamhost = purple_xmlnode_new_child(query, "streamhost");
-		purple_xmlnode_set_attrib(streamhost, "jid", xf->sid);
-		purple_xmlnode_set_attrib(streamhost, "host", local_ips->data);
-		purple_xmlnode_set_attrib(streamhost, "port", port_str);
-		g_free(local_ips->data);
-		local_ips = g_list_delete_link(local_ips, local_ips);
-	}
-	g_free(port_str);
-
-	xep_iq_send_and_free(iq);
-}
-
-static void
-bonjour_bytestreams_handle_failure(PurpleXfer *xfer, const gchar *error_message)
-{
-	XepXfer *xf = XEP_XFER(xfer);
-	PurpleXmlNode *tmp_node;
-	gboolean ret;
-
-	purple_debug_error("bonjour", "Error connecting via SOCKS5 to %s - %s",
-	                   xf->proxy_host, error_message);
-
-	tmp_node = purple_xmlnode_get_next_twin(xf->streamhost);
-	ret = __xep_bytestreams_parse(xf->contact, xfer, tmp_node, xf->iq_id);
-
-	if (!ret) {
-		xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer),
-		                 "404", "cancel");
-		/* Cancel the connection */
-		purple_xfer_cancel_local(xfer);
-	}
-}
-
-static void
-bonjour_bytestreams_connect_cb(GObject *source, GAsyncResult *result,
-                               gpointer user_data)
-{
-	PurpleXfer *xfer = PURPLE_XFER(user_data);
-	XepXfer *xf = XEP_XFER(xfer);
-	GIOStream *stream;
-	GError *error = NULL;
-	GSocket *socket;
-	XepIq *iq;
-	PurpleXmlNode *q_node, *tmp_node;
-	BonjourData *bd;
-
-	stream = g_proxy_connect_finish(G_PROXY(source), result, &error);
-	if (stream == NULL) {
-		if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-			purple_debug_error("bonjour",
-			                   "Unable to connect to destination host: %s",
-			                   error->message);
-			bonjour_bytestreams_handle_failure(
-			        xfer, "Unable to connect to destination host.");
-		}
-
-		g_clear_error(&error);
-		return;
-	}
-
-	if (!G_IS_SOCKET_CONNECTION(stream)) {
-		purple_debug_error("bonjour",
-		                   "GProxy didn't return a GSocketConnection.");
-		bonjour_bytestreams_handle_failure(
-		        xfer, "GProxy didn't return a GSocketConnection.");
-		g_object_unref(stream);
-		return;
-	}
-
-	purple_debug_info("bonjour", "Connected successfully via SOCKS5, starting transfer.\n");
-
-	bd = xf->data;
-
-	/* Here, start the file transfer.*/
-
-	/* Notify Initiator of Connection */
-	iq = xep_iq_new(bd, XEP_IQ_RESULT, purple_xfer_get_remote_user(xfer), bonjour_get_jid(bd->xmpp_data->account), xf->iq_id);
-	q_node = purple_xmlnode_new_child(iq->node, "query");
-	purple_xmlnode_set_namespace(q_node, "http://jabber.org/protocol/bytestreams");
-	tmp_node = purple_xmlnode_new_child(q_node, "streamhost-used");
-	purple_xmlnode_set_attrib(tmp_node, "jid", xf->jid);
-	xep_iq_send_and_free(iq);
-
-	xf->conn = G_SOCKET_CONNECTION(stream);
-	socket = g_socket_connection_get_socket(xf->conn);
-	purple_xfer_start(xfer, g_socket_get_fd(socket), NULL, -1);
-}
-
-/* This is called when we connect to the SOCKS5 proxy server (through any
- * relevant account proxy)
- */
-static void
-bonjour_bytestreams_socks5_connect_to_host_cb(GObject *source,
-                                              GAsyncResult *result,
-                                              gpointer user_data)
-{
-	PurpleXfer *xfer = PURPLE_XFER(user_data);
-	XepXfer *xf = XEP_XFER(xfer);
-	GSocketConnection *conn;
-	GProxy *proxy;
-	GSocketAddress *addr;
-	GInetSocketAddress *inet_addr;
-	GSocketAddress *proxy_addr;
-	PurpleContact *contact = NULL;
-	gchar *hash_input;
-	gchar *dstaddr;
-	GError *error = NULL;
-
-	conn = g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(source),
-	                                              result, &error);
-	if (conn == NULL) {
-		if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-			purple_debug_error("bonjour",
-			                   "Unable to connect to SOCKS5 host: %s",
-			                   error->message);
-			bonjour_bytestreams_handle_failure(
-			        xfer, "Unable to connect to SOCKS5 host.");
-		}
-
-		g_clear_error(&error);
-		return;
-	}
-
-	proxy = g_proxy_get_default_for_protocol("socks5");
-	if (proxy == NULL) {
-		purple_debug_error("bonjour", "SOCKS5 proxy backend missing.");
-		bonjour_bytestreams_handle_failure(xfer,
-		                                   "SOCKS5 proxy backend missing.");
-		g_object_unref(conn);
-		return;
-	}
-
-	addr = g_socket_connection_get_remote_address(conn, &error);
-	if (addr == NULL) {
-		purple_debug_error(
-		        "bonjour",
-		        "Unable to retrieve SOCKS5 host address from connection: %s",
-		        error->message);
-		bonjour_bytestreams_handle_failure(
-		        xfer, "Unable to retrieve SOCKS5 host address from connection");
-		g_object_unref(conn);
-		g_object_unref(proxy);
-		g_clear_error(&error);
-		return;
-	}
-
-	contact = xf->contact;
-	hash_input = g_strdup_printf("%s%s%s", xf->sid,
-	                             purple_contact_info_get_username(PURPLE_CONTACT_INFO(contact)),
-	                             bonjour_get_jid(purple_contact_get_account(contact)));
-	dstaddr = g_compute_checksum_for_string(G_CHECKSUM_SHA1, hash_input, -1);
-	g_free(hash_input);
-
-	purple_debug_info("bonjour", "Connecting to %s using SOCKS5 proxy %s:%d",
-	                  dstaddr, xf->proxy_host, xf->proxy_port);
-
-	inet_addr = G_INET_SOCKET_ADDRESS(addr);
-	proxy_addr =
-	        g_proxy_address_new(g_inet_socket_address_get_address(inet_addr),
-	                            g_inet_socket_address_get_port(inet_addr),
-	                            "socks5", dstaddr, 0, NULL, NULL);
-	g_object_unref(inet_addr);
-
-	g_proxy_connect_async(proxy, G_IO_STREAM(conn), G_PROXY_ADDRESS(proxy_addr),
-	                      xf->cancellable, bonjour_bytestreams_connect_cb,
-	                      xfer);
-	g_object_unref(proxy_addr);
-	g_object_unref(conn);
-	g_object_unref(proxy);
-	g_free(dstaddr);
-}
-
-static void
-bonjour_bytestreams_connect(PurpleXfer *xfer)
-{
-	PurpleAccount *account = NULL;
-	XepXfer *xf;
-	GError *error = NULL;
-
-	if (xfer == NULL) {
-		return;
-	}
-
-	purple_debug_info("bonjour", "bonjour-bytestreams-connect.");
-
-	xf = XEP_XFER(xfer);
-	account = purple_contact_get_account(xf->contact);
-
-	xf->client = purple_gio_socket_client_new(account, &error);
-	if (xf->client == NULL) {
-		/* Cancel the connection */
-		purple_debug_error("bonjour",
-		                   "Failed to connect to SOCKS5 streamhost proxy: %s",
-		                   error->message);
-		g_clear_error(&error);
-		xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer),
-		                 "404", "cancel");
-		purple_xfer_cancel_local(xfer);
-		return;
-	}
-
-	purple_debug_info("bonjour", "Connecting to SOCKS5 proxy %s:%d",
-	                  xf->proxy_host, xf->proxy_port);
-
-	g_socket_client_connect_to_host_async(
-	        xf->client, xf->proxy_host, xf->proxy_port, xf->cancellable,
-	        bonjour_bytestreams_socks5_connect_to_host_cb, xfer);
-}
-
-static void
-xep_xfer_init(XepXfer *xf)
-{
-	xf->cancellable = g_cancellable_new();
-}
-
-static void
-xep_xfer_finalize(GObject *obj) {
-	XepXfer *xf = XEP_XFER(obj);
-	BonjourData *bd = (BonjourData*)xf->data;
-
-	if(bd != NULL) {
-		bd->xfer_lists = g_slist_remove(bd->xfer_lists, PURPLE_XFER(xf));
-		purple_debug_misc("bonjour", "B free xfer from lists(%p).\n", bd->xfer_lists);
-	}
-	g_cancellable_cancel(xf->cancellable);
-	g_clear_object(&xf->cancellable);
-	g_clear_object(&xf->client);
-	if (xf->service) {
-		g_socket_service_stop(xf->service);
-	}
-	g_clear_object(&xf->service);
-	g_clear_object(&xf->conn);
-
-	g_free(xf->iq_id);
-	g_free(xf->jid);
-	g_free(xf->proxy_host);
-	g_free(xf->buddy_ip);
-	g_free(xf->sid);
-
-	g_clear_pointer(&xf->streamhost, purple_xmlnode_free_tree);
-
-	G_OBJECT_CLASS(xep_xfer_parent_class)->finalize(obj);
-}
-
-static void
-xep_xfer_class_finalize(G_GNUC_UNUSED XepXferClass *klass) {
-}
-
-static void
-xep_xfer_class_init(XepXferClass *klass) {
-	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-	PurpleXferClass *xfer_class = PURPLE_XFER_CLASS(klass);
-
-	obj_class->finalize = xep_xfer_finalize;
-
-	xfer_class->init = bonjour_xfer_init;
-	xfer_class->request_denied = bonjour_xfer_request_denied;
-	xfer_class->cancel_recv = bonjour_xfer_cancel_recv;
-	xfer_class->cancel_send = bonjour_xfer_cancel_send;
-	xfer_class->end = bonjour_xfer_end;
-}
-
-void
-xep_xfer_register(GTypeModule *module) {
-	xep_xfer_register_type(module);
-}
diff --git a/libpurple/protocols/bonjour/buddy.h b/libpurple/protocols/bonjour/buddy.h
deleted file mode 100644
--- a/libpurple/protocols/bonjour/buddy.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
- */
-
-#ifndef PURPLE_BONJOUR_BUDDY_H
-#define PURPLE_BONJOUR_BUDDY_H
-
-#include <glib.h>
-
-#include <purple.h>
-
-#include "xmpp.h"
-
-typedef struct
-{
-	PurpleAccount *account;
-
-	gchar *name;
-	GSList *ips;
-	gint port_p2pj;
-
-	gchar *first;
-	gchar *phsh;
-	gchar *status;
-	gchar *email;
-	gchar *last;
-	gchar *jid;
-	gchar *AIM;
-	gchar *vc;
-	gchar *msg;
-	gchar *ext;
-	gchar *nick;
-	gchar *node;
-	gchar *ver;
-
-	BonjourXMPPConversation *conversation;
-
-	gpointer mdns_impl_data;
-} BonjourBuddy;
-
-static const char *const buddy_TXT_records[] = {
-	"1st",
-	"email",
-	"ext",
-	"jid",
-	"last",
-	"msg",
-	"nick",
-	"node",
-	"phsh",
-/*	"port.p2pj", Deprecated - MUST ignore */
-	"status",
-/*	"txtvers", Deprecated - hardcoded to 1 */
-	"vc",
-	"ver",
-	"AIM", /* non standard */
-	NULL
-};
-
-/**
- * Creates a new buddy.
- */
-BonjourBuddy *bonjour_buddy_new(const gchar *name, PurpleAccount *account);
-
-/**
- * Clear any existing values from the buddy.
- * This is called before updating so that we can notice removals
- */
-void clear_bonjour_buddy_values(BonjourBuddy *buddy);
-
-/**
- * Sets a value in the BonjourBuddy struct, destroying the old value
- */
-void set_bonjour_buddy_value(BonjourBuddy *buddy, const char *record_key, const char *value, guint32 len);
-
-/**
- * Check if all the compulsory buddy data is present.
- */
-gboolean bonjour_buddy_check(BonjourBuddy *buddy);
-
-/**
- * If the buddy doesn't previously exists, it is created.
- */
-void bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy);
-
-/**
- * The buddy has signed off Bonjour.
- * If the buddy is being saved, mark as offline, otherwise delete
- */
-void bonjour_buddy_signed_off(PurpleContact *contact);
-
-/**
- * We got the buddy icon data; deal with it
- */
-void bonjour_buddy_got_buddy_icon(BonjourBuddy *buddy, gconstpointer data, gsize len);
-
-/**
- * Deletes a buddy from memory.
- */
-void bonjour_buddy_delete(BonjourBuddy *buddy);
-
-#endif /* PURPLE_BONJOUR_BUDDY_H */
diff --git a/libpurple/protocols/bonjour/buddy.c b/libpurple/protocols/bonjour/buddy.c
deleted file mode 100644
--- a/libpurple/protocols/bonjour/buddy.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
- */
-
-#include <glib.h>
-#include <stdlib.h>
-
-#include <purple.h>
-
-#include "buddy.h"
-#include "bonjour.h"
-#include "glibcompat.h"
-
-/**
- * Creates a new buddy.
- */
-BonjourBuddy *
-bonjour_buddy_new(const gchar *name, PurpleAccount* account)
-{
-	BonjourBuddy *buddy = g_new0(BonjourBuddy, 1);
-
-	buddy->account = account;
-	buddy->name = g_strdup(name);
-
-	_mdns_init_buddy(buddy);
-
-	return buddy;
-}
-
-void
-clear_bonjour_buddy_values(BonjourBuddy *buddy)
-{
-	g_clear_pointer(&buddy->first, g_free);
-	g_clear_pointer(&buddy->email, g_free);
-	g_clear_pointer(&buddy->ext, g_free);
-	g_clear_pointer(&buddy->jid, g_free);
-	g_clear_pointer(&buddy->last, g_free);
-	g_clear_pointer(&buddy->msg, g_free);
-	g_clear_pointer(&buddy->nick, g_free);
-	g_clear_pointer(&buddy->node, g_free);
-	g_clear_pointer(&buddy->phsh, g_free);
-	g_clear_pointer(&buddy->status, g_free);
-	g_clear_pointer(&buddy->vc, g_free);
-	g_clear_pointer(&buddy->ver, g_free);
-	g_clear_pointer(&buddy->AIM, g_free);
-}
-
-void
-set_bonjour_buddy_value(BonjourBuddy* buddy, const char *record_key, const char *value, guint32 len){
-	gchar **fld = NULL;
-
-	g_return_if_fail(record_key != NULL);
-
-	if (purple_strequal(record_key, "1st"))
-		fld = &buddy->first;
-	else if(purple_strequal(record_key, "email"))
-		fld = &buddy->email;
-	else if(purple_strequal(record_key, "ext"))
-		fld = &buddy->ext;
-	else if(purple_strequal(record_key, "jid"))
-		fld = &buddy->jid;
-	else if(purple_strequal(record_key, "last"))
-		fld = &buddy->last;
-	else if(purple_strequal(record_key, "msg"))
-		fld = &buddy->msg;
-	else if(purple_strequal(record_key, "nick"))
-		fld = &buddy->nick;
-	else if(purple_strequal(record_key, "node"))
-		fld = &buddy->node;
-	else if(purple_strequal(record_key, "phsh"))
-		fld = &buddy->phsh;
-	else if(purple_strequal(record_key, "status"))
-		fld = &buddy->status;
-	else if(purple_strequal(record_key, "vc"))
-		fld = &buddy->vc;
-	else if(purple_strequal(record_key, "ver"))
-		fld = &buddy->ver;
-	else if(purple_strequal(record_key, "AIM"))
-		fld = &buddy->AIM;
-
-	if(fld == NULL)
-		return;
-
-	g_free(*fld);
-	*fld = NULL;
-	*fld = g_strndup(value, len);
-}
-
-/**
- * Check if all the compulsory buddy data is present.
- */
-gboolean
-bonjour_buddy_check(BonjourBuddy *buddy)
-{
-	if (buddy->account == NULL)
-		return FALSE;
-
-	if (buddy->name == NULL)
-		return FALSE;
-
-	return TRUE;
-}
-
-/**
- * If the buddy does not yet exist, then create it and add it to
- * our buddy list.  In either case we set the correct status for
- * the buddy.
- */
-void
-bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy)
-{
-	PurpleAccount *account = bonjour_buddy->account;
-	PurpleContact *contact = NULL;
-	PurpleContactManager *manager = NULL;
-	PurplePerson *person = NULL;
-	PurplePresence *presence = NULL;
-	PurplePresencePrimitive primitive = PURPLE_PRESENCE_PRIMITIVE_AVAILABLE;
-
-	/* Translate between the Bonjour status and the Purple status */
-	if(bonjour_buddy->status != NULL &&
-	   g_ascii_strcasecmp("dnd", bonjour_buddy->status) == 0)
-	{
-		primitive = PURPLE_PRESENCE_PRIMITIVE_AWAY;
-	}
-
-	/*
-	 * TODO: Figure out the idle time by getting the "away"
-	 * field from the DNS SD.
-	 */
-
-	/* Determine if we already know about this contact. */
-	manager = purple_contact_manager_get_default();
-	contact = purple_contact_manager_find_with_username(manager, account,
-	                                                    bonjour_buddy->name);
-
-	/* If not, create the contact and add them to the manager. */
-	if(!PURPLE_IS_CONTACT(contact)) {
-		PurpleTags *tags = NULL;
-
-		contact = purple_contact_new(account, NULL);
-		purple_contact_manager_add(manager, contact);
-
-		purple_contact_info_set_username(PURPLE_CONTACT_INFO(contact),
-		                                 bonjour_buddy->name);
-
-		tags = purple_contact_info_get_tags(PURPLE_CONTACT_INFO(contact));
-		purple_tags_add_with_value(tags, "group", BONJOUR_GROUP_NAME);
-	}
-
-	/* Make sure we have a person for this contact as we want them to appear in
-	 * the contact list.
-	 */
-	person = purple_contact_info_get_person(PURPLE_CONTACT_INFO(contact));
-	if(!PURPLE_IS_PERSON(person)) {
-		person = g_object_new(PURPLE_TYPE_PERSON, "id", bonjour_buddy->name,
-		                      NULL);
-		purple_contact_info_set_person(PURPLE_CONTACT_INFO(contact), person);
-		purple_person_add_contact_info(person, PURPLE_CONTACT_INFO(contact));
-
-		/* We remove our reference as the pointer is valid and we're treating
-		 * it just like if we had called _get_person above but with the new
-		 * instance.
-		 */
-		g_object_unref(person);
-	}
-
-	/* Set the alias. */
-	if(!purple_strempty(bonjour_buddy->nick)) {
-		purple_contact_info_set_alias(PURPLE_CONTACT_INFO(contact),
-		                              bonjour_buddy->nick);
-	} else {
-		GStrvBuilder *builder = NULL;
-		GStrv parts = NULL;
-		gchar *alias = NULL;
-
-		builder = g_strv_builder_new();
-
-		if(!purple_strempty(bonjour_buddy->first)) {
-			g_strv_builder_add(builder, bonjour_buddy->first);
-		}
-
-		if(!purple_strempty(bonjour_buddy->last)) {
-			g_strv_builder_add(builder, bonjour_buddy->last);
-		}
-
-		parts = g_strv_builder_end(builder);
-
-		alias = g_strjoinv(" ", parts);
-		g_strfreev(parts);
-
-		if(!purple_strempty(alias)) {
-			purple_contact_info_set_alias(PURPLE_CONTACT_INFO(contact), alias);
-		} else {
-			purple_contact_info_set_alias(PURPLE_CONTACT_INFO(contact), NULL);
-		}
-		g_free(alias);
-	}
-
-	g_object_set_data(G_OBJECT(contact), "bonjour-buddy", bonjour_buddy);
-
-	/* Set the user's status */
-	presence = purple_contact_info_get_presence(PURPLE_CONTACT_INFO(contact));
-	purple_presence_set_primitive(presence, primitive);
-	purple_presence_set_message(presence, bonjour_buddy->msg);
-	purple_presence_set_idle(presence, FALSE, NULL);
-
-	/* TODO: Because we don't save Bonjour buddies in blist.xml,
-	 * we will always have to look up the buddy icon at login time.
-	 * I think we should figure out a way to do something about this. */
-
-#if 0
-	/* Deal with the buddy icon */
-	old_hash = purple_buddy_icons_get_checksum_for_user(buddy);
-	new_hash = (bonjour_buddy->phsh && *(bonjour_buddy->phsh)) ? bonjour_buddy->phsh : NULL;
-	if (new_hash && !purple_strequal(old_hash, new_hash)) {
-		/* Look up the new icon data */
-		/* TODO: Make sure the hash assigned to the retrieved buddy icon is the same
-		 * as what we looked up. */
-		bonjour_dns_sd_retrieve_buddy_icon(bonjour_buddy);
-	} else if (!new_hash)
-		purple_buddy_icons_set_for_user(account, name, NULL, 0, NULL);
-#endif
-
-	g_clear_object(&contact);
-}
-
-/**
- * The buddy has signed off Bonjour.
- * If the buddy is being saved, mark as offline, otherwise delete
- */
-void bonjour_buddy_signed_off(PurpleContact *contact) {
-	BonjourBuddy *bb = NULL;
-	PurplePresence *presence = NULL;
-
-	presence = purple_contact_info_get_presence(PURPLE_CONTACT_INFO(contact));
-	purple_presence_set_primitive(presence, PURPLE_PRESENCE_PRIMITIVE_OFFLINE);
-
-	bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-	if(bb != NULL) {
-		bonjour_buddy_delete(bb);
-	}
-	g_object_set_data(G_OBJECT(contact), "bonjour-buddy", NULL);
-}
-
-/**
- * We got the buddy icon data; deal with it
- */
-void bonjour_buddy_got_buddy_icon(BonjourBuddy *buddy, gconstpointer data, gsize len) {
-	/* Recalculate the hash instead of using the current phsh to make sure it is accurate for the icon. */
-	gchar *hash;
-
-	if (data == NULL || len == 0)
-		return;
-
-	hash = g_compute_checksum_for_data(G_CHECKSUM_SHA1, data, len);
-
-	purple_debug_info("bonjour", "Got buddy icon for %s icon hash='%s' phsh='%s'.\n", buddy->name,
-			  hash, buddy->phsh ? buddy->phsh : "(null)");
-
-	purple_buddy_icons_set_for_user(buddy->account, buddy->name,
-		g_memdup2(data, len), len, hash);
-
-	g_free(hash);
-}
-
-/**
- * Deletes a buddy from memory.
- */
-void
-bonjour_buddy_delete(BonjourBuddy *buddy)
-{
-	g_free(buddy->name);
-	g_slist_free_full(buddy->ips, g_free);
-	g_free(buddy->first);
-	g_free(buddy->phsh);
-	g_free(buddy->status);
-	g_free(buddy->email);
-	g_free(buddy->last);
-	g_free(buddy->jid);
-	g_free(buddy->AIM);
-	g_free(buddy->vc);
-	g_free(buddy->msg);
-	g_free(buddy->ext);
-	g_free(buddy->nick);
-	g_free(buddy->node);
-	g_free(buddy->ver);
-
-	bonjour_xmpp_close_conversation(buddy->conversation);
-	buddy->conversation = NULL;
-
-	/* Clean up any mdns implementation data */
-	_mdns_delete_buddy(buddy);
-
-	g_free(buddy);
-}
diff --git a/libpurple/protocols/bonjour/dns_sd_proxy.h b/libpurple/protocols/bonjour/dns_sd_proxy.h
deleted file mode 100644
--- a/libpurple/protocols/bonjour/dns_sd_proxy.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
- */
-#ifndef PURPLE_BONJOUR_DNS_SD_PROXY_H
-#define PURPLE_BONJOUR_DNS_SD_PROXY_H
-
-#include <stdint.h>
-
-/* The following is a subset of Apple's dns_sd.h file
- * http://www.opensource.apple.com/source/mDNSResponder/mDNSResponder-333.10/mDNSShared/dns_sd.h
- *
- * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1.  Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
- *     contributors may be used to endorse or promote products derived from this
- *     software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#  if defined(_WIN32) && !defined(EFI32) && !defined(EFI64)
-#    define DNSSD_API __stdcall
-#  else
-#    define DNSSD_API
-#  endif
-
-#  define kDNSServiceInterfaceIndexAny 0
-#  define kDNSServiceMaxDomainName 1009
-
-typedef gint32 DNSServiceErrorType;
-typedef guint32 DNSServiceFlags;
-typedef struct _DNSServiceRef_t *DNSServiceRef;
-typedef struct _DNSRecordRef_t *DNSRecordRef;
-typedef guint32 DNSServiceProtocol;
-
-typedef union _TXTRecordRef_t {
-	gchar PrivateData[16];
-	gchar *ForceNaturalAlignment;
-} TXTRecordRef;
-
-typedef void (DNSSD_API *DNSServiceBrowseReply)();
-typedef void (DNSSD_API *DNSServiceGetAddrInfoReply)();
-typedef void (DNSSD_API *DNSServiceQueryRecordReply)(
-	DNSServiceRef sdRef, DNSServiceFlags flags, guint32 interfaceIndex,
-	DNSServiceErrorType errorCode, const gchar *fullname,
-	guint16 rrtype, guint16 rrclass, guint16 rdlen, const void *rdata,
-	guint32 ttl, void *context);
-typedef void (DNSSD_API *DNSServiceRegisterReply)();
-typedef void (DNSSD_API *DNSServiceResolveReply)(
-	DNSServiceRef sdRef, DNSServiceFlags flags, guint32 interfaceIndex,
-	DNSServiceErrorType errorCode, const gchar *fullname,
-	const gchar *hosttarget, guint16 port, guint16 txtLen,
-	const guchar *txtRecord, void *context);
-
-enum {
-	kDNSServiceErr_NoError = 0,
-	kDNSServiceErr_Unknown = -65537,
-};
-
-enum {
-	kDNSServiceFlagsAdd = 0x2,
-	kDNSServiceFlagsLongLivedQuery = 0x100,
-};
-
-enum {
-	kDNSServiceType_NULL = 10,
-	kDNSServiceType_TXT = 16,
-};
-
-enum {
-	kDNSServiceClass_IN = 1,
-};
-
-enum {
-	kDNSServiceProtocol_IPv4 = 0x01,
-};
-
-
-gboolean dns_sd_available(void);
-
-DNSServiceErrorType _wpurple_DNSServiceAddRecord(DNSServiceRef sdRef, DNSRecordRef *RecordRef, DNSServiceFlags flags,
-	uint16_t rrtype, uint16_t rdlen, const void *rdata, uint32_t ttl);
-#define DNSServiceAddRecord(sdRef, RecordRef, flags, rrtype, rdlen, rdata, ttl) \
-	_wpurple_DNSServiceAddRecord(sdRef, RecordRef, flags, rrtype, rdlen, rdata, ttl)
-
-DNSServiceErrorType _wpurple_DNSServiceBrowse(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-	const char *regtype, const char *domain, DNSServiceBrowseReply callBack, void *context);
-#define DNSServiceBrowse(sdRef, flags, interfaceIndex, regtype, domain, callBack, context) \
-	_wpurple_DNSServiceBrowse(sdRef, flags, interfaceIndex, regtype, domain, callBack, context)
-
-int _wpurple_DNSServiceConstructFullName(char *fullName, const char *service, const char *regtype, const char *domain);
-#define DNSServiceConstructFullName(fullName, service, regtype, domain) \
-	_wpurple_DNSServiceConstructFullName(fullName, service, regtype, domain)
-
-DNSServiceErrorType _wpurple_DNSServiceGetAddrInfo(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-	DNSServiceProtocol protocol, const char *hostname, DNSServiceGetAddrInfoReply callBack, void *context);
-#define DNSServiceGetAddrInfo(sdRef, flags, interfaceIndex, protocol, hostname, callBack, context) \
-	_wpurple_DNSServiceGetAddrInfo(sdRef, flags, interfaceIndex, protocol, hostname, callBack, context)
-
-DNSServiceErrorType _wpurple_DNSServiceProcessResult(DNSServiceRef sdRef);
-#define DNSServiceProcessResult(sdRef) \
-	_wpurple_DNSServiceProcessResult(sdRef);
-
-DNSServiceErrorType _wpurple_DNSServiceQueryRecord(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-	const char *fullname, uint16_t rrtype, uint16_t rrclass, DNSServiceQueryRecordReply callBack, void *context);
-#define DNSServiceQueryRecord(sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, callBack, context) \
-	_wpurple_DNSServiceQueryRecord(sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, callBack, context)
-
-void _wpurple_DNSServiceRefDeallocate(DNSServiceRef sdRef);
-#define DNSServiceRefDeallocate(sdRef) \
-	_wpurple_DNSServiceRefDeallocate(sdRef)
-
-int _wpurple_DNSServiceRefSockFD(DNSServiceRef sdRef);
-#define DNSServiceRefSockFD(sdRef) \
-	_wpurple_DNSServiceRefSockFD(sdRef)
-
-DNSServiceErrorType _wpurple_DNSServiceRegister(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-	const char *name, const char *regtype, const char *domain, const char *host, uint16_t port, uint16_t txtLen,
-	const void *txtRecord, DNSServiceRegisterReply callBack, void *context);
-#define DNSServiceRegister(sdRef, flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, callBack, context) \
-	_wpurple_DNSServiceRegister(sdRef, flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, callBack, context)
-
-DNSServiceErrorType _wpurple_DNSServiceResolve(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name,
-	const char *regtype, const char *domain, DNSServiceResolveReply callBack, void *context);
-#define DNSServiceResolve(sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context) \
-	_wpurple_DNSServiceResolve(sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context)
-
-DNSServiceErrorType _wpurple_DNSServiceRemoveRecord(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags);
-#define DNSServiceRemoveRecord(sdRef, RecordRef, flags) \
-	_wpurple_DNSServiceRemoveRecord(sdRef, RecordRef, flags)
-
-DNSServiceErrorType _wpurple_DNSServiceUpdateRecord(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags,
-	uint16_t rdlen, const void *rdata, uint32_t ttl);
-#define DNSServiceUpdateRecord(sdRef, RecordRef, flags, rdlen, rdata, ttl) \
-	_wpurple_DNSServiceUpdateRecord(sdRef, RecordRef, flags, rdlen, rdata, ttl)
-
-void _wpurple_TXTRecordCreate(TXTRecordRef *txtRecord, uint16_t bufferLen, void *buffer);
-#define TXTRecordCreate(txtRecord, bufferLen, buffer) \
-	_wpurple_TXTRecordCreate(txtRecord, bufferLen, buffer)
-
-void _wpurple_TXTRecordDeallocate(TXTRecordRef *txtRecord);
-#define TXTRecordDeallocate(txtRecord) \
-	_wpurple_TXTRecordDeallocate(txtRecord)
-
-const void * _wpurple_TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord);
-#define TXTRecordGetBytesPtr(txtRecord) \
-	_wpurple_TXTRecordGetBytesPtr(txtRecord)
-
-uint16_t _wpurple_TXTRecordGetLength(const TXTRecordRef *txtRecord);
-#define TXTRecordGetLength(txtRecord) \
-	_wpurple_TXTRecordGetLength(txtRecord)
-
-const void * _wpurple_TXTRecordGetValuePtr(uint16_t txtLen, const void *txtRecord, const char *key, uint8_t *valueLen);
-#define TXTRecordGetValuePtr(txtLen, txtRecord, key, valueLen) \
-	_wpurple_TXTRecordGetValuePtr(txtLen, txtRecord, key, valueLen)
-
-DNSServiceErrorType _wpurple_TXTRecordSetValue(TXTRecordRef *txtRecord, const char *key, uint8_t valueSize, const void *value);
-#define TXTRecordSetValue(txtRecord, key, valueSize, value) \
-	_wpurple_TXTRecordSetValue(txtRecord, key, valueSize, value)
-
-#endif /* PURPLE_BONJOUR_DNS_SD_PROXY_H */
diff --git a/libpurple/protocols/bonjour/dns_sd_proxy.c b/libpurple/protocols/bonjour/dns_sd_proxy.c
deleted file mode 100644
--- a/libpurple/protocols/bonjour/dns_sd_proxy.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
- */
-
-#include <gmodule.h>
-
-#include <purple.h>
-
-#include "dns_sd_proxy.h"
-
-static DNSServiceErrorType (DNSSD_API* _DNSServiceAddRecord)(DNSServiceRef sdRef, DNSRecordRef *RecordRef, DNSServiceFlags flags,
-		uint16_t rrtype, uint16_t rdlen, const void *rdata, uint32_t ttl);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceBrowse)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-	const char *regtype, const char *domain, DNSServiceBrowseReply callBack, void *context);
-static int (DNSSD_API* _DNSServiceConstructFullName)(char *fullName, const char *service, const char *regtype, const char *domain);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceGetAddrInfo)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-	DNSServiceProtocol protocol, const char *hostname, DNSServiceGetAddrInfoReply callBack, void *context);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceProcessResult)(DNSServiceRef sdRef);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceQueryRecord)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-	const char *fullname, uint16_t rrtype, uint16_t rrclass, DNSServiceQueryRecordReply callBack, void *context);
-static void (DNSSD_API* _DNSServiceRefDeallocate)(DNSServiceRef sdRef);
-static int (DNSSD_API* _DNSServiceRefSockFD)(DNSServiceRef sdRef);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceRegister)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-	const char *name, const char *regtype, const char *domain, const char *host, uint16_t port, uint16_t txtLen,
-	const void *txtRecord, DNSServiceRegisterReply callBack, void *context);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceResolve)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name,
-	const char *regtype, const char *domain, DNSServiceResolveReply callBack, void *context);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceRemoveRecord)(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceUpdateRecord)(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags,
-	uint16_t rdlen, const void *rdata, uint32_t ttl);
-static void (DNSSD_API* _TXTRecordCreate)(TXTRecordRef *txtRecord, uint16_t bufferLen, void *buffer);
-static void (DNSSD_API* _TXTRecordDeallocate)(TXTRecordRef *txtRecord);
-static const void * (DNSSD_API* _TXTRecordGetBytesPtr)(const TXTRecordRef *txtRecord);
-static int16_t (DNSSD_API* _TXTRecordGetLength)(const TXTRecordRef *txtRecord);
-static const void * (DNSSD_API* _TXTRecordGetValuePtr)(uint16_t txtLen, const void *txtRecord, const char *key, uint8_t *valueLen);
-static DNSServiceErrorType (DNSSD_API* _TXTRecordSetValue)(TXTRecordRef *txtRecord, const char *key, uint8_t valueSize, const void *value);
-
-
-gboolean dns_sd_available(void) {
-	static gboolean initialized = FALSE;
-	static gboolean loaded = FALSE;
-
-	if (!initialized) {
-		GModule *dnssd = NULL;
-		initialized = TRUE;
-		if((dnssd = g_module_open("dnssd.dll", 0)) != NULL &&
-		   g_module_symbol(dnssd, "DNSServiceAddRecord", (gpointer *)&_DNSServiceAddRecord) &&
-		   g_module_symbol(dnssd, "DNSServiceBrowse", (gpointer *)&_DNSServiceBrowse) &&
-		   g_module_symbol(dnssd, "DNSServiceConstructFullName", (gpointer *)&_DNSServiceConstructFullName) &&
-		   g_module_symbol(dnssd, "DNSServiceGetAddrInfo", (gpointer *)&_DNSServiceGetAddrInfo) &&
-		   g_module_symbol(dnssd, "DNSServiceProcessResult", (gpointer *)&_DNSServiceProcessResult) &&
-		   g_module_symbol(dnssd, "DNSServiceQueryRecord", (gpointer *)&_DNSServiceQueryRecord) &&
-		   g_module_symbol(dnssd, "DNSServiceRefDeallocate", (gpointer *)&_DNSServiceRefDeallocate) &&
-		   g_module_symbol(dnssd, "DNSServiceRefSockFD", (gpointer *)&_DNSServiceRefSockFD) &&
-		   g_module_symbol(dnssd, "DNSServiceRegister", (gpointer *)&_DNSServiceRegister) &&
-		   g_module_symbol(dnssd, "DNSServiceResolve", (gpointer *)&_DNSServiceResolve) &&
-		   g_module_symbol(dnssd, "DNSServiceRemoveRecord", (gpointer *)&_DNSServiceRemoveRecord) &&
-		   g_module_symbol(dnssd, "DNSServiceUpdateRecord", (gpointer *)&_DNSServiceUpdateRecord) &&
-		   g_module_symbol(dnssd, "TXTRecordCreate", (gpointer *)&_TXTRecordCreate) &&
-		   g_module_symbol(dnssd, "TXTRecordDeallocate", (gpointer *)&_TXTRecordDeallocate) &&
-		   g_module_symbol(dnssd, "TXTRecordGetBytesPtr", (gpointer *)&_TXTRecordGetBytesPtr) &&
-		   g_module_symbol(dnssd, "TXTRecordGetLength", (gpointer *)&_TXTRecordGetLength) &&
-		   g_module_symbol(dnssd, "TXTRecordGetValuePtr", (gpointer *)&_TXTRecordGetValuePtr) &&
-		   g_module_symbol(dnssd, "TXTRecordSetValue", (gpointer *)&_TXTRecordSetValue))
-		{
-			/* TODO: The dnssd module leaks, but there's not a good
-			 * place to put the cleanup yet, as there's quite a bit
-			 * of abstraction between mDNS API here to the actual
-			 * plugin unload. */
-			loaded = TRUE;
-		} else {
-			g_clear_pointer(&dnssd, g_module_close);
-		}
-	}
-	return loaded;
-}
-
-
-DNSServiceErrorType _wpurple_DNSServiceAddRecord(DNSServiceRef sdRef, DNSRecordRef *RecordRef, DNSServiceFlags flags,
-		uint16_t rrtype, uint16_t rdlen, const void *rdata, uint32_t ttl) {
-	g_return_val_if_fail(_DNSServiceAddRecord != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceAddRecord)(sdRef, RecordRef, flags, rrtype, rdlen, rdata, ttl);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceBrowse(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-		const char *regtype, const char *domain, DNSServiceBrowseReply callBack, void *context) {
-	g_return_val_if_fail(_DNSServiceBrowse != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceBrowse)(sdRef, flags, interfaceIndex, regtype, domain, callBack, context);
-}
-
-int _wpurple_DNSServiceConstructFullName(char *fullName, const char *service, const char *regtype, const char *domain) {
-	g_return_val_if_fail(_DNSServiceConstructFullName != NULL, 0);
-	return (_DNSServiceConstructFullName)(fullName, service, regtype, domain);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceGetAddrInfo(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-		DNSServiceProtocol protocol, const char *hostname, DNSServiceGetAddrInfoReply callBack, void *context) {
-	g_return_val_if_fail(_DNSServiceGetAddrInfo != NULL, 0);
-	return (_DNSServiceGetAddrInfo)(sdRef, flags, interfaceIndex, protocol, hostname, callBack, context);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceProcessResult(DNSServiceRef sdRef) {
-	g_return_val_if_fail(_DNSServiceProcessResult != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceProcessResult)(sdRef);
-}
-
-
-DNSServiceErrorType _wpurple_DNSServiceQueryRecord(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-		const char *fullname, uint16_t rrtype, uint16_t rrclass, DNSServiceQueryRecordReply callBack, void *context) {
-	g_return_val_if_fail(_DNSServiceQueryRecord != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceQueryRecord)(sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, callBack, context);
-}
-
-void _wpurple_DNSServiceRefDeallocate(DNSServiceRef sdRef) {
-	g_return_if_fail(_DNSServiceRefDeallocate != NULL);
-	(_DNSServiceRefDeallocate)(sdRef);
-}
-
-int _wpurple_DNSServiceRefSockFD(DNSServiceRef sdRef) {
-	g_return_val_if_fail(_DNSServiceRefSockFD != NULL, -1);
-	return (_DNSServiceRefSockFD)(sdRef);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceRegister(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-		const char *name, const char *regtype, const char *domain, const char *host, uint16_t port, uint16_t txtLen,
-		const void *txtRecord, DNSServiceRegisterReply callBack, void *context) {
-	g_return_val_if_fail(_DNSServiceRegister != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceRegister)(sdRef, flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, callBack, context);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceResolve(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name,
-		const char *regtype, const char *domain, DNSServiceResolveReply callBack, void *context) {
-	g_return_val_if_fail(_DNSServiceResolve != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceResolve)(sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceRemoveRecord(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags) {
-	g_return_val_if_fail(_DNSServiceRemoveRecord != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceRemoveRecord)(sdRef, RecordRef, flags);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceUpdateRecord(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags,
-		uint16_t rdlen, const void *rdata, uint32_t ttl) {
-	g_return_val_if_fail(_DNSServiceUpdateRecord != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceUpdateRecord)(sdRef, RecordRef, flags, rdlen, rdata, ttl);
-}
-
-void _wpurple_TXTRecordCreate(TXTRecordRef *txtRecord, uint16_t bufferLen, void *buffer) {
-	g_return_if_fail(_TXTRecordCreate != NULL);
-	(_TXTRecordCreate)(txtRecord, bufferLen, buffer);
-}
-
-void _wpurple_TXTRecordDeallocate(TXTRecordRef *txtRecord) {
-	g_return_if_fail(_TXTRecordDeallocate != NULL);
-	(_TXTRecordDeallocate)(txtRecord);
-}
-
-const void * _wpurple_TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) {
-	g_return_val_if_fail(_TXTRecordGetBytesPtr != NULL, NULL);
-	return (_TXTRecordGetBytesPtr)(txtRecord);
-}
-
-uint16_t _wpurple_TXTRecordGetLength(const TXTRecordRef *txtRecord) {
-	g_return_val_if_fail(_TXTRecordGetLength != NULL, 0);
-	return (_TXTRecordGetLength)(txtRecord);
-}
-
-const void * _wpurple_TXTRecordGetValuePtr(uint16_t txtLen, const void *txtRecord, const char *key, uint8_t *valueLen) {
-	g_return_val_if_fail(_TXTRecordGetValuePtr != NULL, NULL);
-	return (_TXTRecordGetValuePtr)(txtLen, txtRecord, key, valueLen);
-}
-
-DNSServiceErrorType _wpurple_TXTRecordSetValue(TXTRecordRef *txtRecord, const char *key, uint8_t valueSize, const void *value) {
-	g_return_val_if_fail(_TXTRecordSetValue != NULL, kDNSServiceErr_Unknown);
-	return (_TXTRecordSetValue)(txtRecord, key, valueSize, value);
-}
-
diff --git a/libpurple/protocols/bonjour/mdns_avahi.c b/libpurple/protocols/bonjour/mdns_avahi.c
deleted file mode 100644
--- a/libpurple/protocols/bonjour/mdns_avahi.c
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
- */
-
-#include <purple.h>
-
-#include "buddy.h"
-#include "bonjour.h"
-
-#include <avahi-client/client.h>
-#include <avahi-client/lookup.h>
-#include <avahi-client/publish.h>
-
-#include <avahi-common/address.h>
-#include <avahi-common/malloc.h>
-#include <avahi-common/error.h>
-#include <avahi-common/strlst.h>
-
-#include <avahi-glib/glib-malloc.h>
-#include <avahi-glib/glib-watch.h>
-
-/* Avahi only defines the types that it actually uses (which at this time doesn't include NULL) */
-#ifndef AVAHI_DNS_TYPE_NULL
-#define AVAHI_DNS_TYPE_NULL 0x0A
-#endif
-
-/* data used by avahi bonjour implementation */
-typedef struct {
-	AvahiClient *client;
-	AvahiGLibPoll *glib_poll;
-	AvahiServiceBrowser *sb;
-	AvahiEntryGroup *group;
-	AvahiEntryGroup *buddy_icon_group;
-} AvahiSessionImplData;
-
-typedef struct {
-	AvahiServiceResolver *resolver;
-	AvahiIfIndex interface;
-	AvahiProtocol protocol;
-	gchar *name;
-	gchar *type;
-	gchar *domain;
-	/* This is a reference to the entry in BonjourBuddy->ips */
-	const char *ip;
-} AvahiSvcResolverData;
-
-typedef struct {
-	GSList *resolvers;
-	AvahiRecordBrowser *buddy_icon_rec_browser;
-} AvahiBuddyImplData;
-
-static gint
-_find_resolver_data(gconstpointer a, gconstpointer b) {
-	const AvahiSvcResolverData *rd_a = a;
-	const AvahiSvcResolverData *rd_b = b;
-	gint ret = 1;
-
-	if(rd_a->interface == rd_b->interface
-			&& rd_a->protocol == rd_b->protocol
-			&& purple_strequal(rd_a->name, rd_b->name)
-			&& purple_strequal(rd_a->type, rd_b->type)
-			&& purple_strequal(rd_a->domain, rd_b->domain)) {
-		ret = 0;
-	}
-
-	return ret;
-}
-
-static gint
-_find_resolver_data_by_resolver(gconstpointer a, gconstpointer b) {
-	const AvahiSvcResolverData *rd_a = a;
-	const AvahiServiceResolver *resolver = b;
-	gint ret = 1;
-
-	if(rd_a->resolver == resolver)
-		ret = 0;
-
-	return ret;
-}
-
-static void
-_cleanup_resolver_data(AvahiSvcResolverData *rd) {
-	if (rd->resolver)
-		avahi_service_resolver_free(rd->resolver);
-	g_free(rd->name);
-	g_free(rd->type);
-	g_free(rd->domain);
-	g_free(rd);
-}
-
-
-static void
-_resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface,
-                   AvahiProtocol protocol, AvahiResolverEvent event,
-                   const char *name, const char *type, const char *domain,
-                   G_GNUC_UNUSED const char *host_name, const AvahiAddress *a,
-                   uint16_t port, AvahiStringList *txt,
-                   G_GNUC_UNUSED AvahiLookupResultFlags flags, void *userdata)
-{
-	BonjourBuddy *bb = NULL;
-	PurpleAccount *account = userdata;
-	PurpleContactManager *manager = NULL;
-	PurpleContact *contact = NULL;
-	AvahiStringList *l;
-	size_t size;
-	char *key, *value;
-	char ip[AVAHI_ADDRESS_STR_MAX];
-	AvahiBuddyImplData *b_impl;
-	AvahiSvcResolverData *rd;
-	GSList *res;
-
-	g_return_if_fail(r != NULL);
-
-	manager = purple_contact_manager_get_default();
-	contact = purple_contact_manager_find_with_username(manager, account,
-	                                                    name);
-	if(PURPLE_IS_CONTACT(contact)) {
-		bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-	}
-
-	switch (event) {
-		case AVAHI_RESOLVER_FAILURE:
-			purple_debug_error("bonjour", "_resolve_callback - Failure: %s\n",
-				avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
-
-			avahi_service_resolver_free(r);
-			if (bb != NULL) {
-				b_impl = bb->mdns_impl_data;
-				res = g_slist_find_custom(b_impl->resolvers, r, _find_resolver_data_by_resolver);
-				if (res != NULL) {
-					rd = res->data;
-					b_impl->resolvers = g_slist_delete_link(b_impl->resolvers, res);
-
-					/* We've already freed the resolver */
-					rd->resolver = NULL;
-					_cleanup_resolver_data(rd);
-
-					/* If this was the last resolver, remove the buddy */
-					if (b_impl->resolvers == NULL) {
-						bonjour_buddy_signed_off(contact);
-					}
-				}
-			}
-			break;
-		case AVAHI_RESOLVER_FOUND:
-
-			purple_debug_info("bonjour", "_resolve_callback - name:%s account:%p bb:%p\n",
-				name, account, bb);
-
-			/* create a buddy record */
-			if (bb == NULL)
-				bb = bonjour_buddy_new(name, account);
-			b_impl = bb->mdns_impl_data;
-
-			/* If we're reusing an existing buddy, it may be a new resolver or an existing one. */
-			res = g_slist_find_custom(b_impl->resolvers, r, _find_resolver_data_by_resolver);
-			if (res != NULL)
-				rd = res->data;
-			else {
-				rd = g_new0(AvahiSvcResolverData, 1);
-				rd->resolver = r;
-				rd->interface = interface;
-				rd->protocol = protocol;
-				rd->name = g_strdup(name);
-				rd->type = g_strdup(type);
-				rd->domain = g_strdup(domain);
-
-				b_impl->resolvers = g_slist_prepend(b_impl->resolvers, rd);
-			}
-
-
-			/* Get the ip as a string */
-			ip[0] = '\0';
-			avahi_address_snprint(ip, AVAHI_ADDRESS_STR_MAX, a);
-
-			if (protocol == AVAHI_PROTO_INET6)
-				append_iface_if_linklocal(ip, interface);
-
-			purple_debug_info("bonjour", "_resolve_callback - name:%s ip:%s prev_ip:%s\n",
-				name, ip, rd->ip);
-
-			if (rd->ip == NULL || !purple_strequal(rd->ip, ip)) {
-				/* We store duplicates in bb->ips, so we always remove the one */
-				if (rd->ip != NULL) {
-					bb->ips = g_slist_remove(bb->ips, rd->ip);
-					g_free((gchar *) rd->ip);
-				}
-				rd->ip = g_strdup(ip);
-				/* IPv6 goes at the front of the list and IPv4 at the end so that we "prefer" IPv6, if present */
-				if (protocol == AVAHI_PROTO_INET6) {
-					bb->ips = g_slist_prepend(bb->ips, (gchar *) rd->ip);
-				} else {
-					bb->ips = g_slist_append(bb->ips, (gchar *) rd->ip);
-				}
-			}
-
-			bb->port_p2pj = port;
-
-			/* Obtain the parameters from the text_record */
-			clear_bonjour_buddy_values(bb);
-			for(l = txt; l != NULL; l = l->next) {
-				if (avahi_string_list_get_pair(l, &key, &value, &size) < 0)
-					continue;
-				set_bonjour_buddy_value(bb, key, value, size);
-				/* TODO: Since we're using the glib allocator, I think we
-				 * can use the values instead of re-copying them */
-				avahi_free(key);
-				avahi_free(value);
-			}
-
-			if (!bonjour_buddy_check(bb)) {
-				b_impl->resolvers = g_slist_remove(b_impl->resolvers, rd);
-				_cleanup_resolver_data(rd);
-				/* If this was the last resolver, remove the buddy */
-				if (b_impl->resolvers == NULL) {
-					if (PURPLE_IS_CONTACT(contact)) {
-						bonjour_buddy_signed_off(contact);
-					} else {
-						bonjour_buddy_delete(bb);
-					}
-				}
-			} else {
-				/* Add or update the buddy in our buddy list */
-				bonjour_buddy_add_to_purple(bb);
-			}
-
-			break;
-		default:
-			purple_debug_info("bonjour", "Unrecognized Service Resolver event: %d.\n", event);
-	}
-
-	g_clear_object(&contact);
-}
-
-static void
-_browser_callback(AvahiServiceBrowser *b, AvahiIfIndex interface,
-                  AvahiProtocol protocol, AvahiBrowserEvent event,
-                  const char *name, const char *type, const char *domain,
-                  G_GNUC_UNUSED AvahiLookupResultFlags flags, void *userdata)
-{
-	PurpleAccount *account = userdata;
-
-	switch (event) {
-		case AVAHI_BROWSER_FAILURE:
-			purple_debug_error("bonjour", "_browser_callback - Failure: %s\n",
-				avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
-			/* TODO: This is an error that should be handled. */
-			break;
-		case AVAHI_BROWSER_NEW:
-			/* A new peer has joined the network and uses iChat bonjour */
-			purple_debug_info("bonjour", "_browser_callback - new service\n");
-			/* Make sure it isn't us */
-			if (purple_utf8_strcasecmp(name, bonjour_get_jid(account)) != 0) {
-				if (!avahi_service_resolver_new(avahi_service_browser_get_client(b),
-						interface, protocol, name, type, domain, protocol,
-						0, _resolver_callback, account)) {
-					purple_debug_warning("bonjour", "_browser_callback -- Error initiating resolver: %s\n",
-						avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
-				}
-			}
-			break;
-		case AVAHI_BROWSER_REMOVE: {
-			PurpleContact *contact = NULL;
-			PurpleContactManager *manager = NULL;
-
-			purple_debug_info("bonjour", "_browser_callback - Remove service\n");
-
-			manager = purple_contact_manager_get_default();
-			contact = purple_contact_manager_find_with_username(manager,
-			                                                    account, name);
-			if (PURPLE_IS_CONTACT(contact)) {
-				BonjourBuddy *bb = NULL;
-				AvahiBuddyImplData *b_impl;
-				GSList *l;
-				AvahiSvcResolverData *rd_search;
-
-				bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-				g_return_if_fail(bb != NULL);
-
-				b_impl = bb->mdns_impl_data;
-
-				/* There may be multiple presences, we should only get rid of this one */
-
-				rd_search = g_new0(AvahiSvcResolverData, 1);
-				rd_search->interface = interface;
-				rd_search->protocol = protocol;
-				rd_search->name = (gchar *) name;
-				rd_search->type = (gchar *) type;
-				rd_search->domain = (gchar *) domain;
-
-				l = g_slist_find_custom(b_impl->resolvers, rd_search, _find_resolver_data);
-
-				g_free(rd_search);
-
-				if (l != NULL) {
-					AvahiSvcResolverData *rd = l->data;
-					b_impl->resolvers =
-					        g_slist_delete_link(b_impl->resolvers, l);
-					/* This IP is no longer available */
-					if (rd->ip != NULL) {
-						bb->ips = g_slist_remove(bb->ips, rd->ip);
-						g_free((gchar *) rd->ip);
-					}
-					_cleanup_resolver_data(rd);
-
-					/* If this was the last resolver, remove the buddy */
-					if (b_impl->resolvers == NULL) {
-						bonjour_buddy_signed_off(contact);
-					}
-				}
-			}
-
-			g_clear_object(&contact);
-
-			break;
-		}
-		case AVAHI_BROWSER_ALL_FOR_NOW:
-		case AVAHI_BROWSER_CACHE_EXHAUSTED:
-			break;
-		default:
-			purple_debug_info("bonjour", "Unrecognized Service browser event: %d.\n", event);
-	}
-}
-
-static void
-_buddy_icon_group_cb(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) {
-	BonjourDnsSd *data = userdata;
-	AvahiSessionImplData *idata = data->mdns_impl_data;
-
-	g_return_if_fail(g == idata->buddy_icon_group || idata->buddy_icon_group == NULL);
-
-	switch(state) {
-		case AVAHI_ENTRY_GROUP_ESTABLISHED:
-			purple_debug_info("bonjour", "Successfully registered buddy icon data.\n");
-			break;
-		case AVAHI_ENTRY_GROUP_COLLISION:
-			purple_debug_error("bonjour", "Collision registering buddy icon data.\n");
-			break;
-		case AVAHI_ENTRY_GROUP_FAILURE:
-			purple_debug_error("bonjour", "Error registering buddy icon data: %s.\n",
-				avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
-			break;
-		case AVAHI_ENTRY_GROUP_UNCOMMITED:
-		case AVAHI_ENTRY_GROUP_REGISTERING:
-			break;
-	}
-
-}
-
-static void
-_entry_group_cb(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) {
-	AvahiSessionImplData *idata = userdata;
-
-	g_return_if_fail(g == idata->group || idata->group == NULL);
-
-	switch(state) {
-		case AVAHI_ENTRY_GROUP_ESTABLISHED:
-			purple_debug_info("bonjour", "Successfully registered service.\n");
-			break;
-		case AVAHI_ENTRY_GROUP_COLLISION:
-			purple_debug_error("bonjour", "Collision registering entry group.\n");
-			/* TODO: Handle error - this should log out the account. (Possibly with "wants to die")*/
-			break;
-		case AVAHI_ENTRY_GROUP_FAILURE:
-			purple_debug_error("bonjour", "Error registering entry group: %s\n.",
-				avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
-			/* TODO: Handle error - this should log out the account.*/
-			break;
-		case AVAHI_ENTRY_GROUP_UNCOMMITED:
-		case AVAHI_ENTRY_GROUP_REGISTERING:
-			break;
-	}
-
-}
-
-static void
-_buddy_icon_record_cb(AvahiRecordBrowser *b,
-                      G_GNUC_UNUSED AvahiIfIndex interface,
-                      G_GNUC_UNUSED AvahiProtocol protocol,
-                      AvahiBrowserEvent event, G_GNUC_UNUSED const char *name,
-                      G_GNUC_UNUSED uint16_t clazz,
-                      G_GNUC_UNUSED uint16_t type,
-                      const void *rdata, size_t size,
-                      G_GNUC_UNUSED AvahiLookupResultFlags flags,
-                      void *userdata)
-{
-	BonjourBuddy *buddy = userdata;
-	AvahiBuddyImplData *idata = buddy->mdns_impl_data;
-
-	switch (event) {
-		case AVAHI_BROWSER_CACHE_EXHAUSTED:
-		case AVAHI_BROWSER_ALL_FOR_NOW:
-			/* Ignore these "meta" informational events */
-			return;
-		case AVAHI_BROWSER_NEW:
-			bonjour_buddy_got_buddy_icon(buddy, rdata, size);
-			break;
-		case AVAHI_BROWSER_REMOVE:
-		case AVAHI_BROWSER_FAILURE:
-			purple_debug_error("bonjour", "Error retrieving buddy icon record: %s\n",
-				avahi_strerror(avahi_client_errno(avahi_record_browser_get_client(b))));
-			break;
-	}
-
-	/* Stop listening */
-	avahi_record_browser_free(b);
-	if (idata->buddy_icon_rec_browser == b) {
-		idata->buddy_icon_rec_browser = NULL;
-	}
-}
-
-/****************************
- * mdns_interface functions *
- ****************************/
-
-static gboolean
-avahi_mdns_init_session(BonjourDnsSd *data)
-{
-	AvahiSessionImplData *idata = g_new0(AvahiSessionImplData, 1);
-	const AvahiPoll *poll_api;
-	int error;
-
-	/* Tell avahi to use g_malloc and g_free */
-	avahi_set_allocator (avahi_glib_allocator ());
-
-	/* This currently depends on the glib mainloop,
-	 * we should make it use the libpurple abstraction */
-
-	idata->glib_poll = avahi_glib_poll_new(NULL, G_PRIORITY_DEFAULT);
-
-	poll_api = avahi_glib_poll_get(idata->glib_poll);
-
-	idata->client = avahi_client_new(poll_api, 0, NULL, data, &error);
-
-	if (idata->client == NULL) {
-		purple_debug_error("bonjour", "Error initializing Avahi: %s\n", avahi_strerror(error));
-		avahi_glib_poll_free(idata->glib_poll);
-		g_free(idata);
-		return FALSE;
-	}
-
-	data->mdns_impl_data = idata;
-
-	bonjour_dns_sd_set_jid(data->account, avahi_client_get_host_name(idata->client));
-
-	return TRUE;
-}
-
-static gboolean
-avahi_mdns_publish(BonjourDnsSd *data, PublishType type, GSList *records)
-{
-	int publish_result = 0;
-	AvahiSessionImplData *idata = data->mdns_impl_data;
-	AvahiStringList *lst = NULL;
-
-	g_return_val_if_fail(idata != NULL, FALSE);
-
-	if (!idata->group) {
-		idata->group = avahi_entry_group_new(idata->client,
-						     _entry_group_cb, idata);
-		if (!idata->group) {
-			purple_debug_error("bonjour",
-				"Unable to initialize the data for the mDNS (%s).\n",
-				avahi_strerror(avahi_client_errno(idata->client)));
-			return FALSE;
-		}
-	}
-
-	while (records) {
-		PurpleKeyValuePair *kvp = records->data;
-		lst = avahi_string_list_add_pair(lst, kvp->key, kvp->value);
-		records = records->next;
-	}
-
-	/* Publish the service */
-	switch (type) {
-		case PUBLISH_START:
-			publish_result = avahi_entry_group_add_service_strlst(
-				idata->group, AVAHI_IF_UNSPEC,
-				AVAHI_PROTO_UNSPEC, 0,
-				bonjour_get_jid(data->account),
-				LINK_LOCAL_RECORD_NAME, NULL, NULL, data->port_p2pj, lst);
-			break;
-		case PUBLISH_UPDATE:
-			publish_result = avahi_entry_group_update_service_txt_strlst(
-				idata->group, AVAHI_IF_UNSPEC,
-				AVAHI_PROTO_UNSPEC, 0,
-				bonjour_get_jid(data->account),
-				LINK_LOCAL_RECORD_NAME, NULL, lst);
-			break;
-	}
-
-	/* Free the memory used by temp data */
-	avahi_string_list_free(lst);
-
-	if (publish_result < 0) {
-		purple_debug_error("bonjour",
-			"Failed to add the " LINK_LOCAL_RECORD_NAME " service. Error: %s\n",
-			avahi_strerror(publish_result));
-		return FALSE;
-	}
-
-	if (type == PUBLISH_START
-			&& (publish_result = avahi_entry_group_commit(idata->group)) < 0) {
-		purple_debug_error("bonjour",
-			"Failed to commit " LINK_LOCAL_RECORD_NAME " service. Error: %s\n",
-			avahi_strerror(publish_result));
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static gboolean
-avahi_mdns_browse(BonjourDnsSd *data)
-{
-	AvahiSessionImplData *idata = data->mdns_impl_data;
-
-	g_return_val_if_fail(idata != NULL, FALSE);
-
-	idata->sb = avahi_service_browser_new(idata->client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, LINK_LOCAL_RECORD_NAME, NULL, 0, _browser_callback, data->account);
-	if (!idata->sb) {
-
-		purple_debug_error("bonjour",
-			"Unable to initialize service browser.  Error: %s.\n",
-			avahi_strerror(avahi_client_errno(idata->client)));
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static gboolean
-avahi_mdns_set_buddy_icon_data(BonjourDnsSd *data, gconstpointer avatar_data, gsize avatar_len)
-{
-	AvahiSessionImplData *idata = data->mdns_impl_data;
-
-	if (idata == NULL || idata->client == NULL)
-		return FALSE;
-
-	if (avatar_data != NULL) {
-		gboolean new_group = FALSE;
-		gchar *svc_name;
-		int ret;
-		AvahiPublishFlags flags = 0;
-
-		if (idata->buddy_icon_group == NULL) {
-			purple_debug_info("bonjour", "Setting new buddy icon.\n");
-			new_group = TRUE;
-
-			idata->buddy_icon_group = avahi_entry_group_new(idata->client,
-				_buddy_icon_group_cb, data);
-		} else {
-			purple_debug_info("bonjour", "Updating existing buddy icon.\n");
-			flags |= AVAHI_PUBLISH_UPDATE;
-		}
-
-		if (idata->buddy_icon_group == NULL) {
-			purple_debug_error("bonjour",
-				"Unable to initialize the buddy icon group (%s).\n",
-				avahi_strerror(avahi_client_errno(idata->client)));
-			return FALSE;
-		}
-
-		svc_name = g_strdup_printf("%s." LINK_LOCAL_RECORD_NAME "local",
-				bonjour_get_jid(data->account));
-
-		ret = avahi_entry_group_add_record(idata->buddy_icon_group, AVAHI_IF_UNSPEC,
-			AVAHI_PROTO_UNSPEC, flags, svc_name,
-			AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_NULL, 120, avatar_data, avatar_len);
-
-		g_free(svc_name);
-
-		if (ret < 0) {
-			purple_debug_error("bonjour",
-				"Failed to register buddy icon. Error: %s\n", avahi_strerror(ret));
-			if (new_group) {
-				avahi_entry_group_free(idata->buddy_icon_group);
-				idata->buddy_icon_group = NULL;
-			}
-			return FALSE;
-		}
-
-		if (new_group && (ret = avahi_entry_group_commit(idata->buddy_icon_group)) < 0) {
-			purple_debug_error("bonjour",
-				"Failed to commit buddy icon group. Error: %s\n", avahi_strerror(ret));
-			avahi_entry_group_free(idata->buddy_icon_group);
-			idata->buddy_icon_group = NULL;
-			return FALSE;
-		}
-	} else if (idata->buddy_icon_group != NULL) {
-		purple_debug_info("bonjour", "Removing existing buddy icon.\n");
-		avahi_entry_group_free(idata->buddy_icon_group);
-		idata->buddy_icon_group = NULL;
-	}
-
-	return TRUE;
-}
-
-static void
-avahi_mdns_stop(BonjourDnsSd *data)
-{
-	AvahiSessionImplData *idata = data->mdns_impl_data;
-
-	if (idata == NULL || idata->client == NULL)
-		return;
-
-	if (idata->sb != NULL)
-		avahi_service_browser_free(idata->sb);
-
-	avahi_client_free(idata->client);
-	avahi_glib_poll_free(idata->glib_poll);
-
-	g_free(idata);
-
-	data->mdns_impl_data = NULL;
-}
-
-static void
-avahi_mdns_init_buddy(BonjourBuddy *buddy)
-{
-	buddy->mdns_impl_data = g_new0(AvahiBuddyImplData, 1);
-}
-
-static void
-avahi_mdns_delete_buddy(BonjourBuddy *buddy)
-{
-	AvahiBuddyImplData *idata = buddy->mdns_impl_data;
-
-	g_return_if_fail(idata != NULL);
-
-	if (idata->buddy_icon_rec_browser != NULL)
-		avahi_record_browser_free(idata->buddy_icon_rec_browser);
-
-	g_slist_free_full(idata->resolvers, (GDestroyNotify)_cleanup_resolver_data);
-
-	g_free(idata);
-
-	buddy->mdns_impl_data = NULL;
-}
-
-static void
-avahi_mdns_retrieve_buddy_icon(BonjourBuddy* buddy)
-{
-	PurpleConnection *conn = purple_account_get_connection(buddy->account);
-	BonjourData *bd = purple_connection_get_protocol_data(conn);
-	AvahiSessionImplData *session_idata = bd->dns_sd_data->mdns_impl_data;
-	AvahiBuddyImplData *idata = buddy->mdns_impl_data;
-	gchar *name;
-
-	g_return_if_fail(idata != NULL);
-
-	if (idata->buddy_icon_rec_browser != NULL)
-		avahi_record_browser_free(idata->buddy_icon_rec_browser);
-
-	purple_debug_info("bonjour", "Retrieving buddy icon for '%s'.\n", buddy->name);
-
-	name = g_strdup_printf("%s." LINK_LOCAL_RECORD_NAME "local", buddy->name);
-	idata->buddy_icon_rec_browser = avahi_record_browser_new(session_idata->client, AVAHI_IF_UNSPEC,
-		AVAHI_PROTO_UNSPEC, name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_NULL, 0,
-		_buddy_icon_record_cb, buddy);
-	g_free(name);
-
-	if (!idata->buddy_icon_rec_browser) {
-		purple_debug_error("bonjour",
-			"Unable to initialize buddy icon record browser.  Error: %s.\n",
-			avahi_strerror(avahi_client_errno(session_idata->client)));
-	}
-
-}
-
-gboolean
-mdns_available(void)
-{
-	_mdns_init_session = avahi_mdns_init_session;
-	_mdns_publish = avahi_mdns_publish;
-	_mdns_browse = avahi_mdns_browse;
-	_mdns_stop = avahi_mdns_stop;
-	_mdns_set_buddy_icon_data = avahi_mdns_set_buddy_icon_data;
-	_mdns_init_buddy = avahi_mdns_init_buddy;
-	_mdns_delete_buddy = avahi_mdns_delete_buddy;
-	_mdns_retrieve_buddy_icon = avahi_mdns_retrieve_buddy_icon;
-
-	return TRUE;
-}
diff --git a/libpurple/protocols/bonjour/mdns_common.h b/libpurple/protocols/bonjour/mdns_common.h
deleted file mode 100644
--- a/libpurple/protocols/bonjour/mdns_common.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
- */
-
-#ifndef PURPLE_BONJOUR_MDNS_COMMON_H
-#define PURPLE_BONJOUR_MDNS_COMMON_H
-
-#include "mdns_types.h"
-
-#include "buddy.h"
-
-/**
- * Allocate space for the dns-sd data.
- */
-BonjourDnsSd *bonjour_dns_sd_new(void);
-
-/**
- * Deallocate the space of the dns-sd data.
- */
-void bonjour_dns_sd_free(BonjourDnsSd *data);
-
-/**
- * Send a new dns-sd packet updating our status.
- */
-void bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message);
-
-/**
- * Retrieve the buddy icon blob
- */
-void bonjour_dns_sd_retrieve_buddy_icon(BonjourBuddy* buddy);
-
-/**
- * Deal with a buddy icon update
- */
-void bonjour_dns_sd_update_buddy_icon(BonjourDnsSd *data);
-
-/**
- * Advertise our presence within the dns-sd daemon and start
- * browsing for other bonjour peers.
- */
-gboolean bonjour_dns_sd_start(BonjourDnsSd *data);
-
-/**
- * Unregister the "_presence._tcp" service at the mDNS daemon.
- */
-void bonjour_dns_sd_stop(BonjourDnsSd *data);
-
-void bonjour_dns_sd_set_jid(PurpleAccount *account, const char *hostname);
-
-/****************************
- * mdns_interface functions *
- ****************************/
-
-typedef gboolean mdns_init_session_func(BonjourDnsSd *data);
-extern mdns_init_session_func *_mdns_init_session;
-
-typedef gboolean mdns_publish_func(BonjourDnsSd *data, PublishType type, GSList *records);
-extern mdns_publish_func *_mdns_publish;
-
-typedef gboolean mdns_browse_func(BonjourDnsSd *data);
-extern mdns_browse_func *_mdns_browse;
-
-typedef void mdns_stop_func(BonjourDnsSd *data);
-extern mdns_stop_func *_mdns_stop;
-
-typedef gboolean mdns_set_buddy_icon_data_func(BonjourDnsSd *data, gconstpointer avatar_data, gsize avatar_len);
-extern mdns_set_buddy_icon_data_func *_mdns_set_buddy_icon_data;
-
-typedef void mdns_init_buddy_func(BonjourBuddy *buddy);
-extern mdns_init_buddy_func *_mdns_init_buddy;
-
-typedef void mdns_delete_buddy_func(BonjourBuddy *buddy);
-extern mdns_delete_buddy_func *_mdns_delete_buddy;
-
-typedef void mdns_retrieve_buddy_icon_func(BonjourBuddy* buddy);
-extern mdns_retrieve_buddy_icon_func *_mdns_retrieve_buddy_icon;
-
-gboolean mdns_available(void);
-
-#endif /* PURPLE_BONJOUR_MDNS_COMMON_H */
diff --git a/libpurple/protocols/bonjour/mdns_common.c b/libpurple/protocols/bonjour/mdns_common.c
deleted file mode 100644
--- a/libpurple/protocols/bonjour/mdns_common.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
- */
-
-#include <string.h>
-
-#include <purple.h>
-
-#include "mdns_common.h"
-#include "bonjour.h"
-#include "buddy.h"
-
-
-/****************************
- * mdns_interface functions *
- ****************************/
-
-mdns_init_session_func *_mdns_init_session = NULL;
-mdns_publish_func *_mdns_publish = NULL;
-mdns_browse_func *_mdns_browse = NULL;
-mdns_stop_func *_mdns_stop = NULL;
-mdns_set_buddy_icon_data_func *_mdns_set_buddy_icon_data = NULL;
-mdns_init_buddy_func *_mdns_init_buddy = NULL;
-mdns_delete_buddy_func *_mdns_delete_buddy = NULL;
-mdns_retrieve_buddy_icon_func *_mdns_retrieve_buddy_icon = NULL;
-
-/**
- * Allocate space for the dns-sd data.
- */
-BonjourDnsSd *
-bonjour_dns_sd_new(void) {
-	BonjourDnsSd *data = g_new0(BonjourDnsSd, 1);
-	return data;
-}
-
-/**
- * Deallocate the space of the dns-sd data.
- */
-void bonjour_dns_sd_free(BonjourDnsSd *data) {
-	g_free(data->first);
-	g_free(data->last);
-	g_free(data->phsh);
-	g_free(data->status);
-	g_free(data->vc);
-	g_free(data->msg);
-	g_free(data);
-}
-
-#define MAX_TXT_CONSTITUENT_LEN 255
-
-/* Make sure that the value isn't longer than it is supposed to be */
-static const char*
-get_max_txt_record_value(const char *key, const char *value)
-{
-	/* "each constituent string of a DNS TXT record is limited to 255 bytes"
-	 * This includes the key and the '='
-	 */
-	static char buffer[MAX_TXT_CONSTITUENT_LEN + 1];
-	gchar *end_valid = NULL;
-	int len = MIN(strlen(value), MAX_TXT_CONSTITUENT_LEN - (strlen(key) + 2));
-
-	strncpy(buffer, value, len);
-
-	buffer[len] = '\0';
-
-	/* If we've cut part of a utf-8 character, kill it */
-	if (!g_utf8_validate(buffer, -1, (const gchar **)&end_valid))
-		*end_valid = '\0';
-
-	return buffer;
-}
-
-static inline GSList *
-_add_txt_record(GSList *list, const gchar *key, const gchar *value)
-{
-	const char *max_value = get_max_txt_record_value(key, value);
-	PurpleKeyValuePair *kvp = purple_key_value_pair_new_full(key, g_strdup(max_value), g_free);
-	return g_slist_prepend(list, kvp);
-}
-
-static GSList *generate_presence_txt_records(BonjourDnsSd *data) {
-	GSList *ret = NULL;
-	char portstring[6];
-	const char *jid, *aim, *email;
-
-	/* Convert the port to a string */
-	g_snprintf(portstring, sizeof(portstring), "%d", data->port_p2pj);
-
-	jid = purple_account_get_string(data->account, "jid", NULL);
-	aim = purple_account_get_string(data->account, "AIM", NULL);
-	email = purple_account_get_string(data->account, "email", NULL);
-
-	/* We should try to follow XEP-0174, but some clients have "issues", so we humor them.
-	 * See http://telepathy.freedesktop.org/wiki/SalutInteroperability
-	 */
-
-	/* Large TXT records are problematic.
-	 * While it is technically possible for this to exceed a standard 512-byte
-	 * DNS message, it shouldn't happen unless we get wacky data entered for
-	 * some of the freeform fields.  It is even less likely to exceed the
-	 * recommended maximum of 1300 bytes.
-	 */
-
-	/* Needed by iChat */
-	ret = _add_txt_record(ret, "txtvers", "1");
-	/* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
-	ret = _add_txt_record(ret, "1st", data->first);
-	/* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
-	ret = _add_txt_record(ret, "last", data->last);
-	/* Needed by Adium */
-	ret = _add_txt_record(ret, "port.p2pj", portstring);
-	/* Needed by iChat, Gaim/Pidgin <= 2.0.1 */
-	ret = _add_txt_record(ret, "status", data->status);
-	ret = _add_txt_record(ret, "node", "libpurple");
-	ret = _add_txt_record(ret, "ver", VERSION);
-	/* Currently always set to "!" since we don't support AV and won't ever be in a conference */
-	ret = _add_txt_record(ret, "vc", data->vc);
-	if (email != NULL && *email != '\0') {
-		ret = _add_txt_record(ret, "email", email);
-	}
-	if (jid != NULL && *jid != '\0') {
-		ret = _add_txt_record(ret, "jid", jid);
-	}
-	/* Nonstandard, but used by iChat */
-	if (aim != NULL && *aim != '\0') {
-		ret = _add_txt_record(ret, "AIM", aim);
-	}
-	if (data->msg != NULL && *data->msg != '\0') {
-		ret = _add_txt_record(ret, "msg", data->msg);
-	}
-	if (data->phsh != NULL && *data->phsh != '\0') {
-		ret = _add_txt_record(ret, "phsh", data->phsh);
-	}
-
-	/* TODO: ext, nick */
-	return ret;
-}
-
-static gboolean publish_presence(BonjourDnsSd *data, PublishType type) {
-	GSList *txt_records;
-	gboolean ret;
-
-	txt_records = generate_presence_txt_records(data);
-	ret = _mdns_publish(data, type, txt_records);
-	g_slist_free_full(txt_records, (GDestroyNotify)purple_key_value_pair_free);
-
-	return ret;
-}
-
-/**
- * Send a new dns-sd packet updating our status.
- */
-void bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message) {
-	g_free(data->status);
-	g_free(data->msg);
-
-	data->status = g_strdup(status);
-	data->msg = g_strdup(status_message);
-
-	/* Update our text record with the new status */
-	publish_presence(data, PUBLISH_UPDATE);
-}
-
-/**
- * Retrieve the buddy icon blob
- */
-void bonjour_dns_sd_retrieve_buddy_icon(BonjourBuddy* buddy) {
-	_mdns_retrieve_buddy_icon(buddy);
-}
-
-void bonjour_dns_sd_update_buddy_icon(BonjourDnsSd *data) {
-	PurpleImage *img;
-
-	if ((img = purple_buddy_icons_find_account_icon(data->account))) {
-		gconstpointer avatar_data;
-		gsize avatar_len;
-
-		avatar_data = purple_image_get_data(img);
-		avatar_len = purple_image_get_data_size(img);
-
-		if (_mdns_set_buddy_icon_data(data, avatar_data, avatar_len)) {
-			g_free(data->phsh);
-			data->phsh = NULL;
-
-			data->phsh = g_compute_checksum_for_data(
-				G_CHECKSUM_SHA1, avatar_data, avatar_len);
-
-			/* Update our TXT record */
-			publish_presence(data, PUBLISH_UPDATE);
-		}
-
-		g_object_unref(img);
-	} else {
-		/* We need to do this regardless of whether data->phsh is set so that we
-		 * cancel any icons that are currently in the process of being set */
-		_mdns_set_buddy_icon_data(data, NULL, 0);
-		if (data->phsh != NULL) {
-			/* Clear the buddy icon */
-			g_free(data->phsh);
-			data->phsh = NULL;
-			/* Update our TXT record */
-			publish_presence(data, PUBLISH_UPDATE);
-		}
-	}
-}
-
-/**
- * Advertise our presence within the dns-sd daemon and start browsing
- * for other bonjour peers.
- */
-gboolean bonjour_dns_sd_start(BonjourDnsSd *data) {
-
-	/* Initialize the dns-sd data and session */
-	if (!_mdns_init_session(data))
-		return FALSE;
-
-	/* Publish our bonjour IM client at the mDNS daemon */
-	if (!publish_presence(data, PUBLISH_START))
-		return FALSE;
-
-	/* Advise the daemon that we are waiting for connections */
-	if (!_mdns_browse(data)) {
-		purple_debug_error("bonjour", "Unable to get service.\n");
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-/**
- * Unregister the "_presence._tcp" service at the mDNS daemon.
- */
-
-void bonjour_dns_sd_stop(BonjourDnsSd *data) {
-	_mdns_stop(data);
-}
-
-void
-bonjour_dns_sd_set_jid(PurpleAccount *account, const char *hostname)
-{
-	PurpleConnection *conn = purple_account_get_connection(account);
-	PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
-	BonjourData *bd = purple_connection_get_protocol_data(conn);
-	const char *tmp, *account_name = purple_contact_info_get_username(info);
-
-	/* Previously we allowed the hostname part of the jid to be set
-	 * explicitly when it should always be the current hostname.
-	 * That is what this is intended to deal with.
-	 */
-	if ((tmp = strchr(account_name, '@'))
-	    && strstr(tmp, hostname) == (tmp + 1)
-	    && *((tmp + 1) + strlen(hostname)) == '\0')
-		bd->jid = g_strdup(account_name);
-	else {
-		const char *tmp2;
-		GString *str = g_string_new("");
-		/* Escape an '@' in the account name */
-		tmp = account_name;
-		while ((tmp2 = strchr(tmp, '@')) != NULL) {
-			g_string_append_len(str, tmp, tmp2 - tmp);
-			g_string_append(str, "\\40");
-			tmp = tmp2 + 1;
-		}
-		g_string_append(str, tmp);
-		g_string_append_c(str, '@');
-		g_string_append(str, hostname);
-
-		bd->jid = g_string_free(str, FALSE);
-	}
-}
diff --git a/libpurple/protocols/bonjour/mdns_dns_sd.h b/libpurple/protocols/bonjour/mdns_dns_sd.h
deleted file mode 100644
--- a/libpurple/protocols/bonjour/mdns_dns_sd.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#include <glib.h>
-
-gboolean dns_sd_mdns_available(void);
diff --git a/libpurple/protocols/bonjour/mdns_dns_sd.c b/libpurple/protocols/bonjour/mdns_dns_sd.c
deleted file mode 100644
--- a/libpurple/protocols/bonjour/mdns_dns_sd.c
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
- */
-
-#include <glib/gi18n-lib.h>
-
-#include <purple.h>
-
-#include "buddy.h"
-#ifdef __APPLE_CC__
-#include <dns_sd.h>
-#else
-#include "dns_sd_proxy.h"
-#endif
-#include "mdns_common.h"
-#include "mdns_dns_sd.h"
-#include "bonjour.h"
-
-static GSList *pending_buddies = NULL;
-
-typedef struct {
-	DNSServiceRef sdRef;
-	PurpleAccount *account;
-	guint input_handler;
-} DnsSDServiceRefHandlerData;
-
-/* data used by win32 bonjour implementation */
-typedef struct {
-	DnsSDServiceRefHandlerData *presence_query;
-	DnsSDServiceRefHandlerData *browser_query;
-	DNSRecordRef buddy_icon_rec;
-} Win32SessionImplData;
-
-typedef struct {
-	DnsSDServiceRefHandlerData *txt_query;
-	uint32_t if_idx;
-	gchar *name;
-	gchar *type;
-	gchar *domain;
-	/* This is a reference to the entry in BonjourBuddy->ips */
-	const char *ip;
-} Win32SvcResolverData;
-
-typedef struct {
-	GSList *resolvers;
-	DnsSDServiceRefHandlerData *null_query;
-} Win32BuddyImplData;
-
-/* data structure for the resolve callback */
-typedef struct {
-	DnsSDServiceRefHandlerData *resolver_query;
-	PurpleAccount *account;
-	BonjourBuddy *bb;
-	Win32SvcResolverData *res_data;
-	gchar *full_service_name;
-} ResolveCallbackArgs;
-
-
-static gint
-_find_resolver_data(gconstpointer a, gconstpointer b) {
-	const Win32SvcResolverData *rd_a = a;
-	const Win32SvcResolverData *rd_b = b;
-	gint ret = 1;
-
-	if(rd_a->if_idx == rd_b->if_idx
-			&& purple_strequal(rd_a->name, rd_b->name)
-			&& purple_strequal(rd_a->type, rd_b->type)
-			&& purple_strequal(rd_a->domain, rd_b->domain)) {
-		ret = 0;
-	}
-
-	return ret;
-}
-
-static void
-_cleanup_resolver_data(Win32SvcResolverData *rd) {
-	if (rd->txt_query != NULL) {
-		g_source_remove(rd->txt_query->input_handler);
-		DNSServiceRefDeallocate(rd->txt_query->sdRef);
-		g_free(rd->txt_query);
-	}
-	g_free(rd->name);
-	g_free(rd->type);
-	g_free(rd->domain);
-	g_free(rd);
-}
-
-static void
-_mdns_handle_event(gpointer data, G_GNUC_UNUSED gint source,
-                   G_GNUC_UNUSED PurpleInputCondition condition)
-{
-	DnsSDServiceRefHandlerData *srh = data;
-	DNSServiceErrorType errorCode = DNSServiceProcessResult(srh->sdRef);
-	if (errorCode != kDNSServiceErr_NoError) {
-		purple_debug_error("bonjour", "Error (%d) handling mDNS response.\n", errorCode);
-		/* This happens when the mDNSResponder goes down, I haven't seen it happen any other time (in my limited testing) */
-		if (errorCode == kDNSServiceErr_Unknown) {
-			purple_connection_error(purple_account_get_connection(srh->account),
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Error communicating with local mDNSResponder."));
-		}
-	}
-}
-
-static void
-_mdns_parse_text_record(BonjourBuddy *buddy, const char *record, uint16_t record_len)
-{
-	const char *txt_entry;
-	uint8_t txt_len;
-	int i;
-
-	clear_bonjour_buddy_values(buddy);
-	for (i = 0; buddy_TXT_records[i] != NULL; i++) {
-		txt_entry = TXTRecordGetValuePtr(record_len, record, buddy_TXT_records[i], &txt_len);
-		if (txt_entry != NULL)
-			set_bonjour_buddy_value(buddy, buddy_TXT_records[i], txt_entry, txt_len);
-	}
-}
-
-static void DNSSD_API
-_mdns_record_query_callback(G_GNUC_UNUSED DNSServiceRef DNSServiceRef,
-                            DNSServiceFlags flags,
-                            G_GNUC_UNUSED uint32_t interfaceIndex,
-                            DNSServiceErrorType errorCode,
-                            G_GNUC_UNUSED const char *fullname,
-                            uint16_t rrtype, G_GNUC_UNUSED uint16_t rrclass,
-                            uint16_t rdlen, const void *rdata,
-                            G_GNUC_UNUSED uint32_t ttl, void *context)
-{
-	if (errorCode != kDNSServiceErr_NoError) {
-		purple_debug_error("bonjour", "record query - callback error (%d).\n", errorCode);
-		/* TODO: Probably should remove the buddy when this happens */
-	} else if (flags & kDNSServiceFlagsAdd) {
-		if (rrtype == kDNSServiceType_TXT) {
-			/* New Buddy */
-			BonjourBuddy *bb = (BonjourBuddy*) context;
-			_mdns_parse_text_record(bb, rdata, rdlen);
-			bonjour_buddy_add_to_purple(bb);
-		} else if (rrtype == kDNSServiceType_NULL) {
-			/* Buddy Icon response */
-			BonjourBuddy *bb = (BonjourBuddy*) context;
-			Win32BuddyImplData *idata = bb->mdns_impl_data;
-
-			g_return_if_fail(idata != NULL);
-
-			bonjour_buddy_got_buddy_icon(bb, rdata, rdlen);
-
-			/* We've got what we need; stop listening */
-			g_source_remove(idata->null_query->input_handler);
-			DNSServiceRefDeallocate(idata->null_query->sdRef);
-			g_free(idata->null_query);
-			idata->null_query = NULL;
-		}
-	}
-}
-
-static void DNSSD_API
-_mdns_resolve_host_callback(G_GNUC_UNUSED DNSServiceRef sdRef,
-                            G_GNUC_UNUSED DNSServiceFlags flags,
-                            G_GNUC_UNUSED uint32_t interfaceIndex,
-                            DNSServiceErrorType errorCode,
-                            G_GNUC_UNUSED const char *hostname,
-                            const struct sockaddr *address,
-                            G_GNUC_UNUSED uint32_t ttl, void *context)
-{
-	ResolveCallbackArgs *args = (ResolveCallbackArgs*) context;
-	Win32BuddyImplData *idata = args->bb->mdns_impl_data;
-	PurpleContact *contact = NULL;
-	PurpleContactManager *manager = NULL;
-	gboolean delete_buddy = FALSE;
-
-	g_source_remove(args->resolver_query->input_handler);
-	DNSServiceRefDeallocate(args->resolver_query->sdRef);
-	g_free(args->resolver_query);
-	args->resolver_query = NULL;
-
-	manager = purple_contact_manager_get_default();
-	contact = purple_contact_manager_find_with_username(manager, args->account,
-	                                                    args->res_data->name);
-
-	if (PURPLE_IS_CONTACT(contact)) {
-		if (g_object_get_data(G_OBJECT(contact), "bonjour-buddy") != args->bb) {
-			purple_debug_error("bonjour", "Found purple buddy for %s not matching bonjour buddy record.",
-				args->res_data->name);
-			goto cleanup;
-		}
-	/* Make sure that the BonjourBuddy associated with this request is still around */
-	} else if (g_slist_find(pending_buddies, args->bb) == NULL) {
-		purple_debug_error("bonjour", "host resolution - complete, but buddy no longer pending.\n");
-		goto cleanup;
-	}
-
-	if (errorCode != kDNSServiceErr_NoError) {
-		purple_debug_error("bonjour", "host resolution - callback error (%d).\n", errorCode);
-		delete_buddy = TRUE;
-	} else {
-		DNSServiceRef txt_query_sr;
-		gchar *ip = NULL;
-
-		/* finally, set up the continuous txt record watcher, and add the buddy to purple */
-		errorCode = DNSServiceQueryRecord(&txt_query_sr, kDNSServiceFlagsLongLivedQuery,
-				kDNSServiceInterfaceIndexAny, args->full_service_name, kDNSServiceType_TXT,
-				kDNSServiceClass_IN, _mdns_record_query_callback, args->bb);
-		if (errorCode == kDNSServiceErr_NoError) {
-			GSocketAddress *addr = g_socket_address_new_from_native(
-			        (gpointer)address, sizeof(struct sockaddr_in));
-			if (G_IS_INET_SOCKET_ADDRESS(addr)) {
-				GInetAddress *inet_addr = g_inet_socket_address_get_address(
-				        G_INET_SOCKET_ADDRESS(addr));
-				ip = g_inet_address_to_string(inet_addr);
-			}
-			g_clear_object(&addr);
-		}
-
-		if (ip) {
-			purple_debug_info("bonjour", "Found buddy %s at %s:%d\n", args->bb->name, ip, args->bb->port_p2pj);
-
-			args->bb->ips = g_slist_prepend(args->bb->ips, ip);
-			args->res_data->ip = args->bb->ips->data;
-
-			args->res_data->txt_query = g_new(DnsSDServiceRefHandlerData, 1);
-			args->res_data->txt_query->sdRef = txt_query_sr;
-			args->res_data->txt_query->account = args->account;
-
-			args->res_data->txt_query->input_handler = purple_input_add(DNSServiceRefSockFD(txt_query_sr),
-				PURPLE_INPUT_READ, _mdns_handle_event, args->res_data->txt_query);
-
-			bonjour_buddy_add_to_purple(args->bb);
-		} else {
-			purple_debug_error("bonjour", "Unable to set up record watcher for buddy %s (%d)\n", args->bb->name, errorCode);
-			delete_buddy = TRUE;
-		}
-	}
-
-	cleanup:
-
-	if (delete_buddy) {
-		idata->resolvers = g_slist_remove(idata->resolvers, args->res_data);
-		_cleanup_resolver_data(args->res_data);
-
-		/* If this was the last resolver, remove the buddy */
-		if (idata->resolvers == NULL) {
-			if (PURPLE_IS_CONTACT(contact)) {
-				bonjour_buddy_signed_off(contact);
-			} else {
-				bonjour_buddy_delete(args->bb);
-			}
-
-			/* Remove from the pending list */
-			pending_buddies = g_slist_remove(pending_buddies, args->bb);
-		}
-	} else {
-		/* Remove from the pending list */
-		pending_buddies = g_slist_remove(pending_buddies, args->bb);
-	}
-
-	/* free the remaining args memory */
-	g_free(args->full_service_name);
-	g_free(args);
-
-	g_clear_object(&contact);
-}
-
-static void DNSSD_API
-_mdns_service_resolve_callback(G_GNUC_UNUSED DNSServiceRef sdRef,
-                               G_GNUC_UNUSED DNSServiceFlags flags,
-                               uint32_t interfaceIndex,
-                               DNSServiceErrorType errorCode,
-                               const char *fullname, const char *hosttarget,
-                               uint16_t port, G_GNUC_UNUSED uint16_t txtLen,
-                               G_GNUC_UNUSED const unsigned char *txtRecord,
-                               void *context)
-{
-	ResolveCallbackArgs *args = (ResolveCallbackArgs*) context;
-	Win32BuddyImplData *idata = args->bb->mdns_impl_data;
-
-	/* remove the input fd and destroy the service ref */
-	g_source_remove(args->resolver_query->input_handler);
-	DNSServiceRefDeallocate(args->resolver_query->sdRef);
-
-	if (errorCode != kDNSServiceErr_NoError)
-		purple_debug_error("bonjour", "service resolver - callback error. (%d)\n", errorCode);
-	else {
-		DNSServiceRef getaddrinfo_sr;
-		/* set more arguments, and start the host resolver */
-		errorCode = DNSServiceGetAddrInfo(&getaddrinfo_sr, 0, interfaceIndex,
-			kDNSServiceProtocol_IPv4, hosttarget, _mdns_resolve_host_callback, args);
-		if (errorCode != kDNSServiceErr_NoError)
-			purple_debug_error("bonjour", "service resolver - host resolution failed.\n");
-		else {
-			args->resolver_query->sdRef = getaddrinfo_sr;
-			args->resolver_query->input_handler = purple_input_add(DNSServiceRefSockFD(getaddrinfo_sr),
-				PURPLE_INPUT_READ, _mdns_handle_event, args->resolver_query);
-			args->full_service_name = g_strdup(fullname);
-
-			/* TODO: Should this be per resolver? */
-			args->bb->port_p2pj = g_ntohs(port);
-
-			/* We don't want to hit the cleanup code */
-			return;
-		}
-	}
-
-	/* If we get this far, clean up */
-
-	g_free(args->resolver_query);
-	args->resolver_query = NULL;
-
-	idata->resolvers = g_slist_remove(idata->resolvers, args->res_data);
-	_cleanup_resolver_data(args->res_data);
-
-	/* If this was the last resolver, remove the buddy */
-	if (idata->resolvers == NULL) {
-		PurpleContact *contact = NULL;
-		PurpleContactManager *manager = NULL;
-
-		manager = purple_contact_manager_get_default();
-		contact = purple_contact_manager_find_with_username(manager,
-		                                                    args->account,
-		                                                    args->bb->name);
-
-		/* See if this is now attached to a PurpleContact */
-		if(PURPLE_IS_CONTACT(contact)) {
-			bonjour_buddy_signed_off(contact);
-		} else {
-			/* Remove from the pending list */
-			pending_buddies = g_slist_remove(pending_buddies, args->bb);
-			bonjour_buddy_delete(args->bb);
-		}
-
-		g_clear_object(&contact);
-	}
-
-	g_free(args);
-
-}
-
-static void DNSSD_API
-_mdns_service_register_callback(G_GNUC_UNUSED DNSServiceRef sdRef,
-                                G_GNUC_UNUSED DNSServiceFlags flags,
-                                DNSServiceErrorType errorCode,
-                                G_GNUC_UNUSED const char *name,
-                                G_GNUC_UNUSED const char *regtype,
-                                G_GNUC_UNUSED const char *domain,
-                                G_GNUC_UNUSED void *context)
-{
-	/* TODO: deal with collision */
-	if (errorCode != kDNSServiceErr_NoError)
-		purple_debug_error("bonjour", "service advertisement - callback error (%d).\n", errorCode);
-	else
-		purple_debug_info("bonjour", "service advertisement - callback.\n");
-}
-
-static void DNSSD_API
-_mdns_service_browse_callback(G_GNUC_UNUSED DNSServiceRef sdRef,
-                              DNSServiceFlags flags, uint32_t interfaceIndex,
-                              DNSServiceErrorType errorCode,
-                              const char *serviceName, const char *regtype,
-                              const char *replyDomain, void *context)
-{
-	PurpleAccount *account = (PurpleAccount*)context;
-
-	if (errorCode != kDNSServiceErr_NoError)
-		purple_debug_error("bonjour", "service browser - callback error (%d)\n", errorCode);
-	else if (flags & kDNSServiceFlagsAdd) {
-		/* A presence service instance has been discovered... check it isn't us! */
-		if (purple_utf8_strcasecmp(serviceName, bonjour_get_jid(account)) != 0) {
-			DNSServiceErrorType resErrorCode;
-			/* OK, lets go ahead and resolve it to add to the buddy list */
-			ResolveCallbackArgs *args = g_new0(ResolveCallbackArgs, 1);
-			DNSServiceRef resolver_sr;
-
-			purple_debug_info("bonjour", "Received new record for '%s' on iface %u (%s, %s)\n",
-							  serviceName, interfaceIndex, regtype ? regtype : "",
-							  replyDomain ? replyDomain : "");
-
-			resErrorCode = DNSServiceResolve(&resolver_sr, 0, interfaceIndex, serviceName, regtype,
-					replyDomain, _mdns_service_resolve_callback, args);
-			if (resErrorCode == kDNSServiceErr_NoError) {
-				GSList *tmp = pending_buddies;
-				PurpleBuddy *pb;
-				BonjourBuddy* bb = NULL;
-				Win32SvcResolverData *rd;
-				Win32BuddyImplData *idata;
-
-				/* Is there an existing buddy? */
-				if ((pb = purple_blist_find_buddy(account, serviceName)))
-					bb = purple_buddy_get_protocol_data(pb);
-				/* Is there a pending buddy? */
-				else {
-					while (tmp) {
-						BonjourBuddy *bb_tmp = tmp->data;
-						if (purple_strequal(bb_tmp->name, serviceName)) {
-							bb = bb_tmp;
-							break;
-						}
-						tmp = tmp->next;
-					}
-				}
-
-				if (bb == NULL) {
-					bb = bonjour_buddy_new(serviceName, account);
-
-					/* This is only necessary for the wacky case where someone previously manually added a buddy. */
-					if (pb == NULL)
-						pending_buddies = g_slist_prepend(pending_buddies, bb);
-					else
-						purple_buddy_set_protocol_data(pb, bb);
-				}
-
-				rd = g_new0(Win32SvcResolverData, 1);
-				rd->if_idx = interfaceIndex;
-				rd->name = g_strdup(serviceName);
-				rd->type = g_strdup(regtype);
-				rd->domain = g_strdup(replyDomain);
-
-				idata = bb->mdns_impl_data;
-				idata->resolvers = g_slist_prepend(idata->resolvers, rd);
-
-				args->bb = bb;
-				args->res_data = rd;
-				args->account = account;
-
-				args->resolver_query = g_new(DnsSDServiceRefHandlerData, 1);
-				args->resolver_query->sdRef = resolver_sr;
-				args->resolver_query->account = account;
-				/* get a file descriptor for this service ref, and add it to the input list */
-				args->resolver_query->input_handler = purple_input_add(DNSServiceRefSockFD(resolver_sr),
-					PURPLE_INPUT_READ, _mdns_handle_event, args->resolver_query);
-			} else {
-				purple_debug_error("bonjour", "service browser - failed to resolve service. (%d)\n", resErrorCode);
-				g_free(args);
-			}
-		}
-	} else {
-		PurpleContact *contact = NULL;
-		PurpleContactManager *manager = NULL;
-
-		manager = purple_contact_manager_get_default();
-		contact = purple_contact_manager_find_with_username(manager, account,
-		                                                    serviceName);
-
-		/* A peer has sent a goodbye packet, remove them from the buddy list */
-		purple_debug_info("bonjour", "Received remove notification for '%s' on iface %u (%s, %s)\n",
-						  serviceName, interfaceIndex, regtype ? regtype : "",
-						  replyDomain ? replyDomain : "");
-
-		if(PURPLE_IS_CONTACT(contact)) {
-			GSList *l;
-			/* There may be multiple presences, we should only get rid of this one */
-			Win32SvcResolverData *rd_search;
-			BonjourBuddy *bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-			Win32BuddyImplData *idata;
-
-			g_return_if_fail(bb != NULL);
-
-			idata = bb->mdns_impl_data;
-
-			rd_search = g_new0(Win32SvcResolverData, 1);
-			rd_search->if_idx = interfaceIndex;
-			rd_search->name = (gchar *) serviceName;
-			rd_search->type = (gchar *) regtype;
-			rd_search->domain = (gchar *) replyDomain;
-
-			l = g_slist_find_custom(idata->resolvers, rd_search, _find_resolver_data);
-
-			g_free(rd_search);
-
-			if (l != NULL) {
-				Win32SvcResolverData *rd = l->data;
-				idata->resolvers = g_slist_delete_link(idata->resolvers, l);
-				/* This IP is no longer available */
-				if (rd->ip != NULL) {
-					bb->ips = g_slist_delete_link(bb->ips, l);
-					g_free((gchar *) rd->ip);
-				}
-				_cleanup_resolver_data(rd);
-
-				/* If this was the last resolver, remove the buddy */
-				if (idata->resolvers == NULL) {
-					purple_debug_info("bonjour", "Removed last presence for buddy '%s'; signing off buddy.\n",
-							  serviceName);
-					bonjour_buddy_signed_off(contact);
-				}
-			}
-		} else {
-			purple_debug_warning("bonjour", "Unable to find contact (%s) to remove\n", serviceName ? serviceName : "(null)");
-			/* TODO: Should we look in the pending buddies list? */
-		}
-
-		g_clear_object(&contact);
-	}
-}
-
-/****************************
- * mdns_interface functions *
- ****************************/
-
-static gboolean
-dns_sd_mdns_init_session(BonjourDnsSd *data)
-{
-	data->mdns_impl_data = g_new0(Win32SessionImplData, 1);
-
-	bonjour_dns_sd_set_jid(data->account, g_get_host_name());
-
-	return TRUE;
-}
-
-static gboolean
-dns_sd_mdns_publish(BonjourDnsSd *data, PublishType type, GSList *records)
-{
-	TXTRecordRef dns_data;
-	gboolean ret = TRUE;
-	DNSServiceErrorType errorCode = kDNSServiceErr_NoError;
-	Win32SessionImplData *idata = data->mdns_impl_data;
-
-	g_return_val_if_fail(idata != NULL, FALSE);
-
-	TXTRecordCreate(&dns_data, 256, NULL);
-
-	while (records) {
-		PurpleKeyValuePair *kvp = records->data;
-		errorCode = TXTRecordSetValue(&dns_data, kvp->key, strlen(kvp->value), kvp->value);
-		if (errorCode != kDNSServiceErr_NoError)
-			break;
-		records = records->next;
-	}
-
-	if (errorCode != kDNSServiceErr_NoError) {
-		purple_debug_error("bonjour", "Unable to allocate memory for text record.(%d)\n", errorCode);
-		ret = FALSE;
-	} else {
-		/* OK, we're done constructing the text record, (re)publish the service */
-		DNSServiceRef presence_sr;
-
-		switch (type) {
-			case PUBLISH_START:
-				purple_debug_info("bonjour", "Registering presence on port %d\n", data->port_p2pj);
-				errorCode = DNSServiceRegister(
-				        &presence_sr, 0, kDNSServiceInterfaceIndexAny,
-				        bonjour_get_jid(data->account), LINK_LOCAL_RECORD_NAME,
-				        NULL, NULL, g_htons(data->port_p2pj),
-				        TXTRecordGetLength(&dns_data),
-				        TXTRecordGetBytesPtr(&dns_data),
-				        _mdns_service_register_callback, NULL);
-				break;
-
-			case PUBLISH_UPDATE:
-				purple_debug_info("bonjour", "Updating presence.\n");
-				errorCode = DNSServiceUpdateRecord(idata->presence_query->sdRef, NULL, 0, TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data), 0);
-				break;
-		}
-
-		if (errorCode != kDNSServiceErr_NoError) {
-			purple_debug_error("bonjour", "Failed to publish presence service.(%d)\n", errorCode);
-			ret = FALSE;
-		} else if (type == PUBLISH_START) {
-			/* We need to do this because according to the Apple docs:
-			 * "the client is responsible for ensuring that DNSServiceProcessResult() is called
-			 * whenever there is a reply from the daemon - the daemon may terminate its connection
-			 * with a client that does not process the daemon's responses */
-			idata->presence_query = g_new(DnsSDServiceRefHandlerData, 1);
-			idata->presence_query->sdRef = presence_sr;
-			idata->presence_query->account = data->account;
-			idata->presence_query->input_handler = purple_input_add(DNSServiceRefSockFD(presence_sr),
-				PURPLE_INPUT_READ, _mdns_handle_event, idata->presence_query);
-		}
-	}
-
-	/* Free the memory used by temp data */
-	TXTRecordDeallocate(&dns_data);
-	return ret;
-}
-
-static gboolean
-dns_sd_mdns_browse(BonjourDnsSd *data)
-{
-	DNSServiceErrorType errorCode;
-	Win32SessionImplData *idata = data->mdns_impl_data;
-	DNSServiceRef browser_sr;
-
-	g_return_val_if_fail(idata != NULL, FALSE);
-
-	errorCode = DNSServiceBrowse(&browser_sr, 0, kDNSServiceInterfaceIndexAny,
-			LINK_LOCAL_RECORD_NAME, NULL,_mdns_service_browse_callback,
-			data->account);
-	if (errorCode == kDNSServiceErr_NoError) {
-		idata->browser_query = g_new(DnsSDServiceRefHandlerData, 1);
-		idata->browser_query->sdRef = browser_sr;
-		idata->browser_query->account = data->account;
-		idata->browser_query->input_handler = purple_input_add(DNSServiceRefSockFD(browser_sr),
-			PURPLE_INPUT_READ, _mdns_handle_event, idata->browser_query);
-		return TRUE;
-	} else
-		purple_debug_error("bonjour", "Error registering Local Link presence browser. (%d)\n", errorCode);
-
-
-	return FALSE;
-}
-
-static void
-dns_sd_mdns_stop(BonjourDnsSd *data)
-{
-	Win32SessionImplData *idata = data->mdns_impl_data;
-
-	if (idata == NULL)
-		return;
-
-	if (idata->presence_query != NULL) {
-		g_source_remove(idata->presence_query->input_handler);
-		DNSServiceRefDeallocate(idata->presence_query->sdRef);
-		g_free(idata->presence_query);
-	}
-
-	if (idata->browser_query != NULL) {
-		g_source_remove(idata->browser_query->input_handler);
-		DNSServiceRefDeallocate(idata->browser_query->sdRef);
-		g_free(idata->browser_query);
-	}
-
-	g_free(idata);
-
-	data->mdns_impl_data = NULL;
-}
-
-static gboolean
-dns_sd_mdns_set_buddy_icon_data(BonjourDnsSd *data, gconstpointer avatar_data, gsize avatar_len)
-{
-	Win32SessionImplData *idata = data->mdns_impl_data;
-	DNSServiceErrorType errorCode = kDNSServiceErr_NoError;
-
-	g_return_val_if_fail(idata != NULL, FALSE);
-
-	if (avatar_data != NULL && idata->buddy_icon_rec == NULL) {
-		purple_debug_info("bonjour", "Setting new buddy icon.\n");
-		errorCode = DNSServiceAddRecord(idata->presence_query->sdRef, &idata->buddy_icon_rec,
-			0, kDNSServiceType_NULL, avatar_len, avatar_data, 0);
-	} else if (avatar_data != NULL) {
-		purple_debug_info("bonjour", "Updating existing buddy icon.\n");
-		errorCode = DNSServiceUpdateRecord(idata->presence_query->sdRef, idata->buddy_icon_rec,
-			0, avatar_len, avatar_data, 0);
-	} else if (idata->buddy_icon_rec != NULL) {
-		purple_debug_info("bonjour", "Removing existing buddy icon.\n");
-		errorCode = DNSServiceRemoveRecord(idata->presence_query->sdRef, idata->buddy_icon_rec, 0);
-		idata->buddy_icon_rec = NULL;
-	}
-
-	if (errorCode != kDNSServiceErr_NoError) {
-		purple_debug_error("bonjour", "Error (%d) setting buddy icon record.\n", errorCode);
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static void
-dns_sd_mdns_init_buddy(BonjourBuddy *buddy)
-{
-	buddy->mdns_impl_data = g_new0(Win32BuddyImplData, 1);
-}
-
-static void
-dns_sd_mdns_delete_buddy(BonjourBuddy *buddy)
-{
-	Win32BuddyImplData *idata = buddy->mdns_impl_data;
-
-	g_return_if_fail(idata != NULL);
-
-	while (idata->resolvers) {
-		Win32SvcResolverData *rd = idata->resolvers->data;
-		_cleanup_resolver_data(rd);
-		idata->resolvers = g_slist_delete_link(idata->resolvers, idata->resolvers);
-	}
-
-	if (idata->null_query != NULL) {
-		g_source_remove(idata->null_query->input_handler);
-		DNSServiceRefDeallocate(idata->null_query->sdRef);
-		g_free(idata->null_query);
-	}
-
-	g_free(idata);
-
-	buddy->mdns_impl_data = NULL;
-}
-
-static void
-dns_sd_mdns_retrieve_buddy_icon(BonjourBuddy* buddy)
-{
-	Win32BuddyImplData *idata = buddy->mdns_impl_data;
-	char svc_name[kDNSServiceMaxDomainName];
-
-	g_return_if_fail(idata != NULL);
-
-	/* Cancel any existing query */
-	if (idata->null_query != NULL) {
-		g_source_remove(idata->null_query->input_handler);
-		DNSServiceRefDeallocate(idata->null_query->sdRef);
-		g_free(idata->null_query);
-		idata->null_query = NULL;
-	}
-
-	if (DNSServiceConstructFullName(svc_name, buddy->name, LINK_LOCAL_RECORD_NAME, "local") != 0)
-		purple_debug_error("bonjour", "Unable to construct full name to retrieve buddy icon for %s.\n", buddy->name);
-	else {
-		DNSServiceRef null_query_sr;
-
-		DNSServiceErrorType errorCode = DNSServiceQueryRecord(&null_query_sr, 0, kDNSServiceInterfaceIndexAny,
-			svc_name, kDNSServiceType_NULL, kDNSServiceClass_IN, _mdns_record_query_callback, buddy);
-
-		if (errorCode == kDNSServiceErr_NoError) {
-			idata->null_query = g_new(DnsSDServiceRefHandlerData, 1);
-
-			idata->null_query->sdRef = null_query_sr;
-			idata->null_query->account = buddy->account;
-
-			idata->null_query->input_handler = purple_input_add(DNSServiceRefSockFD(null_query_sr),
-				PURPLE_INPUT_READ, _mdns_handle_event, idata->null_query);
-		} else
-			purple_debug_error("bonjour", "Unable to query buddy icon record for %s. (%d)\n", buddy->name, errorCode);
-	}
-}
-
-gboolean
-dns_sd_mdns_available(void)
-{
-	if (!dns_sd_available()) {
-		return FALSE;
-	}
-
-	_mdns_init_session = dns_sd_mdns_init_session;
-	_mdns_publish = dns_sd_mdns_publish;
-	_mdns_browse = dns_sd_mdns_browse;
-	_mdns_stop = dns_sd_mdns_stop;
-	_mdns_set_buddy_icon_data = dns_sd_mdns_set_buddy_icon_data;
-	_mdns_init_buddy = dns_sd_mdns_init_buddy;
-	_mdns_delete_buddy = dns_sd_mdns_delete_buddy;
-	_mdns_retrieve_buddy_icon = dns_sd_mdns_retrieve_buddy_icon;
-
-	return TRUE;
-}
diff --git a/libpurple/protocols/bonjour/mdns_types.h b/libpurple/protocols/bonjour/mdns_types.h
deleted file mode 100644
--- a/libpurple/protocols/bonjour/mdns_types.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
- */
-
-#ifndef PURPLE_BONJOUR_MDNS_TYPES_H
-#define PURPLE_BONJOUR_MDNS_TYPES_H
-
-#include <glib.h>
-
-#include <purple.h>
-
-#define LINK_LOCAL_RECORD_NAME "_presence._tcp."
-
-/**
- * Data to be used by the dns-sd connection.
- */
-typedef struct {
-	gpointer mdns_impl_data;
-	PurpleAccount *account;
-	gchar *first;
-	gchar *last;
-	gint port_p2pj;
-	gchar *phsh;
-	gchar *status;
-	gchar *vc;
-	gchar *msg;
-} BonjourDnsSd;
-
-typedef enum {
-	PUBLISH_START,
-	PUBLISH_UPDATE
-} PublishType;
-
-#endif /* PURPLE_BONJOUR_MDNS_TYPES_H */
diff --git a/libpurple/protocols/bonjour/mdns_win32.c b/libpurple/protocols/bonjour/mdns_win32.c
deleted file mode 100644
--- a/libpurple/protocols/bonjour/mdns_win32.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#include <purple.h>
-
-#include "mdns_common.h"
-#include "mdns_dns_sd.h"
-
-/****************************
- * mdns_interface functions *
- ****************************/
-
-gboolean
-mdns_available(void)
-{
-	if (dns_sd_mdns_available()) {
-		return TRUE;
-	}
-
-	return FALSE;
-}
diff --git a/libpurple/protocols/bonjour/meson.build b/libpurple/protocols/bonjour/meson.build
deleted file mode 100644
--- a/libpurple/protocols/bonjour/meson.build
+++ /dev/null
@@ -1,46 +0,0 @@
-BONJOUR_SOURCES = [
-	'bonjour.c',
-	'bonjour.h',
-	'buddy.c',
-	'buddy.h',
-	'xmpp.c',
-	'xmpp.h',
-	'mdns_common.c',
-	'mdns_common.h',
-	'mdns_types.h',
-	'parser.c',
-	'parser.h',
-	'bonjour_ft.c',
-	'bonjour_ft.h'
-]
-
-if IS_WIN32
-	BONJOUR_SOURCES += [
-		'dns_sd_proxy.c', 'dns_sd_proxy.h', 'mdns_dns_sd.c', 'mdns_dns_sd.h',
-		'mdns_win32.c'
-	]
-	gmodule = dependency('gmodule-2.0')
-	bonjour_link_args = ['-lnetapi32']
-else
-	BONJOUR_SOURCES += ['mdns_avahi.c']
-	gmodule = []
-	bonjour_link_args = []
-endif
-
-if DYNAMIC_BONJOUR
-	bonjour_resources = gnome.compile_resources('bonjourresource',
-		'resources/bonjour.gresource.xml',
-		source_dir : 'resources',
-		c_name : 'bonjour')
-	BONJOUR_SOURCES += bonjour_resources
-
-	shared_library('bonjour', BONJOUR_SOURCES,
-	    c_args : ['-DG_LOG_USE_STRUCTURED', '-DG_LOG_DOMAIN="Purple-Bonjour"'],
-	    gnu_symbol_visibility : 'hidden',
-	    link_args : bonjour_link_args,
-	    dependencies : [libxml, avahi, libpurple_dep, glib, gmodule, ws2_32],
-	    install : true,
-	    install_dir : PURPLE_PLUGINDIR)
-
-	devenv.append('PURPLE_PLUGIN_PATH', meson.current_build_dir())
-endif
diff --git a/libpurple/protocols/bonjour/parser.h b/libpurple/protocols/bonjour/parser.h
deleted file mode 100644
--- a/libpurple/protocols/bonjour/parser.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * @file parser.h Bonjour XMPP XML parser functions
- *
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- */
-
-#ifndef PURPLE_BONJOUR_PARSER_H
-#define PURPLE_BONJOUR_PARSER_H
-
-#include "buddy.h"
-#include "xmpp.h"
-
-void bonjour_parser_setup(BonjourXMPPConversation *bconv);
-void bonjour_parser_process(BonjourXMPPConversation *bconv, const char *buf, int len);
-
-#endif /* PURPLE_BONJOUR_PARSER_H */
diff --git a/libpurple/protocols/bonjour/parser.c b/libpurple/protocols/bonjour/parser.c
deleted file mode 100644
--- a/libpurple/protocols/bonjour/parser.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * purple - Bonjour XMPP XML parser stuff
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- *
- */
-#include <purple.h>
-
-#include <libxml/parser.h>
-
-#include "parser.h"
-#include "xmpp.h"
-
-static gboolean
-parse_from_attrib_and_find_buddy(BonjourXMPPConversation *bconv, int nb_attributes, const xmlChar **attributes) {
-	int i;
-
-	/* If the "from" attribute is specified, attach it to the conversation. */
-	for(i=0; i < nb_attributes * 5; i+=5) {
-		if(!xmlStrcmp(attributes[i], (xmlChar*) "from")) {
-			int len = attributes[i+4] - attributes[i+3];
-			bconv->buddy_name = g_strndup((char *)attributes[i+3], len);
-			bonjour_xmpp_conv_match_by_name(bconv);
-
-			return (PURPLE_IS_CONTACT(bconv->contact));
-		}
-	}
-
-	return FALSE;
-}
-
-static void
-bonjour_parser_element_start_libxml(void *user_data,
-                                    const xmlChar *element_name,
-                                    const xmlChar *prefix,
-                                    const xmlChar *namespace,
-                                    G_GNUC_UNUSED int nb_namespaces,
-                                    G_GNUC_UNUSED const xmlChar **namespaces,
-                                    int nb_attributes,
-                                    G_GNUC_UNUSED int nb_defaulted,
-                                    const xmlChar **attributes)
-{
-	BonjourXMPPConversation *bconv = user_data;
-
-	PurpleXmlNode *node;
-	int i;
-
-	g_return_if_fail(element_name != NULL);
-
-	if(!xmlStrcmp(element_name, (xmlChar*) "stream")) {
-		if(!bconv->recv_stream_start) {
-			bconv->recv_stream_start = TRUE;
-
-			if(!PURPLE_IS_CONTACT(bconv->contact)) {
-				parse_from_attrib_and_find_buddy(bconv, nb_attributes, attributes);
-			}
-
-			bonjour_xmpp_stream_started(bconv);
-		}
-	} else {
-
-		/* If we haven't yet attached a buddy and this isn't "<stream:features />",
-		 * try to get a "from" attribute as a last resort to match our buddy. */
-		if(!PURPLE_IS_CONTACT(bconv->contact)
-				&& !(prefix && !xmlStrcmp(prefix, (xmlChar*) "stream")
-					&& !xmlStrcmp(element_name, (xmlChar*) "features"))
-				&& !parse_from_attrib_and_find_buddy(bconv, nb_attributes, attributes))
-		{
-			/* We've run out of options for finding who the conversation is from
-			   using explicitly specified stuff; see if we can make a good match
-			   by using the IP */
-			bonjour_xmpp_conv_match_by_ip(bconv);
-		}
-
-		if(bconv->current)
-			node = purple_xmlnode_new_child(bconv->current, (const char*) element_name);
-		else
-			node = purple_xmlnode_new((const char*) element_name);
-		purple_xmlnode_set_namespace(node, (const char*) namespace);
-
-		for(i=0; i < nb_attributes * 5; i+=5) {
-			const char *name = (const char *)attributes[i];
-			const char *prefix = (const char *)attributes[i+1];
-			const char *attrib_ns = (const char *)attributes[i+2];
-			char *txt;
-			int attrib_len = attributes[i+4] - attributes[i+3];
-			char *attrib = g_malloc(attrib_len + 1);
-
-			memcpy(attrib, attributes[i+3], attrib_len);
-			attrib[attrib_len] = '\0';
-
-			txt = attrib;
-			attrib = purple_unescape_text(txt);
-			g_free(txt);
-			purple_xmlnode_set_attrib_full(node, name, attrib_ns, prefix, attrib);
-			g_free(attrib);
-		}
-
-		bconv->current = node;
-	}
-}
-
-static void
-bonjour_parser_element_end_libxml(void *user_data, const xmlChar *element_name,
-                                  G_GNUC_UNUSED const xmlChar *prefix,
-                                  G_GNUC_UNUSED const xmlChar *namespace)
-{
-	BonjourXMPPConversation *bconv = user_data;
-
-	if(!bconv->current) {
-		/* We don't keep a reference to the start stream PurpleXmlNode,
-		 * so we have to check for it here to close the conversation */
-		if(!xmlStrcmp(element_name, (xmlChar*) "stream"))
-			/* Asynchronously close the conversation to prevent bonjour_parser_setup()
-			 * being called from within this context */
-			async_bonjour_xmpp_close_conversation(bconv);
-		return;
-	}
-
-	if(bconv->current->parent) {
-		if(!xmlStrcmp((xmlChar*) bconv->current->name, element_name))
-			bconv->current = bconv->current->parent;
-	} else {
-		PurpleXmlNode *packet = bconv->current;
-		bconv->current = NULL;
-		bonjour_xmpp_process_packet(bconv->contact, packet);
-		purple_xmlnode_free(packet);
-	}
-}
-
-static void
-bonjour_parser_element_text_libxml(void *user_data, const xmlChar *text, int text_len)
-{
-	BonjourXMPPConversation *bconv = user_data;
-
-	if(!bconv->current)
-		return;
-
-	if(!text || !text_len)
-		return;
-
-	purple_xmlnode_insert_data(bconv->current, (const char*) text, text_len);
-}
-
-static void
-bonjour_parser_structured_error_handler(void *user_data, const xmlError *error)
-{
-	BonjourXMPPConversation *bconv = user_data;
-
-	purple_debug_error("bonjour", "XML parser error for BonjourXMPPConversation %p: "
-	                             "Domain %i, code %i, level %i: %s",
-	                   bconv,
-	                   error->domain, error->code, error->level,
-	                   (error->message ? error->message : "(null)\n"));
-}
-
-static xmlSAXHandler bonjour_parser_libxml = {
-	NULL,									/*internalSubset*/
-	NULL,									/*isStandalone*/
-	NULL,									/*hasInternalSubset*/
-	NULL,									/*hasExternalSubset*/
-	NULL,									/*resolveEntity*/
-	NULL,									/*getEntity*/
-	NULL,									/*entityDecl*/
-	NULL,									/*notationDecl*/
-	NULL,									/*attributeDecl*/
-	NULL,									/*elementDecl*/
-	NULL,									/*unparsedEntityDecl*/
-	NULL,									/*setDocumentLocator*/
-	NULL,									/*startDocument*/
-	NULL,									/*endDocument*/
-	NULL,									/*startElement*/
-	NULL,									/*endElement*/
-	NULL,									/*reference*/
-	bonjour_parser_element_text_libxml,		/*characters*/
-	NULL,									/*ignorableWhitespace*/
-	NULL,									/*processingInstruction*/
-	NULL,									/*comment*/
-	NULL,									/*warning*/
-	NULL,									/*error*/
-	NULL,									/*fatalError*/
-	NULL,									/*getParameterEntity*/
-	NULL,									/*cdataBlock*/
-	NULL,									/*externalSubset*/
-	XML_SAX2_MAGIC,							/*initialized*/
-	NULL,									/*_private*/
-	bonjour_parser_element_start_libxml,	/*startElementNs*/
-	bonjour_parser_element_end_libxml,		/*endElementNs*/
-	(xmlStructuredErrorFunc)bonjour_parser_structured_error_handler /*serror*/
-};
-
-void
-bonjour_parser_setup(BonjourXMPPConversation *bconv)
-{
-
-	/* This seems backwards, but it makes sense. The libxml code creates
-	 * the parser context when you try to use it (this way, it can figure
-	 * out the encoding at creation time. So, setting up the parser is
-	 * just a matter of destroying any current parser. */
-	if (bconv->context) {
-		xmlParseChunk(bconv->context, NULL,0,1);
-		xmlFreeParserCtxt(bconv->context);
-		bconv->context = NULL;
-	}
-}
-
-
-void bonjour_parser_process(BonjourXMPPConversation *bconv, const char *buf, int len)
-{
-
-	if (bconv->context == NULL) {
-		/* libxml inconsistently starts parsing on creating the
-		 * parser, so do a ParseChunk right afterwards to force it. */
-		bconv->context = xmlCreatePushParserCtxt(&bonjour_parser_libxml, bconv, buf, len, NULL);
-		xmlParseChunk(bconv->context, "", 0, 0);
-	} else if (xmlParseChunk(bconv->context, buf, len, 0) < 0)
-		/* TODO: What should we do here - I assume we should display an error or something (maybe just print something to the conv?) */
-		purple_debug_error("bonjour", "Error parsing xml.\n");
-
-}
-
diff --git a/libpurple/protocols/bonjour/resources/bonjour.gresource.xml b/libpurple/protocols/bonjour/resources/bonjour.gresource.xml
deleted file mode 100644
--- a/libpurple/protocols/bonjour/resources/bonjour.gresource.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<gresources>
-  <gresource prefix="/im/pidgin/libpurple/bonjour">
-    <file>icons/16x16/apps/im-bonjour.png</file>
-    <file>icons/16x16/apps/scalable/im-bonjour.svg</file>
-    <file>icons/22x22/apps/im-bonjour.png</file>
-    <file>icons/22x22/apps/scalable/im-bonjour.svg</file>
-    <file>icons/48x48/apps/im-bonjour.png</file>
-    <file>icons/scalable/apps/im-bonjour.svg</file>
-  </gresource>
-</gresources>
diff --git a/libpurple/protocols/bonjour/resources/icons/16x16/apps/im-bonjour.png b/libpurple/protocols/bonjour/resources/icons/16x16/apps/im-bonjour.png
deleted file mode 100644
index a5c898ab0de3881ccd2f536856aecde32cf904a8..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/libpurple/protocols/bonjour/resources/icons/16x16/apps/scalable/im-bonjour.svg b/libpurple/protocols/bonjour/resources/icons/16x16/apps/scalable/im-bonjour.svg
deleted file mode 100644
--- a/libpurple/protocols/bonjour/resources/icons/16x16/apps/scalable/im-bonjour.svg
+++ /dev/null
@@ -1,189 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="16px"
-   height="16px"
-   id="svg4239"
-   sodipodi:version="0.32"
-   inkscape:version="0.46"
-   sodipodi:docbase="/home/hbons/GUI/Tango/Gaim Refresh/protocols/16/scalable"
-   sodipodi:docname="bonjour.svg"
-   inkscape:export-filename="/home/hbons/Bureaublad/bonjour.png"
-   inkscape:export-xdpi="90"
-   inkscape:export-ydpi="90"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape">
-  <defs
-     id="defs4241">
-    <inkscape:perspective
-       sodipodi:type="inkscape:persp3d"
-       inkscape:vp_x="0 : 8 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_z="16 : 8 : 1"
-       inkscape:persp3d-origin="8 : 5.3333333 : 1"
-       id="perspective24" />
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient8630">
-      <stop
-         style="stop-color:#ce5c00;stop-opacity:1;"
-         offset="0"
-         id="stop8632" />
-      <stop
-         style="stop-color:#a24700;stop-opacity:1"
-         offset="1"
-         id="stop8634" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient8630"
-       id="linearGradient8636"
-       x1="5.3974791"
-       y1="2.3890932"
-       x2="7.286067"
-       y2="5.4647174"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient8630"
-       id="linearGradient8640"
-       gradientUnits="userSpaceOnUse"
-       x1="5.3974791"
-       y1="2.3890932"
-       x2="7.286067"
-       y2="5.4647174" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient8630"
-       id="linearGradient8644"
-       gradientUnits="userSpaceOnUse"
-       x1="5.3974791"
-       y1="2.3890932"
-       x2="7.286067"
-       y2="5.4647174" />
-    <filter
-       inkscape:collect="always"
-       id="filter8686">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.44714331"
-         id="feGaussianBlur8688" />
-    </filter>
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="22.197802"
-     inkscape:cx="19.610287"
-     inkscape:cy="10.016761"
-     inkscape:current-layer="layer1"
-     showgrid="true"
-     inkscape:grid-bbox="true"
-     inkscape:document-units="px"
-     inkscape:window-width="1440"
-     inkscape:window-height="847"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:grid-points="true"
-     inkscape:snap-nodes="false"
-     inkscape:snap-bbox="true"
-     objecttolerance="10"
-     gridtolerance="10">
-    <inkscape:grid
-       type="xygrid"
-       id="grid7858"
-       visible="true"
-       enabled="true" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata4244">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     id="layer1"
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer">
-    <path
-       style="opacity:1;fill:#888a85;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 12.25 0.8125 C 11.212904 0.82548147 9.8237981 1.3178148 8 2.75 C 13.624569 0.9376896 12.09375 3.9687501 12.09375 3.96875 C 12.730846 2.6945576 15.125 3.1250001 15.125 3.125 C 15.125 3.125 14.531611 0.78394076 12.25 0.8125 z M 5 1 C 5 1 6.2894977 2.4031671 5.96875 3.875 C 6.2142693 3.9629227 6.4825344 4.1298951 6.75 4.3125 C 6.3025525 4.8585397 4.5708564 7.0310338 3.59375 9.53125 C 1.0655137 6.5798281 2.28125 6.2187501 2.28125 6.21875 C 2.28125 6.21875 0.78185481 5.3348778 0.75 4.15625 C 0.75 4.15625 -2.0476392 7.5220008 3.5 9.78125 C 3.0973823 10.886071 2.8800606 12.018686 3.0625 13 C 3.0625 13 3.6157102 11.426301 5.03125 10.96875 C 4.9701968 10.621698 4.9938478 10.192279 5.0625 9.71875 C 5.3532166 7.7135288 6.5068895 5.1127489 6.84375 4.375 C 8.4782617 5.5373726 10.241354 7.9344916 10.75 8.65625 C 8.5490333 9.3974261 5.2127054 9.7062603 5.0625 9.71875 C 5.2473055 9.7481019 12.134313 10.824709 14.9375 8.625 C 14.9375 8.625 13.27052 8.9201184 12.15625 8 C 11.847198 8.2378763 11.367484 8.4425412 10.84375 8.625 C 10.458227 7.6220151 8.2341467 2.1234583 5 1 z M 11 10 C 10.948461 14.034482 8.8749996 13.6875 8.875 13.6875 C 8.875 13.6875 9.2741924 15.554033 8 16 C 8 16 14.4206 15.813404 11 10 z "
-       id="path8669" />
-    <path
-       sodipodi:type="arc"
-       style="fill:#ffac5b;fill-opacity:1;stroke:url(#linearGradient8636);stroke-width:1.5861057;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path3210"
-       sodipodi:cx="5.6698728"
-       sodipodi:cy="3.7607069"
-       sodipodi:rx="2.7512043"
-       sodipodi:ry="2.0574222"
-       d="M 8.421077,3.7607069 A 2.7512043,2.0574222 0 1 1 2.9186685,3.7607069 A 2.7512043,2.0574222 0 1 1 8.421077,3.7607069 z"
-       transform="matrix(0.5452158,0,0,0.7290669,-9.1304146e-2,0.2581915)" />
-    <path
-       sodipodi:type="arc"
-       style="fill:#ffac5b;fill-opacity:1;stroke:url(#linearGradient8640);stroke-width:1.58610499;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path8638"
-       sodipodi:cx="5.6698728"
-       sodipodi:cy="3.7607069"
-       sodipodi:rx="2.7512043"
-       sodipodi:ry="2.0574222"
-       d="M 8.421077,3.7607069 A 2.7512043,2.0574222 0 1 1 2.9186685,3.7607069 A 2.7512043,2.0574222 0 1 1 8.421077,3.7607069 z"
-       transform="matrix(0.5452157,0,0,0.7290676,10.908697,3.2581906)" />
-    <path
-       sodipodi:type="arc"
-       style="fill:#ffac5b;fill-opacity:1;stroke:url(#linearGradient8644);stroke-width:1.58610499;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path8642"
-       sodipodi:cx="5.6698728"
-       sodipodi:cy="3.7607069"
-       sodipodi:rx="2.7512043"
-       sodipodi:ry="2.0574222"
-       d="M 8.421077,3.7607069 A 2.7512043,2.0574222 0 1 1 2.9186685,3.7607069 A 2.7512043,2.0574222 0 1 1 8.421077,3.7607069 z"
-       transform="matrix(0.5452157,0,0,0.7290676,2.9086961,11.25819)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.47685185;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       id="path8682"
-       sodipodi:cx="2.3731835"
-       sodipodi:cy="2.1909397"
-       sodipodi:rx="0.90786207"
-       sodipodi:ry="1.0352813"
-       d="M 3.2810456,2.1909397 A 0.90786207,1.0352813 0 1 1 1.4653214,2.1909397 A 0.90786207,1.0352813 0 1 1 3.2810456,2.1909397 z"
-       transform="matrix(1.1014889,0,0,0.9659211,-0.6140352,-0.1162747)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.47685188;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       id="path8684"
-       sodipodi:cx="2.3731835"
-       sodipodi:cy="2.1909397"
-       sodipodi:rx="0.90786207"
-       sodipodi:ry="1.0352813"
-       d="M 3.2810456,2.1909397 A 0.90786207,1.0352813 0 1 1 1.4653214,2.1909397 A 0.90786207,1.0352813 0 1 1 3.2810456,2.1909397 z"
-       transform="matrix(1.1014889,0,0,0.9659211,10.385965,2.8837252)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.47685188;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       id="path8686"
-       sodipodi:cx="2.3731835"
-       sodipodi:cy="2.1909397"
-       sodipodi:rx="0.90786207"
-       sodipodi:ry="1.0352813"
-       d="M 3.2810456,2.1909397 A 0.90786207,1.0352813 0 1 1 1.4653214,2.1909397 A 0.90786207,1.0352813 0 1 1 3.2810456,2.1909397 z"
-       transform="matrix(1.1014889,0,0,0.9659211,2.3859647,10.883725)" />
-  </g>
-</svg>
diff --git a/libpurple/protocols/bonjour/resources/icons/22x22/apps/im-bonjour.png b/libpurple/protocols/bonjour/resources/icons/22x22/apps/im-bonjour.png
deleted file mode 100644
index 5f27d985387b066bc6da3bbbbce449395c67c68f..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/libpurple/protocols/bonjour/resources/icons/22x22/apps/scalable/im-bonjour.svg b/libpurple/protocols/bonjour/resources/icons/22x22/apps/scalable/im-bonjour.svg
deleted file mode 100644
--- a/libpurple/protocols/bonjour/resources/icons/22x22/apps/scalable/im-bonjour.svg
+++ /dev/null
@@ -1,198 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="24"
-   height="24"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.46"
-   version="1.0"
-   sodipodi:docbase="/home/hbons/Desktop/Gaim Refresh/protocols"
-   sodipodi:docname="bonjour.svg"
-   inkscape:export-filename="/home/hbons/Desktop/Gaim Refresh/protocols/bonjour.png"
-   inkscape:export-xdpi="90"
-   inkscape:export-ydpi="90"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape">
-  <defs
-     id="defs4">
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient3150">
-      <stop
-         style="stop-color:#2e3436;stop-opacity:1;"
-         offset="0"
-         id="stop3152" />
-      <stop
-         style="stop-color:#2e3436;stop-opacity:0;"
-         offset="1"
-         id="stop3154" />
-    </linearGradient>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3150"
-       id="radialGradient3156"
-       cx="10.748654"
-       cy="10.457643"
-       fx="10.748654"
-       fy="10.457643"
-       r="6.6449099"
-       gradientTransform="matrix(-0.842757,5.698892e-16,-4.565819e-9,-0.35721,19.80716,14.19321)"
-       gradientUnits="userSpaceOnUse" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="24.007726"
-     inkscape:cx="19.418659"
-     inkscape:cy="14.593926"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="true"
-     fill="#babdb6"
-     inkscape:window-width="1268"
-     inkscape:window-height="971"
-     inkscape:window-x="6"
-     inkscape:window-y="21" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <image
-       id="image2218"
-       height="24.071428"
-       width="23.131142"
-       sodipodi:absref="/home/hbons/Desktop/indextop20050412.jpg"
-       xlink:href="/home/hbons/Desktop/indextop20050412.jpg"
-       x="0"
-       y="1.0807102"
-       style="opacity:0" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.35;fill:url(#radialGradient3156);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path3140"
-       sodipodi:cx="10.748654"
-       sodipodi:cy="10.457643"
-       sodipodi:rx="6.6449099"
-       sodipodi:ry="2.3675451"
-       d="M 17.393564 10.457643 A 6.6449099 2.3675451 0 1 1  4.1037445,10.457643 A 6.6449099 2.3675451 0 1 1  17.393564 10.457643 z"
-       transform="matrix(1.805894,0,0,1.478326,-7.410926,5.0402)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#f57900;fill-opacity:1;stroke:#ce5c00;stroke-width:1.18495774;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path3210"
-       sodipodi:cx="5.6698728"
-       sodipodi:cy="3.7607069"
-       sodipodi:rx="2.7512043"
-       sodipodi:ry="2.0574222"
-       d="M 8.421077 3.7607069 A 2.7512043 2.0574222 0 1 1  2.9186685,3.7607069 A 2.7512043 2.0574222 0 1 1  8.421077 3.7607069 z"
-       transform="matrix(0.728546,0,0,0.977547,0.373616,1.964643)" />
-    <path
-       style="fill:#babdb6;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1"
-       d="M 26.5,4.3717336 C 30.06901,-1.9135499 35.080181,2.3148691 35.080181,5.6521385 L 32.664416,4.7456069 C 31.625041,2.6021767 26.5,4.3717336 26.5,4.3717336 z "
-       id="rect3251"
-       sodipodi:nodetypes="cccc" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#f57900;fill-opacity:1;stroke:#ce5c00;stroke-width:1.18495774;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path3265"
-       sodipodi:cx="5.6698728"
-       sodipodi:cy="3.7607069"
-       sodipodi:rx="2.7512043"
-       sodipodi:ry="2.0574222"
-       d="M 8.421077 3.7607069 A 2.7512043 2.0574222 0 1 1  2.9186685,3.7607069 A 2.7512043 2.0574222 0 1 1  8.421077 3.7607069 z"
-       transform="matrix(0.728546,0,0,0.977547,16.36486,1.964643)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#f57900;fill-opacity:1;stroke:#ce5c00;stroke-width:1.18495774;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path3267"
-       sodipodi:cx="5.6698728"
-       sodipodi:cy="3.7607069"
-       sodipodi:rx="2.7512043"
-       sodipodi:ry="2.0574222"
-       d="M 8.421077 3.7607069 A 2.7512043 2.0574222 0 1 1  2.9186685,3.7607069 A 2.7512043 2.0574222 0 1 1  8.421077 3.7607069 z"
-       transform="matrix(0.728546,0,0,0.977547,8.383099,14.96465)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.35;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2.36390281;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path3278"
-       sodipodi:cx="5.6698728"
-       sodipodi:cy="3.7607069"
-       sodipodi:rx="2.7512043"
-       sodipodi:ry="2.0574222"
-       d="M 8.421077 3.7607069 A 2.7512043 2.0574222 0 1 1  2.9186685,3.7607069 A 2.7512043 2.0574222 0 1 1  8.421077 3.7607069 z"
-       transform="matrix(0.3652,0,0,0.490017,2.442502,3.775647)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.35;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2.36390281;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path3280"
-       sodipodi:cx="5.6698728"
-       sodipodi:cy="3.7607069"
-       sodipodi:rx="2.7512043"
-       sodipodi:ry="2.0574222"
-       d="M 8.421077 3.7607069 A 2.7512043 2.0574222 0 1 1  2.9186685,3.7607069 A 2.7512043 2.0574222 0 1 1  8.421077 3.7607069 z"
-       transform="matrix(0.3652,0,0,0.490017,18.41586,3.801155)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.35;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2.36390281;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path3282"
-       sodipodi:cx="5.6698728"
-       sodipodi:cy="3.7607069"
-       sodipodi:rx="2.7512043"
-       sodipodi:ry="2.0574222"
-       d="M 8.421077 3.7607069 A 2.7512043 2.0574222 0 1 1  2.9186685,3.7607069 A 2.7512043 2.0574222 0 1 1  8.421077 3.7607069 z"
-       transform="matrix(0.3652,0,0,0.490017,10.4341,16.79505)" />
-    <path
-       style="opacity:1;fill:#babdb6;fill-opacity:1;stroke:#888a85;stroke-width:0.99999976;stroke-miterlimit:4;stroke-opacity:1"
-       d="M 7.7318759,2.7396133 C 12.169337,3.9286259 14.955511,8.0423718 15.280153,9.2539565 C 14.057144,8.5478522 8.4371398,5.666617 8.4371398,5.666617 L 7.7318759,2.7396133 z "
-       id="rect3098"
-       sodipodi:nodetypes="cccc" />
-    <path
-       style="opacity:1;fill:#babdb6;fill-opacity:1;stroke:#888a85;stroke-width:0.99999893;stroke-miterlimit:4;stroke-opacity:1"
-       d="M 8.2402219,17.350151 C 6.3014525,13.204266 8.7140226,9.106829 9.6009641,8.2198893 C 9.6009631,9.6320977 10.392827,15.689612 10.392827,15.689612 L 8.2402219,17.350151 z "
-       id="path3101"
-       sodipodi:nodetypes="cccc" />
-    <path
-       style="opacity:1;fill:#babdb6;fill-opacity:1;stroke:#888a85;stroke-width:0.99999946;stroke-miterlimit:4;stroke-opacity:1"
-       d="M 20.999419,10.287708 C 17.750972,13.53615 13.261202,14.092622 12.049619,13.767978 C 13.272629,13.061875 18.044934,9.5274806 18.044934,9.5274806 L 20.999419,10.287708 z "
-       id="path3103"
-       sodipodi:nodetypes="cccc" />
-    <path
-       style="opacity:1;fill:#babdb6;fill-opacity:1;stroke:#888a85;stroke-width:0.99999946;stroke-miterlimit:4;stroke-opacity:1"
-       d="M 1.5549628,8.708934 C 1.5526429,11.954488 4.7660086,13.487253 6.3046441,13.487253 C 5.4626496,12.028876 3.7044795,9.4471457 3.7044795,9.4471457 L 1.5549628,8.708934 z "
-       id="path3105"
-       sodipodi:nodetypes="cccc" />
-    <path
-       style="opacity:1;fill:#babdb6;fill-opacity:1;stroke:#888a85;stroke-width:0.99999946;stroke-miterlimit:4;stroke-opacity:1"
-       d="M 19.83722,1.3615728 C 16.493168,0.56581196 13.018,2.1889619 12.593131,3.5931305 C 14.361353,3.5931305 16.849492,3.4926544 16.849492,3.4926544 L 19.83722,1.3615728 z "
-       id="path3107"
-       sodipodi:nodetypes="cccc" />
-    <path
-       style="opacity:1;fill:#babdb6;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-miterlimit:4;stroke-opacity:1"
-       d="M 16.5,20.072196 C 19.311894,18.451427 18.826975,15.382116 18.057657,14.049618 C 17.215662,15.507995 16.53488,17.120673 16.53488,17.120673 L 16.5,20.072196 z "
-       id="path3109"
-       sodipodi:nodetypes="cccc" />
-  </g>
-</svg>
diff --git a/libpurple/protocols/bonjour/resources/icons/48x48/apps/im-bonjour.png b/libpurple/protocols/bonjour/resources/icons/48x48/apps/im-bonjour.png
deleted file mode 100644
index 197b33d56fb32ded28df8d95185e7a3ecef37f18..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/libpurple/protocols/bonjour/resources/icons/scalable/apps/im-bonjour.svg b/libpurple/protocols/bonjour/resources/icons/scalable/apps/im-bonjour.svg
deleted file mode 100644
--- a/libpurple/protocols/bonjour/resources/icons/scalable/apps/im-bonjour.svg
+++ /dev/null
@@ -1,207 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="48"
-   height="48"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.46"
-   version="1.0"
-   sodipodi:docbase="/home/hbons/Desktop/Gaim Refresh/protocols/48/scalable"
-   sodipodi:docname="bonjour.svg"
-   inkscape:export-filename="/home/hbons/Desktop/Gaim Refresh/protocols/48/bonjour.png"
-   inkscape:export-xdpi="90"
-   inkscape:export-ydpi="90"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape">
-  <defs
-     id="defs4">
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient2314">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop2316" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop2318" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient3150">
-      <stop
-         style="stop-color:#2e3436;stop-opacity:1;"
-         offset="0"
-         id="stop3152" />
-      <stop
-         style="stop-color:#2e3436;stop-opacity:0;"
-         offset="1"
-         id="stop3154" />
-    </linearGradient>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3150"
-       id="radialGradient3156"
-       cx="10.748654"
-       cy="10.457643"
-       fx="10.748654"
-       fy="10.457643"
-       r="6.6449099"
-       gradientTransform="matrix(-0.934099,4.045903e-17,-5.060684e-9,-0.395926,20.78896,14.59809)"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2314"
-       id="linearGradient2320"
-       x1="11.237947"
-       y1="2.7057509"
-       x2="11.237947"
-       y2="10.98068"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2314"
-       id="linearGradient2324"
-       gradientUnits="userSpaceOnUse"
-       x1="11.237947"
-       y1="2.6204424"
-       x2="11.237947"
-       y2="10.810062" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2314"
-       id="linearGradient2328"
-       gradientUnits="userSpaceOnUse"
-       x1="11.237947"
-       y1="2.876368"
-       x2="11.237947"
-       y2="10.89537" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="12.003863"
-     inkscape:cx="41.170813"
-     inkscape:cy="23.799748"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="true"
-     fill="#f57900"
-     inkscape:window-width="1268"
-     inkscape:window-height="972"
-     inkscape:window-x="6"
-     inkscape:window-y="21" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.35;fill:url(#radialGradient3156);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path3140"
-       sodipodi:cx="10.748654"
-       sodipodi:cy="10.457643"
-       sodipodi:rx="6.6449099"
-       sodipodi:ry="2.3675451"
-       d="M 17.393564 10.457643 A 6.6449099 2.3675451 0 1 1  4.1037445,10.457643 A 6.6449099 2.3675451 0 1 1  17.393564 10.457643 z"
-       transform="matrix(3.611787,0,0,2.323081,-14.82185,18.20605)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#f57900;fill-opacity:1;fill-rule:evenodd;stroke:#ce5c00;stroke-width:0.77285618;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path1341"
-       sodipodi:cx="11.237947"
-       sodipodi:cy="7.9095716"
-       sodipodi:rx="3.0935922"
-       sodipodi:ry="3.0935922"
-       d="M 14.33154 7.9095716 A 3.0935922 3.0935922 0 1 1  8.1443553,7.9095716 A 3.0935922 3.0935922 0 1 1  14.33154 7.9095716 z"
-       transform="matrix(1.290432,0,0,1.297381,-3.009737,-2.680289)" />
-    <path
-       style="fill:#babdb6;fill-opacity:1;fill-rule:evenodd;stroke:#7d7f7a;stroke-width:0.99999958;stroke-miterlimit:4;stroke-opacity:1"
-       d="M 35.46875,4.5366208 C 31.635379,4.6522391 27.705058,6.4906706 25.53125,9.7866208 C 26.103022,9.4743488 35.303923,4.6093611 38.34375,12.599121 C 39.472527,11.34018 43.22049,11.040461 45.5,12.224121 C 44.713989,6.8257933 40.179035,4.3945539 35.46875,4.5366208 z M 17.46875,4.5678708 C 18.127573,6.5529792 17.95859,8.1732436 17.53125,9.1616208 C 21.771815,8.0014671 29.858933,21.430311 30.5,22.505371 C 25.376692,11.592709 20.897066,5.8681195 17.46875,4.5678708 z M 5.34375,7.5678708 C -3.2027906,14.070713 3.9432311,26.177264 13.4375,26.536621 C 12.842607,26.198616 3.4390694,20.691845 9.4375,13.724121 C 7.6531589,13.401091 5.4098365,10.216725 5.34375,7.5678708 z M 21.46875,14.599121 C 14.518079,24.752705 11.892887,31.742633 12.65625,35.567871 C 14.072321,33.976734 15.618903,33.346912 16.75,33.255371 C 13.282151,29.863924 20.985214,15.493469 21.46875,14.599121 z M 37.40625,21.630371 C 36.029184,26.189083 21.006896,27.252123 18.78125,27.380371 C 31.047662,28.025568 38.491655,26.618231 41.5,23.942871 C 39.411924,23.554843 38.044876,22.56197 37.40625,21.630371 z M 33.125,28.599121 C 33.123038,29.265224 33.537967,40.230123 24.458146,38.651097 C 25.058081,40.306995 23.321409,43.5863 21.031089,44.953234 C 30.971079,48.901331 37.527529,36.737136 33.125,28.599121 z "
-       id="rect2206"
-       sodipodi:nodetypes="ccccccccccccccccccccccccc" />
-    <path
-       sodipodi:type="inkscape:offset"
-       inkscape:radius="-0.97818917"
-       inkscape:original="M 35.46875 4.53125 C 31.635379 4.6468685 27.705058 6.4852998 25.53125 9.78125 C 26.103022 9.4689777 35.303923 4.6039901 38.34375 12.59375 C 39.472527 11.334809 43.22049 11.03509 45.5 12.21875 C 44.713989 6.8204222 40.179035 4.3891831 35.46875 4.53125 z M 17.46875 4.5625 C 18.127573 6.5476086 17.95859 8.1678728 17.53125 9.15625 C 21.771815 7.996096 29.858933 21.42494 30.5 22.5 C 25.376692 11.587338 20.897066 5.8627487 17.46875 4.5625 z M 5.34375 7.5625 C -3.2027906 14.065342 3.9432311 26.171893 13.4375 26.53125 C 12.842607 26.193245 3.4390694 20.686474 9.4375 13.71875 C 7.6531589 13.39572 5.4098365 10.211354 5.34375 7.5625 z M 21.46875 14.59375 C 14.518079 24.747334 11.892887 31.737262 12.65625 35.5625 C 14.072321 33.971363 15.618903 33.341541 16.75 33.25 C 13.282151 29.858553 20.985214 15.488098 21.46875 14.59375 z M 37.40625 21.625 C 36.029184 26.183712 21.006896 27.246752 18.78125 27.375 C 31.047662 28.020197 38.491655 26.61286 41.5 23.9375 C 39.411924 23.549472 38.044876 22.556599 37.40625 21.625 z M 33.125 28.59375 C 33.123038 29.259853 33.548571 40.235276 24.46875 38.65625 C 25.068686 40.312149 23.32157 43.601816 21.03125 44.96875 C 30.971239 48.916845 37.527529 36.731765 33.125 28.59375 z "
-       xlink:href="#rect2206"
-       style="opacity:0.4;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999958;stroke-miterlimit:4;stroke-opacity:1"
-       id="path2265"
-       d="M 35.5,6.4375 C 33.368939,6.5017749 31.254587,7.2183109 29.4375,8.375 C 29.955273,8.2616185 30.342793,8.0837857 30.90625,8.03125 C 32.406836,7.8913382 34.078294,8.0394993 35.59375,8.8125 C 36.831972,9.4440897 37.86888,10.628822 38.6875,12.1875 C 39.489624,11.770011 40.411361,11.500994 41.4375,11.4375 C 42.258666,11.386689 43.10461,11.462473 43.9375,11.625 C 43.379009,10.119471 42.589365,8.8531272 41.40625,8.03125 C 39.790488,6.908825 37.677617,6.3718209 35.5,6.4375 z M 18.78125,7.53125 C 18.821476,8.1885616 18.763233,8.7406401 18.65625,9.28125 C 19.760339,9.4560073 20.842148,9.9390765 21.875,10.78125 C 22.166416,11.018866 22.428639,11.416981 22.71875,11.6875 C 22.66814,11.618108 22.612837,11.505519 22.5625,11.4375 C 21.155108,9.5357202 19.912201,8.3834952 18.78125,7.53125 z M 4.78125,10.5 C 2.1367338,13.32142 1.9732812,16.73063 3.5,19.84375 C 4.6796069,22.249077 6.8918614,24.272293 9.5,25.4375 C 9.0508422,24.984485 8.5946267,24.68144 8.1875,24.125 C 7.2714393,22.872975 6.524154,21.350596 6.46875,19.59375 C 6.4232564,18.151162 7.0064835,16.584718 8.0625,15.03125 C 7.2533732,14.545104 6.5354947,13.881423 5.9375,13 C 5.4271977,12.247833 5.0629652,11.390597 4.78125,10.5 z M 37.5625,24 C 36.85358,24.922553 35.872279,25.684009 34.625,26.25 C 33.981881,26.541835 33.133881,26.670217 32.40625,26.90625 C 35.442669,26.486299 37.633021,25.855821 39.1875,25.0625 C 38.533201,24.753288 38.014785,24.406514 37.5625,24 z M 15.59375,27.6875 C 15.447519,28.018151 15.191854,28.433804 15.0625,28.75 C 14.093097,31.119641 13.782747,32.928132 13.6875,34.4375 C 14.296929,34.034852 14.855783,33.77311 15.4375,33.59375 C 14.976511,32.494336 14.815677,31.243494 15,29.84375 C 15.08934,29.165305 15.417606,28.406637 15.59375,27.6875 z M 33.3125,33.78125 C 33.133192,34.418356 33.085183,34.999527 32.78125,35.65625 C 32.13654,37.049308 31.160565,38.398872 29.65625,39.3125 C 28.414521,40.06665 26.766693,40.371954 24.875,40.25 C 24.843897,41.165669 24.622124,42.10692 24.15625,43.03125 C 23.766181,43.805178 23.234663,44.527693 22.625,45.1875 C 26.385249,45.969725 29.45049,44.399 31.40625,41.59375 C 32.935546,39.400201 33.59997,36.546168 33.3125,33.78125 z "
-       inkscape:href="#rect2206" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#f57900;fill-opacity:1;fill-rule:evenodd;stroke:#ce5c00;stroke-width:0.77265418;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2216"
-       sodipodi:cx="11.237947"
-       sodipodi:cy="7.9095716"
-       sodipodi:rx="3.0935922"
-       sodipodi:ry="3.0935922"
-       d="M 14.33154 7.9095716 A 3.0935922 3.0935922 0 1 1  8.1443553,7.9095716 A 3.0935922 3.0935922 0 1 1  14.33154 7.9095716 z"
-       transform="matrix(-0.645216,1.118132,-1.123564,-0.649031,58.6294,10.13592)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#f57900;fill-opacity:1;fill-rule:evenodd;stroke:#ce5c00;stroke-width:0.77285618;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2222"
-       sodipodi:cx="11.237947"
-       sodipodi:cy="7.9095716"
-       sodipodi:rx="3.0935922"
-       sodipodi:ry="3.0935922"
-       d="M 14.33154 7.9095716 A 3.0935922 3.0935922 0 1 1  8.1443553,7.9095716 A 3.0935922 3.0935922 0 1 1  14.33154 7.9095716 z"
-       transform="matrix(-0.645216,-1.117547,1.123565,-0.64869,15.8724,57.25531)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.6;fill:url(#linearGradient2320);fill-opacity:1.0;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.02678573;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2228"
-       sodipodi:cx="11.237947"
-       sodipodi:cy="7.9095716"
-       sodipodi:rx="3.0935922"
-       sodipodi:ry="3.0935922"
-       d="M 14.33154 7.9095716 A 3.0935922 3.0935922 0 1 1  8.1443553,7.9095716 A 3.0935922 3.0935922 0 1 1  14.33154 7.9095716 z"
-       transform="matrix(0.971301,0,0,0.976532,0.576636,-0.142509)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.6;fill:url(#linearGradient2324);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.02678573;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2322"
-       sodipodi:cx="11.237947"
-       sodipodi:cy="7.9095716"
-       sodipodi:rx="3.0935922"
-       sodipodi:ry="3.0935922"
-       d="M 14.33154 7.9095716 A 3.0935922 3.0935922 0 1 1  8.1443553,7.9095716 A 3.0935922 3.0935922 0 1 1  14.33154 7.9095716 z"
-       transform="matrix(0.971301,0,0,0.976532,31.58938,9.755058)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.6;fill:url(#linearGradient2328);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.02678573;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2326"
-       sodipodi:cx="11.237947"
-       sodipodi:cy="7.9095716"
-       sodipodi:rx="3.0935922"
-       sodipodi:ry="3.0935922"
-       d="M 14.33154 7.9095716 A 3.0935922 3.0935922 0 1 1  8.1443553,7.9095716 A 3.0935922 3.0935922 0 1 1  14.33154 7.9095716 z"
-       transform="matrix(0.971301,0,0,0.976532,6.579761,31.79704)" />
-  </g>
-</svg>
diff --git a/libpurple/protocols/bonjour/xmpp.h b/libpurple/protocols/bonjour/xmpp.h
deleted file mode 100644
--- a/libpurple/protocols/bonjour/xmpp.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * @file xmpp.h The Purple interface to mDNS and peer to peer XMPP.
- *
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- *
- */
-
-#ifndef PURPLE_BONJOUR_XMPP_H
-#define PURPLE_BONJOUR_XMPP_H
-
-#include <libxml/parser.h>
-
-#include <purple.h>
-
-typedef struct
-{
-	GSocketService *service;
-	guint16 port;
-	PurpleAccount *account;
-	GSList *pending_conversations;
-} BonjourXMPP;
-
-typedef struct
-{
-	GCancellable *cancellable;
-	GSocketConnection *socket;
-	GInputStream *input;
-	GOutputStream *output;
-	guint rx_handler;
-	guint tx_handler;
-	guint close_timeout;
-	PurpleCircularBuffer *tx_buf;
-	int sent_stream_start; /* 0 = Unsent, 1 = Partial, 2 = Complete */
-	gboolean recv_stream_start;
-	gpointer stream_data;
-	xmlParserCtxt *context;
-	PurpleXmlNode *current;
-	PurpleContact *contact;
-	PurpleAccount *account;
-
-	/* The following are only needed before attaching to a PurpleBuddy */
-	gchar *buddy_name;
-	gchar *ip;
-	/* This points to a data entry in BonjourBuddy->ips */
-	const gchar *ip_link;
-} BonjourXMPPConversation;
-
-/**
- * Start listening for xmpp connections.
- *
- * @return -1 if there was a problem, else returns the listening
- *         port number.
- */
-gint bonjour_xmpp_start(BonjourXMPP *data);
-
-int bonjour_xmpp_send_message(BonjourXMPP *data, const char *to, const char *body);
-
-void bonjour_xmpp_close_conversation(BonjourXMPPConversation *bconv);
-
-void async_bonjour_xmpp_close_conversation(BonjourXMPPConversation *bconv);
-
-void bonjour_xmpp_stream_started(BonjourXMPPConversation *bconv);
-
-void bonjour_xmpp_process_packet(PurpleContact *contact, PurpleXmlNode *packet);
-
-void bonjour_xmpp_stop(BonjourXMPP *data);
-
-void bonjour_xmpp_conv_match_by_ip(BonjourXMPPConversation *bconv);
-
-void bonjour_xmpp_conv_match_by_name(BonjourXMPPConversation *bconv);
-
-typedef enum {
-	XEP_IQ_SET,
-	XEP_IQ_GET,
-	XEP_IQ_RESULT,
-	XEP_IQ_ERROR,
-	XEP_IQ_NONE
-} XepIqType;
-
-typedef struct {
-	XepIqType type;
-	char *id;
-	PurpleXmlNode *node;
-	char *to;
-	void *data;
-} XepIq;
-
-XepIq *xep_iq_new(void *data, XepIqType type, const char *to, const char *from, const char *id);
-int xep_iq_send_and_free(XepIq *iq);
-
-void append_iface_if_linklocal(char *ip, guint32 interface_param);
-
-#endif /* PURPLE_BONJOUR_XMPP_H */
diff --git a/libpurple/protocols/bonjour/xmpp.c b/libpurple/protocols/bonjour/xmpp.c
deleted file mode 100644
--- a/libpurple/protocols/bonjour/xmpp.c
+++ /dev/null
@@ -1,1423 +0,0 @@
-/*
- * purple - Bonjour Protocol Plugin
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- */
-
-#include <glib/gi18n-lib.h>
-
-#include <purple.h>
-
-#include <sys/types.h>
-
-#include <glib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "xmpp.h"
-#include "parser.h"
-#include "bonjour.h"
-#include "buddy.h"
-#include "bonjour_ft.h"
-
-#define STREAM_END "</stream:stream>"
-/* TODO: specify version='1.0' and send stream features */
-#define DOCTYPE "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" \
-		"<stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" from=\"%s\" to=\"%s\">"
-
-enum sent_stream_start_types {
-	NOT_SENT       = 0,
-	PARTIALLY_SENT = 1,
-	FULLY_SENT     = 2
-};
-
-static void
-xep_iq_parse(PurpleXmlNode *packet, PurpleContact *contact);
-
-static BonjourXMPPConversation *
-bonjour_xmpp_conv_new(PurpleContact *contact, PurpleAccount *account,
-                      const char *ip)
-{
-
-	BonjourXMPPConversation *bconv = g_new0(BonjourXMPPConversation, 1);
-	bconv->cancellable = g_cancellable_new();
-	bconv->tx_buf = purple_circular_buffer_new(512);
-	bconv->tx_handler = 0;
-	bconv->rx_handler = 0;
-	bconv->contact = contact;
-	bconv->account = account;
-	bconv->ip = g_strdup(ip);
-
-	bonjour_parser_setup(bconv);
-
-	return bconv;
-}
-
-static const char *
-_font_size_ichat_to_purple(int size)
-{
-	if (size > 24) {
-		return "7";
-	} else if (size >= 21) {
-		return "6";
-	} else if (size >= 17) {
-		return "5";
-	} else if (size >= 14) {
-		return "4";
-	} else if (size >= 12) {
-		return "3";
-	} else if (size >= 10) {
-		return "2";
-	}
-
-	return "1";
-}
-
-static gchar *
-get_xmlnode_contents(PurpleXmlNode *node)
-{
-	gchar *contents;
-
-	contents = purple_xmlnode_to_str(node, NULL);
-
-	/* we just want the stuff inside <font></font>
-	 * There isn't stuff exposed in PurpleXmlNode.c to do this more cleanly. */
-
-	if (contents) {
-		char *bodystart = strchr(contents, '>');
-		char *bodyend = bodystart ? strrchr(bodystart, '<') : NULL;
-		if (bodystart && bodyend && (bodystart + 1) != bodyend) {
-			*bodyend = '\0';
-			memmove(contents, bodystart + 1, (bodyend - bodystart));
-		}
-	}
-
-	return contents;
-}
-
-static void
-_xmpp_parse_and_write_message_to_ui(PurpleXmlNode *message_node,
-                                    PurpleContact *contact)
-{
-	PurpleXmlNode *body_node, *html_node, *events_node;
-	PurpleAccount *account = NULL;
-	PurpleConnection *gc = NULL;
-	gchar *body = NULL;
-	const char *username = NULL;
-
-	account = purple_contact_get_account(contact);
-	gc = purple_account_get_connection(account);
-
-	body_node = purple_xmlnode_get_child(message_node, "body");
-	html_node = purple_xmlnode_get_child(message_node, "html");
-
-	if (body_node == NULL && html_node == NULL) {
-		purple_debug_error("bonjour", "No body or html node found, discarding message.\n");
-		return;
-	}
-
-	events_node = purple_xmlnode_get_child_with_namespace(message_node, "x", "jabber:x:event");
-	if (events_node != NULL) {
-		if (purple_xmlnode_get_child(events_node, "id") != NULL) {
-			/* The user is just typing */
-			/* TODO: Deal with typing notification */
-			return;
-		}
-	}
-
-	if (html_node != NULL) {
-		PurpleXmlNode *html_body_node;
-
-		html_body_node = purple_xmlnode_get_child(html_node, "body");
-		if (html_body_node != NULL) {
-			PurpleXmlNode *html_body_font_node;
-
-			html_body_font_node = purple_xmlnode_get_child(html_body_node, "font");
-			/* Types of messages sent by iChat */
-			if (html_body_font_node != NULL) {
-				gchar *html_body;
-				const char *font_face, *font_size, *font_color,
-					*ichat_balloon_color, *ichat_text_color;
-
-				font_face = purple_xmlnode_get_attrib(html_body_font_node, "face");
-				/* The absolute iChat font sizes should be converted to 1..7 range */
-				font_size = purple_xmlnode_get_attrib(html_body_font_node, "ABSZ");
-				if (font_size != NULL)
-					font_size = _font_size_ichat_to_purple(atoi(font_size));
-				font_color = purple_xmlnode_get_attrib(html_body_font_node, "color");
-				ichat_balloon_color = purple_xmlnode_get_attrib(html_body_node, "ichatballooncolor");
-				ichat_text_color = purple_xmlnode_get_attrib(html_body_node, "ichattextcolor");
-
-				html_body = get_xmlnode_contents(html_body_font_node);
-
-				if (html_body == NULL)
-					/* This is the kind of formatted messages that Purple creates */
-					html_body = purple_xmlnode_to_str(html_body_font_node, NULL);
-
-				if (html_body != NULL) {
-					GString *str = g_string_new("<font");
-
-					if (font_face)
-						g_string_append_printf(str, " face='%s'", font_face);
-					if (font_size)
-						g_string_append_printf(str, " size='%s'", font_size);
-					if (font_color)
-						g_string_append_printf(str, " color='%s'", font_color);
-					else if (ichat_text_color)
-						g_string_append_printf(str, " color='%s'", ichat_text_color);
-					if (ichat_balloon_color)
-						g_string_append_printf(str, " back='%s'", ichat_balloon_color);
-					g_string_append_printf(str, ">%s</font>", html_body);
-
-					body = g_string_free(str, FALSE);
-
-					g_free(html_body);
-				}
-			}
-		}
-	}
-
-	/* Compose the message */
-	if (body == NULL && body_node != NULL)
-		body = purple_xmlnode_get_data(body_node);
-
-	if (body == NULL) {
-		purple_debug_error("bonjour", "No html body or regular body found.\n");
-		return;
-	}
-
-	/* Send the message to the UI */
-	username = purple_contact_info_get_username(PURPLE_CONTACT_INFO(contact));
-	purple_serv_got_im(gc, username, body, 0, time(NULL));
-
-	g_free(body);
-}
-
-static GSList *
-_find_match_buddies_by_address(const BonjourXMPP *jdata, const char *address)
-{
-	PurpleContactManager *manager = NULL;
-	GListModel *contacts = NULL;
-	GSList *ret = NULL;
-
-	manager = purple_contact_manager_get_default();
-	contacts = purple_contact_manager_get_all(manager, jdata->account);
-	for(guint i = 0; i < g_list_model_get_n_items(contacts); i++) {
-		PurpleContact *contact = NULL;
-		BonjourBuddy *bb = NULL;
-
-		contact = g_list_model_get_item(contacts, i);
-		bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-		if(bb != NULL) {
-			if(g_slist_find_custom(bb->ips, address,
-			                       (GCompareFunc)g_ascii_strcasecmp))
-			{
-				ret = g_slist_prepend(ret, contact);
-			}
-		}
-
-		g_clear_object(&contact);
-	}
-
-	return ret;
-}
-
-static void
-_send_data_write_cb(GObject *stream, gpointer data)
-{
-	PurpleContact *contact = data;
-	BonjourBuddy *bb = NULL;
-	BonjourXMPPConversation *bconv = NULL;
-	gsize writelen;
-	gssize ret;
-	GError *error = NULL;
-
-	bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-	bconv = bb->conversation;
-	writelen = purple_circular_buffer_get_max_read(bconv->tx_buf);
-
-	if (writelen == 0) {
-		g_clear_handle_id(&bconv->tx_handler, g_source_remove);
-		return;
-	}
-
-	ret = g_pollable_output_stream_write_nonblocking(
-	        G_POLLABLE_OUTPUT_STREAM(stream),
-	        purple_circular_buffer_get_output(bconv->tx_buf), writelen,
-	        bconv->cancellable, &error);
-
-	if (ret < 0 && error->code == G_IO_ERROR_WOULD_BLOCK) {
-		g_clear_error(&error);
-		return;
-	} else if (ret <= 0) {
-		PurpleAccount *account = NULL;
-		PurpleConversation *conv = NULL;
-		PurpleConversationManager *manager = NULL;
-
-		manager = purple_conversation_manager_get_default();
-
-		purple_debug_error(
-		        "bonjour",
-		        "Error sending message to buddy %s error: %s",
-		        purple_contact_info_get_username(PURPLE_CONTACT_INFO(contact)),
-		        error ? error->message : "(null)");
-
-		account = purple_contact_get_account(contact);
-
-		conv = purple_conversation_manager_find_im(manager, account, bb->name);
-		if (conv != NULL) {
-			purple_conversation_write_system_message(conv,
-				_("Unable to send message."),
-				PURPLE_MESSAGE_ERROR);
-		}
-
-		bonjour_xmpp_close_conversation(bb->conversation);
-		bb->conversation = NULL;
-		g_clear_error(&error);
-
-		return;
-	}
-
-	purple_circular_buffer_mark_read(bconv->tx_buf, ret);
-}
-
-static gint
-_send_data(PurpleContact *contact, char *message)
-{
-	BonjourBuddy *bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-	BonjourXMPPConversation *bconv = bb->conversation;
-	gsize len = strlen(message);
-	gssize ret;
-	GError *error = NULL;
-
-	/* If we're not ready to actually send, append it to the buffer */
-	if (bconv->tx_handler != 0
-			|| bconv->sent_stream_start != FULLY_SENT
-			|| !bconv->recv_stream_start
-			|| purple_circular_buffer_get_max_read(bconv->tx_buf) > 0) {
-		ret = -1;
-		g_set_error_literal(&error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
-		                    "Not yet ready to send.");
-	} else {
-		ret = g_pollable_output_stream_write_nonblocking(
-		        G_POLLABLE_OUTPUT_STREAM(bconv->output), message, len,
-		        bconv->cancellable, &error);
-	}
-
-	if (ret == -1 && error->code == G_IO_ERROR_WOULD_BLOCK) {
-		ret = 0;
-		g_clear_error(&error);
-	} else if (ret <= 0) {
-		PurpleAccount *account;
-		PurpleConversation *conv;
-		PurpleConversationManager *manager;
-
-		manager = purple_conversation_manager_get_default();
-
-		purple_debug_error(
-		        "bonjour",
-		        "Error sending message to buddy %s error: %s",
-		        purple_contact_info_get_username(PURPLE_CONTACT_INFO(contact)),
-		        error ? error->message : "(null)");
-
-		account = purple_contact_get_account(contact);
-
-		conv = purple_conversation_manager_find_im(manager, account, bb->name);
-		if (conv != NULL) {
-			purple_conversation_write_system_message(conv,
-				_("Unable to send message."),
-				PURPLE_MESSAGE_ERROR);
-		}
-
-		bonjour_xmpp_close_conversation(bb->conversation);
-		bb->conversation = NULL;
-		g_clear_error(&error);
-		return -1;
-	}
-
-	if ((gsize)ret < len) {
-		/* Don't interfere with the stream starting */
-		if (bconv->sent_stream_start == FULLY_SENT &&
-		    bconv->recv_stream_start && bconv->tx_handler == 0) {
-			GSource *source =
-			        g_pollable_output_stream_create_source(
-			                G_POLLABLE_OUTPUT_STREAM(bconv->output),
-			                bconv->cancellable);
-			g_source_set_callback(source,
-			                      G_SOURCE_FUNC(_send_data_write_cb),
-			                      g_object_ref(contact), g_object_unref);
-			bconv->tx_handler = g_source_attach(source, NULL);
-			g_source_unref(source);
-		}
-		purple_circular_buffer_append(bconv->tx_buf, message + ret, len - ret);
-	}
-
-	return ret;
-}
-
-void
-bonjour_xmpp_process_packet(PurpleContact *contact, PurpleXmlNode *packet) {
-	g_return_if_fail(PURPLE_IS_CONTACT(contact));
-	g_return_if_fail(packet != NULL);
-
-	if (purple_strequal(packet->name, "message")) {
-		_xmpp_parse_and_write_message_to_ui(packet, contact);
-	} else if (purple_strequal(packet->name, "iq")) {
-		xep_iq_parse(packet, contact);
-	} else {
-		purple_debug_warning("bonjour", "Unknown packet: %s\n",
-			packet->name ? packet->name : "(null)");
-	}
-}
-
-static void
-bonjour_xmpp_stream_ended(BonjourXMPPConversation *bconv) {
-	/* Inform the user that the conversation has been closed */
-	BonjourBuddy *bb = NULL;
-	const gchar *name = "(unknown)";
-
-	if(PURPLE_IS_CONTACT(bconv->contact)) {
-		PurpleContactInfo *info = PURPLE_CONTACT_INFO(bconv->contact);
-
-		name = purple_contact_info_get_username(info);
-		bb = g_object_get_data(G_OBJECT(bconv->contact), "bonjour-buddy");
-	}
-
-	purple_debug_info("bonjour", "Received conversation close notification from %s.\n", name);
-
-	/* Close the socket, clear the watcher and free memory */
-	bonjour_xmpp_close_conversation(bconv);
-	if(bb != NULL) {
-		bb->conversation = NULL;
-	}
-}
-
-static gboolean
-_client_socket_handler(GObject *stream, gpointer data)
-{
-	BonjourXMPPConversation *bconv = data;
-	GError *error = NULL;
-	gssize len;
-	static char message[4096];
-
-	/* Read the data from the socket */
-	len = g_pollable_input_stream_read_nonblocking(
-	        G_POLLABLE_INPUT_STREAM(stream), message, sizeof(message) - 1,
-	        bconv->cancellable, &error);
-	if (len == -1) {
-		/* There has been an error reading from the socket */
-		if (error == NULL || (error->code != G_IO_ERROR_WOULD_BLOCK &&
-		                      error->code != G_IO_ERROR_CANCELLED)) {
-			purple_debug_warning(
-			        "bonjour",
-			        "receive of %" G_GSSIZE_FORMAT " error: %s",
-			        len, error ? error->message : "(null)");
-
-			bonjour_xmpp_close_conversation(bconv);
-			if(PURPLE_IS_CONTACT(bconv->contact)) {
-				BonjourBuddy *bb = NULL;
-
-				bb = g_object_get_data(G_OBJECT(bconv->contact),
-				                       "bonjour-buddy");
-				if(bb != NULL) {
-					bb->conversation = NULL;
-				}
-			}
-
-			/* I guess we really don't need to notify the user.
-			 * If they try to send another message it'll reconnect */
-		}
-		g_clear_error(&error);
-		return FALSE;
-	} else if (len == 0) { /* The other end has closed the socket */
-		const gchar *name = NULL;
-		name = purple_contact_info_get_username(PURPLE_CONTACT_INFO(bconv->contact));
-		purple_debug_warning("bonjour", "Connection closed (without stream end) by %s.\n", (name) ? name : "(unknown)");
-		bonjour_xmpp_stream_ended(bconv);
-		return FALSE;
-	}
-
-	message[len] = '\0';
-
-	purple_debug_info("bonjour", "Receive: -%s- %" G_GSSIZE_FORMAT " bytes\n", message, len);
-	bonjour_parser_process(bconv, message, len);
-
-	return TRUE;
-}
-
-struct _stream_start_data {
-	char *msg;
-};
-
-static void
-_start_stream(GObject *stream, gpointer data)
-{
-	BonjourXMPPConversation *bconv = data;
-	struct _stream_start_data *ss = bconv->stream_data;
-	GError *error = NULL;
-	gsize len;
-	gssize ret;
-
-	len = strlen(ss->msg);
-
-	/* Start Stream */
-	ret = g_pollable_output_stream_write_nonblocking(
-	        G_POLLABLE_OUTPUT_STREAM(stream), ss->msg, len,
-	        bconv->cancellable, &error);
-
-	if (ret == -1 && error->code == G_IO_ERROR_WOULD_BLOCK) {
-		g_clear_error(&error);
-		return;
-	} else if (ret <= 0) {
-		PurpleConversation *conv;
-		PurpleConversationManager *manager;
-		BonjourBuddy *bb = NULL;
-		const char *bname = bconv->buddy_name;
-
-		manager = purple_conversation_manager_get_default();
-
-		if(PURPLE_IS_CONTACT(bconv->contact)) {
-			bb = g_object_get_data(G_OBJECT(bconv->contact), "bonjour-buddy");
-			bname = purple_contact_info_get_username(PURPLE_CONTACT_INFO(bconv->contact));
-		}
-
-		purple_debug_error(
-		        "bonjour",
-		        "Error starting stream with buddy %s at %s error: %s",
-		        bname ? bname : "(unknown)", bconv->ip,
-		        error ? error->message : "(null)");
-
-		conv = purple_conversation_manager_find_im(manager, bconv->account,
-		                                           bname);
-		if (conv != NULL) {
-			purple_conversation_write_system_message(conv,
-				_("Unable to send the message, the conversation couldn't be started."),
-				PURPLE_MESSAGE_ERROR);
-		}
-
-		bonjour_xmpp_close_conversation(bconv);
-		if(bb != NULL) {
-			bb->conversation = NULL;
-		}
-
-		g_clear_error(&error);
-		return;
-	}
-
-	/* This is EXTREMELY unlikely to happen */
-	if (G_UNLIKELY((gsize)ret < len)) {
-		char *tmp = g_strdup(ss->msg + ret);
-		g_free(ss->msg);
-		ss->msg = tmp;
-		return;
-	}
-
-	g_free(ss->msg);
-	g_free(ss);
-	bconv->stream_data = NULL;
-
-	/* Stream started; process the send buffer if there is one */
-	g_clear_handle_id(&bconv->tx_handler, g_source_remove);
-	bconv->sent_stream_start = FULLY_SENT;
-
-	bonjour_xmpp_stream_started(bconv);
-}
-
-static gboolean
-bonjour_xmpp_send_stream_init(BonjourXMPPConversation *bconv,
-                                GError **error)
-{
-	gchar *stream_start;
-	gsize len;
-	gssize ret;
-	const char *bname = bconv->buddy_name;
-
-	g_return_val_if_fail(error != NULL, FALSE);
-
-	if(PURPLE_IS_CONTACT(bconv->contact)) {
-		bname = purple_contact_info_get_username(PURPLE_CONTACT_INFO(bconv->contact));
-	}
-
-	/* If we have no idea who "to" is, use an empty string.
-	 * If we don't know now, it is because the other side isn't playing nice, so they can't complain. */
-	if (bname == NULL)
-		bname = "";
-
-	stream_start = g_strdup_printf(DOCTYPE, bonjour_get_jid(bconv->account), bname);
-	len = strlen(stream_start);
-
-	bconv->sent_stream_start = PARTIALLY_SENT;
-
-	/* Start the stream */
-	ret = g_pollable_output_stream_write_nonblocking(
-	        G_POLLABLE_OUTPUT_STREAM(bconv->output), stream_start, len,
-	        bconv->cancellable, error);
-	if (ret == -1 && (*error)->code == G_IO_ERROR_WOULD_BLOCK) {
-		ret = 0;
-		g_clear_error(error);
-	} else if (ret <= 0) {
-		purple_debug_error(
-		        "bonjour",
-		        "Error starting stream with buddy %s at %s error: %s",
-		        (*bname) ? bname : "(unknown)", bconv->ip,
-		        *error ? (*error)->message : "(null)");
-
-		if(PURPLE_IS_CONTACT(bconv->contact)) {
-			PurpleConversation *conv;
-			PurpleConversationManager *manager;
-
-			manager = purple_conversation_manager_get_default();
-
-			conv = purple_conversation_manager_find_im(manager, bconv->account,
-			                                           bname);
-			if (conv != NULL) {
-				purple_conversation_write_system_message(conv,
-					_("Unable to send the message, the conversation couldn't be started."),
-					PURPLE_MESSAGE_ERROR);
-			}
-		}
-
-		purple_gio_graceful_close(G_IO_STREAM(bconv->socket),
-		                          G_INPUT_STREAM(bconv->input),
-		                          G_OUTPUT_STREAM(bconv->output));
-		g_clear_object(&bconv->socket);
-		g_clear_object(&bconv->input);
-		g_clear_object(&bconv->output);
-		g_free(stream_start);
-
-		return FALSE;
-	}
-
-	/* This is unlikely to happen */
-	if ((gsize)ret < len) {
-		GSource *source;
-		struct _stream_start_data *ss = g_new(struct _stream_start_data, 1);
-		ss->msg = g_strdup(stream_start + ret);
-		bconv->stream_data = ss;
-		/* Finish sending the stream start */
-		source = g_pollable_output_stream_create_source(
-		        G_POLLABLE_OUTPUT_STREAM(bconv->output),
-		        bconv->cancellable);
-		g_source_set_callback(source, G_SOURCE_FUNC(_start_stream), bconv,
-		                      NULL);
-		bconv->tx_handler = g_source_attach(source, NULL);
-		g_source_unref(source);
-	} else {
-		bconv->sent_stream_start = FULLY_SENT;
-	}
-
-	g_free(stream_start);
-
-	return TRUE;
-}
-
-/* This gets called when we've successfully sent our <stream:stream />
- * AND when we've received a <stream:stream /> */
-void
-bonjour_xmpp_stream_started(BonjourXMPPConversation *bconv)
-{
-	GError *error = NULL;
-
-	if (bconv->sent_stream_start == NOT_SENT &&
-	    !bonjour_xmpp_send_stream_init(bconv, &error)) {
-		const char *bname = bconv->buddy_name;
-
-		if(PURPLE_IS_CONTACT(bconv->contact)) {
-			bname = purple_contact_info_get_username(PURPLE_CONTACT_INFO(bconv->contact));
-		}
-
-		purple_debug_error(
-		        "bonjour",
-		        "Error starting stream with buddy %s at %s error: %s",
-		        bname ? bname : "(unknown)", bconv->ip,
-		        error ? error->message : "(null)");
-
-		if(PURPLE_IS_CONTACT(bconv->contact)) {
-			PurpleConversation *conv;
-			PurpleConversationManager *manager;
-
-			manager = purple_conversation_manager_get_default();
-
-			conv = purple_conversation_manager_find_im(manager, bconv->account,
-			                                           bname);
-			if (conv != NULL) {
-				purple_conversation_write_system_message(conv,
-					_("Unable to send the message, the conversation couldn't be started."),
-					PURPLE_MESSAGE_ERROR);
-			}
-		}
-
-		/* We don't want to receive anything else */
-		purple_gio_graceful_close(G_IO_STREAM(bconv->socket),
-		                          G_INPUT_STREAM(bconv->input),
-		                          G_OUTPUT_STREAM(bconv->output));
-		g_clear_object(&bconv->socket);
-		g_clear_object(&bconv->input);
-		g_clear_object(&bconv->output);
-
-		/* This must be asynchronous because it destroys the parser and we
-		 * may be in the middle of parsing.
-		 */
-		async_bonjour_xmpp_close_conversation(bconv);
-		g_clear_error(&error);
-		return;
-	}
-
-	/* If the stream has been completely started and we know who we're talking to, we can start doing stuff. */
-	/* I don't think the circ_buffer can actually contain anything without a buddy being associated, but lets be explicit. */
-	if(bconv->sent_stream_start == FULLY_SENT && bconv->recv_stream_start &&
-	   PURPLE_IS_CONTACT(bconv->contact) &&
-	   purple_circular_buffer_get_max_read(bconv->tx_buf) > 0)
-	{
-		/* Watch for when we can write the buffered messages */
-		GSource *source = g_pollable_output_stream_create_source(
-		        G_POLLABLE_OUTPUT_STREAM(bconv->output),
-		        bconv->cancellable);
-		g_source_set_callback(source, G_SOURCE_FUNC(_send_data_write_cb),
-		                      g_object_ref(bconv->contact), g_object_unref);
-		bconv->tx_handler = g_source_attach(source, NULL);
-		g_source_unref(source);
-		/* We can probably write the data right now. */
-		g_object_ref(bconv->contact);
-		_send_data_write_cb(G_OBJECT(bconv->output), bconv->contact);
-		g_object_unref(bconv->contact);
-	}
-}
-
-#ifndef INET6_ADDRSTRLEN
-#define INET6_ADDRSTRLEN 46
-#endif
-
-static void
-_server_socket_handler(G_GNUC_UNUSED GSocketService *service,
-                       GSocketConnection *connection,
-                       G_GNUC_UNUSED GObject *source_object, gpointer data)
-{
-	BonjourXMPP *jdata = data;
-	GSocketAddress *their_addr; /* connector's address information */
-	GInetAddress *their_inet_addr;
-	gchar *address_text;
-	BonjourXMPPConversation *bconv;
-	GSList *contacts;
-	GSource *source;
-
-	their_addr = g_socket_connection_get_remote_address(connection, NULL);
-	if (their_addr == NULL) {
-		return;
-	}
-	their_inet_addr = g_inet_socket_address_get_address(
-	        G_INET_SOCKET_ADDRESS(their_addr));
-
-	/* Look for the buddy that has opened the conversation and fill information */
-	address_text = g_inet_address_to_string(their_inet_addr);
-	if (g_inet_address_get_family(their_inet_addr) ==
-	            G_SOCKET_FAMILY_IPV6 &&
-	    g_inet_address_get_is_link_local(their_inet_addr)) {
-		gchar *tmp = g_strdup_printf(
-		        "%s%%%d", address_text,
-		        g_inet_socket_address_get_scope_id(
-		                G_INET_SOCKET_ADDRESS(their_addr)));
-		g_free(address_text);
-		address_text = tmp;
-	}
-	g_object_unref(their_addr);
-
-	purple_debug_info("bonjour", "Received incoming connection from %s.\n", address_text);
-
-	contacts = _find_match_buddies_by_address(jdata, address_text);
-	if (contacts == NULL) {
-		purple_debug_info("bonjour", "We don't like invisible buddies, this is not a superheroes comic\n");
-		g_free(address_text);
-		return;
-	}
-
-	g_slist_free(contacts);
-
-	/* We've established that this *could* be from one of our buddies.
-	 * Wait for the stream open to see if that matches too before assigning it.
-	 */
-	bconv = bonjour_xmpp_conv_new(NULL, jdata->account, address_text);
-
-	/* We wait for the stream start before doing anything else */
-	bconv->socket = g_object_ref(connection);
-	bconv->input = g_object_ref(
-	        g_io_stream_get_input_stream(G_IO_STREAM(bconv->socket)));
-	bconv->output = g_object_ref(
-	        g_io_stream_get_output_stream(G_IO_STREAM(bconv->socket)));
-	source = g_pollable_input_stream_create_source(
-	        G_POLLABLE_INPUT_STREAM(bconv->input), bconv->cancellable);
-	g_source_set_callback(source, G_SOURCE_FUNC(_client_socket_handler),
-	                      bconv, NULL);
-	bconv->rx_handler = g_source_attach(source, NULL);
-	g_source_unref(source);
-	g_free(address_text);
-}
-
-gint
-bonjour_xmpp_start(BonjourXMPP *jdata)
-{
-	GError *error = NULL;
-	guint16 port;
-
-	purple_debug_info("bonjour", "Attempting to bind IP socket to port %d.",
-	                  jdata->port);
-
-	/* Open a listening server for incoming conversations */
-	jdata->service = g_socket_service_new();
-	g_socket_listener_set_backlog(G_SOCKET_LISTENER(jdata->service), 10);
-	port = jdata->port;
-	if (!g_socket_listener_add_inet_port(G_SOCKET_LISTENER(jdata->service),
-	                                     port, NULL, &error)) {
-		purple_debug_info("bonjour",
-		                  "Unable to bind to specified port %i: %s",
-		                  port, error ? error->message : "(unknown)");
-		g_clear_error(&error);
-		port = g_socket_listener_add_any_inet_port(
-		        G_SOCKET_LISTENER(jdata->service), NULL, &error);
-		if (port == 0) {
-			purple_debug_error(
-			        "bonjour", "Unable to create socket: %s",
-			        error ? error->message : "(unknown)");
-			g_clear_error(&error);
-			return -1;
-		}
-	}
-	purple_debug_info("bonjour", "Bound IP socket to port %u.", port);
-	jdata->port = port;
-
-	g_signal_connect(G_OBJECT(jdata->service), "incoming",
-	                 G_CALLBACK(_server_socket_handler), jdata);
-
-	return jdata->port;
-}
-
-static void
-_connected_to_buddy(GObject *source, GAsyncResult *res, gpointer user_data)
-{
-	BonjourBuddy *bb = NULL;
-	PurpleAccount *account = NULL;
-	PurpleContact *contact = user_data;
-	GSocketConnection *conn;
-	GSource *rx_source;
-	GError *error = NULL;
-	const char *username = NULL;
-
-	bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-	conn = g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(source),
-	                                              res, &error);
-	username = purple_contact_info_get_username(PURPLE_CONTACT_INFO(contact));
-	account = purple_contact_get_account(contact);
-
-	if (conn == NULL) {
-		PurpleConversation *conv = NULL;
-		PurpleConversationManager *manager = NULL;
-		GSList *tmp;
-
-		if (error && error->code == G_IO_ERROR_CANCELLED) {
-			/* This conversation was closed before it started. */
-			g_error_free(error);
-			g_clear_object(&contact);
-
-			return;
-		}
-
-		purple_debug_error("bonjour",
-		                   "Error connecting to buddy %s at %s:%d "
-		                   "(%s); Trying next IP address",
-		                   username,
-		                   bb->conversation->ip, bb->port_p2pj,
-		                   error ? error->message : "(unknown)");
-		g_clear_error(&error);
-
-		/* There may be multiple entries for the same IP - one per
-		 * presence received (e.g. multiple interfaces).
-		 * We need to make sure that we find the previously used entry.
-		 */
-		tmp = g_slist_find(bb->ips, bb->conversation->ip_link);
-		if (tmp)
-			tmp = g_slist_next(tmp);
-
-		if (tmp != NULL) {
-			const gchar *ip;
-			GSocketClient *client;
-
-			bb->conversation->ip_link = ip = tmp->data;
-
-			purple_debug_info("bonjour", "Starting conversation with %s at %s:%d\n",
-					  username, ip, bb->port_p2pj);
-
-			/* Make sure to connect without a proxy. */
-			client = g_socket_client_new();
-			if (client != NULL) {
-				g_free(bb->conversation->ip);
-				bb->conversation->ip = g_strdup(ip);
-				/* We pass our reference on contact to the callback. */
-				g_socket_client_connect_to_host_async(
-				        client, ip, bb->port_p2pj,
-				        bb->conversation->cancellable,
-				        _connected_to_buddy, contact);
-				g_object_unref(client);
-				return;
-			}
-		}
-
-		purple_debug_error("bonjour",
-		                   "No more addresses for buddy %s. Aborting",
-		                   username);
-
-		manager = purple_conversation_manager_get_default();
-
-		conv = purple_conversation_manager_find_im(manager, account, bb->name);
-		if (conv != NULL) {
-			purple_conversation_write_system_message(conv,
-				_("Unable to send the message, the conversation couldn't be started."),
-				PURPLE_MESSAGE_ERROR);
-		}
-
-		bonjour_xmpp_close_conversation(bb->conversation);
-		bb->conversation = NULL;
-
-		g_clear_object(&contact);
-
-		return;
-	}
-
-	bb->conversation->socket = conn;
-	bb->conversation->input =
-	        g_object_ref(g_io_stream_get_input_stream(G_IO_STREAM(conn)));
-	bb->conversation->output =
-	        g_object_ref(g_io_stream_get_output_stream(G_IO_STREAM(conn)));
-
-	if (!bonjour_xmpp_send_stream_init(bb->conversation, &error)) {
-		PurpleConversation *conv = NULL;
-		PurpleConversationManager *manager = NULL;
-
-		purple_debug_error("bonjour",
-		                   "Error starting stream with buddy %s at "
-		                   "%s:%d error: %s",
-		                   username,
-		                   bb->conversation->ip, bb->port_p2pj,
-		                   error ? error->message : "(null)");
-
-		manager = purple_conversation_manager_get_default();
-
-		conv = purple_conversation_manager_find_im(manager, account, bb->name);
-		if (conv != NULL) {
-			purple_conversation_write_system_message(conv,
-				_("Unable to send the message, the conversation couldn't be started."),
-				PURPLE_MESSAGE_ERROR);
-		}
-
-		bonjour_xmpp_close_conversation(bb->conversation);
-		bb->conversation = NULL;
-		g_clear_error(&error);
-		g_clear_object(&contact);
-
-		return;
-	}
-
-	/* Start listening for the stream acknowledgement */
-	rx_source = g_pollable_input_stream_create_source(
-	        G_POLLABLE_INPUT_STREAM(bb->conversation->input),
-	        bb->conversation->cancellable);
-	g_source_set_callback(rx_source, G_SOURCE_FUNC(_client_socket_handler),
-	                      bb->conversation, NULL);
-	bb->conversation->rx_handler = g_source_attach(rx_source, NULL);
-	g_source_unref(rx_source);
-	g_clear_object(&contact);
-}
-
-void
-bonjour_xmpp_conv_match_by_name(BonjourXMPPConversation *bconv) {
-	BonjourBuddy *bb = NULL;
-	PurpleContact *contact = NULL;
-	PurpleContactManager *manager = NULL;
-
-	g_return_if_fail(bconv->ip != NULL);
-	g_return_if_fail(!PURPLE_IS_CONTACT(bconv->contact));
-
-	manager = purple_contact_manager_get_default();
-	contact = purple_contact_manager_find_with_username(manager,
-	                                                    bconv->account,
-	                                                    bconv->buddy_name);
-
-	if(contact && (bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy"))) {
-		const char *username = NULL;
-
-		username = purple_contact_info_get_username(PURPLE_CONTACT_INFO(contact));
-
-		purple_debug_info("bonjour",
-		                  "Found buddy %s for incoming conversation \"from\" attrib.\n",
-		                  username);
-
-		/* Check that one of the buddy's IPs matches */
-		if (g_slist_find_custom(bb->ips, bconv->ip, (GCompareFunc)g_ascii_strcasecmp)) {
-			PurpleConnection *pc = purple_account_get_connection(bconv->account);
-			BonjourData *bd = purple_connection_get_protocol_data(pc);
-			BonjourXMPP *jdata = bd->xmpp_data;
-
-			purple_debug_info("bonjour", "Matched buddy %s to incoming conversation \"from\" attrib and IP (%s)",
-			                  username, bconv->ip);
-
-			/* Attach conv. to buddy and remove from pending list */
-			jdata->pending_conversations = g_slist_remove(jdata->pending_conversations, bconv);
-
-			/* Check if the buddy already has a conversation and, if so, replace it */
-			if (bb->conversation != NULL && bb->conversation != bconv) {
-				bonjour_xmpp_close_conversation(bb->conversation);
-			}
-
-			bconv->contact = contact;
-			bb->conversation = bconv;
-		}
-	}
-
-	/* We've failed to match a buddy - give up */
-	if(!PURPLE_IS_CONTACT(bconv->contact)) {
-		/* This must be asynchronous because it destroys the parser and we
-		 * may be in the middle of parsing.
-		 */
-		async_bonjour_xmpp_close_conversation(bconv);
-	}
-
-	g_clear_object(&contact);
-}
-
-
-void
-bonjour_xmpp_conv_match_by_ip(BonjourXMPPConversation *bconv) {
-	PurpleConnection *pc = purple_account_get_connection(bconv->account);
-	BonjourData *bd = purple_connection_get_protocol_data(pc);
-	BonjourXMPP *jdata = bd->xmpp_data;
-	GSList *contacts;
-
-	contacts = _find_match_buddies_by_address(jdata, bconv->ip);
-
-	/* If there is exactly one match, use it */
-	if (!contacts) {
-		purple_debug_error("bonjour", "No buddies matched for ip %s.", bconv->ip);
-	} else if (contacts->next != NULL) {
-		purple_debug_error("bonjour", "More than one buddy matched for ip %s.", bconv->ip);
-	} else {
-		PurpleContact *contact = contacts->data;
-		BonjourBuddy *bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-
-		purple_debug_info("bonjour", "Matched buddy %s to incoming conversation using IP (%s)",
-		                  purple_contact_info_get_username(PURPLE_CONTACT_INFO(contact)),
-		                  bconv->ip);
-
-		/* Attach conv. to buddy and remove from pending list */
-		jdata->pending_conversations = g_slist_remove(jdata->pending_conversations, bconv);
-
-		/* Check if the buddy already has a conversation and, if so, replace it */
-		if (bb->conversation != NULL && bb->conversation != bconv) {
-			bonjour_xmpp_close_conversation(bb->conversation);
-		}
-
-		bconv->contact = contact;
-		bb->conversation = bconv;
-	}
-
-	/* We've failed to match a buddy - give up */
-	if(!PURPLE_IS_CONTACT(bconv->contact)) {
-		/* This must be asynchronous because it destroys the parser and we
-		 * may be in the middle of parsing.
-		 */
-		async_bonjour_xmpp_close_conversation(bconv);
-	}
-
-	g_slist_free(contacts);
-}
-
-static PurpleContact *
-_find_or_start_conversation(BonjourXMPP *jdata, const gchar *to)
-{
-	PurpleContact *contact = NULL;
-	PurpleContactManager *manager = NULL;
-	BonjourBuddy *bb = NULL;
-
-	g_return_val_if_fail(jdata != NULL, NULL);
-	g_return_val_if_fail(to != NULL, NULL);
-
-	manager = purple_contact_manager_get_default();
-	contact = purple_contact_manager_find_with_username(manager,
-	                                                    jdata->account, to);
-
-	if(!PURPLE_IS_CONTACT(contact)) {
-		return NULL;
-	}
-
-	bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy");
-	if(bb == NULL) {
-		g_clear_object(&contact);
-		return NULL;
-	}
-
-	/* Check if there is a previously open conversation */
-	if (bb->conversation == NULL) {
-		GSocketClient *client;
-		/* Start with the first IP address. */
-		const gchar *ip = bb->ips->data;
-
-		purple_debug_info("bonjour",
-		                  "Starting conversation with %s at %s:%d", to,
-		                  ip, bb->port_p2pj);
-
-		/* Make sure to connect without a proxy. */
-		client = g_socket_client_new();
-		if (client == NULL) {
-			purple_debug_error("bonjour",
-			                   "Unable to connect to buddy (%s).",
-			                   to);
-			g_clear_object(&contact);
-			return NULL;
-		}
-
-		bb->conversation = bonjour_xmpp_conv_new(contact, jdata->account, ip);
-		bb->conversation->ip_link = ip;
-
-		g_socket_client_connect_to_host_async(
-		        client, ip, bb->port_p2pj,
-		        bb->conversation->cancellable, _connected_to_buddy,
-		        g_object_ref(contact));
-		g_object_unref(client);
-	}
-	return contact;
-}
-
-int
-bonjour_xmpp_send_message(BonjourXMPP *jdata, const gchar *to, const gchar *body)
-{
-	PurpleXmlNode *message_node, *node, *node2;
-	gchar *message, *xhtml;
-	PurpleContact *contact = NULL;
-	BonjourBuddy *bb;
-	int ret;
-
-	contact = _find_or_start_conversation(jdata, to);
-	if(!PURPLE_IS_CONTACT(contact) ||
-	   (bb = g_object_get_data(G_OBJECT(contact), "bonjour-buddy")) == NULL)
-	{
-		purple_debug_info("bonjour", "Can't send a message to an offline buddy (%s).\n", to);
-		g_clear_object(&contact);
-		/* You can not send a message to an offline buddy */
-		return -10000;
-	}
-
-	purple_markup_html_to_xhtml(body, &xhtml, &message);
-
-	message_node = purple_xmlnode_new("message");
-	purple_xmlnode_set_attrib(message_node, "to", bb->name);
-	purple_xmlnode_set_attrib(message_node, "from", bonjour_get_jid(jdata->account));
-	purple_xmlnode_set_attrib(message_node, "type", "chat");
-
-	/* Enclose the message from the UI within a "font" node */
-	node = purple_xmlnode_new_child(message_node, "body");
-	purple_xmlnode_insert_data(node, message, strlen(message));
-	g_free(message);
-
-	node = purple_xmlnode_new_child(message_node, "html");
-	purple_xmlnode_set_namespace(node, "http://www.w3.org/1999/xhtml");
-
-	node = purple_xmlnode_new_child(node, "body");
-	message = g_strdup_printf("<font>%s</font>", xhtml);
-	node2 = purple_xmlnode_from_str(message, strlen(message));
-	g_free(xhtml);
-	g_free(message);
-	purple_xmlnode_insert_child(node, node2);
-
-	node = purple_xmlnode_new_child(message_node, "x");
-	purple_xmlnode_set_namespace(node, "jabber:x:event");
-	purple_xmlnode_insert_child(node, purple_xmlnode_new("composing"));
-
-	message = purple_xmlnode_to_str(message_node, NULL);
-	purple_xmlnode_free(message_node);
-
-	ret = _send_data(contact, message) >= 0;
-
-	g_free(message);
-
-	g_clear_object(&contact);
-
-	return ret;
-}
-
-static gboolean
-_async_bonjour_xmpp_close_conversation_cb(gpointer data) {
-	BonjourXMPPConversation *bconv = data;
-	bonjour_xmpp_close_conversation(bconv);
-	return FALSE;
-}
-
-void
-async_bonjour_xmpp_close_conversation(BonjourXMPPConversation *bconv) {
-	PurpleConnection *pc = purple_account_get_connection(bconv->account);
-	BonjourData *bd = purple_connection_get_protocol_data(pc);
-	BonjourXMPP *jdata = bd->xmpp_data;
-
-	jdata->pending_conversations = g_slist_remove(jdata->pending_conversations, bconv);
-
-	/* Disconnect this conv. from the buddy here so it can't be disposed of twice.*/
-	if(PURPLE_IS_CONTACT(bconv->contact)) {
-		BonjourBuddy *bb = g_object_get_data(G_OBJECT(bconv->contact), "bonjour-buddy");
-		if (bb->conversation == bconv)
-			bb->conversation = NULL;
-	}
-
-	bconv->close_timeout = g_timeout_add(0, _async_bonjour_xmpp_close_conversation_cb, bconv);
-}
-
-void
-bonjour_xmpp_close_conversation(BonjourXMPPConversation *bconv)
-{
-	BonjourData *bd = NULL;
-	PurpleConnection *pc = NULL;
-
-	if (bconv == NULL) {
-		return;
-	}
-
-	pc = purple_account_get_connection(bconv->account);
-	PURPLE_ASSERT_CONNECTION_IS_VALID(pc);
-
-	bd = purple_connection_get_protocol_data(pc);
-	if (bd) {
-		bd->xmpp_data->pending_conversations = g_slist_remove(
-			bd->xmpp_data->pending_conversations, bconv);
-	}
-
-	/* Cancel any file transfers that are waiting to begin */
-	/* There won't be any transfers if it hasn't been attached to a buddy */
-	if (PURPLE_IS_CONTACT(bconv->contact) && bd != NULL) {
-		GSList *xfers, *tmp_next;
-		const char *username = NULL;
-
-		xfers = bd->xfer_lists;
-		username = purple_contact_info_get_username(PURPLE_CONTACT_INFO(bconv->contact));
-
-		while (xfers != NULL) {
-			PurpleXfer *xfer = xfers->data;
-
-			tmp_next = xfers->next;
-
-			/* We only need to cancel this if it hasn't actually started transferring. */
-			/* This will change if we ever support IBB transfers. */
-			if (purple_strequal(purple_xfer_get_remote_user(xfer), username)
-					&& (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_NOT_STARTED
-						|| purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_UNKNOWN))
-			{
-				purple_xfer_cancel_remote(xfer);
-			}
-			xfers = tmp_next;
-		}
-	}
-
-	/* Close the socket and remove the watcher */
-	if (bconv->socket != NULL) {
-		/* Send the end of the stream to the other end of the conversation */
-		if (bconv->sent_stream_start == FULLY_SENT) {
-			size_t len = strlen(STREAM_END);
-			if (g_pollable_output_stream_write_nonblocking(
-			            G_POLLABLE_OUTPUT_STREAM(bconv->output),
-			            STREAM_END, len, bconv->cancellable,
-			            NULL) != (gssize)len) {
-				purple_debug_error("bonjour",
-					"bonjour_xmpp_close_conversation: "
-					"couldn't send data\n");
-			}
-		}
-		/* TODO: We're really supposed to wait for "</stream:stream>" before closing the socket */
-		purple_gio_graceful_close(G_IO_STREAM(bconv->socket),
-		                          G_INPUT_STREAM(bconv->input),
-		                          G_OUTPUT_STREAM(bconv->output));
-	}
-	g_clear_handle_id(&bconv->rx_handler, g_source_remove);
-	g_clear_handle_id(&bconv->tx_handler, g_source_remove);
-
-	/* Cancel any pending operations. */
-	if (bconv->cancellable != NULL) {
-		g_cancellable_cancel(bconv->cancellable);
-		g_clear_object(&bconv->cancellable);
-	}
-
-	/* Free all the data related to the conversation */
-	g_clear_object(&bconv->socket);
-	g_clear_object(&bconv->input);
-	g_clear_object(&bconv->output);
-
-	g_object_unref(bconv->tx_buf);
-	if (bconv->stream_data != NULL) {
-		struct _stream_start_data *ss = bconv->stream_data;
-		g_free(ss->msg);
-		g_free(ss);
-	}
-
-	if (bconv->context != NULL) {
-		bonjour_parser_setup(bconv);
-	}
-
-	g_clear_handle_id(&bconv->close_timeout, g_source_remove);
-
-	g_free(bconv->buddy_name);
-	g_free(bconv->ip);
-	g_free(bconv);
-}
-
-void
-bonjour_xmpp_stop(BonjourXMPP *jdata)
-{
-	/* Close the server socket and remove the watcher */
-	if (jdata->service) {
-		g_socket_service_stop(jdata->service);
-		g_socket_listener_close(G_SOCKET_LISTENER(jdata->service));
-		g_clear_object(&jdata->service);
-	}
-
-	/* Close all the conversation sockets and remove all the watchers after sending end streams */
-	if (!purple_account_is_disconnected(jdata->account)) {
-		PurpleContactManager *manager = NULL;
-		GListModel *model = NULL;
-
-		manager = purple_contact_manager_get_default();
-		model = purple_contact_manager_get_all(manager, jdata->account);
-
-		for(guint i = 0; i < g_list_model_get_n_items(model); i++) {
-			PurpleContact *contact = g_list_model_get_item(model, i);
-			BonjourBuddy *bb = g_object_get_data(G_OBJECT(contact),
-			                                     "bonjour-buddy");
-
-			if(bb != NULL && bb->conversation != NULL) {
-				/* Any ongoing connection attempt is cancelled
-				 * when a connection is destroyed */
-				bonjour_xmpp_close_conversation(bb->conversation);
-				bb->conversation = NULL;
-			}
-
-			g_clear_object(&contact);
-		}
-	}
-
-	g_slist_free_full(jdata->pending_conversations, (GDestroyNotify)bonjour_xmpp_close_conversation);
-}
-
-XepIq *
-xep_iq_new(void *data, XepIqType type, const char *to, const char *from, const char *id)
-{
-	PurpleXmlNode *iq_node = NULL;
-	XepIq *iq = NULL;
-
-	g_return_val_if_fail(data != NULL, NULL);
-	g_return_val_if_fail(to != NULL, NULL);
-	g_return_val_if_fail(id != NULL, NULL);
-
-	iq_node = purple_xmlnode_new("iq");
-
-	purple_xmlnode_set_attrib(iq_node, "to", to);
-	purple_xmlnode_set_attrib(iq_node, "from", from);
-	purple_xmlnode_set_attrib(iq_node, "id", id);
-	switch (type) {
-		case XEP_IQ_SET:
-			purple_xmlnode_set_attrib(iq_node, "type", "set");
-			break;
-		case XEP_IQ_GET:
-			purple_xmlnode_set_attrib(iq_node, "type", "get");
-			break;
-		case XEP_IQ_RESULT:
-			purple_xmlnode_set_attrib(iq_node, "type", "result");
-			break;
-		case XEP_IQ_ERROR:
-			purple_xmlnode_set_attrib(iq_node, "type", "error");
-			break;
-		case XEP_IQ_NONE:
-		default:
-			purple_xmlnode_set_attrib(iq_node, "type", "none");
-			break;
-	}
-
-	iq = g_new0(XepIq, 1);
-	iq->node = iq_node;
-	iq->type = type;
-	iq->data = ((BonjourData*)data)->xmpp_data;
-	iq->to = (char*)to;
-
-	return iq;
-}
-
-static void
-xep_iq_parse(PurpleXmlNode *packet, PurpleContact *contact) {
-	PurpleAccount *account;
-	PurpleConnection *gc;
-
-	account = purple_contact_get_account(contact);
-	gc = purple_account_get_connection(account);
-
-	if(purple_xmlnode_get_child(packet, "si") != NULL ||
-	   purple_xmlnode_get_child(packet, "error") != NULL)
-	{
-		xep_si_parse(gc, packet, contact);
-	} else {
-		xep_bytestreams_parse(gc, packet, contact);
-	}
-}
-
-int
-xep_iq_send_and_free(XepIq *iq)
-{
-	int ret = -1;
-	PurpleContact *contact = NULL;
-
-	/* start the talk, reuse the message socket  */
-	contact = _find_or_start_conversation((BonjourXMPP*) iq->data, iq->to);
-	/* Send the message */
-	if(PURPLE_IS_CONTACT(contact)) {
-		/* Convert xml node into stream */
-		gchar *msg = purple_xmlnode_to_str(iq->node, NULL);
-		ret = _send_data(contact, msg);
-		g_free(msg);
-		g_clear_object(&contact);
-	}
-
-	purple_xmlnode_free(iq->node);
-	iq->node = NULL;
-	g_free(iq);
-
-	return (ret >= 0) ? 0 : -1;
-}
-
-void
-append_iface_if_linklocal(char *ip, guint32 interface_param) {
-	GInetAddress *addr;
-	int len_remain = INET6_ADDRSTRLEN - strlen(ip);
-
-	if (len_remain <= 1)
-		return;
-
-	addr = g_inet_address_new_from_string(ip);
-	if (addr == NULL ||
-	    g_inet_address_get_family(addr) != G_SOCKET_FAMILY_IPV6 ||
-	    !g_inet_address_get_is_link_local(addr))
-	{
-		g_clear_object(&addr);
-		return;
-	}
-	g_clear_object(&addr);
-
-	g_snprintf(ip + strlen(ip), len_remain, "%%%d", interface_param);
-}
diff --git a/libpurple/protocols/meson.build b/libpurple/protocols/meson.build
--- a/libpurple/protocols/meson.build
+++ b/libpurple/protocols/meson.build
@@ -1,2 +1,1 @@
-subdir('bonjour')
 subdir('jabber')
diff --git a/meson.build b/meson.build
--- a/meson.build
+++ b/meson.build
@@ -260,29 +260,13 @@
 birb_dep = dependency('birb')
 
 #######################################################################
-# Check for Native Avahi headers (for Bonjour)
-#######################################################################
-
-if IS_WIN32
-	# Just keep enabled.
-	enable_avahi = get_option('avahi').enabled() or get_option('avahi').auto()
-	avahi = []
-else
-	# Attempt to autodetect Avahi
-	avahi_client = dependency('avahi-client', required : get_option('avahi'))
-	avahi_glib = dependency('avahi-glib', required : get_option('avahi'))
-	avahi = [avahi_client, avahi_glib]
-	enable_avahi = avahi_client.found() and avahi_glib.found()
-endif
-
-#######################################################################
 # Check for Xeme XMPP Library
 #######################################################################
 xeme = dependency('xeme')
 
 dependency('shoes', required : false)
 
-DEFAULT_PRPLS = ['bonjour', 'demo', 'ircv3', 'jabber', 'xmpp']
+DEFAULT_PRPLS = ['demo', 'ircv3', 'jabber', 'xmpp']
 
 dynamic_list = get_option('dynamic-prpls').split(',')
 if dynamic_list == ['all']
@@ -292,8 +276,6 @@
 foreach prpl : dynamic_list
 	if prpl == ''
 		# The list was empty; do nothing.
-	elif prpl == 'bonjour' and not enable_avahi
-		# Do nothing.
 	elif prpl == 'xmpp' and not xeme.found()
 		# Do nothing.
 	else
@@ -301,7 +283,6 @@
 	endif
 endforeach
 
-DYNAMIC_BONJOUR = DYNAMIC_PRPLS.contains('bonjour')
 DYNAMIC_DEMO = DYNAMIC_PRPLS.contains('demo')
 DYNAMIC_IRCV3 = DYNAMIC_PRPLS.contains('ircv3')
 DYNAMIC_JABBER = DYNAMIC_PRPLS.contains('jabber')
diff --git a/po/POTFILES.in b/po/POTFILES.in
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -61,16 +61,6 @@
 libpurple/plugins/statenotify/statenotify.c
 libpurple/plugins/wincred/wincred.c
 libpurple/prefs.c
-libpurple/protocols/bonjour/bonjour.c
-libpurple/protocols/bonjour/bonjour_ft.c
-libpurple/protocols/bonjour/buddy.c
-libpurple/protocols/bonjour/dns_sd_proxy.c
-libpurple/protocols/bonjour/mdns_avahi.c
-libpurple/protocols/bonjour/mdns_common.c
-libpurple/protocols/bonjour/mdns_dns_sd.c
-libpurple/protocols/bonjour/mdns_win32.c
-libpurple/protocols/bonjour/parser.c
-libpurple/protocols/bonjour/xmpp.c
 libpurple/protocols.c
 libpurple/protocols/jabber/adhoccommands.c
 libpurple/protocols/jabber/auth.c
diff --git a/protocols/bonjour/meson.build b/protocols/bonjour/meson.build
--- a/protocols/bonjour/meson.build
+++ b/protocols/bonjour/meson.build
@@ -11,10 +11,6 @@
 	'purplebonjourprotocol.h',
 ]
 
-if not DYNAMIC_BONJOUR
-	subdir_done()
-endif
-
 bonjour_resources = gnome.compile_resources('bonjourresource',
 	'resources/bonjour.gresource.xml',
 	source_dir : 'resources',
