diff --git a/libpurple/protocols/gg/avatar.h b/libpurple/protocols/gg/avatar.h
deleted file mode 100644
--- a/libpurple/protocols/gg/avatar.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_AVATAR_H
-#define PURPLE_GG_AVATAR_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-typedef struct _ggp_avatar_session_data ggp_avatar_session_data;
-
-void ggp_avatar_setup(PurpleConnection *gc);
-void ggp_avatar_cleanup(PurpleConnection *gc);
-
-void ggp_avatar_buddy_update(PurpleConnection *gc, uin_t uin, time_t timestamp);
-void ggp_avatar_buddy_remove(PurpleConnection *gc, uin_t uin);
-
-void ggp_avatar_own_set(PurpleProtocolServer *protocol_server, PurpleConnection *gc, PurpleImage *img);
-
-#endif /* PURPLE_GG_AVATAR_H */
# HG changeset patch
# Node ID a7e82e86e35a
# Parent  8019945e1c21
diff --git a/libpurple/protocols/gg/avatar.c b/libpurple/protocols/gg/avatar.c
deleted file mode 100644
--- a/libpurple/protocols/gg/avatar.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "avatar.h"
-
-#include "libpurple/glibcompat.h"
-
-#include "gg.h"
-#include "utils.h"
-#include "oauth/oauth-purple.h"
-
-/* Common */
-
-#define GGP_AVATAR_USERAGENT "GG Client build 11.0.0.7562"
-#define GGP_AVATAR_SIZE_MAX 1048576
-
-/* Buddy avatars updating */
-
-typedef struct
-{
-	uin_t uin;
-	time_t timestamp;
-	PurpleConnection *gc;
-	SoupMessage *msg;
-} ggp_avatar_buddy_update_req;
-
-#define GGP_AVATAR_BUDDY_URL "http://avatars.gg.pl/%u/s,big"
-
-/* Own avatar setting */
-
-struct _ggp_avatar_session_data {
-	PurpleImage *own_img;
-};
-
-#define GGP_AVATAR_RESPONSE_MAX 10240
-
-/*******************************************************************************
- * Common.
- ******************************************************************************/
-
-static inline ggp_avatar_session_data *
-ggp_avatar_get_avdata(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	return accdata->avatar_data;
-}
-
-void ggp_avatar_setup(PurpleConnection *gc)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-
-	info->avatar_data = g_new0(ggp_avatar_session_data, 1);
-}
-
-void ggp_avatar_cleanup(PurpleConnection *gc)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-
-	g_free(info->avatar_data);
-}
-
-/*******************************************************************************
- * Buddy avatars updating.
- ******************************************************************************/
-
-void ggp_avatar_buddy_remove(PurpleConnection *gc, uin_t uin)
-{
-	if (purple_debug_is_verbose()) {
-		purple_debug_misc("gg", "ggp_avatar_buddy_remove(%p, %u)\n", gc, uin);
-	}
-
-	purple_buddy_icons_set_for_user(purple_connection_get_account(gc),
-		ggp_uin_to_str(uin), NULL, 0, NULL);
-}
-
-static void
-ggp_avatar_buddy_update_received(GObject *source, GAsyncResult *result,
-                                 gpointer data)
-{
-	ggp_avatar_buddy_update_req *pending_update = data;
-	GBytes *response_body = NULL;
-	GError *error = NULL;
-	const char *error_message = NULL;
-	PurpleBuddy *buddy;
-	PurpleAccount *account;
-	PurpleConnection *gc = pending_update->gc;
-	gchar timestamp_str[20];
-	char *got_data = NULL;
-	gsize got_len = 0;
-
-	PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
-
-	if(SOUP_STATUS_IS_SUCCESSFUL(soup_message_get_status(pending_update->msg))) {
-		response_body = soup_session_send_and_read_finish(SOUP_SESSION(source),
-		                                                  result, &error);
-		error_message = error != NULL ? error->message : "unknown";
-	} else {
-		error_message = soup_message_get_reason_phrase(pending_update->msg);
-	}
-	if(response_body == NULL) {
-		purple_debug_error("gg",
-		                   "ggp_avatar_buddy_update_received: bad response "
-		                   "while getting avatar for %u: %s",
-		                   pending_update->uin, error_message);
-		g_object_unref(pending_update->msg);
-		g_free(pending_update);
-		g_clear_error(&error);
-		return;
-	}
-
-	account = purple_connection_get_account(gc);
-	buddy = purple_blist_find_buddy(account,
-	                                ggp_uin_to_str(pending_update->uin));
-
-	if (!buddy) {
-		purple_debug_warning(
-		        "gg", "ggp_avatar_buddy_update_received: buddy %u disappeared",
-		        pending_update->uin);
-		g_object_unref(pending_update->msg);
-		g_free(pending_update);
-		return;
-	}
-
-	g_snprintf(timestamp_str, sizeof(timestamp_str), "%lu",
-	           pending_update->timestamp);
-	got_data = g_bytes_unref_to_data(response_body, &got_len);
-	purple_buddy_icons_set_for_user(account, purple_buddy_get_name(buddy),
-	                                got_data, got_len, timestamp_str);
-
-	purple_debug_info("gg",
-	                  "ggp_avatar_buddy_update_received: got avatar for buddy "
-	                  "%u [ts=%lu]",
-	                  pending_update->uin, pending_update->timestamp);
-	g_object_unref(pending_update->msg);
-	g_free(pending_update);
-}
-
-void
-ggp_avatar_buddy_update(PurpleConnection *gc, uin_t uin, time_t timestamp)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	gchar *url;
-	SoupMessage *req;
-	ggp_avatar_buddy_update_req *pending_update;
-	PurpleBuddy *buddy;
-	PurpleAccount *account = purple_connection_get_account(gc);
-	time_t old_timestamp;
-	const char *old_timestamp_str;
-
-	if (purple_debug_is_verbose()) {
-		purple_debug_misc("gg", "ggp_avatar_buddy_update(%p, %u, %lu)", gc, uin,
-		                  timestamp);
-	}
-
-	buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin));
-
-	if (!buddy) {
-		PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
-
-		if (ggp_str_to_uin(purple_contact_info_get_username(info)) == uin) {
-			purple_debug_misc(
-			        "gg",
-			        "ggp_avatar_buddy_update(%p): own avatar update requested, "
-			        "but we don't have ourselves on buddy list",
-			        gc);
-		} else {
-			purple_debug_warning("gg",
-			                     "ggp_avatar_buddy_update(%p): %u update "
-			                     "requested, but he's not on buddy list",
-			                     gc, uin);
-		}
-		return;
-	}
-
-	old_timestamp_str = purple_buddy_icons_get_checksum_for_user(buddy);
-	old_timestamp = old_timestamp_str ? g_ascii_strtoull(
-		old_timestamp_str, NULL, 10) : 0;
-	if (old_timestamp == timestamp) {
-		if (purple_debug_is_verbose()) {
-			purple_debug_misc("gg",
-			                  "ggp_avatar_buddy_update(%p): %u have up to date "
-			                  "avatar with ts=%lu",
-			                  gc, uin, timestamp);
-		}
-		return;
-	}
-	if (old_timestamp > timestamp) {
-		purple_debug_warning("gg",
-		                     "ggp_avatar_buddy_update(%p): saved timestamp for "
-		                     "%u is newer than received (%lu > %lu)",
-		                     gc, uin, old_timestamp, timestamp);
-	}
-
-	purple_debug_info("gg",
-	                  "ggp_avatar_buddy_update(%p): updating %u with ts=%lu...",
-	                  gc, uin, timestamp);
-
-	pending_update = g_new(ggp_avatar_buddy_update_req, 1);
-	pending_update->uin = uin;
-	pending_update->timestamp = timestamp;
-	pending_update->gc = gc;
-
-	url = g_strdup_printf(GGP_AVATAR_BUDDY_URL, pending_update->uin);
-	pending_update->msg = req = soup_message_new("GET", url);
-	g_free(url);
-	soup_message_headers_replace(soup_message_get_request_headers(req),
-	                             "User-Agent", GGP_AVATAR_USERAGENT);
-	// purple_http_request_set_max_len(req, GGP_AVATAR_SIZE_MAX);
-	soup_session_send_and_read_async(info->http, req, G_PRIORITY_DEFAULT, NULL,
-	                                 ggp_avatar_buddy_update_received,
-	                                 pending_update);
-}
-
-/*******************************************************************************
- * Own avatar setting.
- ******************************************************************************/
-
-/*
- * TODO: use new, GG11 method, when IMToken will be provided by libgadu.
- *
- * POST https://avatars.mpa.gg.pl/avatars/user,<uin>/0
- * Authorization: IMToken 0123456789abcdef0123456789abcdef01234567
- * photo=<avatar content>
- */
-
-static void
-ggp_avatar_own_sent(GObject *source, GAsyncResult *result, gpointer data) {
-	SoupMessage *msg = data;
-	GBytes *response_body = NULL;
-	GError *error = NULL;
-	const char *buffer = NULL;
-	gsize size = 0;
-
-	if (!SOUP_STATUS_IS_SUCCESSFUL(soup_message_get_status(msg))) {
-		purple_debug_error("gg", "ggp_avatar_own_sent: avatar not sent. %s",
-		                   soup_message_get_reason_phrase(msg));
-		g_object_unref(msg);
-		return;
-	}
-	g_clear_object(&msg);
-
-	response_body = soup_session_send_and_read_finish(SOUP_SESSION(source),
-	                                                  result, &error);
-	if(response_body == NULL) {
-		purple_debug_error("gg", "ggp_avatar_own_sent: avatar not sent. %s",
-		                   error->message);
-		g_error_free(error);
-		return;
-	}
-
-	buffer = g_bytes_get_data(response_body, &size);
-	purple_debug_info("gg", "ggp_avatar_own_sent: %.*s", (int)size, buffer);
-	g_bytes_unref(response_body);
-}
-
-static void
-ggp_avatar_own_got_token(PurpleConnection *gc, const gchar *token,
-	gpointer _img)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	ggp_avatar_session_data *avdata = ggp_avatar_get_avdata(gc);
-	SoupMessage *req;
-	SoupMessageHeaders *headers;
-	PurpleImage *img = _img;
-	gchar *img_data, *uin_str;
-	PurpleAccount *account = purple_connection_get_account(gc);
-	PurpleContactInfo *contact_info = PURPLE_CONTACT_INFO(account);
-	uin_t uin = ggp_str_to_uin(purple_contact_info_get_username(contact_info));
-
-	if (img != avdata->own_img) {
-		purple_debug_warning("gg", "ggp_avatar_own_got_token: "
-			"avatar was changed in meantime\n");
-		return;
-	}
-	avdata->own_img = NULL;
-
-	img_data = g_base64_encode(purple_image_get_data(img),
-		purple_image_get_data_size(img));
-	uin_str = g_strdup_printf("%d", uin);
-
-	purple_debug_misc("gg", "ggp_avatar_own_got_token: "
-		"uploading new avatar...\n");
-
-	req = soup_message_new_from_encoded_form(
-	        "POST", "http://avatars.nowe.gg/upload",
-	        soup_form_encode("uin", uin_str, "photo", img_data, NULL));
-	// purple_http_request_set_max_len(req, GGP_AVATAR_RESPONSE_MAX);
-	headers = soup_message_get_request_headers(req);
-	soup_message_headers_replace(headers, "Authorization", token);
-	soup_message_headers_replace(headers, "From", "avatars to avatars");
-	soup_session_send_and_read_async(info->http, req, G_PRIORITY_DEFAULT, NULL,
-	                                 ggp_avatar_own_sent, req);
-	g_free(img_data);
-	g_free(uin_str);
-}
-
-void
-ggp_avatar_own_set(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                   PurpleConnection *gc, PurpleImage *img)
-{
-	ggp_avatar_session_data *avdata;
-
-	PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
-
-	purple_debug_info("gg", "ggp_avatar_own_set(%p, %p)", gc, img);
-
-	avdata = ggp_avatar_get_avdata(gc);
-
-	if (img == NULL) {
-		purple_debug_warning("gg", "ggp_avatar_own_set: avatar removing is "
-		                           "probably not possible within old protocol");
-		return;
-	}
-
-	avdata->own_img = img;
-
-	ggp_oauth_request(gc, ggp_avatar_own_got_token, img, NULL, NULL);
-}
diff --git a/libpurple/protocols/gg/blist.h b/libpurple/protocols/gg/blist.h
deleted file mode 100644
--- a/libpurple/protocols/gg/blist.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * @file blist.h
- *
- * purple
- *
- * Copyright (C) 2005  Bartosz Oler <bartosz@bzimage.us>
- *
- * 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_GG_BLIST_H
-#define PURPLE_GG_BLIST_H
-
-#include <purple.h>
-
-void
-ggp_buddylist_send(PurpleConnection *gc);
-
-/**
- * Load buddylist from server into the roster.
- *
- * @param gc PurpleConnection
- * @param buddylist Pointer to the buddylist that will be loaded.
- */
-/* void ggp_buddylist_load(PurpleConnection *gc, char *buddylist) {{{ */
-void
-ggp_buddylist_load(PurpleConnection *gc, char *buddylist);
-
-/**
- * Get all the buddies in the current account.
- *
- * @param account Current account.
- *
- * @return List of buddies.
- */
-char *
-ggp_buddylist_dump(PurpleAccount *account);
-
-/**
- * Returns the best name of a buddy from the buddylist.
- *
- * @param gc  PurpleConnection instance.
- * @param uin UIN of the buddy.
- *
- * @return Name of the buddy, or UIN converted to string, if there is no such
- * user on the list.
- */
-const char * ggp_buddylist_get_buddy_name(PurpleConnection *gc, uin_t uin);
-
-#endif /* PURPLE_GG_BLIST_H */
-
-/* vim: set ts=8 sts=0 sw=8 noet: */
diff --git a/libpurple/protocols/gg/blist.c b/libpurple/protocols/gg/blist.c
deleted file mode 100644
--- a/libpurple/protocols/gg/blist.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/**
- * @file buddylist.c
- *
- * purple
- *
- * Copyright (C) 2005  Bartosz Oler <bartosz@bzimage.us>
- *
- * 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 <libgadu.h>
-
-#include "gg.h"
-#include "utils.h"
-#include "blist.h"
-
-#define F_FIRSTNAME 0
-#define F_LASTNAME 1
-/* #define F_ 2 */
-#define F_NICKNAME 3
-#define F_PHONE 4
-#define F_GROUP 5
-#define F_UIN 6
-
-/* void ggp_buddylist_send(PurpleConnection *gc) {{{ */
-/* this is for for notify purposes, not synchronizing buddy list */
-void ggp_buddylist_send(PurpleConnection *gc)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	PurpleAccount *account = purple_connection_get_account(gc);
-	GSList *buddies;
-	uin_t *userlist;
-	gchar *types;
-	int i = 0, ret = 0;
-	int size;
-
-	buddies = purple_blist_find_buddies(account, NULL);
-
-	size = g_slist_length(buddies);
-	userlist = g_new(uin_t, size);
-	types    = g_new(gchar, size);
-
-	for (buddies = purple_blist_find_buddies(account, NULL); buddies;
-			buddies = g_slist_delete_link(buddies, buddies), ++i)
-	{
-		PurpleBuddy *buddy = buddies->data;
-		const gchar *name = purple_buddy_get_name(buddy);
-
-		userlist[i] = ggp_str_to_uin(name);
-		types[i]    = GG_USER_NORMAL;
-		purple_debug_info("gg", "ggp_buddylist_send: adding %d\n",
-			userlist[i]);
-	}
-
-	ret = gg_notify_ex(info->session, userlist, types, size);
-	purple_debug_info("gg", "send: ret=%d; size=%d\n", ret, size);
-
-	if (userlist) {
-		g_free(userlist);
-		g_free(types);
-	}
-}
-/* }}} */
-
-/* void ggp_buddylist_load(PurpleConnection *gc, char *buddylist) {{{ */
-void ggp_buddylist_load(PurpleConnection *gc, char *buddylist)
-{
-	PurpleBuddy *buddy;
-	PurpleGroup *group;
-	gchar **users_tbl;
-	int i;
-	char *utf8buddylist = ggp_convert_from_cp1250(buddylist);
-
-	/* Don't limit the number of records in a buddylist. */
-	users_tbl = g_strsplit(utf8buddylist, "\r\n", -1);
-
-	for (i = 0; users_tbl[i] != NULL; i++) {
-		gchar **data_tbl;
-		gchar *name, *show, *g;
-
-		if (!*users_tbl[i])
-			continue;
-
-		data_tbl = g_strsplit(users_tbl[i], ";", 8);
-		if (g_strv_length(data_tbl) < 8) {
-			purple_debug_warning("gg",
-				"Something is wrong on line %d of the buddylist. Skipping.\n",
-				i + 1);
-			continue;
-		}
-
-		show = data_tbl[F_NICKNAME];
-		name = data_tbl[F_UIN];
-		if ('\0' == *name || !atol(name)) {
-			purple_debug_warning("gg",
-				"Identifier on line %d of the buddylist is not a number. Skipping.\n",
-				i + 1);
-			continue;
-		}
-
-		if ('\0' == *show) {
-			show = name;
-		}
-
-		purple_debug_info("gg", "got buddy: name=%s; show=%s\n", name, show);
-
-		if (purple_blist_find_buddy(purple_connection_get_account(gc), name)) {
-			g_strfreev(data_tbl);
-			continue;
-		}
-
-		g = g_strdup("Gadu-Gadu");
-
-		if ('\0' != *(data_tbl[F_GROUP])) {
-			/* XXX: Probably buddy should be added to all the groups. */
-			/* Hard limit to at most 50 groups */
-			gchar **group_tbl = g_strsplit(data_tbl[F_GROUP], ",", 50);
-			if (g_strv_length(group_tbl) > 0) {
-				g_free(g);
-				g = g_strdup(group_tbl[0]);
-			}
-			g_strfreev(group_tbl);
-		}
-
-		buddy = purple_buddy_new(purple_connection_get_account(gc),
-			name, *show == '\0' ? NULL : show);
-
-		if (!(group = purple_blist_find_group(g))) {
-			group = purple_group_new(g);
-			purple_blist_add_group(group, NULL);
-		}
-
-		purple_blist_add_buddy(buddy, NULL, group, NULL);
-		g_free(g);
-
-		g_strfreev(data_tbl);
-	}
-	g_strfreev(users_tbl);
-	g_free(utf8buddylist);
-
-	ggp_buddylist_send(gc);
-}
-/* }}} */
-
-/* char *ggp_buddylist_dump(PurpleAccount *account) {{{ */
-char *ggp_buddylist_dump(PurpleAccount *account)
-{
-	GSList *buddies;
-	GString *buddylist = g_string_sized_new(1024);
-	char *ptr;
-
-	for (buddies = purple_blist_find_buddies(account, NULL); buddies;
-		buddies = g_slist_delete_link(buddies, buddies))
-	{
-		PurpleBuddy *buddy = buddies->data;
-		PurpleGroup *group = purple_buddy_get_group(buddy);
-		const char *bname = purple_buddy_get_name(buddy);
-		const char *gname = purple_group_get_name(group);
-		const char *alias = purple_buddy_get_alias(buddy);
-
-		if (alias == NULL)
-			alias = bname;
-
-		g_string_append_printf(buddylist,
-				"%s;%s;%s;%s;%s;%s;%s;%s%s\r\n",
-				alias, alias, alias, alias,
-				"", gname, bname, "", "");
-	}
-
-	ptr = ggp_convert_to_cp1250(buddylist->str);
-	g_string_free(buddylist, TRUE);
-	return ptr;
-}
-/* }}} */
-
-const char * ggp_buddylist_get_buddy_name(PurpleConnection *gc, uin_t uin)
-{
-	const char *uin_s = ggp_uin_to_str(uin);
-	PurpleBuddy *buddy = purple_blist_find_buddy(
-		purple_connection_get_account(gc), uin_s);
-
-	if (buddy != NULL)
-		return purple_buddy_get_alias(buddy);
-	else
-		return uin_s;
-}
-
-/* vim: set ts=8 sts=0 sw=8 noet: */
diff --git a/libpurple/protocols/gg/chat.h b/libpurple/protocols/gg/chat.h
deleted file mode 100644
--- a/libpurple/protocols/gg/chat.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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_GG_CHAT_H
-#define PURPLE_GG_CHAT_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-typedef struct _ggp_chat_session_data ggp_chat_session_data;
-
-#include "gg.h"
-
-void ggp_chat_setup(PurpleConnection *gc);
-void ggp_chat_cleanup(PurpleConnection *gc);
-
-void ggp_chat_got_event(PurpleConnection *gc, const struct gg_event *ev);
-
-GList * ggp_chat_info(PurpleProtocolChat *protocol_chat, PurpleConnection *gc);
-GHashTable * ggp_chat_info_defaults(PurpleProtocolChat *protocol_chat, PurpleConnection *gc,
-	const char *chat_name);
-char * ggp_chat_get_name(PurpleProtocolChat *protocol_chat, GHashTable *components);
-void ggp_chat_join(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, GHashTable *components);
-void ggp_chat_leave(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, int local_id);
-void ggp_chat_invite(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, int local_id, const char *message,
-	const char *who);
-int ggp_chat_send(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, int local_id, PurpleConversation *conversation, PurpleMessage *msg);
-
-void ggp_chat_got_message(PurpleConnection *gc, uint64_t chat_id,
-	const char *message, time_t time, uin_t who);
-
-PurpleRoomlist * ggp_chat_roomlist_get_list(PurpleProtocolRoomlist *protocol_roomlist, PurpleConnection *gc);
-
-#endif /* PURPLE_GG_CHAT_H */
diff --git a/libpurple/protocols/gg/chat.c b/libpurple/protocols/gg/chat.c
deleted file mode 100644
--- a/libpurple/protocols/gg/chat.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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.h>
-#include <glib/gi18n-lib.h>
-
-#include "chat.h"
-
-#include "gg.h"
-#include "utils.h"
-#include "message-prpl.h"
-
-typedef struct _ggp_chat_local_info ggp_chat_local_info;
-
-struct _ggp_chat_session_data
-{
-	ggp_chat_local_info *chats;
-	int chats_count;
-
-	gboolean got_all_chats_info;
-	GSList *pending_joins;
-};
-
-struct _ggp_chat_local_info
-{
-	int local_id;
-	uint64_t id;
-
-	PurpleChatConversation *conv;
-	PurpleConnection *gc;
-
-	gboolean left;
-	gboolean previously_joined;
-
-	uin_t *participants;
-	int participants_count;
-};
-
-static ggp_chat_local_info * ggp_chat_new(PurpleConnection *gc, uint64_t id);
-static ggp_chat_local_info * ggp_chat_get(PurpleConnection *gc, uint64_t id);
-static void ggp_chat_open_conv(ggp_chat_local_info *chat);
-static ggp_chat_local_info * ggp_chat_get_local(PurpleConnection *gc,
-	int local_id);
-static void ggp_chat_joined(ggp_chat_local_info *chat, uin_t uin);
-static void ggp_chat_left(ggp_chat_local_info *chat, uin_t uin);
-static const gchar * ggp_chat_get_name_from_id(uint64_t id);
-static uint64_t ggp_chat_get_id_from_name(const gchar * name);
-static void ggp_chat_join_id(PurpleConnection *gc, uint64_t id);
-
-static inline ggp_chat_session_data *
-ggp_chat_get_sdata(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	return accdata->chat_data;
-}
-
-void ggp_chat_setup(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	ggp_chat_session_data *sdata = g_new0(ggp_chat_session_data, 1);
-
-	accdata->chat_data = sdata;
-}
-
-void ggp_chat_cleanup(PurpleConnection *gc)
-{
-	ggp_chat_session_data *sdata = ggp_chat_get_sdata(gc);
-	int i;
-
-	g_slist_free_full(sdata->pending_joins, g_free);
-	for (i = 0; i < sdata->chats_count; i++)
-		g_free(sdata->chats[i].participants);
-	g_free(sdata->chats);
-	g_free(sdata);
-}
-
-static ggp_chat_local_info * ggp_chat_new(PurpleConnection *gc, uint64_t id)
-{
-	ggp_chat_session_data *sdata = ggp_chat_get_sdata(gc);
-	int local_id;
-	ggp_chat_local_info *chat;
-
-	if (NULL != (chat = ggp_chat_get(gc, id)))
-		return chat;
-
-	local_id = sdata->chats_count++;
-	sdata->chats = g_realloc(sdata->chats,
-		sdata->chats_count * sizeof(ggp_chat_local_info));
-	chat = &sdata->chats[local_id];
-
-	chat->local_id = local_id;
-	chat->id = id;
-	chat->conv = NULL;
-	chat->gc = gc;
-	chat->left = FALSE;
-	chat->previously_joined = FALSE;
-	chat->participants = NULL;
-	chat->participants_count = 0;
-
-	return chat;
-}
-
-static ggp_chat_local_info * ggp_chat_get(PurpleConnection *gc, uint64_t id)
-{
-	ggp_chat_session_data *sdata = ggp_chat_get_sdata(gc);
-	int i;
-
-	for (i = 0; i < sdata->chats_count; i++) {
-		if (sdata->chats[i].id == id)
-			return &sdata->chats[i];
-	}
-
-	return NULL;
-}
-
-static void ggp_chat_open_conv(ggp_chat_local_info *chat)
-{
-	PurpleConversation *conv;
-	int i;
-
-	if (chat->conv != NULL)
-		return;
-
-	conv = purple_serv_got_joined_chat(chat->gc, chat->local_id,
-		ggp_chat_get_name_from_id(chat->id));
-	chat->conv = PURPLE_CHAT_CONVERSATION(conv);
-	if (chat->previously_joined) {
-		purple_conversation_write_system_message(
-			PURPLE_CONVERSATION(chat->conv),
-			_("You have re-joined the chat"), 0);
-	}
-	chat->previously_joined = TRUE;
-
-	purple_chat_conversation_clear_users(chat->conv);
-	for (i = 0; i < chat->participants_count; i++) {
-		purple_chat_conversation_add_user(chat->conv,
-			ggp_uin_to_str(chat->participants[i]), NULL,
-			PURPLE_CHAT_USER_NONE, FALSE);
-	}
-}
-
-static ggp_chat_local_info * ggp_chat_get_local(PurpleConnection *gc,
-	int local_id)
-{
-	ggp_chat_session_data *sdata = ggp_chat_get_sdata(gc);
-	int i;
-
-	for (i = 0; i < sdata->chats_count; i++) {
-		if (sdata->chats[i].local_id == local_id)
-			return &sdata->chats[i];
-	}
-
-	return NULL;
-}
-
-void ggp_chat_got_event(PurpleConnection *gc, const struct gg_event *ev)
-{
-	ggp_chat_session_data *sdata = ggp_chat_get_sdata(gc);
-	ggp_chat_local_info *chat;
-	uint32_t i;
-
-	if (ev->type == GG_EVENT_CHAT_INFO) {
-		const struct gg_event_chat_info *eci = &ev->event.chat_info;
-		chat = ggp_chat_new(gc, eci->id);
-		for (i = 0; i < eci->participants_count; i++)
-			ggp_chat_joined(chat, eci->participants[i]);
-	} else if (ev->type == GG_EVENT_CHAT_INFO_GOT_ALL) {
-		GSList *it = sdata->pending_joins;
-		sdata->got_all_chats_info = TRUE;
-		while (it) {
-			uint64_t *id_p = it->data;
-			ggp_chat_join_id(gc, *id_p);
-			it = g_slist_next(it);
-		}
-		g_clear_slist(&sdata->pending_joins, g_free);
-	} else if (ev->type == GG_EVENT_CHAT_INFO_UPDATE) {
-		const struct gg_event_chat_info_update *eciu =
-			&ev->event.chat_info_update;
-		chat = ggp_chat_get(gc, eciu->id);
-		if (!chat) {
-			purple_debug_error("gg", "ggp_chat_got_event: "
-				"chat %" G_GUINT64_FORMAT " not found\n",
-				eciu->id);
-			return;
-		}
-		if (eciu->type == GG_CHAT_INFO_UPDATE_ENTERED)
-			ggp_chat_joined(chat, eciu->participant);
-		else if (eciu->type == GG_CHAT_INFO_UPDATE_EXITED)
-			ggp_chat_left(chat, eciu->participant);
-		else
-			purple_debug_warning("gg", "ggp_chat_got_event: "
-				"unknown update type - %d", eciu->type);
-	} else if (ev->type == GG_EVENT_CHAT_CREATED) {
-		PurpleAccount *account = purple_connection_get_account(gc);
-		PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
-		const struct gg_event_chat_created *ecc = &ev->event.chat_created;
-		uin_t me = ggp_str_to_uin(purple_contact_info_get_username(info));
-
-		chat = ggp_chat_new(gc, ecc->id);
-		ggp_chat_joined(chat, me);
-		ggp_chat_open_conv(chat);
-	} else if (ev->type == GG_EVENT_CHAT_INVITE_ACK) {
-		/* ignore */
-	} else {
-		purple_debug_error("gg", "ggp_chat_got_event: unexpected event - %d",
-		                   ev->type);
-	}
-}
-
-static int ggp_chat_participant_find(ggp_chat_local_info *chat, uin_t uin)
-{
-	int i;
-	for (i = 0; i < chat->participants_count; i++)
-		if (chat->participants[i] == uin)
-			return i;
-	return -1;
-}
-
-static void ggp_chat_joined(ggp_chat_local_info *chat, uin_t uin)
-{
-	int idx = ggp_chat_participant_find(chat, uin);
-	if (idx >= 0) {
-		purple_debug_warning("gg", "ggp_chat_joined: "
-			"user %u is already present in chat %" G_GUINT64_FORMAT
-			"\n", uin, chat->id);
-		return;
-	}
-	chat->participants_count++;
-	chat->participants = g_realloc(chat->participants,
-		sizeof(uin) * chat->participants_count);
-	chat->participants[chat->participants_count - 1] = uin;
-
-	if (!chat->conv)
-		return;
-	purple_chat_conversation_add_user(chat->conv,
-		ggp_uin_to_str(uin), NULL, PURPLE_CHAT_USER_NONE, TRUE);
-}
-
-static void ggp_chat_left(ggp_chat_local_info *chat, uin_t uin)
-{
-	PurpleAccount *account = NULL;
-	PurpleContactInfo *info = NULL;
-	uin_t me;
-	int idx = ggp_chat_participant_find(chat, uin);
-
-	if (idx < 0) {
-		purple_debug_warning("gg", "ggp_chat_joined: "
-			"user %u isn't present in chat %" G_GUINT64_FORMAT "\n",
-			uin, chat->id);
-		return;
-	}
-	chat->participants[idx] =
-		chat->participants[chat->participants_count - 1];
-	chat->participants_count--;
-	chat->participants = g_realloc(chat->participants,
-		sizeof(uin) * chat->participants_count);
-
-	if (chat->conv == NULL)
-		return;
-
-	account = purple_connection_get_account(chat->gc);
-	info = PURPLE_CONTACT_INFO(account);
-	me = ggp_str_to_uin(purple_contact_info_get_username(info));
-
-	if (me == uin) {
-		purple_conversation_write_system_message(
-			PURPLE_CONVERSATION(chat->conv),
-			_("You have left the chat"), 0);
-		purple_serv_got_chat_left(chat->gc, chat->local_id);
-		chat->conv = NULL;
-		chat->left = TRUE;
-	}
-	purple_chat_conversation_remove_user(chat->conv, ggp_uin_to_str(uin), NULL);
-}
-
-GList *
-ggp_chat_info(G_GNUC_UNUSED PurpleProtocolChat *protocol_chat,
-              G_GNUC_UNUSED PurpleConnection *gc)
-{
-	GList *m = NULL;
-	PurpleProtocolChatEntry *pce;
-
-	pce = g_new0(PurpleProtocolChatEntry, 1);
-	pce->label = _("_Conference identifier");
-	pce->identifier = "id";
-	pce->required = FALSE;
-	m = g_list_append(m, pce);
-
-	return m;
-}
-
-GHashTable *
-ggp_chat_info_defaults(G_GNUC_UNUSED PurpleProtocolChat *protocol_chat,
-                       G_GNUC_UNUSED PurpleConnection *gc,
-                       const gchar *chat_name)
-{
-	GHashTable *defaults;
-
-	defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
-
-	if (chat_name != NULL && ggp_chat_get_id_from_name(chat_name) != 0)
-		g_hash_table_insert(defaults, "id", g_strdup(chat_name));
-
-	return defaults;
-}
-
-gchar *
-ggp_chat_get_name(G_GNUC_UNUSED PurpleProtocolChat *protocol_chat,
-                  GHashTable *components)
-{
-	return g_strdup((gchar*)g_hash_table_lookup(components, "id"));
-}
-
-static const gchar * ggp_chat_get_name_from_id(uint64_t id)
-{
-	static gchar buff[30];
-	g_snprintf(buff, sizeof(buff), "%" G_GUINT64_FORMAT, id);
-	return buff;
-}
-
-static uint64_t ggp_chat_get_id_from_name(const gchar * name)
-{
-	uint64_t id;
-	gchar *endptr;
-
-	if (name == NULL)
-		return 0;
-
-	id = g_ascii_strtoull(name, &endptr, 10);
-
-	if (*endptr != '\0' || id == G_MAXUINT64)
-		return 0;
-
-	return id;
-}
-
-void
-ggp_chat_join(G_GNUC_UNUSED PurpleProtocolChat *protocol_chat,
-              PurpleConnection *gc, GHashTable *components)
-{
-	ggp_chat_session_data *sdata = ggp_chat_get_sdata(gc);
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	const gchar *id_cs;
-	gchar *id_s;
-	uint64_t id;
-
-	id_cs = g_hash_table_lookup(components, "id");
-	id_s = g_strdup(id_cs);
-	if (id_s)
-		g_strstrip(id_s);
-	if (id_s == NULL || id_s[0] == '\0') {
-		g_free(id_s);
-		if (gg_chat_create(info->session) < 0) {
-			purple_debug_error("gg", "ggp_chat_join; "
-				"cannot create\n");
-			purple_serv_got_join_chat_failed(gc, components);
-		}
-		return;
-	}
-	id = ggp_chat_get_id_from_name(id_s);
-	g_free(id_s);
-
-	if (!id) {
-		char *buff = g_strdup_printf(
-			_("%s is not a valid room identifier"), id_cs);
-		purple_notify_error(gc, _("Invalid Room Identifier"),
-			_("Invalid Room Identifier"), buff, NULL);
-		g_free(buff);
-		purple_serv_got_join_chat_failed(gc, components);
-		return;
-	}
-
-	if (sdata->got_all_chats_info)
-		ggp_chat_join_id(gc, id);
-	else {
-		uint64_t *id_p = g_new(uint64_t, 1);
-		*id_p = id;
-		sdata->pending_joins = g_slist_append(sdata->pending_joins, id_p);
-	}
-
-}
-
-static void ggp_chat_join_id(PurpleConnection *gc, uint64_t id)
-{
-	GHashTable *components;
-	PurpleProtocol *protocol = purple_connection_get_protocol(gc);
-
-	ggp_chat_local_info *chat = ggp_chat_get(gc, id);
-
-	if (chat && !chat->left) {
-		ggp_chat_open_conv(chat);
-		return;
-	}
-
-	if (!chat) {
-		char *id_s = g_strdup_printf("%" G_GUINT64_FORMAT, id);
-		char *buff = g_strdup_printf(
-			_("%s is not a valid room identifier"), id_s);
-		g_free(id_s);
-		purple_notify_error(gc, _("Invalid Room Identifier"),
-			_("Invalid Room Identifier"), buff, NULL);
-		g_free(buff);
-	} else { /* if (chat->left) */
-		purple_notify_error(gc, _("Could not join chat room"),
-			_("Could not join chat room"),
-			_("You have to ask for invitation from another chat "
-			"participant"), NULL);
-	}
-
-	components = ggp_chat_info_defaults(PURPLE_PROTOCOL_CHAT(protocol), gc,
-	                                    ggp_chat_get_name_from_id(id));
-	purple_serv_got_join_chat_failed(gc, components);
-	g_hash_table_destroy(components);
-}
-
-void
-ggp_chat_leave(G_GNUC_UNUSED PurpleProtocolChat *protocol_chat,
-               PurpleConnection *gc, gint local_id)
-{
-	PurpleAccount *account = NULL;
-	PurpleContactInfo *contact_info = NULL;
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	ggp_chat_local_info *chat;
-	uin_t me;
-
-	chat = ggp_chat_get_local(gc, local_id);
-	if (!chat) {
-		purple_debug_error("gg", "ggp_chat_leave: "
-			"chat %u doesn't exists\n", local_id);
-		return;
-	}
-
-	if (gg_chat_leave(info->session, chat->id) < 0) {
-		purple_debug_error("gg", "ggp_chat_leave: "
-			"unable to leave chat %" G_GUINT64_FORMAT "\n",
-			chat->id);
-	}
-	chat->conv = NULL;
-
-	account = purple_connection_get_account(chat->gc);
-	contact_info = PURPLE_CONTACT_INFO(account);
-	me = ggp_str_to_uin(purple_contact_info_get_username(contact_info));
-
-	ggp_chat_left(chat, me);
-	chat->left = TRUE;
-}
-
-void
-ggp_chat_invite(G_GNUC_UNUSED PurpleProtocolChat *protocol_chat,
-                PurpleConnection *gc, gint local_id,
-                G_GNUC_UNUSED const gchar *message, const gchar *who)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	ggp_chat_local_info *chat;
-	uin_t invited;
-
-	chat = ggp_chat_get_local(gc, local_id);
-	if (!chat) {
-		purple_debug_error("gg", "ggp_chat_invite: "
-			"chat %u doesn't exists\n", local_id);
-		return;
-	}
-
-	invited = ggp_str_to_uin(who);
-	if (gg_chat_invite(info->session, chat->id, &invited, 1) < 0) {
-		purple_debug_error("gg", "ggp_chat_invite: "
-			"unable to invite %s to chat %" G_GUINT64_FORMAT "\n",
-			who, chat->id);
-	}
-}
-
-gint
-ggp_chat_send(G_GNUC_UNUSED PurpleProtocolChat *protocol_chat,
-              PurpleConnection *gc, gint local_id,
-              G_GNUC_UNUSED PurpleConversation *conversation,
-              PurpleMessage *msg)
-{
-	PurpleAccount *account = NULL;
-	PurpleContactInfo *contact_info = NULL;
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	GDateTime *dt = NULL;
-	PurpleConversation *conv;
-	PurpleConversationManager *manager;
-	ggp_chat_local_info *chat;
-	gboolean succ = TRUE;
-	const gchar *me;
-	gchar *gg_msg;
-
-	chat = ggp_chat_get_local(gc, local_id);
-	if (!chat) {
-		purple_debug_error("gg", "ggp_chat_send: "
-			"chat %u doesn't exists\n", local_id);
-		return -1;
-	}
-
-	manager = purple_conversation_manager_get_default();
-	conv = purple_conversation_manager_find_chat(manager,
-	                                             purple_connection_get_account(gc),
-	                                             ggp_chat_get_name_from_id(chat->id));
-
-	gg_msg = ggp_message_format_to_gg(conv,
-		purple_message_get_contents(msg));
-
-	if (gg_chat_send_message(info->session, chat->id, gg_msg, TRUE) < 0)
-		succ = FALSE;
-	g_free(gg_msg);
-
-	account = purple_connection_get_account(gc);
-	contact_info = PURPLE_CONTACT_INFO(account);
-	me = purple_contact_info_get_username(contact_info);
-	dt = purple_message_get_timestamp(msg);
-	purple_serv_got_chat_in(gc, chat->local_id, me,
-		purple_message_get_flags(msg),
-		purple_message_get_contents(msg),
-		(time_t)g_date_time_to_unix(dt));
-
-	return succ ? 0 : -1;
-}
-
-void ggp_chat_got_message(PurpleConnection *gc, uint64_t chat_id,
-	const char *message, time_t time, uin_t who)
-{
-	PurpleAccount *account = NULL;
-	PurpleContactInfo *info = NULL;
-	ggp_chat_local_info *chat;
-	uin_t me;
-
-	account = purple_connection_get_account(gc);
-	info = PURPLE_CONTACT_INFO(account);
-	me = ggp_str_to_uin(purple_contact_info_get_username(info));
-
-	chat = ggp_chat_get(gc, chat_id);
-	if (!chat) {
-		purple_debug_error("gg", "ggp_chat_got_message: "
-			"chat %" G_GUINT64_FORMAT " doesn't exists\n", chat_id);
-		return;
-	}
-
-	ggp_chat_open_conv(chat);
-	if (who == me) {
-		GDateTime *dt = NULL;
-		PurpleMessage *pmsg;
-		const char *username = NULL;
-
-		username = purple_contact_info_get_name_for_display(info);
-
-		pmsg = purple_message_new_outgoing(username, ggp_uin_to_str(who),
-		                                   message, 0);
-
-		dt = g_date_time_new_from_unix_local((gint64)time);
-		purple_message_set_timestamp(pmsg, dt);
-		g_date_time_unref(dt);
-
-		purple_conversation_write_message(
-			PURPLE_CONVERSATION(chat->conv), pmsg);
-	} else {
-		purple_serv_got_chat_in(gc, chat->local_id, ggp_uin_to_str(who),
-			PURPLE_MESSAGE_RECV, message, time);
-	}
-}
-
-static gboolean ggp_chat_roomlist_get_list_finish(gpointer roomlist)
-{
-	purple_roomlist_set_in_progress(PURPLE_ROOMLIST(roomlist), FALSE);
-	g_object_unref(roomlist);
-
-	return FALSE;
-}
-
-PurpleRoomlist *
-ggp_chat_roomlist_get_list(G_GNUC_UNUSED PurpleProtocolRoomlist *protocol_roomlist,
-                           PurpleConnection *gc)
-{
-	ggp_chat_session_data *sdata = ggp_chat_get_sdata(gc);
-	PurpleRoomlist *roomlist;
-	int i;
-
-	purple_debug_info("gg", "ggp_chat_roomlist_get_list\n");
-
-	roomlist = purple_roomlist_new(purple_connection_get_account(gc));
-
-	for (i = sdata->chats_count - 1; i >= 0 ; i--) {
-		PurpleRoomlistRoom *room;
-		ggp_chat_local_info *chat = &sdata->chats[i];
-		const gchar *name;
-		GDateTime *date = NULL;
-		const gchar *status;
-		int count = chat->participants_count;
-
-		date = g_date_time_new_from_unix_local((uint32_t)(chat->id >> 32));
-
-		if (chat->conv) {
-			status = _("Joined");
-		} else if (chat->left) {
-			/* Translators: For Gadu-Gadu, this is one possible status for a
-			   chat room. It means you had previously joined the chat room but
-			   you have since left it. You cannot rejoin without another
-			   invitation. */
-			status = _("Chat left");
-		} else {
-			status = _("Can join chat");
-			count--;
-		}
-
-		name = ggp_chat_get_name_from_id(chat->id);
-		room = purple_roomlist_room_new(name, NULL);
-		purple_roomlist_room_set_user_count(room, (guint)count);
-		purple_roomlist_room_add_field(room, "id", g_strdup(name));
-		purple_roomlist_room_add_field(room, "date",
-		                               g_date_time_format(date, "%c"));
-		purple_roomlist_room_add_field(room, "status", g_strdup(status));
-		purple_roomlist_room_add(roomlist, room);
-		g_object_unref(room);
-		g_date_time_unref(date);
-	}
-
-	/* TODO
-	 * purple_roomlist_set_in_progress(roomlist, FALSE);
-	 */
-	g_object_ref(roomlist);
-	g_timeout_add(1, ggp_chat_roomlist_get_list_finish, roomlist);
-	return roomlist;
-}
diff --git a/libpurple/protocols/gg/edisc.h b/libpurple/protocols/gg/edisc.h
deleted file mode 100644
--- a/libpurple/protocols/gg/edisc.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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_GG_EDISC_H
-#define PURPLE_GG_EDISC_H
-
-#include <purple.h>
-
-typedef struct _ggp_edisc_session_data ggp_edisc_session_data;
-
-G_BEGIN_DECLS
-
-#define GGP_TYPE_XFER (ggp_xfer_get_type())
-G_DECLARE_FINAL_TYPE(GGPXfer, ggp_xfer, GGP, XFER, PurpleXfer);
-
-void ggp_xfer_register(GTypeModule *module);
-
-/* Setting up. */
-void ggp_edisc_setup(PurpleConnection *gc, GProxyResolver *resolver);
-void ggp_edisc_cleanup(PurpleConnection *gc);
-
-/* General xfer functions. */
-void ggp_edisc_xfer_ticket_changed(PurpleConnection *gc,
-	const char *data);
-
-/* Sending a file. */
-gboolean ggp_edisc_xfer_can_receive_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who);
-void ggp_edisc_xfer_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who,
-	const char *filename);
-PurpleXfer * ggp_edisc_xfer_send_new(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who);
-
-G_END_DECLS
-
-#endif /* PURPLE_GG_EDISC_H */
diff --git a/libpurple/protocols/gg/edisc.c b/libpurple/protocols/gg/edisc.c
deleted file mode 100644
--- a/libpurple/protocols/gg/edisc.c
+++ /dev/null
@@ -1,1344 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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 "edisc.h"
-
-#include "gg.h"
-#include "libgaduw.h"
-#include "utils.h"
-
-#include <json-glib/json-glib.h>
-
-#include <glib/gi18n-lib.h>
-
-#include <purple.h>
-
-#define GGP_EDISC_OS "WINNT x86-msvc"
-#define GGP_EDISC_TYPE "desktop"
-#define GGP_EDISC_API "6"
-
-#define GGP_EDISC_RESPONSE_MAX 10240
-#define GGP_EDISC_FNAME_ALLOWED "1234567890" \
-	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" \
-	" [](){}-+=_;'<>,.&$!"
-
-typedef struct _ggp_edisc_xfer ggp_edisc_xfer;
-
-struct _ggp_edisc_session_data
-{
-	GHashTable *xfers_initialized;
-	GHashTable *xfers_history;
-
-	SoupSession *session;
-	gchar *security_token;
-
-	SoupMessage *auth_request;
-	gboolean auth_done;
-	GSList *auth_pending;
-};
-
-struct _GGPXfer
-{
-	PurpleXfer parent;
-	GCancellable *cancellable;
-
-	gchar *filename;
-	gchar *ticket_id;
-
-	gboolean allowed, ready;
-
-	PurpleConnection *gc;
-	SoupMessage *msg;
-	gint handler;
-};
-
-typedef enum
-{
-	GGP_EDISC_XFER_ACK_STATUS_UNKNOWN,
-	GGP_EDISC_XFER_ACK_STATUS_ALLOWED,
-	GGP_EDISC_XFER_ACK_STATUS_REJECTED
-} ggp_edisc_xfer_ack_status;
-
-typedef void (*ggp_ggdrive_auth_cb)(PurpleConnection *gc, gboolean success,
-	gpointer user_data);
-
-/*******************************************************************************
- * Setting up.
- ******************************************************************************/
-
-static inline ggp_edisc_session_data *
-ggp_edisc_get_sdata(PurpleConnection *gc)
-{
-	GGPInfo *accdata;
-
-	PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
-
-	accdata = purple_connection_get_protocol_data(gc);
-	g_return_val_if_fail(accdata != NULL, NULL);
-
-	return accdata->edisc_data;
-}
-
-void
-ggp_edisc_setup(PurpleConnection *gc, GProxyResolver *resolver)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	ggp_edisc_session_data *sdata = g_new0(ggp_edisc_session_data, 1);
-
-	accdata->edisc_data = sdata;
-
-	sdata->session = soup_session_new_with_options("proxy-resolver", resolver,
-	                                               NULL);
-	soup_session_add_feature_by_type(sdata->session, SOUP_TYPE_COOKIE_JAR);
-	sdata->xfers_initialized = g_hash_table_new(g_str_hash, g_str_equal);
-	sdata->xfers_history = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
-}
-
-void ggp_edisc_cleanup(PurpleConnection *gc)
-{
-	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc);
-
-	g_return_if_fail(sdata != NULL);
-
-	soup_session_abort(sdata->session);
-	g_slist_free_full(sdata->auth_pending, g_free);
-	g_free(sdata->security_token);
-
-	g_object_unref(sdata->session);
-	g_hash_table_destroy(sdata->xfers_initialized);
-	g_hash_table_destroy(sdata->xfers_history);
-
-	g_free(sdata);
-}
-
-/*******************************************************************************
- * Misc.
- ******************************************************************************/
-
-static void
-ggp_edisc_set_defaults(SoupMessage *msg)
-{
-	SoupMessageHeaders *headers = soup_message_get_request_headers(msg);
-
-	// purple_http_request_set_max_len(msg, GGP_EDISC_RESPONSE_MAX);
-	soup_message_headers_replace(headers, "X-gged-api-version",
-	                             GGP_EDISC_API);
-
-	/* optional fields */
-	soup_message_headers_replace(
-	        headers, "User-Agent",
-	        "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20120613 "
-	        "GG/11.0.0.8169 (WINNT_x86-msvc; pl; beta; standard)");
-	soup_message_headers_replace(
-	        headers, "Accept",
-	        "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
-	soup_message_headers_replace(headers, "Accept-Language",
-	                             "pl,en-us;q=0.7,en;q=0.3");
-	/* soup_message_headers_replace(headers, "Accept-Encoding",
-	 *                              "gzip, deflate"); */
-	soup_message_headers_replace(headers, "Accept-Charset",
-	                             "ISO-8859-2,utf-8;q=0.7,*;q=0.7");
-	soup_message_headers_replace(headers, "Connection", "keep-alive");
-	soup_message_headers_replace(
-	        headers, "Content-Type",
-	        "application/x-www-form-urlencoded; charset=UTF-8");
-}
-
-static int ggp_edisc_parse_error(const gchar *data)
-{
-	JsonParser *parser;
-	JsonObject *result;
-	int error_id;
-
-	parser = ggp_json_parse(data);
-	result = json_node_get_object(json_parser_get_root(parser));
-	result = json_object_get_object_member(result, "result");
-	error_id = json_object_get_int_member(result, "appStatus");
-	purple_debug_info("gg", "edisc error: %s (%d)\n",
-		json_object_get_string_member(result, "errorMsg"),
-		error_id);
-	g_object_unref(parser);
-
-	return error_id;
-}
-
-static ggp_edisc_xfer_ack_status
-ggp_edisc_xfer_parse_ack_status(const gchar *str)
-{
-	g_return_val_if_fail(str != NULL, GGP_EDISC_XFER_ACK_STATUS_UNKNOWN);
-
-	if (g_strcmp0("unknown", str) == 0) {
-		return GGP_EDISC_XFER_ACK_STATUS_UNKNOWN;
-	}
-	if (g_strcmp0("allowed", str) == 0) {
-		return GGP_EDISC_XFER_ACK_STATUS_ALLOWED;
-	}
-	if (g_strcmp0("rejected", str) == 0) {
-		return GGP_EDISC_XFER_ACK_STATUS_REJECTED;
-	}
-
-	purple_debug_warning(
-	        "gg", "ggp_edisc_xfer_parse_ack_status: unknown status (%s)", str);
-	return GGP_EDISC_XFER_ACK_STATUS_UNKNOWN;
-}
-
-/*******************************************************************************
- * General xfer functions.
- ******************************************************************************/
-
-static const gchar *
-ggp_edisc_xfer_ticket_url(const gchar *ticket_id)
-{
-	static gchar ticket_url[150];
-
-	g_snprintf(ticket_url, sizeof(ticket_url),
-	           "https://drive.mpa.gg.pl/send_ticket/%s", ticket_id);
-
-	return ticket_url;
-}
-
-static void ggp_edisc_xfer_error(PurpleXfer *xfer, const gchar *msg)
-{
-	if (purple_xfer_is_cancelled(xfer))
-		g_return_if_reached();
-	purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_CANCEL_REMOTE);
-	purple_xfer_conversation_write(xfer, msg, TRUE);
-	purple_xfer_error(
-		purple_xfer_get_xfer_type(xfer),
-		purple_xfer_get_account(xfer),
-		purple_xfer_get_remote_user(xfer),
-		msg);
-	purple_xfer_end(xfer);
-}
-
-/*******************************************************************************
- * Authentication.
- ******************************************************************************/
-
-typedef struct _ggp_edisc_auth_data {
-	ggp_ggdrive_auth_cb cb;
-	gpointer user_data;
-} ggp_edisc_auth_data;
-
-static void
-ggp_ggdrive_auth_results(PurpleConnection *gc, gboolean success)
-{
-	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc);
-	GSList *it;
-
-	purple_debug_info("gg", "ggp_ggdrive_auth_results(gc=%p): %d", gc, success);
-
-	g_return_if_fail(sdata != NULL);
-
-	for (it = sdata->auth_pending; it; it = g_slist_delete_link(it, it)) {
-		ggp_edisc_auth_data *auth = it->data;
-
-		auth->cb(gc, success, auth->user_data);
-		g_free(auth);
-	}
-	sdata->auth_pending = NULL;
-	sdata->auth_done = TRUE;
-}
-
-static void
-ggp_ggdrive_auth_done(GObject *source, GAsyncResult *async_result,
-                      gpointer data)
-{
-	PurpleConnection *gc = data;
-	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc);
-	GBytes *response_body = NULL;
-	const char *buffer = NULL;
-	gsize size = 0;
-	SoupStatus status_code;
-	JsonParser *parser;
-	JsonObject *result;
-	int status = -1;
-	GError *error = NULL;
-
-	g_return_if_fail(sdata != NULL);
-
-	status_code = soup_message_get_status(sdata->auth_request);
-	if (!SOUP_STATUS_IS_SUCCESSFUL(status_code)) {
-		purple_debug_misc("gg",
-		                  "ggp_ggdrive_auth_done: authentication failed due to "
-		                  "unsuccessful request (code = %d)",
-		                  status_code);
-		g_clear_object(&sdata->auth_request);
-		ggp_ggdrive_auth_results(gc, FALSE);
-		return;
-	}
-
-	response_body = soup_session_send_and_read_finish(SOUP_SESSION(source),
-	                                                  async_result, &error);
-	if(response_body == NULL) {
-		purple_debug_misc("gg",
-		                  "ggp_ggdrive_auth_done: authentication failed due to "
-		                  "unsuccessful request (%s)",
-		                  error->message);
-		g_error_free(error);
-		g_clear_object(&sdata->auth_request);
-		ggp_ggdrive_auth_results(gc, FALSE);
-		return;
-	}
-
-	buffer = g_bytes_get_data(response_body, &size);
-	parser = ggp_json_parse(buffer);
-	result = json_node_get_object(json_parser_get_root(parser));
-	result = json_object_get_object_member(result, "result");
-	if (json_object_has_member(result, "status"))
-		status = json_object_get_int_member(result, "status");
-	g_object_unref(parser);
-
-	if (status != 0) {
-		purple_debug_misc("gg",
-		                  "ggp_ggdrive_auth_done: authentication failed due to "
-		                  "bad result (status=%d)",
-		                  status);
-		if (purple_debug_is_verbose()) {
-			purple_debug_misc("gg", "ggp_ggdrive_auth_done: result = %.*s",
-			                  (int)size, buffer);
-		}
-		g_bytes_unref(response_body);
-		g_clear_object(&sdata->auth_request);
-		ggp_ggdrive_auth_results(gc, FALSE);
-		return;
-	}
-
-	sdata->security_token = g_strdup(soup_message_headers_get_one(
-	        soup_message_get_response_headers(sdata->auth_request),
-	        "X-gged-security-token"));
-	if (!sdata->security_token) {
-		purple_debug_misc("gg", "ggp_ggdrive_auth_done: authentication failed "
-		                        "due to missing security token header");
-		g_bytes_unref(response_body);
-		g_clear_object(&sdata->auth_request);
-		ggp_ggdrive_auth_results(gc, FALSE);
-		return;
-	}
-
-	if (purple_debug_is_unsafe()) {
-		purple_debug_misc("gg", "ggp_ggdrive_auth_done: security_token=%s",
-		                  sdata->security_token);
-	}
-
-	g_clear_pointer(&response_body, g_bytes_unref);
-	g_clear_object(&sdata->auth_request);
-
-	ggp_ggdrive_auth_results(gc, TRUE);
-}
-
-static void
-ggp_ggdrive_auth(PurpleConnection *gc, ggp_ggdrive_auth_cb cb,
-                 gpointer user_data)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc);
-	ggp_edisc_auth_data *auth;
-	const gchar *imtoken;
-	gchar *metadata;
-	gchar *tmp;
-	SoupMessage *msg;
-	SoupMessageHeaders *headers;
-
-	g_return_if_fail(sdata != NULL);
-
-	imtoken = ggp_get_imtoken(gc);
-	if (!imtoken) {
-		cb(gc, FALSE, user_data);
-		return;
-	}
-
-	if (sdata->auth_done) {
-		cb(gc, sdata->security_token != NULL, user_data);
-		return;
-	}
-
-	auth = g_new0(ggp_edisc_auth_data, 1);
-	auth->cb = cb;
-	auth->user_data = user_data;
-	sdata->auth_pending = g_slist_prepend(sdata->auth_pending, auth);
-
-	if (sdata->auth_request) {
-		return;
-	}
-
-	purple_debug_info("gg", "ggp_ggdrive_auth(gc=%p)", gc);
-
-	msg = soup_message_new("PUT", "https://drive.mpa.gg.pl/signin");
-	ggp_edisc_set_defaults(msg);
-	headers = soup_message_get_request_headers(msg);
-
-	metadata = g_strdup_printf("{"
-	                           "\"id\": \"%032x\", "
-	                           "\"name\": \"%s\", "
-	                           "\"os_version\": \"" GGP_EDISC_OS "\", "
-	                           "\"client_version\": \"%s\", "
-	                           "\"type\": \"" GGP_EDISC_TYPE "\"}",
-	                           g_random_int_range(1, 1 << 16),
-	                           g_get_host_name(), ggp_libgaduw_version(gc));
-
-	tmp = g_strdup_printf("IMToken %s", imtoken);
-	soup_message_headers_replace(headers, "Authorization", tmp);
-	g_free(tmp);
-	tmp = g_strdup_printf("gg/pl:%u", accdata->session->uin);
-	soup_message_headers_replace(headers, "X-gged-user", tmp);
-	g_free(tmp);
-	soup_message_headers_replace(headers, "X-gged-client-metadata", metadata);
-	g_free(metadata);
-
-	sdata->auth_request = msg;
-	soup_session_send_and_read_async(sdata->session, msg, G_PRIORITY_DEFAULT,
-	                                 NULL, ggp_ggdrive_auth_done, gc);
-}
-
-static void
-ggp_edisc_xfer_send_ticket_changed(G_GNUC_UNUSED PurpleConnection *gc,
-                                   PurpleXfer *xfer, gboolean is_allowed)
-{
-	GGPXfer *edisc_xfer = GGP_XFER(xfer);
-	if (!edisc_xfer) {
-		purple_debug_error(
-		        "gg",
-		        "ggp_edisc_event_ticket_changed: transfer %p already free'd",
-		        xfer);
-		return;
-	}
-
-	if (!is_allowed) {
-		purple_debug_info(
-		        "gg", "ggp_edisc_event_ticket_changed: transfer %p rejected",
-		        xfer);
-		purple_xfer_cancel_remote(xfer);
-		return;
-	}
-
-	if (edisc_xfer->allowed) {
-		purple_debug_misc(
-		        "gg",
-		        "ggp_edisc_event_ticket_changed: transfer %p already allowed",
-		        xfer);
-		return;
-	}
-	edisc_xfer->allowed = TRUE;
-
-	purple_xfer_start(xfer, -1, NULL, 0);
-}
-
-/*******************************************************************************
- * Sending a file.
- ******************************************************************************/
-
-gboolean
-ggp_edisc_xfer_can_receive_file(G_GNUC_UNUSED PurpleProtocolXfer *prplxfer,
-                                PurpleConnection *gc, const char *who)
-{
-	PurpleBuddy *buddy;
-
-	g_return_val_if_fail(gc != NULL, FALSE);
-	g_return_val_if_fail(who != NULL, FALSE);
-
-	buddy = purple_blist_find_buddy(purple_connection_get_account(gc), who);
-	if (buddy == NULL) {
-		return FALSE;
-	}
-
-	/* TODO: check, if this buddy have us on his list */
-
-	return PURPLE_BUDDY_IS_ONLINE(buddy);
-}
-
-static void
-ggp_edisc_xfer_send_init_ticket_created(GObject *source, GAsyncResult *result,
-                                        gpointer data)
-{
-	PurpleXfer *xfer = data;
-	GGPXfer *edisc_xfer = GGP_XFER(xfer);
-	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(edisc_xfer->gc);
-	GBytes *response_body = NULL;
-	const char *buffer = NULL;
-	gsize size = 0;
-	ggp_edisc_xfer_ack_status ack_status;
-	JsonParser *parser;
-	JsonObject *ticket;
-	GError *error = NULL;
-
-	if (purple_xfer_is_cancelled(xfer))
-		return;
-
-	g_return_if_fail(sdata != NULL);
-
-	response_body = soup_session_send_and_read_finish(SOUP_SESSION(source),
-	                                                  result, &error);
-	if(response_body == NULL) {
-		purple_debug_error("gg",
-		                   "ggp_edisc_xfer_send_init_ticket_created: failed "
-		                   "to send file: %s", error->message);
-		g_clear_object(&edisc_xfer->msg);
-		ggp_edisc_xfer_error(xfer, _("Unable to send file"));
-		g_error_free(error);
-		return;
-	}
-
-	buffer = g_bytes_get_data(response_body, &size);
-
-	if(!SOUP_STATUS_IS_SUCCESSFUL(soup_message_get_status(edisc_xfer->msg))) {
-		int error_id = ggp_edisc_parse_error(buffer);
-
-		g_bytes_unref(response_body);
-		g_clear_object(&edisc_xfer->msg);
-
-		if(error_id == 206) {
-			/* recipient not logged in */
-			ggp_edisc_xfer_error(xfer, _("Recipient not logged in"));
-		} else if(error_id == 207) {
-			/* bad sender recipient relation */
-			ggp_edisc_xfer_error(xfer,
-			                     _("You aren't on the recipient's buddy list"));
-		} else {
-			ggp_edisc_xfer_error(xfer, _("Unable to send file"));
-		}
-		return;
-	}
-
-	parser = ggp_json_parse(buffer);
-	ticket = json_node_get_object(json_parser_get_root(parser));
-	ticket = json_object_get_object_member(ticket, "result");
-	ticket = json_object_get_object_member(ticket, "send_ticket");
-	edisc_xfer->ticket_id = g_strdup(json_object_get_string_member(
-		ticket, "id"));
-	ack_status = ggp_edisc_xfer_parse_ack_status(
-		json_object_get_string_member(ticket, "ack_status"));
-	/* send_mode: "normal", "publink" (for legacy clients) */
-
-	g_object_unref(parser);
-	g_bytes_unref(response_body);
-	g_clear_object(&edisc_xfer->msg);
-
-	if (edisc_xfer->ticket_id == NULL) {
-		purple_debug_error("gg",
-			"ggp_edisc_xfer_send_init_ticket_created: "
-			"couldn't get ticket id\n");
-		return;
-	}
-
-	purple_debug_info("gg", "ggp_edisc_xfer_send_init_ticket_created: "
-		"ticket \"%s\" created\n", edisc_xfer->ticket_id);
-
-	g_hash_table_insert(sdata->xfers_initialized, edisc_xfer->ticket_id, xfer);
-	g_hash_table_add(sdata->xfers_history, g_strdup(edisc_xfer->ticket_id));
-
-	if (ack_status != GGP_EDISC_XFER_ACK_STATUS_UNKNOWN)
-		ggp_edisc_xfer_send_ticket_changed(edisc_xfer->gc, xfer,
-			ack_status == GGP_EDISC_XFER_ACK_STATUS_ALLOWED);
-}
-
-static void
-ggp_edisc_xfer_send_init_authenticated(PurpleConnection *gc, gboolean success,
-                                       gpointer _xfer)
-{
-	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc);
-	SoupMessage *msg;
-	PurpleXfer *xfer = _xfer;
-	GGPXfer *edisc_xfer = GGP_XFER(xfer);
-	gchar *data;
-	GBytes *body = NULL;
-
-	if (purple_xfer_is_cancelled(xfer)) {
-		return;
-	}
-
-	if (!success) {
-		ggp_edisc_xfer_error(xfer, _("Authentication failed"));
-		return;
-	}
-
-	g_return_if_fail(sdata != NULL);
-
-	msg = soup_message_new("PUT", "https://drive.mpa.gg.pl/send_ticket");
-	ggp_edisc_set_defaults(msg);
-
-	soup_message_headers_replace(soup_message_get_request_headers(msg),
-	                             "X-gged-security-token",
-	                             sdata->security_token);
-
-	data = g_strdup_printf("{\"send_ticket\":{"
-	                       "\"recipient\":\"%s\","
-	                       "\"file_name\":\"%s\","
-	                       "\"file_size\":\"%u\""
-	                       "}}",
-	                       purple_xfer_get_remote_user(xfer),
-	                       edisc_xfer->filename,
-	                       (int)purple_xfer_get_size(xfer));
-	body = g_bytes_new_take(data, strlen(data));
-	soup_message_set_request_body_from_bytes(msg,
-	                                         "application/x-www-form-urlencoded; charset=UTF-8",
-	                                         body);
-	g_bytes_unref(body);
-
-	edisc_xfer->msg = msg;
-	soup_session_send_and_read_async(sdata->session, msg, G_PRIORITY_DEFAULT,
-	                                 edisc_xfer->cancellable,
-	                                 ggp_edisc_xfer_send_init_ticket_created,
-	                                 xfer);
-}
-
-static void
-ggp_edisc_xfer_send_init(PurpleXfer *xfer)
-{
-	GGPXfer *edisc_xfer = GGP_XFER(xfer);
-
-	purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_NOT_STARTED);
-
-	edisc_xfer->filename = g_strdup(purple_xfer_get_filename(xfer));
-	g_strcanon(edisc_xfer->filename, GGP_EDISC_FNAME_ALLOWED, '_');
-
-	ggp_ggdrive_auth(edisc_xfer->gc, ggp_edisc_xfer_send_init_authenticated,
-	                 xfer);
-}
-
-static void
-ggp_edisc_xfer_send_done(GObject *source, GAsyncResult *async_result,
-                         gpointer data)
-{
-	PurpleXfer *xfer = data;
-	GGPXfer *edisc_xfer = GGP_XFER(xfer);
-	GBytes *response_body = NULL;
-	JsonParser *parser = NULL;
-	JsonObject *result = NULL;
-	int result_status = -1;
-	GError *error = NULL;
-
-	if(purple_xfer_is_cancelled(xfer)) {
-		return;
-	}
-
-	g_return_if_fail(edisc_xfer != NULL);
-
-	if(!SOUP_STATUS_IS_SUCCESSFUL(soup_message_get_status(edisc_xfer->msg))) {
-		g_clear_object(&edisc_xfer->msg);
-		ggp_edisc_xfer_error(xfer, _("Error while sending a file"));
-		return;
-	}
-
-	response_body = soup_session_send_and_read_finish(SOUP_SESSION(source),
-	                                                  async_result, &error);
-	if(response_body == NULL) {
-		g_clear_object(&edisc_xfer->msg);
-		ggp_edisc_xfer_error(xfer, _("Error while sending a file"));
-		g_error_free(error);
-		return;
-	}
-
-	parser = ggp_json_parse(g_bytes_get_data(response_body, NULL));
-	result = json_node_get_object(json_parser_get_root(parser));
-	result = json_object_get_object_member(result, "result");
-	if(json_object_has_member(result, "status")) {
-		result_status = json_object_get_int_member(result, "status");
-	}
-	g_object_unref(parser);
-	g_clear_pointer(&response_body, g_bytes_unref);
-	g_clear_object(&edisc_xfer->msg);
-
-	if(result_status == 0) {
-		purple_xfer_set_completed(xfer, TRUE);
-		purple_xfer_end(xfer);
-	} else {
-		ggp_edisc_xfer_error(xfer, _("Error while sending a file"));
-	}
-}
-
-static void
-ggp_edisc_xfer_send_start_msg_cb(SoupMessage *msg, gpointer data) {
-	PurpleXfer *xfer = data;
-	GInputStream *stream = NULL;
-	/* TODO: Actually fill in stream with something. */
-	soup_message_set_request_body(msg, NULL, stream,
-	                              purple_xfer_get_size(xfer));
-}
-
-static void ggp_edisc_xfer_send_start(PurpleXfer *xfer)
-{
-	ggp_edisc_session_data *sdata;
-	GGPXfer *edisc_xfer;
-	gchar *upload_url, *filename_e;
-	SoupMessage *msg;
-	SoupMessageHeaders *headers;
-
-	g_return_if_fail(xfer != NULL);
-	edisc_xfer = GGP_XFER(xfer);
-	g_return_if_fail(edisc_xfer != NULL);
-	sdata = ggp_edisc_get_sdata(edisc_xfer->gc);
-	g_return_if_fail(sdata != NULL);
-
-	filename_e = purple_strreplace(edisc_xfer->filename, " ", "%20");
-	upload_url = g_strdup_printf("https://drive.mpa.gg.pl/me/file/outbox/"
-		"%s%%2C%s", edisc_xfer->ticket_id, filename_e);
-	g_free(filename_e);
-	msg = soup_message_new("PUT", upload_url);
-	g_free(upload_url);
-
-	ggp_edisc_set_defaults(msg);
-
-	headers = soup_message_get_request_headers(msg);
-	soup_message_headers_replace(headers, "X-gged-local-revision", "0");
-	soup_message_headers_replace(headers, "X-gged-security-token",
-	                             sdata->security_token);
-	soup_message_headers_replace(headers, "X-gged-metadata",
-	                             "{\"node_type\": \"file\"}");
-
-	soup_message_headers_set_content_length(headers,
-	                                        purple_xfer_get_size(xfer));
-	edisc_xfer->msg = msg;
-
-	g_signal_connect(msg, "starting",
-	                 G_CALLBACK(ggp_edisc_xfer_send_start_msg_cb), xfer);
-	g_signal_connect(msg, "restarted",
-	                 G_CALLBACK(ggp_edisc_xfer_send_start_msg_cb), xfer);
-	soup_session_send_and_read_async(sdata->session, msg, G_PRIORITY_DEFAULT,
-	                                 edisc_xfer->cancellable,
-	                                 ggp_edisc_xfer_send_done, xfer);
-}
-
-PurpleXfer *
-ggp_edisc_xfer_send_new(G_GNUC_UNUSED PurpleProtocolXfer *prplxfer,
-                        PurpleConnection *gc, const char *who)
-{
-	GGPXfer *xfer;
-
-	g_return_val_if_fail(gc != NULL, NULL);
-	g_return_val_if_fail(who != NULL, NULL);
-
-	xfer = g_object_new(
-		GGP_TYPE_XFER,
-		"account", purple_connection_get_account(gc),
-		"type", PURPLE_XFER_TYPE_SEND,
-		"remote-user", who,
-		NULL
-	);
-
-	xfer->gc = gc;
-
-	return PURPLE_XFER(xfer);
-}
-
-void ggp_edisc_xfer_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who,
-	const char *filename)
-{
-	PurpleXfer *xfer;
-
-	g_return_if_fail(gc != NULL);
-	g_return_if_fail(who != NULL);
-
-	/* Nothing interesting here, this code is common among protocols.
-	 * See ggp_edisc_xfer_send_new. */
-
-	xfer = ggp_edisc_xfer_send_new(prplxfer, gc, who);
-	if (filename)
-		purple_xfer_request_accepted(xfer, filename);
-	else
-		purple_xfer_request(xfer);
-}
-
-/*******************************************************************************
- * Receiving a file.
- ******************************************************************************/
-
-static PurpleXfer *
-ggp_edisc_xfer_recv_new(PurpleConnection *gc, const char *who)
-{
-	GGPXfer *xfer;
-
-	g_return_val_if_fail(gc != NULL, NULL);
-	g_return_val_if_fail(who != NULL, NULL);
-
-	xfer = g_object_new(GGP_TYPE_XFER, "account",
-	                    purple_connection_get_account(gc), "type",
-	                    PURPLE_XFER_TYPE_RECEIVE, "remote-user", who, NULL);
-
-	xfer->gc = gc;
-
-	return PURPLE_XFER(xfer);
-}
-
-static void
-ggp_edisc_xfer_recv_ack_done(GObject *source, GAsyncResult *result,
-                             gpointer data)
-{
-	PurpleXfer *xfer = data;
-	GGPXfer *edisc_xfer = NULL;
-	GBytes *response_body = NULL;
-	const gchar *buffer = NULL;
-	gsize size = 0;
-	GError *error = NULL;
-
-	if (purple_xfer_is_cancelled(xfer)) {
-		g_return_if_reached();
-	}
-
-	edisc_xfer = GGP_XFER(xfer);
-
-	if(!SOUP_STATUS_IS_SUCCESSFUL(soup_message_get_status(edisc_xfer->msg))) {
-		g_clear_object(&edisc_xfer->msg);
-		ggp_edisc_xfer_error(xfer, _("Cannot confirm file transfer."));
-		return;
-	}
-
-	response_body = soup_session_send_and_read_finish(SOUP_SESSION(source),
-	                                                  result, &error);
-	if(response_body == NULL) {
-		purple_debug_error("gg", "ggp_edisc_xfer_recv_ack_done: failed: %s",
-		                   error->message);
-		g_error_free(error);
-		g_clear_object(&edisc_xfer->msg);
-		ggp_edisc_xfer_error(xfer, _("Cannot confirm file transfer."));
-		return;
-	}
-
-	buffer = g_bytes_get_data(response_body, &size);
-	purple_debug_info("gg", "ggp_edisc_xfer_recv_ack_done: [%.*s]", (int)size,
-	                  buffer);
-
-	g_bytes_unref(response_body);
-	g_clear_object(&edisc_xfer->msg);
-}
-
-static void ggp_edisc_xfer_recv_ack(PurpleXfer *xfer, gboolean accept)
-{
-	GGPXfer *edisc_xfer = GGP_XFER(xfer);
-	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(edisc_xfer->gc);
-	SoupMessage *msg;
-	SoupMessageHeaders *headers;
-
-	g_return_if_fail(sdata != NULL);
-
-	edisc_xfer->allowed = accept;
-
-	msg = soup_message_new("PUT",
-	                       ggp_edisc_xfer_ticket_url(edisc_xfer->ticket_id));
-	ggp_edisc_set_defaults(msg);
-
-	headers = soup_message_get_request_headers(msg);
-	soup_message_headers_replace(headers, "X-gged-security-token",
-	                             sdata->security_token);
-	soup_message_headers_replace(headers, "X-gged-ack-status",
-	                             accept ? "allow" : "reject");
-
-	if(accept) {
-		edisc_xfer->msg = msg;
-		soup_session_send_and_read_async(sdata->session, msg,
-		                                 G_PRIORITY_DEFAULT,
-		                                 edisc_xfer->cancellable,
-		                                 ggp_edisc_xfer_recv_ack_done, xfer);
-	} else {
-		edisc_xfer->msg = NULL;
-		soup_session_send_and_read_async(sdata->session, msg,
-		                                 G_PRIORITY_DEFAULT,
-		                                 edisc_xfer->cancellable, NULL, NULL);
-		g_object_unref(msg);
-	}
-}
-
-static void
-ggp_edisc_xfer_recv_reject(PurpleXfer *xfer)
-{
-	ggp_edisc_xfer_recv_ack(xfer, FALSE);
-}
-
-static void
-ggp_edisc_xfer_recv_accept(PurpleXfer *xfer)
-{
-	ggp_edisc_xfer_recv_ack(xfer, TRUE);
-}
-
-static void ggp_edisc_xfer_recv_ticket_completed(PurpleXfer *xfer)
-{
-	GGPXfer *edisc_xfer = GGP_XFER(xfer);
-
-	if (edisc_xfer->ready)
-		return;
-	edisc_xfer->ready = TRUE;
-
-	purple_xfer_start(xfer, -1, NULL, 0);
-}
-
-static gboolean
-ggp_edisc_xfer_recv_pollable_source_cb(GObject *pollable_stream, gpointer data)
-{
-	PurpleXfer *xfer = data;
-	GGPXfer *edisc_xfer = GGP_XFER(xfer);
-	guchar buf[4096];
-	gssize len;
-	gboolean stored;
-	GError *error = NULL;
-
-	do {
-		len = g_pollable_input_stream_read_nonblocking(
-		        G_POLLABLE_INPUT_STREAM(pollable_stream), buf, sizeof(buf),
-		        edisc_xfer->cancellable, &error);
-		if(len == 0) {
-			/* End of file */
-			if(purple_xfer_get_bytes_remaining(xfer) == 0) {
-				purple_xfer_set_completed(xfer, TRUE);
-				purple_xfer_end(xfer);
-			} else {
-				purple_debug_warning("gg", "ggp_edisc_xfer_recv_done: didn't "
-				                     "receive everything");
-				ggp_edisc_xfer_error(xfer, _("Error while receiving a file"));
-			}
-			edisc_xfer->handler = 0;
-			return G_SOURCE_REMOVE;
-
-		} else if(len < 0) {
-			/* Errors occurred */
-			if(error->code == G_IO_ERROR_WOULD_BLOCK) {
-				g_error_free(error);
-				return G_SOURCE_CONTINUE;
-			} else if(error->code == G_IO_ERROR_CANCELLED) {
-				g_error_free(error);
-			} else {
-				purple_debug_warning("gg", "ggp_edisc_xfer_recv_done: lost "
-				                     "connection with server: %s",
-				                     error->message);
-				ggp_edisc_xfer_error(xfer, _("Error while receiving a file"));
-				g_error_free(error);
-			}
-			edisc_xfer->handler = 0;
-			return G_SOURCE_REMOVE;
-		}
-
-		if(len > purple_xfer_get_bytes_remaining(xfer)) {
-			purple_debug_error("gg", "ggp_edisc_xfer_recv_writer: saved too "
-			                   "much (%" G_GSIZE_FORMAT
-			                   " > %" G_GOFFSET_FORMAT ")",
-			                   len, purple_xfer_get_bytes_remaining(xfer));
-			ggp_edisc_xfer_error(xfer, _("Error while receiving a file"));
-			edisc_xfer->handler = 0;
-			return G_SOURCE_REMOVE;
-		}
-
-		stored = purple_xfer_write_file(xfer, buf, len);
-		if(!stored) {
-			purple_debug_error("gg", "ggp_edisc_xfer_recv_writer: failed to save");
-			ggp_edisc_xfer_error(xfer, _("Error while receiving a file"));
-			edisc_xfer->handler = 0;
-			return G_SOURCE_REMOVE;
-		}
-	} while(len > 0);
-
-	return G_SOURCE_CONTINUE;
-}
-
-static void
-ggp_edisc_xfer_recv_done_cb(GObject *source, GAsyncResult *result,
-                            gpointer data)
-{
-	PurpleXfer *xfer = data;
-	GGPXfer *edisc_xfer = GGP_XFER(xfer);
-	GInputStream *input = NULL;
-	GSource *poll = NULL;
-	GError *error = NULL;
-
-	if(!SOUP_STATUS_IS_SUCCESSFUL(soup_message_get_status(edisc_xfer->msg))) {
-		g_clear_object(&edisc_xfer->msg);
-		ggp_edisc_xfer_error(xfer, _("Error while receiving a file"));
-		return;
-	}
-
-	input = soup_session_send_finish(SOUP_SESSION(source), result, &error);
-	if(input == NULL) {
-		purple_debug_warning("gg", "ggp_edisc_xfer_recv_done_cb: error "
-		                     "receiving file: %s", error->message);
-		g_error_free(error);
-		g_clear_object(&edisc_xfer->msg);
-		ggp_edisc_xfer_error(xfer, _("Error while receiving a file"));
-		return;
-	}
-
-	poll = g_pollable_input_stream_create_source(G_POLLABLE_INPUT_STREAM(input),
-	                                             edisc_xfer->cancellable);
-	g_source_set_callback(poll,
-	                      G_SOURCE_FUNC(ggp_edisc_xfer_recv_pollable_source_cb),
-	                      xfer, NULL);
-	edisc_xfer->handler = g_source_attach(poll, NULL);
-	g_source_unref(poll);
-	g_clear_object(&edisc_xfer->msg);
-}
-
-static void
-ggp_edisc_xfer_recv_start(PurpleXfer *xfer)
-{
-	ggp_edisc_session_data *sdata;
-	GGPXfer *edisc_xfer;
-	gchar *upload_url;
-	SoupMessage *msg;
-
-	g_return_if_fail(xfer != NULL);
-	edisc_xfer = GGP_XFER(xfer);
-	g_return_if_fail(edisc_xfer != NULL);
-	sdata = ggp_edisc_get_sdata(edisc_xfer->gc);
-	g_return_if_fail(sdata != NULL);
-
-	upload_url =
-	        g_strdup_printf("https://drive.mpa.gg.pl/me/file/inbox/"
-	                        "%s,%s?api_version=%s&security_token=%s",
-	                        edisc_xfer->ticket_id,
-	                        purple_url_encode(purple_xfer_get_filename(xfer)),
-	                        GGP_EDISC_API, sdata->security_token);
-	msg = soup_message_new("GET", upload_url);
-	g_free(upload_url);
-
-	ggp_edisc_set_defaults(msg);
-	// purple_http_request_set_max_len(msg, purple_xfer_get_size(xfer) + 1);
-
-	edisc_xfer->msg = msg;
-	soup_session_send_async(sdata->session, msg, G_PRIORITY_DEFAULT,
-	                        edisc_xfer->cancellable,
-	                        ggp_edisc_xfer_recv_done_cb, xfer);
-}
-
-static void
-ggp_edisc_xfer_recv_ticket_update_got(GObject *source,
-                                      GAsyncResult *async_result,
-                                      gpointer data)
-{
-	SoupMessage *msg = data;
-	PurpleConnection *gc = NULL;
-	GBytes *response_body = NULL;
-	PurpleXfer *xfer;
-	GGPXfer *edisc_xfer;
-	const char *buffer = NULL;
-	gsize size = 0;
-	JsonParser *parser;
-	JsonObject *result;
-	int status = -1;
-	ggp_edisc_session_data *sdata;
-
-	const gchar *ticket_id, *file_name, *send_mode_str;
-	uin_t sender, recipient;
-	int file_size;
-	SoupStatus status_code;
-	GError *error = NULL;
-
-	status_code = soup_message_get_status(msg);
-	if (!SOUP_STATUS_IS_SUCCESSFUL(status_code)) {
-		purple_debug_error("gg",
-		                   "ggp_edisc_xfer_recv_ticket_update_got: cannot "
-		                   "fetch update for ticket (code=%d)",
-		                   status_code);
-		g_object_unref(msg);
-		return;
-	}
-
-	response_body = soup_session_send_and_read_finish(SOUP_SESSION(source),
-	                                                  async_result, &error);
-	if(response_body == NULL) {
-		purple_debug_error("gg",
-		                   "ggp_edisc_xfer_recv_ticket_update_got: cannot "
-		                   "fetch update for ticket (%s)",
-		                   error->message);
-		g_error_free(error);
-		g_object_unref(msg);
-		return;
-	}
-
-	gc = g_object_get_data(G_OBJECT(msg), "purple-connection");
-	sdata = ggp_edisc_get_sdata(gc);
-	if(sdata == NULL) {
-		g_bytes_unref(response_body);
-		g_object_unref(msg);
-		g_return_if_reached();
-		return;
-	}
-
-	buffer = g_bytes_get_data(response_body, &size);
-	parser = ggp_json_parse(buffer);
-	g_clear_pointer(&response_body, g_bytes_unref);
-	g_clear_object(&msg);
-
-	result = json_node_get_object(json_parser_get_root(parser));
-	result = json_object_get_object_member(result, "result");
-	if (json_object_has_member(result, "status"))
-		status = json_object_get_int_member(result, "status");
-	result = json_object_get_object_member(result, "send_ticket");
-
-	if (status != 0) {
-		purple_debug_warning("gg",
-		                     "ggp_edisc_xfer_recv_ticket_update_got: failed to "
-		                     "get update (status=%d)",
-		                     status);
-		g_object_unref(parser);
-		return;
-	}
-
-	ticket_id = json_object_get_string_member(result, "id");
-	sender = ggp_str_to_uin(json_object_get_string_member(result, "sender"));
-	recipient =
-	        ggp_str_to_uin(json_object_get_string_member(result, "recipient"));
-	file_size = g_ascii_strtoll(
-	        json_object_get_string_member(result, "file_size"), NULL, 10);
-	file_name = json_object_get_string_member(result, "file_name");
-
-	/* GG11: normal
-	 * AQQ 2.4.2.10: direct_inbox
-	 */
-	send_mode_str = json_object_get_string_member(result, "send_mode");
-
-	/* more fields:
-	 * send_progress (float), ack_status, send_status
-	 */
-
-	if (purple_debug_is_verbose() && purple_debug_is_unsafe()) {
-		purple_debug_info("gg",
-		                  "Got ticket update: id=%s, sender=%u, recipient=%u, "
-		                  "file name=\"%s\", file size=%d, send mode=%s)",
-		                  ticket_id, sender, recipient, file_name, file_size,
-		                  send_mode_str);
-	}
-
-	xfer = g_hash_table_lookup(sdata->xfers_initialized, ticket_id);
-	if (xfer != NULL) {
-		purple_debug_misc("gg",
-		                  "ggp_edisc_xfer_recv_ticket_update_got: ticket %s "
-		                  "already updated",
-		                  purple_debug_is_unsafe() ? ticket_id : "");
-		g_object_unref(parser);
-		return;
-	}
-
-	if (recipient != ggp_get_my_uin(gc)) {
-		purple_debug_misc("gg",
-		                  "ggp_edisc_xfer_recv_ticket_update_got: ticket %s is "
-		                  "not for incoming transfer (its from %u to %u)",
-		                  purple_debug_is_unsafe() ? ticket_id : "", sender,
-		                  recipient);
-		g_object_unref(parser);
-		return;
-	}
-
-	xfer = ggp_edisc_xfer_recv_new(gc, ggp_uin_to_str(sender));
-	purple_xfer_set_filename(xfer, file_name);
-	purple_xfer_set_size(xfer, file_size);
-	purple_xfer_request(xfer);
-	edisc_xfer = GGP_XFER(xfer);
-	edisc_xfer->ticket_id = g_strdup(ticket_id);
-	g_hash_table_insert(sdata->xfers_initialized, edisc_xfer->ticket_id, xfer);
-	g_hash_table_add(sdata->xfers_history, g_strdup(ticket_id));
-
-	g_object_unref(parser);
-}
-
-static void
-ggp_edisc_xfer_recv_ticket_update_authenticated(PurpleConnection *gc,
-                                                gboolean success,
-                                                gpointer _ticket)
-{
-	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc);
-	SoupMessage *msg;
-	gchar *ticket = _ticket;
-
-	g_return_if_fail(sdata != NULL);
-
-	if (!success) {
-		purple_debug_warning(
-		        "gg",
-		        "ggp_edisc_xfer_recv_ticket_update_authenticated: update of "
-		        "ticket %s aborted due to authentication failure",
-		        ticket);
-		g_free(ticket);
-		return;
-	}
-
-	msg = soup_message_new("GET", ggp_edisc_xfer_ticket_url(ticket));
-	g_free(ticket);
-
-	ggp_edisc_set_defaults(msg);
-
-	soup_message_headers_replace(soup_message_get_request_headers(msg),
-	                             "X-gged-security-token",
-	                             sdata->security_token);
-
-	g_object_set_data(G_OBJECT(msg), "purple-connection", gc);
-	soup_session_send_and_read_async(sdata->session, msg, G_PRIORITY_DEFAULT,
-	                                 NULL,
-	                                 ggp_edisc_xfer_recv_ticket_update_got,
-	                                 msg);
-}
-
-static void
-ggp_edisc_xfer_recv_ticket_got(PurpleConnection *gc, const gchar *ticket_id)
-{
-	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc);
-
-	g_return_if_fail(sdata != NULL);
-
-	if (g_hash_table_contains(sdata->xfers_history, ticket_id)) {
-		return;
-	}
-
-	ggp_ggdrive_auth(gc, ggp_edisc_xfer_recv_ticket_update_authenticated,
-	                 g_strdup(ticket_id));
-}
-
-void
-ggp_edisc_xfer_ticket_changed(PurpleConnection *gc, const char *data)
-{
-	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc);
-	PurpleXfer *xfer;
-	JsonParser *parser;
-	JsonObject *ticket;
-	const gchar *ticket_id, *send_status;
-	ggp_edisc_xfer_ack_status ack_status;
-	gboolean is_completed;
-
-	g_return_if_fail(sdata != NULL);
-
-	parser = ggp_json_parse(data);
-	ticket = json_node_get_object(json_parser_get_root(parser));
-	ticket_id = json_object_get_string_member(ticket, "id");
-	ack_status = ggp_edisc_xfer_parse_ack_status(
-	        json_object_get_string_member(ticket, "ack_status"));
-	send_status = json_object_get_string_member(ticket, "send_status");
-
-	if (ticket_id == NULL) {
-		ticket_id = "";
-	}
-	xfer = g_hash_table_lookup(sdata->xfers_initialized, ticket_id);
-	if (xfer == NULL) {
-		purple_debug_misc("gg",
-		                  "ggp_edisc_event_ticket_changed: ticket %s not "
-		                  "found, updating it...",
-		                  purple_debug_is_unsafe() ? ticket_id : "");
-		ggp_edisc_xfer_recv_ticket_got(gc, ticket_id);
-		g_object_unref(parser);
-		return;
-	}
-
-	is_completed = FALSE;
-	if (g_strcmp0("in_progress", send_status) == 0) {
-		/* do nothing */
-	} else if (g_strcmp0("completed", send_status) == 0) {
-		is_completed = TRUE;
-	} else if (g_strcmp0("expired", send_status) == 0)
-		ggp_edisc_xfer_error(xfer, _("File transfer expired."));
-	else {
-		purple_debug_warning(
-		        "gg", "ggp_edisc_event_ticket_changed: unknown send_status=%s",
-		        send_status);
-		g_object_unref(parser);
-		return;
-	}
-
-	g_object_unref(parser);
-
-	if (purple_xfer_get_xfer_type(xfer) == PURPLE_XFER_TYPE_RECEIVE) {
-		if (is_completed) {
-			ggp_edisc_xfer_recv_ticket_completed(xfer);
-		}
-	} else {
-		if (ack_status != GGP_EDISC_XFER_ACK_STATUS_UNKNOWN) {
-			ggp_edisc_xfer_send_ticket_changed(
-			        gc, xfer, ack_status == GGP_EDISC_XFER_ACK_STATUS_ALLOWED);
-		}
-	}
-}
-
-/*******************************************************************************
- * GObject implementation
- ******************************************************************************/
-
-G_DEFINE_DYNAMIC_TYPE_EXTENDED(GGPXfer, ggp_xfer, PURPLE_TYPE_XFER,
-                               G_TYPE_FLAG_FINAL, {})
-
-static void
-ggp_xfer_init_xfer(PurpleXfer *xfer) {
-	PurpleXferType type = purple_xfer_get_xfer_type(xfer);
-
-	if(type == PURPLE_XFER_TYPE_SEND) {
-		ggp_edisc_xfer_send_init(xfer);
-	} else if(type == PURPLE_XFER_TYPE_RECEIVE) {
-		ggp_edisc_xfer_recv_accept(xfer);
-	}
-}
-
-static void
-ggp_xfer_start(PurpleXfer *xfer) {
-	PurpleXferType type = purple_xfer_get_xfer_type(xfer);
-
-	if(type == PURPLE_XFER_TYPE_SEND) {
-		ggp_edisc_xfer_send_start(xfer);
-	} else if(type == PURPLE_XFER_TYPE_RECEIVE) {
-		ggp_edisc_xfer_recv_start(xfer);
-	}
-}
-
-static void
-ggp_xfer_init(GGPXfer *xfer) {
-	xfer->cancellable = g_cancellable_new();
-}
-
-static void
-ggp_xfer_finalize(GObject *obj) {
-	GGPXfer *edisc_xfer = GGP_XFER(obj);
-	ggp_edisc_session_data *sdata;
-
-	sdata = ggp_edisc_get_sdata(edisc_xfer->gc);
-
-	g_free(edisc_xfer->filename);
-	g_cancellable_cancel(edisc_xfer->cancellable);
-	g_clear_object(&edisc_xfer->cancellable);
-	g_clear_object(&edisc_xfer->msg);
-
-	g_clear_handle_id(&edisc_xfer->handler, g_source_remove);
-
-	if (edisc_xfer->ticket_id != NULL) {
-		g_hash_table_remove(sdata->xfers_initialized,
-			edisc_xfer->ticket_id);
-	}
-
-	G_OBJECT_CLASS(ggp_xfer_parent_class)->finalize(obj);
-}
-
-static void
-ggp_xfer_class_finalize(G_GNUC_UNUSED GGPXferClass *klass) {
-}
-
-static void
-ggp_xfer_class_init(GGPXferClass *klass) {
-	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-	PurpleXferClass *xfer_class = PURPLE_XFER_CLASS(klass);
-
-	obj_class->finalize = ggp_xfer_finalize;
-
-	xfer_class->init = ggp_xfer_init_xfer;
-	xfer_class->start = ggp_xfer_start;
-	xfer_class->request_denied = ggp_edisc_xfer_recv_reject;
-}
-
-void
-ggp_xfer_register(GTypeModule *module) {
-	ggp_xfer_register_type(module);
-}
diff --git a/libpurple/protocols/gg/gg.h b/libpurple/protocols/gg/gg.h
deleted file mode 100644
--- a/libpurple/protocols/gg/gg.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * @file gg.h
- *
- * purple
- *
- * Copyright (C) 2005  Bartosz Oler <bartosz@bzimage.us>
- *
- * 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_GG_GG_H
-#define PURPLE_GG_GG_H
-
-#define GGP_UIN_LEN_MAX 10
-
-#include <gmodule.h>
-#include <libgadu.h>
-#include <libsoup/soup.h>
-
-#include "search.h"
-
-#include <purple.h>
-
-#include "image-prpl.h"
-#include "avatar.h"
-#include "roster.h"
-#include "multilogon.h"
-#include "status.h"
-#include "chat.h"
-#include "message-prpl.h"
-#include "edisc.h"
-
-#define GGP_TYPE_PROTOCOL (ggp_protocol_get_type())
-
-G_MODULE_EXPORT
-G_DECLARE_FINAL_TYPE(GGPProtocol, ggp_protocol, GGP, PROTOCOL, PurpleProtocol)
-
-typedef struct {
-	struct gg_session *session;
-	SoupSession *http;
-	guint inpa;
-
-	gchar *imtoken;
-	gboolean imtoken_warned;
-
-	ggp_image_session_data *image_data;
-	ggp_avatar_session_data *avatar_data;
-	ggp_roster_session_data roster_data;
-	ggp_multilogon_session_data *multilogon_data;
-	ggp_status_session_data *status_data;
-	ggp_chat_session_data *chat_data;
-	ggp_message_session_data *message_data;
-	ggp_edisc_session_data *edisc_data;
-} GGPInfo;
-
-typedef struct
-{
-	gboolean blocked;
-	gboolean not_a_friend;
-} ggp_buddy_data;
-
-ggp_buddy_data * ggp_buddy_get_data(PurpleBuddy *buddy);
-
-const gchar * ggp_get_imtoken(PurpleConnection *gc);
-
-uin_t ggp_own_uin(PurpleConnection *gc);
-
-void ggp_async_login_handler(gpointer _gc, gint fd, PurpleInputCondition cond);
-
-#endif /* PURPLE_GG_GG_H */
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
deleted file mode 100644
--- a/libpurple/protocols/gg/gg.c
+++ /dev/null
@@ -1,1452 +0,0 @@
-/**
- * @file gg.c Gadu-Gadu protocol plugin
- *
- * purple
- *
- * Copyright (C) 2005  Bartosz Oler <bartosz@bzimage.us>
- *
- * Some parts of the code are adapted or taken from the previous implementation
- * of this plugin written by Arkadiusz Miskiewicz <misiek@pld.org.pl>
- * Some parts Copyright (C) 2009  Krzysztof Klinikowski <grommasher@gmail.com>
- *
- * Thanks to Google's Summer of Code Program.
- *
- * 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 <gplugin.h>
-#include <gplugin-native.h>
-
-#include <purple.h>
-
-#include "gg.h"
-#include "chat.h"
-#include "search.h"
-#include "blist.h"
-#include "utils.h"
-#include "resolver-purple.h"
-#include "purplew.h"
-#include "libgadu-events.h"
-#include "multilogon.h"
-#include "status.h"
-#include "servconn.h"
-#include "tcpsocket.h"
-#include "pubdir-prpl.h"
-#include "message-prpl.h"
-#include "html.h"
-#include "libgaduw.h"
-
-struct _GGPProtocol {
-	PurpleProtocol parent;
-};
-
-/* ---------------------------------------------------------------------- */
-static PurpleProtocol *my_protocol = NULL;
-
-/* ---------------------------------------------------------------------- */
-
-ggp_buddy_data * ggp_buddy_get_data(PurpleBuddy *buddy)
-{
-	ggp_buddy_data *buddy_data = purple_buddy_get_protocol_data(buddy);
-	if (buddy_data)
-		return buddy_data;
-
-	buddy_data = g_new0(ggp_buddy_data, 1); /* TODO: leak */
-	purple_buddy_set_protocol_data(buddy, buddy_data);
-	return buddy_data;
-}
-
-static void
-ggp_buddy_free(G_GNUC_UNUSED PurpleProtocolClient *client, PurpleBuddy *buddy)
-{
-	ggp_buddy_data *buddy_data = purple_buddy_get_protocol_data(buddy);
-
-	if (!buddy_data) {
-		return;
-	}
-
-	g_free(buddy_data);
-	purple_buddy_set_protocol_data(buddy, NULL);
-}
-
-const gchar * ggp_get_imtoken(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-
-	if (accdata->imtoken)
-		return accdata->imtoken;
-
-	if (accdata->imtoken_warned)
-		return NULL;
-	accdata->imtoken_warned = TRUE;
-
-	purple_notify_error(gc, _("Authentication failed"),
-		_("IMToken value has not been received."),
-		_("Some features will be disabled. "
-		"You may try again after a while."),
-		purple_request_cpar_from_connection(gc));
-	return NULL;
-}
-
-uin_t
-ggp_own_uin(PurpleConnection *gc) {
-	PurpleAccount *account = purple_connection_get_account(gc);
-	PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
-
-	return ggp_str_to_uin(purple_contact_info_get_username(info));
-}
-
-/* ---------------------------------------------------------------------- */
-/* buddy list import/export from/to file */
-
-static void ggp_callback_buddylist_save_ok(PurpleConnection *gc, const char *filename)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-
-	char *buddylist = ggp_buddylist_dump(account);
-
-	purple_debug_info("gg", "Saving...\n");
-	purple_debug_info("gg", "file = %s\n", filename);
-
-	if (buddylist == NULL) {
-		purple_notify_info(account, _("Save Buddylist..."), _("Your "
-			"buddylist is empty, nothing was written to the file."),
-			NULL, purple_request_cpar_from_connection(gc));
-		return;
-	}
-
-	if (g_file_set_contents(filename, buddylist, -1, NULL)) {
-		purple_notify_info(account, _("Save Buddylist..."),
-			_("Buddylist saved successfully!"), NULL,
-			purple_request_cpar_from_connection(gc));
-	} else {
-		PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
-		gchar *primary = NULL;
-
-		primary = g_strdup_printf(_("Couldn't write buddy list for %s to %s"),
-		                          purple_contact_info_get_username(info),
-		                          filename);
-		purple_notify_error(account, _("Save Buddylist..."),
-			primary, NULL, purple_request_cpar_from_connection(gc));
-		g_free(primary);
-	}
-
-	g_free(buddylist);
-}
-
-static void ggp_callback_buddylist_load_ok(PurpleConnection *gc, gchar *file)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	GError *error = NULL;
-	char *buddylist = NULL;
-	gsize length;
-
-	purple_debug_info("gg", "file_name = %s\n", file);
-
-	if (!g_file_get_contents(file, &buddylist, &length, &error)) {
-		purple_notify_error(account, _("Couldn't load buddylist"),
-			_("Couldn't load buddylist"), error->message,
-			purple_request_cpar_from_connection(gc));
-
-		purple_debug_error("gg",
-			"Couldn't load buddylist. file = %s; error = %s\n",
-			file, error->message);
-
-		g_error_free(error);
-
-		return;
-	}
-
-	ggp_buddylist_load(gc, buddylist);
-	g_free(buddylist);
-
-	purple_notify_info(account, _("Load Buddylist..."),
-		_("Buddylist loaded successfully!"), NULL,
-		purple_request_cpar_from_connection(gc));
-}
-/* }}} */
-
-static void
-ggp_action_buddylist_save(G_GNUC_UNUSED GSimpleAction *action,
-                          GVariant *parameter,
-                          G_GNUC_UNUSED gpointer data)
-{
-	const gchar *account_id = NULL;
-	PurpleAccountManager *manager = NULL;
-	PurpleAccount *account = NULL;
-	PurpleConnection *connection = NULL;
-
-	if(!g_variant_is_of_type(parameter, G_VARIANT_TYPE_STRING)) {
-		g_critical("GG save buddylist action parameter is of incorrect type %s",
-		           g_variant_get_type_string(parameter));
-	}
-
-	account_id = g_variant_get_string(parameter, NULL);
-	manager = purple_account_manager_get_default();
-	account = purple_account_manager_find_by_id(manager, account_id);
-	connection = purple_account_get_connection(account);
-
-	purple_request_file(action, _("Save buddylist..."), NULL, TRUE,
-		G_CALLBACK(ggp_callback_buddylist_save_ok), NULL,
-		purple_request_cpar_from_connection(connection), connection);
-
-	g_clear_object(&account);
-}
-
-static void
-ggp_action_buddylist_load(G_GNUC_UNUSED GSimpleAction *action,
-                          GVariant *parameter,
-                          G_GNUC_UNUSED gpointer data)
-{
-	const gchar *account_id = NULL;
-	PurpleAccountManager *manager = NULL;
-	PurpleAccount *account = NULL;
-	PurpleConnection *connection = NULL;
-
-	if(!g_variant_is_of_type(parameter, G_VARIANT_TYPE_STRING)) {
-		g_critical("GG load buddylist action parameter is of incorrect type %s",
-		           g_variant_get_type_string(parameter));
-	}
-
-	account_id = g_variant_get_string(parameter, NULL);
-	manager = purple_account_manager_get_default();
-	account = purple_account_manager_find_by_id(manager, account_id);
-	connection = purple_account_get_connection(account);
-
-	purple_request_file(action, _("Load buddylist from file..."), NULL,
-		FALSE, G_CALLBACK(ggp_callback_buddylist_load_ok), NULL,
-		purple_request_cpar_from_connection(connection), connection);
-
-	g_clear_object(&account);
-}
-
-/* ----- BLOCK BUDDIES -------------------------------------------------- */
-
-#if 0
-static void ggp_add_deny(PurpleProtocolPrivacy *privacy, PurpleConnection *gc,
-                         const char *who)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	uin_t uin = ggp_str_to_uin(who);
-
-	purple_debug_info("gg", "ggp_add_deny: %u\n", uin);
-
-	gg_remove_notify_ex(info->session, uin, GG_USER_NORMAL);
-	gg_add_notify_ex(info->session, uin, GG_USER_BLOCKED);
-}
-
-static void ggp_remove_deny(PurpleProtocolPrivacy *privacy,
-                            PurpleConnection *gc, const char *who)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	uin_t uin = ggp_str_to_uin(who);
-
-	purple_debug_info("gg", "ggp_rem_deny: %u\n", uin);
-
-	gg_remove_notify_ex(info->session, uin, GG_USER_BLOCKED);
-	gg_add_notify_ex(info->session, uin, GG_USER_NORMAL);
-}
-#endif
-
-/* ---------------------------------------------------------------------- */
-/* ----- INTERNAL CALLBACKS --------------------------------------------- */
-/* ---------------------------------------------------------------------- */
-
-static void ggp_typing_notification_handler(PurpleConnection *gc, uin_t uin, int length) {
-	gchar *from;
-
-	from = g_strdup_printf("%u", uin);
-	if (length)
-		purple_serv_got_typing(gc, from, 0, PURPLE_IM_TYPING);
-	else
-		purple_serv_got_typing_stopped(gc, from);
-	g_free(from);
-}
-
-/**
- * Handling of XML events.
- *
- * @param gc PurpleConnection.
- * @param data Raw XML contents.
- *
- * @see http://toxygen.net/libgadu/protocol/#ch1.13
- * @todo: this may not be necessary anymore
- */
-static void
-ggp_xml_event_handler(G_GNUC_UNUSED PurpleConnection *gc, char *data)
-{
-	PurpleXmlNode *xml = NULL;
-	PurpleXmlNode *xmlnode_next_event;
-
-	xml = purple_xmlnode_from_str(data, -1);
-	if (xml == NULL) {
-		purple_debug_error("gg", "ggp_xml_event_handler: "
-			"invalid xml: [%s]\n", data);
-		goto out;
-	}
-
-	xmlnode_next_event = purple_xmlnode_get_child(xml, "event");
-	while (xmlnode_next_event != NULL) {
-		PurpleXmlNode *xmlnode_current_event = xmlnode_next_event;
-
-		PurpleXmlNode *xmlnode_type;
-		char *event_type_raw;
-		int event_type = 0;
-
-		PurpleXmlNode *xmlnode_sender;
-		char *event_sender_raw;
-		uin_t event_sender = 0;
-
-		xmlnode_next_event = purple_xmlnode_get_next_twin(xmlnode_next_event);
-
-		xmlnode_type = purple_xmlnode_get_child(xmlnode_current_event, "type");
-		if (xmlnode_type == NULL)
-			continue;
-		event_type_raw = purple_xmlnode_get_data(xmlnode_type);
-		if (event_type_raw != NULL)
-			event_type = atoi(event_type_raw);
-		g_free(event_type_raw);
-
-		xmlnode_sender = purple_xmlnode_get_child(xmlnode_current_event, "sender");
-		if (xmlnode_sender != NULL) {
-			event_sender_raw = purple_xmlnode_get_data(xmlnode_sender);
-			if (event_sender_raw != NULL)
-				event_sender = ggp_str_to_uin(event_sender_raw);
-			g_free(event_sender_raw);
-		}
-
-		switch (event_type)
-		{
-			case 28: /* avatar update */
-				purple_debug_info("gg",
-					"ggp_xml_event_handler: avatar updated (uid: %u)\n",
-					event_sender);
-				break;
-			default:
-				purple_debug_error("gg",
-					"ggp_xml_event_handler: unsupported event type=%d from=%u\n",
-					event_type, event_sender);
-		}
-	}
-
-	out:
-		if (xml)
-			purple_xmlnode_free(xml);
-}
-
-static void
-ggp_callback_recv(gpointer _gc, G_GNUC_UNUSED gint fd,
-                  G_GNUC_UNUSED PurpleInputCondition cond)
-{
-	PurpleConnection *gc = _gc;
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	struct gg_event *ev;
-
-	if (!(ev = gg_watch_fd(info->session))) {
-		purple_debug_error("gg",
-			"ggp_callback_recv: gg_watch_fd failed -- CRITICAL!\n");
-		purple_connection_error (gc,
-			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-			_("Unable to read from socket"));
-		return;
-	}
-
-	if (purple_debug_is_verbose()) {
-		purple_debug_misc("gg", "ggp_callback_recv: got event %s",
-			gg_debug_event(ev->type));
-	}
-
-	g_source_remove(info->inpa);
-	info->inpa = purple_input_add(info->session->fd,
-		ggp_tcpsocket_inputcond_gg_to_purple(info->session->check),
-		ggp_callback_recv, gc);
-
-	switch (ev->type) {
-		case GG_EVENT_NONE:
-			/* Nothing happened. */
-			break;
-		case GG_EVENT_CONN_FAILED:
-			purple_connection_error (gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Server disconnected"));
-			break;
-		case GG_EVENT_MSG:
-			ggp_message_got(gc, &ev->event.msg);
-			break;
-		case GG_EVENT_ACK:
-		case GG_EVENT_ACK110:
-			break;
-		case GG_EVENT_IMAGE_REPLY:
-			ggp_image_recv(gc, &ev->event.image_reply);
-			break;
-		case GG_EVENT_IMAGE_REQUEST:
-			ggp_image_send(gc, &ev->event.image_request);
-			break;
-		case GG_EVENT_NOTIFY60:
-		case GG_EVENT_STATUS60:
-			ggp_status_got_others(gc, ev);
-			break;
-		case GG_EVENT_TYPING_NOTIFICATION:
-			ggp_typing_notification_handler(gc, ev->event.typing_notification.uin,
-				ev->event.typing_notification.length);
-			break;
-		case GG_EVENT_XML_EVENT:
-			purple_debug_info("gg", "GG_EVENT_XML_EVENT\n");
-			ggp_xml_event_handler(gc, ev->event.xml_event.data);
-			break;
-		case GG_EVENT_USER_DATA:
-			ggp_events_user_data(gc, &ev->event.user_data);
-			break;
-		case GG_EVENT_JSON_EVENT:
-			ggp_events_json(gc, &ev->event.json_event);
-			break;
-		case GG_EVENT_USERLIST100_VERSION:
-			ggp_roster_version(gc, &ev->event.userlist100_version);
-			break;
-		case GG_EVENT_USERLIST100_REPLY:
-			ggp_roster_reply(gc, &ev->event.userlist100_reply);
-			break;
-		case GG_EVENT_MULTILOGON_MSG:
-			ggp_message_got_multilogon(gc, &ev->event.multilogon_msg);
-			break;
-		case GG_EVENT_MULTILOGON_INFO:
-			ggp_multilogon_info(gc, &ev->event.multilogon_info);
-			break;
-		case GG_EVENT_IMTOKEN:
-			purple_debug_info("gg", "gg11: got IMTOKEN\n");
-			g_free(info->imtoken);
-			info->imtoken = g_strdup(ev->event.imtoken.imtoken);
-			break;
-		case GG_EVENT_PONG110:
-			purple_debug_info("gg", "gg11: got PONG110 %lu\n",
-				(long unsigned)ev->event.pong110.time);
-			break;
-		case GG_EVENT_CHAT_INFO:
-		case GG_EVENT_CHAT_INFO_GOT_ALL:
-		case GG_EVENT_CHAT_INFO_UPDATE:
-		case GG_EVENT_CHAT_CREATED:
-		case GG_EVENT_CHAT_INVITE_ACK:
-			ggp_chat_got_event(gc, ev);
-			break;
-		case GG_EVENT_DISCONNECT:
-			ggp_servconn_remote_disconnect(gc);
-			break;
-		default:
-			purple_debug_warning("gg",
-				"unsupported event type=%d\n", ev->type);
-			break;
-	}
-
-	gg_free_event(ev);
-}
-
-void
-ggp_async_login_handler(gpointer _gc, G_GNUC_UNUSED gint fd,
-                        G_GNUC_UNUSED PurpleInputCondition cond)
-{
-	PurpleConnection *gc = _gc;
-	GGPInfo *info;
-	struct gg_event *ev;
-
-	PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
-
-	info = purple_connection_get_protocol_data(gc);
-
-	purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n",
-			info->session->check, info->session->state);
-
-	switch (info->session->state) {
-		case GG_STATE_ERROR:
-			purple_debug_info("gg", "GG_STATE_ERROR\n");
-			break;
-		case GG_STATE_RESOLVING:
-			purple_debug_info("gg", "GG_STATE_RESOLVING\n");
-			break;
-		case GG_STATE_RESOLVING_GG:
-			purple_debug_info("gg", "GG_STATE_RESOLVING_GG\n");
-			break;
-		case GG_STATE_CONNECTING_HUB:
-			purple_debug_info("gg", "GG_STATE_CONNECTING_HUB\n");
-			break;
-		case GG_STATE_READING_DATA:
-			purple_debug_info("gg", "GG_STATE_READING_DATA\n");
-			break;
-		case GG_STATE_CONNECTING_GG:
-			purple_debug_info("gg", "GG_STATE_CONNECTING_GG\n");
-			break;
-		case GG_STATE_READING_KEY:
-			purple_debug_info("gg", "GG_STATE_READING_KEY\n");
-			break;
-		case GG_STATE_READING_REPLY:
-			purple_debug_info("gg", "GG_STATE_READING_REPLY\n");
-			break;
-		case GG_STATE_TLS_NEGOTIATION:
-			purple_debug_info("gg", "GG_STATE_TLS_NEGOTIATION\n");
-			break;
-		case GG_STATE_RESOLVING_HUB:
-			purple_debug_info("gg", "GG_STATE_RESOLVING_HUB\n");
-			break;
-		case GG_STATE_READING_HUB:
-			purple_debug_info("gg", "GG_STATE_READING_HUB\n");
-			break;
-		default:
-			purple_debug_error("gg", "unknown state = %d\n",
-				info->session->state);
-		break;
-	}
-
-	if (!(ev = gg_watch_fd(info->session))) {
-		purple_debug_error("gg", "login_handler: gg_watch_fd failed!\n");
-		purple_connection_error (gc,
-			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-			_("Unable to read from socket"));
-		return;
-	}
-	purple_debug_info("gg", "login_handler: session->fd = %d\n", info->session->fd);
-	purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n",
-			info->session->check, info->session->state);
-
-	g_clear_handle_id(&info->inpa, g_source_remove);
-
-	/** XXX I think that this shouldn't be done if ev->type is GG_EVENT_CONN_FAILED or GG_EVENT_CONN_SUCCESS -datallah */
-	if (info->session->fd >= 0)
-		info->inpa = purple_input_add(info->session->fd,
-			(info->session->check == 1) ? PURPLE_INPUT_WRITE :
-				PURPLE_INPUT_READ,
-			ggp_async_login_handler, gc);
-
-	switch (ev->type) {
-		case GG_EVENT_NONE:
-			/* Nothing happened. */
-			purple_debug_info("gg", "GG_EVENT_NONE\n");
-			break;
-		case GG_EVENT_CONN_SUCCESS:
-			{
-				purple_debug_info("gg", "GG_EVENT_CONN_SUCCESS:"
-					" successfully connected to %s\n",
-					info->session->connect_host);
-				ggp_servconn_add_server(info->session->
-					connect_host);
-				g_source_remove(info->inpa);
-				info->inpa = purple_input_add(info->session->fd,
-					PURPLE_INPUT_READ,
-					ggp_callback_recv, gc);
-
-				purple_connection_set_state(gc, PURPLE_CONNECTION_STATE_CONNECTED);
-
-				ggp_buddylist_send(gc);
-				ggp_roster_request_update(gc);
-			}
-			break;
-		case GG_EVENT_CONN_FAILED:
-			g_clear_handle_id(&info->inpa, g_source_remove);
-			purple_debug_info("gg", "Connection failure: %d\n",
-				ev->event.failure);
-			switch (ev->event.failure) {
-				case GG_FAILURE_RESOLVING:
-					purple_connection_error(gc,
-						PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-						_("Unable to resolve "
-						"hostname"));
-					break;
-				case GG_FAILURE_PASSWORD:
-					purple_connection_error(gc,
-						PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
-						_("Incorrect password"));
-					break;
-				case GG_FAILURE_TLS:
-					purple_connection_error(gc,
-						PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
-						_("SSL Connection Failed"));
-					break;
-				case GG_FAILURE_INTRUDER:
-					purple_connection_error(gc,
-						PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
-						_("Your account has been "
-						"disabled because too many "
-						"incorrect passwords were "
-						"entered"));
-					break;
-				case GG_FAILURE_UNAVAILABLE:
-					purple_connection_error(gc,
-						PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-						_("Service temporarily "
-						"unavailable"));
-					break;
-				case GG_FAILURE_PROXY:
-					purple_connection_error(gc,
-						PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-						_("Error connecting to proxy "
-						"server"));
-					break;
-				case GG_FAILURE_HUB:
-					purple_connection_error(gc,
-						PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-						_("Error connecting to master "
-						"server"));
-					break;
-				case GG_FAILURE_INTERNAL:
-					purple_connection_error(gc,
-						PURPLE_CONNECTION_ERROR_OTHER_ERROR,
-						_("Internal error"));
-					break;
-				default:
-					purple_connection_error(gc,
-						PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-						_("Connection failed"));
-			}
-			break;
-		case GG_EVENT_MSG:
-			if (ev->event.msg.sender == 0) {
-				if (ev->event.msg.message == NULL)
-					break;
-
-				/* system messages are mostly ads */
-				purple_debug_info("gg", "System message:\n%s\n",
-					ev->event.msg.message);
-			} else {
-				purple_debug_warning("gg", "GG_EVENT_MSG: message from user %u "
-					"unexpected while connecting:\n%s\n",
-					ev->event.msg.sender,
-					ev->event.msg.message);
-			}
-			break;
-		default:
-			purple_debug_error("gg", "strange event: %d\n", ev->type);
-			break;
-	}
-
-	gg_free_event(ev);
-}
-
-static gboolean
-gg_uri_handler_find_account(PurpleAccount *account,
-                            G_GNUC_UNUSED gconstpointer data)
-{
-	const gchar *protocol_id;
-
-	protocol_id = purple_account_get_protocol_id(account);
-
-	return (purple_strequal(protocol_id, "prpl-gg") &&
-	        purple_account_is_connected(account));
-}
-
-static gboolean
-gg_uri_handler(const gchar *scheme, const gchar *screenname,
-               G_GNUC_UNUSED GHashTable *params)
-{
-	PurpleAccountManager *manager = NULL;
-	PurpleAccount *account;
-	PurpleConversation *im;
-
-	g_return_val_if_fail(screenname != NULL, FALSE);
-
-	if (!purple_strequal(scheme, "gg")) {
-		return FALSE;
-	}
-
-	if (screenname[0] == '\0') {
-		purple_debug_warning("gg", "Invalid empty screenname in URI");
-		return FALSE;
-	}
-
-	/* Find online Gadu-Gadu account */
-	manager = purple_account_manager_get_default();
-	account = purple_account_manager_find_custom(manager,
-	                                             (GEqualFunc)gg_uri_handler_find_account,
-	                                             NULL);
-
-	if (account == NULL) {
-		return FALSE;
-	}
-
-	im = purple_im_conversation_new(account, screenname);
-	purple_conversation_present(im);
-
-	g_clear_object(&account);
-
-	return TRUE;
-}
-
-/* ---------------------------------------------------------------------- */
-/* ----- PurpleProtocol ----------------------------------------- */
-/* ---------------------------------------------------------------------- */
-
-static PurpleBuddyIconSpec *
-ggp_protocol_get_buddy_icon_spec(G_GNUC_UNUSED PurpleProtocol *protocol) {
-	return purple_buddy_icon_spec_new("png",
-	                                  1, 1, 200, 200, 0,
-	                                  PURPLE_ICON_SCALE_DISPLAY |
-	                                  PURPLE_ICON_SCALE_SEND);
-}
-
-static GList *
-ggp_protocol_get_account_options(G_GNUC_UNUSED PurpleProtocol *protocol) {
-	PurpleAccountOption *option = NULL;
-	PurpleKeyValuePair *kvp = NULL;
-	GList *encryption_options = NULL;
-	GList *protocol_version = NULL;
-	GList *opts = NULL;
-
-	option = purple_account_option_string_new(_("GG server"), "gg_server", "");
-	opts = g_list_append(opts, option);
-
-	/* setup encryption options */
-	kvp = purple_key_value_pair_new(_("Use encryption if available"),
-	                                "opportunistic_tls");
-	encryption_options = g_list_append(encryption_options, kvp);
-
-	kvp = purple_key_value_pair_new(_("Require encryption"), "require_tls");
-	encryption_options = g_list_append(encryption_options, kvp);
-
-	kvp = purple_key_value_pair_new(_("Don't use encryption"), "none");
-	encryption_options = g_list_append(encryption_options, kvp);
-
-	option = purple_account_option_list_new(_("Connection security"),
-	                                        "encryption", encryption_options);
-	opts = g_list_append(opts, option);
-
-	/* setup the protocol version */
-	kvp = purple_key_value_pair_new(_("Default"), "default");
-	protocol_version = g_list_append(protocol_version, kvp);
-
-	kvp = purple_key_value_pair_new("GG 10", "gg10");
-	protocol_version = g_list_append(protocol_version, kvp);
-
-	kvp = purple_key_value_pair_new("GG 11", "gg11");
-	protocol_version = g_list_append(protocol_version, kvp);
-
-	option = purple_account_option_list_new(_("Protocol version"),
-	                                        "protocol_version",
-	                                        protocol_version);
-	opts = g_list_append(opts, option);
-
-	option = purple_account_option_bool_new(_("Show links from strangers"),
-	                                        "show_links_from_strangers", 1);
-	opts = g_list_append(opts, option);
-
-	return opts;
-}
-
-static const char *
-ggp_normalize(G_GNUC_UNUSED PurpleProtocolClient *client,
-              G_GNUC_UNUSED PurpleAccount *account, const char *who)
-{
-	static char normalized[21]; /* maximum unsigned long long int size */
-
-	uin_t uin = ggp_str_to_uin(who);
-	if(uin <= 0) {
-		return NULL;
-	}
-
-	g_snprintf(normalized, sizeof(normalized), "%u", uin);
-
-	return normalized;
-}
-
-static void
-ggp_login(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleAccount *account) {
-	PurpleConnection *gc = purple_account_get_connection(account);
-	PurpleContactInfo *contact_info = PURPLE_CONTACT_INFO(account);
-	struct gg_login_params *glp;
-	GGPInfo *info;
-	const char *address;
-	const gchar *encryption_type, *protocol_version;
-	GProxyResolver *resolver;
-	GError *error = NULL;
-
-	purple_connection_set_flags(gc,
-		PURPLE_CONNECTION_FLAG_HTML |
-		PURPLE_CONNECTION_FLAG_NO_URLDESC);
-
-	resolver = purple_proxy_get_proxy_resolver(account, &error);
-	if (resolver == NULL) {
-		purple_debug_error("gg", "Unable to get account proxy resolver: %s",
-		                   error->message);
-		purple_connection_take_error(gc, error);
-		return;
-	}
-
-	glp = g_new0(struct gg_login_params, 1);
-	glp->struct_size = sizeof(struct gg_login_params);
-	info = g_new0(GGPInfo, 1);
-
-	purple_connection_set_protocol_data(gc, info);
-
-	info->http = soup_session_new_with_options("proxy-resolver", resolver,
-	                                           NULL);
-
-	ggp_tcpsocket_setup(gc, glp);
-	ggp_image_setup(gc);
-	ggp_avatar_setup(gc);
-	ggp_roster_setup(gc);
-	ggp_multilogon_setup(gc);
-	ggp_status_setup(gc);
-	ggp_chat_setup(gc);
-	ggp_message_setup(gc);
-	ggp_edisc_setup(gc, resolver);
-	g_object_unref(resolver);
-
-	glp->uin = ggp_str_to_uin(purple_contact_info_get_username(contact_info));
-	glp->password =
-		ggp_convert_to_cp1250(purple_connection_get_password(gc));
-
-	if (glp->uin == 0) {
-		purple_connection_error(gc,
-			PURPLE_CONNECTION_ERROR_INVALID_USERNAME,
-			_("The username specified is invalid."));
-		purple_str_wipe(glp->password);
-		g_free(glp);
-		return;
-	}
-
-	glp->image_size = 255;
-	glp->status_flags = GG_STATUS_FLAG_UNKNOWN;
-
-	if (purple_account_get_bool(account, "show_links_from_strangers", 1))
-		glp->status_flags |= GG_STATUS_FLAG_SPAM;
-
-	glp->encoding = GG_ENCODING_UTF8;
-	glp->protocol_features = (GG_FEATURE_DND_FFC |
-		GG_FEATURE_TYPING_NOTIFICATION | GG_FEATURE_MULTILOGON |
-		GG_FEATURE_USER_DATA);
-
-	glp->async = 1;
-
-	encryption_type = purple_account_get_string(account, "encryption",
-		"opportunistic_tls");
-	purple_debug_info("gg", "Requested encryption type: %s\n",
-		encryption_type);
-	if (purple_strequal(encryption_type, "opportunistic_tls"))
-		glp->tls = GG_SSL_ENABLED;
-	else if (purple_strequal(encryption_type, "require_tls")) {
-		if (gg_libgadu_check_feature(GG_LIBGADU_FEATURE_SSL))
-			glp->tls = GG_SSL_REQUIRED;
-		else {
-			purple_connection_error(gc,
-				PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
-				_("SSL support unavailable"));
-			purple_str_wipe(glp->password);
-			g_free(glp);
-			return;
-		}
-	}
-	else /* encryption_type == "none" */
-		glp->tls = GG_SSL_DISABLED;
-	purple_debug_misc("gg", "TLS mode: %d\n", glp->tls);
-
-	protocol_version = purple_account_get_string(account,
-		"protocol_version", "default");
-	purple_debug_info("gg", "Requested protocol version: %s\n",
-		protocol_version);
-	if (purple_strequal(protocol_version, "gg10"))
-		glp->protocol_version = GG_PROTOCOL_VERSION_100;
-	else if (purple_strequal(protocol_version, "gg11"))
-		glp->protocol_version = GG_PROTOCOL_VERSION_110;
-	glp->compatibility = GG_COMPAT_1_12_0;
-
-	ggp_status_set_initial(gc, glp);
-
-	address = purple_account_get_string(account, "gg_server", "");
-	if (address && *address)
-		glp->connect_host = g_strdup(address);
-
-	info->session = gg_login(glp);
-	g_free(glp->connect_host);
-	purple_str_wipe(glp->password);
-	g_free(glp);
-
-	if (info->session == NULL) {
-		purple_connection_error (gc,
-			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-			_("Connection failed"));
-		return;
-	}
-
-	if (info->session->fd > 0) {
-		info->inpa = purple_input_add(info->session->fd,
-			PURPLE_INPUT_READ, ggp_async_login_handler, gc);
-	}
-}
-
-static void
-ggp_close(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleConnection *gc) {
-	PurpleAccount *account;
-	GGPInfo *info;;
-
-	g_return_if_fail(gc != NULL);
-
-	account = purple_connection_get_account(gc);
-	info = purple_connection_get_protocol_data(gc);
-
-	purple_notify_close_with_handle(gc);
-
-	if (info) {
-		if (info->session != NULL) {
-			ggp_status_set_disconnected(account);
-			gg_logoff(info->session);
-			gg_free_session(info->session);
-		}
-
-		ggp_image_cleanup(gc);
-		ggp_avatar_cleanup(gc);
-		ggp_roster_cleanup(gc);
-		ggp_multilogon_cleanup(gc);
-		ggp_status_cleanup(gc);
-		ggp_chat_cleanup(gc);
-		ggp_message_cleanup(gc);
-		ggp_edisc_cleanup(gc);
-
-		g_clear_handle_id(&info->inpa, g_source_remove);
-		g_free(info->imtoken);
-
-		if (info->http) {
-			soup_session_abort(info->http);
-			g_object_unref(info->http);
-		}
-
-		purple_connection_set_protocol_data(gc, NULL);
-		g_free(info);
-	}
-
-	purple_debug_info("gg", "Connection closed.\n");
-}
-
-static unsigned int
-ggp_send_typing(G_GNUC_UNUSED PurpleProtocolIM *im, PurpleConnection *gc,
-                const char *name, PurpleIMTypingState state)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	int dummy_length; /* we don't send real length of typed message */
-
-	if (state == PURPLE_IM_TYPED) /* not supported */
-		return 1;
-
-	if (state == PURPLE_IM_TYPING)
-		dummy_length = (int)g_random_int();
-	else /* PURPLE_IM_NOT_TYPING */
-		dummy_length = 0;
-
-	gg_typing_notification(
-		info->session,
-		ggp_str_to_uin(name),
-		dummy_length);
-
-	return 1; /* wait 1 second before another notification */
-}
-
-static void
-ggp_add_buddy(PurpleProtocolServer *protocol_server, PurpleConnection *gc,
-              PurpleBuddy *buddy, PurpleGroup *group, const gchar *message)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	PurpleContactInfo *contact_info = PURPLE_CONTACT_INFO(account);
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	const gchar *name = purple_buddy_get_name(buddy);
-
-	gg_add_notify(info->session, ggp_str_to_uin(name));
-
-	/* gg server won't tell us our status here */
-	if(purple_strequal(purple_contact_info_get_username(contact_info), name)) {
-		ggp_status_fake_to_self(gc);
-	}
-
-	ggp_roster_add_buddy(protocol_server, gc, buddy, group, message);
-	ggp_pubdir_request_buddy_alias(gc, buddy);
-}
-
-static void
-ggp_remove_buddy(PurpleProtocolServer *protocol_server, PurpleConnection *gc,
-                 PurpleBuddy *buddy, PurpleGroup *group)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-
-	gg_remove_notify(info->session, ggp_str_to_uin(purple_buddy_get_name(buddy)));
-	ggp_roster_remove_buddy(protocol_server, gc, buddy, group);
-}
-
-static void
-ggp_keepalive(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-              PurpleConnection *gc)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-
-	/* purple_debug_info("gg", "Keeping connection alive....\n"); */
-
-	if (gg_ping(info->session) < 0) {
-		purple_debug_info("gg", "Not connected to the server "
-				"or gg_session is not correct\n");
-		purple_connection_error (gc,
-			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-			_("Not connected to the server"));
-	}
-}
-
-static void
-ggp_action_multilogon(G_GNUC_UNUSED GSimpleAction *action,
-                      GVariant *parameter,
-                      G_GNUC_UNUSED gpointer data)
-{
-	const gchar *account_id = NULL;
-	PurpleAccountManager *manager = NULL;
-	PurpleAccount *account = NULL;
-	PurpleConnection *connection = NULL;
-
-	if(!g_variant_is_of_type(parameter, G_VARIANT_TYPE_STRING)) {
-		g_critical("GG multilogin action parameter is of incorrect type %s",
-		           g_variant_get_type_string(parameter));
-	}
-
-	account_id = g_variant_get_string(parameter, NULL);
-	manager = purple_account_manager_get_default();
-	account = purple_account_manager_find_by_id(manager, account_id);
-	connection = purple_account_get_connection(account);
-	g_clear_object(&account);
-
-	ggp_multilogon_dialog(connection);
-}
-
-static void
-ggp_action_status_broadcasting(G_GNUC_UNUSED GSimpleAction *action,
-                               GVariant *parameter,
-                               G_GNUC_UNUSED gpointer data)
-{
-	const gchar *account_id = NULL;
-	PurpleAccountManager *manager = NULL;
-	PurpleAccount *account = NULL;
-	PurpleConnection *connection = NULL;
-
-	if(!g_variant_is_of_type(parameter, G_VARIANT_TYPE_STRING)) {
-		g_critical("GG broadcast action parameter is of incorrect type %s",
-		           g_variant_get_type_string(parameter));
-	}
-
-	account_id = g_variant_get_string(parameter, NULL);
-	manager = purple_account_manager_get_default();
-	account = purple_account_manager_find_by_id(manager, account_id);
-	connection = purple_account_get_connection(account);
-	g_clear_object(&account);
-
-	ggp_status_broadcasting_dialog(connection);
-}
-
-static void
-ggp_action_search(G_GNUC_UNUSED GSimpleAction *action,
-                  GVariant *parameter,
-                  G_GNUC_UNUSED gpointer data)
-{
-	const gchar *account_id = NULL;
-	PurpleAccountManager *manager = NULL;
-	PurpleAccount *account = NULL;
-	PurpleConnection *connection = NULL;
-
-	if(!g_variant_is_of_type(parameter, G_VARIANT_TYPE_STRING)) {
-		g_critical("GG search action parameter is of incorrect type %s",
-		           g_variant_get_type_string(parameter));
-	}
-
-	account_id = g_variant_get_string(parameter, NULL);
-	manager = purple_account_manager_get_default();
-	account = purple_account_manager_find_by_id(manager, account_id);
-	connection = purple_account_get_connection(account);
-	g_clear_object(&account);
-
-	ggp_pubdir_search(connection, NULL);
-}
-
-static void
-ggp_action_set_info(G_GNUC_UNUSED GSimpleAction *action,
-                    GVariant *parameter,
-                    G_GNUC_UNUSED gpointer data)
-{
-	const gchar *account_id = NULL;
-	PurpleAccountManager *manager = NULL;
-	PurpleAccount *account = NULL;
-	PurpleConnection *connection = NULL;
-
-	if(!g_variant_is_of_type(parameter, G_VARIANT_TYPE_STRING)) {
-		g_critical("GG set info action parameter is of incorrect type %s",
-		           g_variant_get_type_string(parameter));
-	}
-
-	account_id = g_variant_get_string(parameter, NULL);
-	manager = purple_account_manager_get_default();
-	account = purple_account_manager_find_by_id(manager, account_id);
-	connection = purple_account_get_connection(account);
-	g_clear_object(&account);
-
-	ggp_pubdir_set_info(connection);
-}
-
-static const gchar *
-ggp_protocol_actions_get_prefix(G_GNUC_UNUSED PurpleProtocolActions *actions) {
-	return "prpl-gg";
-}
-
-static GActionGroup *
-ggp_protocol_actions_get_action_group(G_GNUC_UNUSED PurpleProtocolActions *actions,
-                                      G_GNUC_UNUSED PurpleConnection *connection)
-{
-	GSimpleActionGroup *group = NULL;
-	GActionEntry entries[] = {
-		{
-			.name = "multilogon",
-			.activate = ggp_action_multilogon,
-			.parameter_type = "s",
-		},
-		{
-			.name = "broadcasting",
-			.activate = ggp_action_status_broadcasting,
-			.parameter_type = "s",
-		},
-		{
-			.name = "search",
-			.activate = ggp_action_search,
-			.parameter_type = "s",
-		},
-		{
-			.name = "set-info",
-			.activate = ggp_action_set_info,
-			.parameter_type = "s",
-		},
-		{
-			.name = "save-buddylist",
-			.activate = ggp_action_buddylist_save,
-			.parameter_type = "s",
-		},
-		{
-			.name = "load-buddylist",
-			.activate = ggp_action_buddylist_load,
-			.parameter_type = "s",
-		},
-	};
-	gsize nentries = G_N_ELEMENTS(entries);
-
-	group = g_simple_action_group_new();
-	g_action_map_add_action_entries(G_ACTION_MAP(group), entries, nentries,
-	                                NULL);
-
-	return G_ACTION_GROUP(group);
-}
-
-static GMenu *
-ggp_protocol_actions_get_menu(G_GNUC_UNUSED PurpleProtocolActions *actions,
-                              G_GNUC_UNUSED PurpleConnection *connection) {
-	GMenu *menu = NULL, *submenu = NULL;
-	GMenuItem *item = NULL;
-
-	menu = g_menu_new();
-
-	item = g_menu_item_new(_("Show other sessions"), "prpl-gg.multilogon");
-	g_menu_item_set_attribute(item, PURPLE_MENU_ATTRIBUTE_DYNAMIC_TARGET, "s",
-	                          "account");
-	g_menu_append_item(menu, item);
-	g_object_unref(item);
-
-	item = g_menu_item_new(_("Show status only for buddies"),
-	                       "prpl-gg.broadcasting");
-	g_menu_item_set_attribute(item, PURPLE_MENU_ATTRIBUTE_DYNAMIC_TARGET, "s",
-	                          "account");
-	g_menu_append_item(menu, item);
-	g_object_unref(item);
-
-	item = g_menu_item_new(_("Find buddies..."), "prpl-gg.search");
-	g_menu_item_set_attribute(item, PURPLE_MENU_ATTRIBUTE_DYNAMIC_TARGET, "s",
-	                          "account");
-	g_menu_append_item(menu, item);
-	g_object_unref(item);
-
-	item = g_menu_item_new(_("Set User Info"), "prpl-gg.set-info");
-	g_menu_item_set_attribute(item, PURPLE_MENU_ATTRIBUTE_DYNAMIC_TARGET, "s",
-	                          "account");
-	g_menu_append_item(menu, item);
-	g_object_unref(item);
-
-	/* Buddy list management. */
-	submenu = g_menu_new();
-
-	item = g_menu_item_new(_("Save to file..."), "prpl-gg.save-buddylist");
-	g_menu_item_set_attribute(item, PURPLE_MENU_ATTRIBUTE_DYNAMIC_TARGET, "s",
-	                          "account");
-	g_menu_append_item(menu, item);
-	g_object_unref(item);
-
-	item = g_menu_item_new(_("Load from file..."), "prpl-gg.load-buddylist");
-	g_menu_item_set_attribute(item, PURPLE_MENU_ATTRIBUTE_DYNAMIC_TARGET, "s",
-	                          "account");
-	g_menu_append_item(menu, item);
-	g_object_unref(item);
-
-	g_menu_append_submenu(menu, _("Buddy list"), G_MENU_MODEL(submenu));
-	g_object_unref(submenu);
-
-	return menu;
-}
-
-static const char *
-ggp_list_emblem(G_GNUC_UNUSED PurpleProtocolClient *client,
-                PurpleBuddy *buddy)
-{
-	ggp_buddy_data *buddy_data = ggp_buddy_get_data(buddy);
-
-	if (buddy_data->blocked)
-		return "not-authorized";
-	if (buddy_data->not_a_friend)
-		return "unavailable";
-
-	return NULL;
-}
-
-static gboolean
-ggp_offline_message(G_GNUC_UNUSED PurpleProtocolClient *client,
-                    G_GNUC_UNUSED PurpleBuddy *buddy)
-{
-	return TRUE;
-}
-
-static GHashTable *
-ggp_get_account_text_table(G_GNUC_UNUSED PurpleProtocolClient *client,
-                           G_GNUC_UNUSED PurpleAccount *account)
-{
-	GHashTable *table;
-	table = g_hash_table_new(g_str_hash, g_str_equal);
-	g_hash_table_insert(table, "login_label", (gpointer)_("GG number..."));
-	return table;
-}
-
-static gssize
-ggp_get_max_message_size(G_GNUC_UNUSED PurpleProtocolClient *client,
-                         G_GNUC_UNUSED PurpleConversation *conv)
-{
-	/* TODO: it may depend on protocol version or other factors */
-	return 1200; /* no more than 1232 */
-}
-
-static void
-ggp_protocol_init(G_GNUC_UNUSED GGPProtocol *self) {
-}
-
-static void
-ggp_protocol_class_init(GGPProtocolClass *klass)
-{
-	PurpleProtocolClass *protocol_class = PURPLE_PROTOCOL_CLASS(klass);
-
-	protocol_class->login = ggp_login;
-	protocol_class->close = ggp_close;
-	protocol_class->status_types = ggp_status_types;
-
-	protocol_class->get_account_options = ggp_protocol_get_account_options;
-	protocol_class->get_buddy_icon_spec = ggp_protocol_get_buddy_icon_spec;
-}
-
-static void
-ggp_protocol_class_finalize(G_GNUC_UNUSED GGPProtocolClass *klass)
-{
-}
-
-static void
-ggp_protocol_actions_iface_init(PurpleProtocolActionsInterface *iface)
-{
-	iface->get_prefix = ggp_protocol_actions_get_prefix;
-	iface->get_action_group = ggp_protocol_actions_get_action_group;
-	iface->get_menu = ggp_protocol_actions_get_menu;
-}
-
-static void
-ggp_protocol_client_iface_init(PurpleProtocolClientInterface *client_iface)
-{
-	client_iface->list_emblem            = ggp_list_emblem;
-	client_iface->buddy_free             = ggp_buddy_free;
-	client_iface->normalize              = ggp_normalize;
-	client_iface->offline_message        = ggp_offline_message;
-	client_iface->get_account_text_table = ggp_get_account_text_table;
-	client_iface->get_max_message_size   = ggp_get_max_message_size;
-}
-
-static void
-ggp_protocol_server_iface_init(PurpleProtocolServerInterface *server_iface)
-{
-	server_iface->get_info       = ggp_pubdir_get_info_protocol;
-	server_iface->set_status     = ggp_status_set_purplestatus;
-	server_iface->add_buddy      = ggp_add_buddy;
-	server_iface->remove_buddy   = ggp_remove_buddy;
-	server_iface->keepalive      = ggp_keepalive;
-	server_iface->alias_buddy    = ggp_roster_alias_buddy;
-	server_iface->group_buddy    = ggp_roster_group_buddy;
-	server_iface->rename_group   = ggp_roster_rename_group;
-	server_iface->set_buddy_icon = ggp_avatar_own_set;
-}
-
-static void
-ggp_protocol_im_iface_init(PurpleProtocolIMInterface *im_iface)
-{
-	im_iface->send        = ggp_message_send_im;
-	im_iface->send_typing = ggp_send_typing;
-}
-
-static void
-ggp_protocol_chat_iface_init(PurpleProtocolChatInterface *chat_iface)
-{
-	chat_iface->info          = ggp_chat_info;
-	chat_iface->info_defaults = ggp_chat_info_defaults;
-	chat_iface->join          = ggp_chat_join;
-	chat_iface->get_name      = ggp_chat_get_name;
-	chat_iface->invite        = ggp_chat_invite;
-	chat_iface->leave         = ggp_chat_leave;
-	chat_iface->send          = ggp_chat_send;
-
-	chat_iface->reject        = NULL; /* TODO */
-}
-
-static void
-ggp_protocol_roomlist_iface_init(PurpleProtocolRoomlistInterface *roomlist_iface)
-{
-	roomlist_iface->get_list = ggp_chat_roomlist_get_list;
-}
-
-static void
-ggp_protocol_xfer_iface_init(PurpleProtocolXferInterface *xfer_iface)
-{
-	xfer_iface->can_receive = ggp_edisc_xfer_can_receive_file;
-	xfer_iface->send_file   = ggp_edisc_xfer_send_file;
-	xfer_iface->new_xfer    = ggp_edisc_xfer_send_new;
-}
-
-G_DEFINE_DYNAMIC_TYPE_EXTENDED(
-	GGPProtocol,
-	ggp_protocol,
-	PURPLE_TYPE_PROTOCOL,
-	G_TYPE_FLAG_FINAL,
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_ACTIONS,
-	                              ggp_protocol_actions_iface_init)
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_CLIENT,
-	                              ggp_protocol_client_iface_init)
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_SERVER,
-	                              ggp_protocol_server_iface_init)
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_IM,
-	                              ggp_protocol_im_iface_init)
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_CHAT,
-	                              ggp_protocol_chat_iface_init)
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_ROOMLIST,
-	                              ggp_protocol_roomlist_iface_init)
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_XFER,
-	                              ggp_protocol_xfer_iface_init))
-
-static PurpleProtocol *
-ggp_protocol_new(void) {
-	return g_object_new(
-		GGP_TYPE_PROTOCOL,
-		"id", "prpl-gg",
-		"name", "Gadu-Gadu",
-		"description", _("Gadu-Gadu is a Polish instant messaging network."),
-		"icon-name", "im-gadu-gadu",
-		"icon-resource-path", "/im/pidgin/libpurple/gg/icons",
-		NULL);
-}
-
-static GPluginPluginInfo *
-gg_query(G_GNUC_UNUSED GError **error)
-{
-	GPluginPluginInfo *info = NULL;
-	gchar *description = NULL;
-	const gchar * const authors[] = {
-		"boler@sourceforge.net",
-		NULL
-	};
-
-	description = g_strdup_printf(N_("Polish popular IM\nlibgadu version %s"),
-	                              gg_libgadu_version());
-
-	info = purple_plugin_info_new(
-		"id",           "prpl-gg",
-		"name",         "Gadu-Gadu Protocol",
-		"version",      DISPLAY_VERSION,
-		"category",     N_("Protocol"),
-		"summary",      N_("Gadu-Gadu Protocol Plugin"),
-		"description",  description,
-		"authors",      authors,
-		"website",      PURPLE_WEBSITE,
-		"abi-version",  PURPLE_ABI_VERSION,
-		"flags",        PURPLE_PLUGIN_INFO_FLAGS_INTERNAL |
-		                PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD,
-		NULL
-	);
-
-	g_free(description);
-
-	return info;
-}
-
-static gboolean
-gg_load(GPluginPlugin *plugin, GError **error)
-{
-	PurpleProtocolManager *manager = purple_protocol_manager_get_default();
-
-	ggp_protocol_register_type(G_TYPE_MODULE(plugin));
-
-	ggp_xfer_register(G_TYPE_MODULE(plugin));
-
-	my_protocol = ggp_protocol_new();
-	if(!purple_protocol_manager_register(manager, my_protocol, error)) {
-		g_clear_object(&my_protocol);
-
-		return FALSE;
-	}
-
-	purple_prefs_add_none("/plugins/prpl/gg");
-
-	purple_debug_info("gg", "Loading Gadu-Gadu protocol plugin with "
-		"libgadu %s...\n", gg_libgadu_version());
-
-	ggp_libgaduw_setup();
-	ggp_resolver_purple_setup();
-	ggp_servconn_setup(NULL);
-	ggp_html_setup();
-	ggp_message_setup_global();
-
-	purple_signal_connect(purple_get_core(), "uri-handler", plugin,
-			G_CALLBACK(gg_uri_handler), NULL);
-
-	return TRUE;
-}
-
-static gboolean
-gg_unload(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;
-	}
-
-	purple_signal_disconnect(purple_get_core(), "uri-handler", plugin,
-			G_CALLBACK(gg_uri_handler));
-
-	ggp_servconn_cleanup();
-	ggp_html_cleanup();
-	ggp_message_cleanup_global();
-	ggp_libgaduw_cleanup();
-
-	g_clear_object(&my_protocol);
-
-	return TRUE;
-}
-
-GPLUGIN_NATIVE_PLUGIN_DECLARE(gg)
-
-/* vim: set ts=8 sts=0 sw=8 noet: */
diff --git a/libpurple/protocols/gg/html.h b/libpurple/protocols/gg/html.h
deleted file mode 100644
--- a/libpurple/protocols/gg/html.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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_GG_HTML_H
-#define PURPLE_GG_HTML_H
-
-#include <purple.h>
-
-typedef enum
-{
-	GGP_HTML_TAG_UNKNOWN,
-	GGP_HTML_TAG_EOM,
-	GGP_HTML_TAG_A,
-	GGP_HTML_TAG_B,
-	GGP_HTML_TAG_I,
-	GGP_HTML_TAG_U,
-	GGP_HTML_TAG_S,
-	GGP_HTML_TAG_IMG,
-	GGP_HTML_TAG_FONT,
-	GGP_HTML_TAG_SPAN,
-	GGP_HTML_TAG_DIV,
-	GGP_HTML_TAG_BR,
-	GGP_HTML_TAG_HR,
-} ggp_html_tag;
-
-void ggp_html_setup(void);
-void ggp_html_cleanup(void);
-
-GHashTable * ggp_html_tag_attribs(const gchar *attribs_str);
-GHashTable * ggp_html_css_attribs(const gchar *attribs_str);
-int ggp_html_decode_color(const gchar *str);
-ggp_html_tag ggp_html_parse_tag(const gchar *tag_str);
-
-#endif /* PURPLE_GG_HTML_H */
diff --git a/libpurple/protocols/gg/html.c b/libpurple/protocols/gg/html.c
deleted file mode 100644
--- a/libpurple/protocols/gg/html.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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 "html.h"
-
-typedef struct
-{
-	GRegex *re_html_attr;
-	GRegex *re_css_attr;
-	GRegex *re_color_hex;
-	GRegex *re_color_rgb;
-} ggp_html_global_data;
-
-static ggp_html_global_data global_data;
-
-void ggp_html_setup(void)
-{
-	global_data.re_html_attr = g_regex_new(
-		"([a-z-]+)=\"([^\"]+)\"",
-		G_REGEX_OPTIMIZE, 0, NULL);
-	global_data.re_css_attr = g_regex_new(
-		"([a-z-]+): *([^;]+)",
-		G_REGEX_OPTIMIZE, 0, NULL);
-	global_data.re_color_hex = g_regex_new(
-		"^#([0-9a-fA-F]+){6}$",
-		G_REGEX_OPTIMIZE, 0, NULL);
-	global_data.re_color_rgb = g_regex_new(
-		"^rgb\\(([0-9]+), *([0-9]+), *([0-9]+)\\)$",
-		G_REGEX_OPTIMIZE, 0, NULL);
-}
-
-void ggp_html_cleanup(void)
-{
-	g_regex_unref(global_data.re_html_attr);
-	g_regex_unref(global_data.re_css_attr);
-	g_regex_unref(global_data.re_color_hex);
-	g_regex_unref(global_data.re_color_rgb);
-}
-
-GHashTable * ggp_html_tag_attribs(const gchar *attribs_str)
-{
-	GMatchInfo *match;
-	GHashTable *attribs = g_hash_table_new_full(g_str_hash, g_str_equal,
-		g_free, g_free);
-
-	if (attribs_str == NULL)
-		return attribs;
-
-	g_regex_match(global_data.re_html_attr, attribs_str, 0, &match);
-	while (g_match_info_matches(match)) {
-		g_hash_table_insert(attribs,
-			g_match_info_fetch(match, 1),
-			g_match_info_fetch(match, 2));
-
-		g_match_info_next(match, NULL);
-	}
-	g_match_info_free(match);
-
-	return attribs;
-}
-
-GHashTable * ggp_html_css_attribs(const gchar *attribs_str)
-{
-	GMatchInfo *match;
-	GHashTable *attribs = g_hash_table_new_full(g_str_hash, g_str_equal,
-		g_free, g_free);
-
-	if (attribs_str == NULL)
-		return attribs;
-
-	g_regex_match(global_data.re_css_attr, attribs_str, 0, &match);
-	while (g_match_info_matches(match)) {
-		g_hash_table_insert(attribs,
-			g_match_info_fetch(match, 1),
-			g_match_info_fetch(match, 2));
-
-		g_match_info_next(match, NULL);
-	}
-	g_match_info_free(match);
-
-	return attribs;
-}
-
-int ggp_html_decode_color(const gchar *str)
-{
-	GMatchInfo *match;
-	int color = -1;
-
-	g_regex_match(global_data.re_color_hex, str, 0, &match);
-	if (g_match_info_matches(match)) {
-		if (sscanf(str + 1, "%x", &color) != 1)
-			color = -1;
-	}
-	g_match_info_free(match);
-	if (color >= 0)
-		return color;
-
-	g_regex_match(global_data.re_color_rgb, str, 0, &match);
-	if (g_match_info_matches(match)) {
-		int r = -1, g = -1, b = -1;
-		gchar *c_str;
-
-		c_str = g_match_info_fetch(match, 1);
-		if (c_str)
-			r = atoi(c_str);
-		g_free(c_str);
-
-		c_str = g_match_info_fetch(match, 2);
-		if (c_str)
-			g = atoi(c_str);
-		g_free(c_str);
-
-		c_str = g_match_info_fetch(match, 3);
-		if (c_str)
-			b = atoi(c_str);
-		g_free(c_str);
-
-		if (r >= 0 && r < 256 && g >= 0 && g < 256 && b >= 0 && b < 256)
-			color = (r << 16) | (g << 8) | b;
-	}
-	g_match_info_free(match);
-	if (color >= 0)
-		return color;
-
-	return -1;
-}
-
-ggp_html_tag ggp_html_parse_tag(const gchar *tag_str)
-{
-	if (0 == g_ascii_strcasecmp(tag_str, "eom"))
-		return GGP_HTML_TAG_EOM;
-	if (0 == g_ascii_strcasecmp(tag_str, "span"))
-		return GGP_HTML_TAG_SPAN;
-	if (0 == g_ascii_strcasecmp(tag_str, "div"))
-		return GGP_HTML_TAG_DIV;
-	if (0 == g_ascii_strcasecmp(tag_str, "br"))
-		return GGP_HTML_TAG_BR;
-	if (0 == g_ascii_strcasecmp(tag_str, "a"))
-		return GGP_HTML_TAG_A;
-	if (0 == g_ascii_strcasecmp(tag_str, "b"))
-		return GGP_HTML_TAG_B;
-	if (0 == g_ascii_strcasecmp(tag_str, "i"))
-		return GGP_HTML_TAG_I;
-	if (0 == g_ascii_strcasecmp(tag_str, "u"))
-		return GGP_HTML_TAG_U;
-	if (0 == g_ascii_strcasecmp(tag_str, "s"))
-		return GGP_HTML_TAG_S;
-	if (0 == g_ascii_strcasecmp(tag_str, "img"))
-		return GGP_HTML_TAG_IMG;
-	if (0 == g_ascii_strcasecmp(tag_str, "font"))
-		return GGP_HTML_TAG_FONT;
-	if (0 == g_ascii_strcasecmp(tag_str, "hr"))
-		return GGP_HTML_TAG_HR;
-	return GGP_HTML_TAG_UNKNOWN;
-}
diff --git a/libpurple/protocols/gg/image-prpl.h b/libpurple/protocols/gg/image-prpl.h
deleted file mode 100644
--- a/libpurple/protocols/gg/image-prpl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_IMAGE_PRPL_H
-#define PURPLE_GG_IMAGE_PRPL_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-#define GGP_IMAGE_SIZE_MAX 255000
-#define GGP_IMAGE_ID_FORMAT "%016" G_GINT64_MODIFIER "x"
-
-typedef struct _ggp_image_session_data ggp_image_session_data;
-
-typedef enum
-{
-	GGP_IMAGE_PREPARE_OK = 0,
-	GGP_IMAGE_PREPARE_FAILURE,
-	GGP_IMAGE_PREPARE_TOO_BIG
-} ggp_image_prepare_result;
-
-void
-ggp_image_setup(PurpleConnection *gc);
-
-void
-ggp_image_cleanup(PurpleConnection *gc);
-
-ggp_image_prepare_result
-ggp_image_prepare(PurpleConversation *conv, PurpleImage *image, uint64_t *id);
-
-void
-ggp_image_recv(PurpleConnection *gc,
-	const struct gg_event_image_reply *image_reply);
-
-void
-ggp_image_send(PurpleConnection *gc,
-	const struct gg_event_image_request *image_request);
-
-PurpleImage *
-ggp_image_request(PurpleConnection *gc, uin_t uin, uint64_t id);
-
-#endif /* PURPLE_GG_IMAGE_PRPL_H */
diff --git a/libpurple/protocols/gg/image-prpl.c b/libpurple/protocols/gg/image-prpl.c
deleted file mode 100644
--- a/libpurple/protocols/gg/image-prpl.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "image-prpl.h"
-
-#include "gg.h"
-#include "utils.h"
-
-#include <purple.h>
-
-struct _ggp_image_session_data
-{
-	GHashTable *recv_images;
-	GHashTable *sent_images;
-};
-
-typedef struct
-{
-	PurpleImage *image;
-	gchar *conv_name; /* TODO: callback */
-} ggp_image_sent;
-
-static void ggp_image_sent_free(gpointer _sent_image)
-{
-	ggp_image_sent *sent_image = _sent_image;
-	g_object_unref(sent_image->image);
-	g_free(sent_image->conv_name);
-	g_free(sent_image);
-}
-
-static uint64_t ggp_image_params_to_id(uint32_t crc32, uint32_t size)
-{
-	return ((uint64_t)crc32 << 32) | size;
-}
-
-static inline ggp_image_session_data *
-ggp_image_get_sdata(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	return accdata->image_data;
-}
-
-void ggp_image_setup(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	ggp_image_session_data *sdata = g_new0(ggp_image_session_data, 1);
-
-	accdata->image_data = sdata;
-
-	sdata->recv_images = g_hash_table_new_full(
-		g_int64_hash, g_int64_equal, g_free, g_object_unref);
-	sdata->sent_images = g_hash_table_new_full(
-		g_int64_hash, g_int64_equal, g_free,
-		ggp_image_sent_free);
-}
-
-void ggp_image_cleanup(PurpleConnection *gc)
-{
-	ggp_image_session_data *sdata = ggp_image_get_sdata(gc);
-
-	g_hash_table_destroy(sdata->recv_images);
-	g_hash_table_destroy(sdata->sent_images);
-	g_free(sdata);
-}
-
-ggp_image_prepare_result
-ggp_image_prepare(PurpleConversation *conv, PurpleImage *image, uint64_t *id)
-{
-	PurpleConnection *gc = purple_conversation_get_connection(conv);
-	ggp_image_session_data *sdata = ggp_image_get_sdata(gc);
-	size_t image_size;
-	gconstpointer image_data;
-	uint32_t image_crc;
-	ggp_image_sent *sent_image;
-
-	g_return_val_if_fail(image, GGP_IMAGE_PREPARE_FAILURE);
-
-	image_size = purple_image_get_data_size(image);
-
-	if (image_size > GGP_IMAGE_SIZE_MAX) {
-		purple_debug_warning("gg", "ggp_image_prepare: image "
-			"is too big (max bytes: %d)\n", GGP_IMAGE_SIZE_MAX);
-		return GGP_IMAGE_PREPARE_TOO_BIG;
-	}
-
-	g_object_ref(image);
-	image_data = purple_image_get_data(image);
-	image_crc = gg_crc32(0, image_data, image_size);
-
-	purple_debug_info("gg", "ggp_image_prepare: image prepared "
-		"[crc=%u, size=%" G_GSIZE_FORMAT "]",
-		image_crc, image_size);
-
-	*id = ggp_image_params_to_id(image_crc, image_size);
-
-	g_object_ref(image);
-	sent_image = g_new(ggp_image_sent, 1);
-	sent_image->image = image;
-	sent_image->conv_name = g_strdup(purple_conversation_get_name(conv));
-	g_hash_table_insert(sdata->sent_images, ggp_uint64dup(*id),
-		sent_image);
-
-	return GGP_IMAGE_PREPARE_OK;
-}
-
-void ggp_image_recv(PurpleConnection *gc,
-	const struct gg_event_image_reply *image_reply)
-{
-	ggp_image_session_data *sdata = ggp_image_get_sdata(gc);
-	PurpleImage *img;
-	uint64_t id;
-
-	id = ggp_image_params_to_id(image_reply->crc32, image_reply->size);
-	img = g_hash_table_lookup(sdata->recv_images, &id);
-	if (!img) {
-		purple_debug_warning("gg", "ggp_image_recv: "
-			"image " GGP_IMAGE_ID_FORMAT " wasn't requested\n",
-			id);
-		return;
-	}
-
-	purple_debug_info("gg", "ggp_image_recv: got image "
-		"[crc=%u, size=%u, filename=%s, id=" GGP_IMAGE_ID_FORMAT "]",
-		image_reply->crc32, image_reply->size,
-		image_reply->filename, id);
-
-	img = purple_image_new_from_data(
-		(const guint8 *)image_reply->image,
-		image_reply->size
-	);
-	purple_image_set_friendly_filename(img, image_reply->filename);
-
-	g_hash_table_insert(sdata->recv_images, &id, img);
-}
-
-void ggp_image_send(PurpleConnection *gc,
-	const struct gg_event_image_request *image_request)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	ggp_image_session_data *sdata = ggp_image_get_sdata(gc);
-	ggp_image_sent *sent_image;
-	PurpleConversation *conv;
-	PurpleConversationManager *manager;
-	uint64_t id;
-	uin_t sender;
-	gchar *gg_filename;
-
-	purple_debug_info("gg", "ggp_image_send: got image request "
-		"[uin=%u, crc=%u, size=%u]\n",
-		image_request->sender,
-		image_request->crc32,
-		image_request->size);
-
-	id = ggp_image_params_to_id(image_request->crc32, image_request->size);
-
-	sent_image = g_hash_table_lookup(sdata->sent_images, &id);
-
-	sender = ggp_str_to_uin(purple_contact_info_get_username(info));
-	if (sent_image == NULL && image_request->sender == sender) {
-		purple_debug_misc("gg", "ggp_image_send: requested image "
-			"not found, but this may be another session request\n");
-		return;
-	}
-	if (sent_image == NULL) {
-		purple_debug_warning("gg", "ggp_image_send: requested image "
-			"not found\n");
-		return;
-	}
-
-	purple_debug_misc("gg", "ggp_image_send: requested image found "
-		"[id=" GGP_IMAGE_ID_FORMAT ", conv=%s]\n",
-		id, sent_image->conv_name);
-
-	g_return_if_fail(sent_image->image);
-
-	/* TODO: check allowed recipients */
-	gg_filename = g_strdup_printf(GGP_IMAGE_ID_FORMAT, id);
-	gg_image_reply(accdata->session, image_request->sender,
-		gg_filename,
-		purple_image_get_data(sent_image->image),
-		purple_image_get_data_size(sent_image->image));
-	g_free(gg_filename);
-
-	manager = purple_conversation_manager_get_default();
-	conv = purple_conversation_manager_find(manager,
-	                                        purple_connection_get_account(gc),
-	                                        sent_image->conv_name);
-	if (conv != NULL) {
-		gchar *msg = g_strdup_printf(_("Image delivered to %u."),
-			image_request->sender);
-		purple_conversation_write_system_message(conv, msg,
-			PURPLE_MESSAGE_NO_LOG | PURPLE_MESSAGE_NOTIFY);
-		g_free(msg);
-	}
-}
-
-PurpleImage *
-ggp_image_request(PurpleConnection *gc, uin_t uin, uint64_t id)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	ggp_image_session_data *sdata = ggp_image_get_sdata(gc);
-	PurpleImage *img;
-	uint32_t crc = id >> 32;
-	uint32_t size = id;
-
-	if (size > GGP_IMAGE_SIZE_MAX && crc <= GGP_IMAGE_SIZE_MAX) {
-		uint32_t tmp;
-		purple_debug_warning("gg", "ggp_image_request: "
-			"crc and size are swapped!\n");
-		tmp = crc;
-		crc = size;
-		size = tmp;
-		id = ggp_image_params_to_id(crc, size);
-	}
-
-	img = g_hash_table_lookup(sdata->recv_images, &id);
-	if (img) {
-		purple_debug_info("gg", "ggp_image_request: "
-			"image " GGP_IMAGE_ID_FORMAT " got from cache", id);
-		return img;
-	}
-
-
-	g_hash_table_insert(sdata->recv_images, ggp_uint64dup(id), NULL);
-
-	purple_debug_info("gg", "ggp_image_request: requesting image "
-		GGP_IMAGE_ID_FORMAT, id);
-	if (gg_image_request(accdata->session, uin, size, crc) != 0)
-		purple_debug_error("gg", "ggp_image_request: failed");
-
-	return img;
-}
diff --git a/libpurple/protocols/gg/keymapper.h b/libpurple/protocols/gg/keymapper.h
deleted file mode 100644
--- a/libpurple/protocols/gg/keymapper.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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_GG_KEYMAPPER_H
-#define PURPLE_GG_KEYMAPPER_H
-
-typedef struct _ggp_keymapper ggp_keymapper;
-
-#include <purple.h>
-
-ggp_keymapper *
-ggp_keymapper_new(void);
-
-void
-ggp_keymapper_free(ggp_keymapper *km);
-
-gpointer
-ggp_keymapper_to_key(ggp_keymapper *km, guint64 val);
-
-/* The key have to be valid. */
-guint64
-ggp_keymapper_from_key(ggp_keymapper *km, gpointer key);
-
-#endif /* PURPLE_GG_KEYMAPPER_H */
diff --git a/libpurple/protocols/gg/keymapper.c b/libpurple/protocols/gg/keymapper.c
deleted file mode 100644
--- a/libpurple/protocols/gg/keymapper.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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 "keymapper.h"
-
-/* The problem: we want to convert 64-bit unique integers into unique gpointer
- * keys (that may be 32-bit or 64-bit, or whatever else). We also want to
- * convert it back.
- *
- * The idea: let's store every value in our internal memory. Then, its address
- * can be also an unique key. We also need a map, to quickly figure out the
- * address for any previously stored value.
- *
- * The naming problem: values becomes the keys and vice-versa.
- */
-
-/* TODO
- * For a 64-bit gpointer, keymapper could just do nothing and return the value
- * as a key. But it have to be figured out at a compile time.
- */
-
-struct _ggp_keymapper
-{
-	/* Table keys: pointers to 64-bit mapped *values*.
-	 * Table values: keys (gpointers) corresponding to mapped values.
-	 *
-	 * Ultimately, both keys and values are the same pointers.
-	 *
-	 * Yes, it's hard to comment it well enough.
-	 */
-	GHashTable *val_to_key;
-};
-
-ggp_keymapper *
-ggp_keymapper_new(void)
-{
-	ggp_keymapper *km;
-
-	km = g_new0(ggp_keymapper, 1);
-	km->val_to_key = g_hash_table_new_full(g_int64_hash, g_int64_equal,
-		g_free, NULL);
-
-	return km;
-}
-
-void
-ggp_keymapper_free(ggp_keymapper *km)
-{
-	if (km == NULL)
-		return;
-
-	g_hash_table_destroy(km->val_to_key);
-	g_free(km);
-}
-
-gpointer
-ggp_keymapper_to_key(ggp_keymapper *km, guint64 val)
-{
-	guint64 *key;
-
-	g_return_val_if_fail(km != NULL, NULL);
-
-	key = g_hash_table_lookup(km->val_to_key, &val);
-	if (key)
-		return key;
-
-	key = g_new(guint64, 1);
-	*key = val;
-
-	g_hash_table_insert(km->val_to_key, key, key);
-
-	return key;
-}
-
-guint64
-ggp_keymapper_from_key(ggp_keymapper *km, gpointer key)
-{
-	g_return_val_if_fail(km != NULL, 0);
-	g_return_val_if_fail(key != NULL, 0);
-
-	return *((guint64*)key);
-}
diff --git a/libpurple/protocols/gg/libgadu-events.h b/libpurple/protocols/gg/libgadu-events.h
deleted file mode 100644
--- a/libpurple/protocols/gg/libgadu-events.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_LIBGADU_EVENTS_H
-#define PURPLE_GG_LIBGADU_EVENTS_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-#include "gg.h"
-
-void ggp_events_user_data(PurpleConnection *gc,
-	struct gg_event_user_data *data);
-
-void ggp_events_json(PurpleConnection *gc, struct gg_event_json_event *ev);
-
-#endif /* PURPLE_GG_LIBGADU_EVENTS_H */
diff --git a/libpurple/protocols/gg/libgadu-events.c b/libpurple/protocols/gg/libgadu-events.c
deleted file mode 100644
--- a/libpurple/protocols/gg/libgadu-events.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "libgadu-events.h"
-
-#include "avatar.h"
-#include "edisc.h"
-
-void ggp_events_user_data(PurpleConnection *gc, struct gg_event_user_data *data)
-{
-	guint user_idx;
-	gboolean is_update;
-
-	purple_debug_info("gg", "GG_EVENT_USER_DATA [type=%d, user_count=%"
-		G_GSIZE_FORMAT "]\n", data->type, data->user_count);
-
-	/*
-	type =
-		1, 3:	user information sent after connecting (divided by
-			20 contacts; 3 - last one; 1 - rest of them)
-		0: data update
-	*/
-	is_update = (data->type == 0);
-
-	for (user_idx = 0; user_idx < data->user_count; user_idx++) {
-		struct gg_event_user_data_user *data_user =
-			&data->users[user_idx];
-		uin_t uin = data_user->uin;
-		guint attr_idx;
-		gboolean got_avatar = FALSE;
-		for (attr_idx = 0; attr_idx < data_user->attr_count; attr_idx++) {
-			struct gg_event_user_data_attr *data_attr =
-				&data_user->attrs[attr_idx];
-			if (strcmp(data_attr->key, "avatar") == 0) {
-				time_t timestamp;
-				if (data_attr->type == 0) {
-					ggp_avatar_buddy_remove(gc, uin);
-					continue;
-				}
-
-				timestamp = atoi(data_attr->value);
-				if (timestamp <= 0)
-					continue;
-				got_avatar = TRUE;
-				ggp_avatar_buddy_update(gc, uin, timestamp);
-			}
-		}
-
-		if (!is_update && !got_avatar)
-			ggp_avatar_buddy_remove(gc, uin);
-	}
-}
-
-static void ggp_events_new_version(const gchar *data)
-{
-	/* data = {"severity":"download"} */
-	purple_debug_info("gg", "Gadu-Gadu server reports new client version."
-		" %s", data);
-}
-
-void ggp_events_json(PurpleConnection *gc, struct gg_event_json_event *ev)
-{
-	static const gchar *ignored_events[] = {
-		"edisc/scope_files_changed",
-		"notifications/state",
-		"invitations/list",
-		"notifications/list", /* gifts */
-		NULL
-	};
-	const gchar **it;
-
-	if (g_strcmp0("edisc/send_ticket_changed", ev->type) == 0) {
-		ggp_edisc_xfer_ticket_changed(gc, ev->data);
-		return;
-	}
-
-	if (g_strcmp0("updates/new-version", ev->type) == 0) {
-		ggp_events_new_version(ev->data);
-		return;
-	}
-
-	for (it = ignored_events; *it != NULL; it++) {
-		if (g_strcmp0(*it, ev->type) == 0)
-			return;
-	}
-
-	if (purple_debug_is_unsafe() && purple_debug_is_verbose())
-		purple_debug_warning("gg", "ggp_events_json: "
-			"unhandled event \"%s\": %s\n",
-			ev->type, ev->data);
-	else
-		purple_debug_warning("gg", "ggp_events_json: "
-			"unhandled event \"%s\"\n", ev->type);
-}
diff --git a/libpurple/protocols/gg/libgaduw.h b/libpurple/protocols/gg/libgaduw.h
deleted file mode 100644
--- a/libpurple/protocols/gg/libgaduw.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_LIBGADUW_H
-#define PURPLE_GG_LIBGADUW_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-#include "purplew.h"
-
-typedef void (*ggp_libgaduw_http_cb)(struct gg_http *h, gboolean success,
-	gboolean cancelled, gpointer user_data);
-
-typedef struct
-{
-	gpointer user_data;
-	ggp_libgaduw_http_cb cb;
-
-	gboolean cancelled;
-	struct gg_http *h;
-	ggp_purplew_request_processing_handle *processing;
-	guint inpa;
-} ggp_libgaduw_http_req;
-
-void ggp_libgaduw_setup(void);
-void ggp_libgaduw_cleanup(void);
-
-const gchar * ggp_libgaduw_version(PurpleConnection *gc);
-
-ggp_libgaduw_http_req * ggp_libgaduw_http_watch(PurpleConnection *gc,
-	struct gg_http *h, ggp_libgaduw_http_cb cb, gpointer user_data,
-	gboolean show_processing);
-void ggp_libgaduw_http_cancel(ggp_libgaduw_http_req *req);
-
-#endif /* PURPLE_GG_LIBGADUW_H */
diff --git a/libpurple/protocols/gg/libgaduw.c b/libpurple/protocols/gg/libgaduw.c
deleted file mode 100644
--- a/libpurple/protocols/gg/libgaduw.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "libgaduw.h"
-
-#include "purplew.h"
-#include "gg.h"
-
-#include <ctype.h>
-
-static void ggp_libgaduw_debug_handler(int level, const char * format,
-	va_list args);
-
-/*******************************************************************************
- * Setup/cleanup.
- ******************************************************************************/
-
-void ggp_libgaduw_setup(void)
-{
-	gg_debug_handler = ggp_libgaduw_debug_handler;
-}
-
-void ggp_libgaduw_cleanup(void)
-{
-	gg_debug_handler = NULL;
-}
-
-/*******************************************************************************
- * General.
- ******************************************************************************/
-
-const gchar * ggp_libgaduw_version(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	const gchar *ver = accdata->session->client_version;
-
-	if (ver != NULL && isdigit(ver[0]))
-		return ver;
-	return GG_DEFAULT_CLIENT_VERSION;
-}
-
-static void ggp_libgaduw_debug_handler(int level, const char * format,
-	va_list args)
-{
-	PurpleDebugLevel purple_level;
-	char msgbuff[1000];
-	int ret;
-
-	if ((level & GG_DEBUG_NET) || (level & GG_DEBUG_FUNCTION) ||
-		(level & GG_DEBUG_VERBOSE))
-	{
-		if (!purple_debug_is_verbose())
-			return;
-	}
-
-	if ((level & GG_DEBUG_DUMP) || /* GG session protocol packets */
-		(level & GG_DEBUG_TRAFFIC)) /* HTTP traffic */
-	{
-		if (!purple_debug_is_verbose() || !purple_debug_is_unsafe())
-			return;
-	}
-
-	/* Don't use glib's printf family, since it might not support
-	 * system-specific formatting modifiers (like %Iu for size on win32). */
-	ret = vsnprintf(msgbuff, sizeof(msgbuff) / sizeof(char), format, args);
-
-	if (ret <= 0) {
-		purple_debug_error("gg",
-			"failed to printf the following message: %s",
-			format ? format : "(null)");
-
-		return;
-	}
-
-	if (level & GG_DEBUG_ERROR)
-		purple_level = PURPLE_DEBUG_ERROR;
-	else if (level & GG_DEBUG_WARNING)
-		purple_level = PURPLE_DEBUG_WARNING;
-	else
-		purple_level = PURPLE_DEBUG_MISC;
-
-	purple_debug(purple_level, "gg", "%s", msgbuff);
-}
-
-/*******************************************************************************
- * HTTP requests.
- ******************************************************************************/
-
-static void ggp_libgaduw_http_processing_cancel(PurpleConnection *gc,
-	void *_req);
-
-static void ggp_libgaduw_http_handler(gpointer _req, gint fd,
-	PurpleInputCondition cond);
-
-static void ggp_libgaduw_http_finish(ggp_libgaduw_http_req *req,
-	gboolean success);
-
-/******************************************************************************/
-
-ggp_libgaduw_http_req * ggp_libgaduw_http_watch(PurpleConnection *gc,
-	struct gg_http *h, ggp_libgaduw_http_cb cb,
-	gpointer user_data, gboolean show_processing)
-{
-	ggp_libgaduw_http_req *req;
-	purple_debug_misc("gg", "ggp_libgaduw_http_watch(h=%p, "
-		"show_processing=%d)\n", h, show_processing);
-
-	req = g_new(ggp_libgaduw_http_req, 1);
-	req->user_data = user_data;
-	req->cb = cb;
-	req->cancelled = FALSE;
-	req->h = h;
-	req->processing = NULL;
-	if (show_processing)
-		req->processing = ggp_purplew_request_processing(gc, NULL,
-			req, ggp_libgaduw_http_processing_cancel);
-	req->inpa = ggp_purplew_http_input_add(h, ggp_libgaduw_http_handler,
-		req);
-
-	return req;
-}
-
-static void
-ggp_libgaduw_http_processing_cancel(G_GNUC_UNUSED PurpleConnection *gc,
-                                    void *_req)
-{
-	ggp_libgaduw_http_req *req = _req;
-	req->processing = NULL;
-	ggp_libgaduw_http_cancel(req);
-}
-
-static void
-ggp_libgaduw_http_handler(gpointer _req, G_GNUC_UNUSED gint fd,
-                          G_GNUC_UNUSED PurpleInputCondition cond)
-{
-	ggp_libgaduw_http_req *req = _req;
-
-	if (req->h->callback(req->h) == -1 || req->h->state == GG_STATE_ERROR) {
-		purple_debug_error("gg", "ggp_libgaduw_http_handler: failed to "
-			"make http request: %d\n", req->h->error);
-		ggp_libgaduw_http_finish(req, FALSE);
-		return;
-	}
-
-	if (purple_debug_is_verbose()) {
-		purple_debug_misc("gg", "ggp_libgaduw_http_handler: got fd "
-			"update [check=%d, state=%d]\n", req->h->check,
-			req->h->state);
-	}
-
-	if (req->h->state != GG_STATE_DONE) {
-		g_source_remove(req->inpa);
-		req->inpa = ggp_purplew_http_input_add(req->h,
-			ggp_libgaduw_http_handler, req);
-		return;
-	}
-
-	if (!req->h->data || !req->h->body) {
-		purple_debug_error("gg", "ggp_libgaduw_http_handler: got empty "
-			"http response: %d\n", req->h->error);
-		ggp_libgaduw_http_finish(req, FALSE);
-		return;
-	}
-
-	ggp_libgaduw_http_finish(req, TRUE);
-}
-
-void ggp_libgaduw_http_cancel(ggp_libgaduw_http_req *req)
-{
-	purple_debug_misc("gg", "ggp_libgaduw_http_cancel\n");
-	req->cancelled = TRUE;
-	gg_http_stop(req->h);
-	ggp_libgaduw_http_finish(req, FALSE);
-}
-
-static void ggp_libgaduw_http_finish(ggp_libgaduw_http_req *req,
-	gboolean success)
-{
-	purple_debug_misc("gg", "ggp_libgaduw_http_finish(h=%p, processing=%p):"
-		" success=%d\n", req->h, req->processing, success);
-	if (req->processing) {
-		ggp_purplew_request_processing_done(req->processing);
-		req->processing = NULL;
-	}
-	g_source_remove(req->inpa);
-	req->cb(req->h, success, req->cancelled, req->user_data);
-	req->h->destroy(req->h);
-	g_free(req);
-}
diff --git a/libpurple/protocols/gg/meson.build b/libpurple/protocols/gg/meson.build
deleted file mode 100644
--- a/libpurple/protocols/gg/meson.build
+++ /dev/null
@@ -1,66 +0,0 @@
-GG_SOURCES = [
-	'avatar.c',
-	'avatar.h',
-	'blist.c',
-	'blist.h',
-	'chat.c',
-	'chat.h',
-	'edisc.c',
-	'edisc.h',
-	'gg.c',
-	'gg.h',
-	'html.c',
-	'html.h',
-	'image-prpl.c',
-	'image-prpl.h',
-	'keymapper.c',
-	'keymapper.h',
-	'libgadu-events.c',
-	'libgadu-events.h',
-	'libgaduw.c',
-	'libgaduw.h',
-	'message-prpl.c',
-	'message-prpl.h',
-	'multilogon.c',
-	'multilogon.h',
-	'pubdir-prpl.c',
-	'pubdir-prpl.h',
-	'purplew.c',
-	'purplew.h',
-	'resolver-purple.c',
-	'resolver-purple.h',
-	'roster.c',
-	'roster.h',
-	'servconn.c',
-	'servconn.h',
-	'status.c',
-	'status.h',
-	'tcpsocket.c',
-	'tcpsocket.h',
-	'utils.c',
-	'utils.h',
-	'validator.c',
-	'validator.h',
-	'xml.c',
-	'xml.h',
-	'oauth/oauth.c',
-	'oauth/oauth.h',
-	'oauth/oauth-purple.c',
-	'oauth/oauth-purple.h'
-]
-
-if DYNAMIC_GG
-	gg_resources = gnome.compile_resources('ggresource',
-		'resources/gg.gresource.xml',
-		source_dir : 'resources',
-		c_name : 'gg')
-	GG_SOURCES += gg_resources
-
-	shared_library('gg', GG_SOURCES,
-	    c_args : ['-DG_LOG_USE_STRUCTURED', '-DG_LOG_DOMAIN="Purple-GaduGadu"'],
-	    gnu_symbol_visibility : 'hidden',
-	    dependencies : [libgadu, json, libpurple_dep, libsoup, glib],
-	    install : true, install_dir : PURPLE_PLUGINDIR)
-
-	devenv.append('PURPLE_PLUGIN_PATH', meson.current_build_dir())
-endif
diff --git a/libpurple/protocols/gg/message-prpl.h b/libpurple/protocols/gg/message-prpl.h
deleted file mode 100644
--- a/libpurple/protocols/gg/message-prpl.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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_GG_MESSAGE_PRPL_H
-#define PURPLE_GG_MESSAGE_PRPL_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-typedef struct _ggp_message_session_data ggp_message_session_data;
-
-void ggp_message_setup_global(void);
-void ggp_message_cleanup_global(void);
-void ggp_message_setup(PurpleConnection *gc);
-void ggp_message_cleanup(PurpleConnection *gc);
-
-void ggp_message_got(PurpleConnection *gc, const struct gg_event_msg *ev);
-void ggp_message_got_multilogon(PurpleConnection *gc,
-	const struct gg_event_msg *ev);
-
-int ggp_message_send_im(PurpleProtocolIM *im, PurpleConnection *gc, PurpleConversation *conversation, PurpleMessage *msg);
-gchar * ggp_message_format_to_gg(PurpleConversation *conv, const gchar *text);
-
-#endif /* PURPLE_GG_MESSAGE_PRPL_H */
diff --git a/libpurple/protocols/gg/message-prpl.c b/libpurple/protocols/gg/message-prpl.c
deleted file mode 100644
--- a/libpurple/protocols/gg/message-prpl.c
+++ /dev/null
@@ -1,699 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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 <errno.h>
-
-#include "message-prpl.h"
-
-#include "gg.h"
-#include "chat.h"
-#include "utils.h"
-#include "html.h"
-
-#define GGP_GG10_DEFAULT_FORMAT "<span style=\"color:#000000; " \
-	"font-family:'MS Shell Dlg 2'; font-size:9pt; \">"
-#define GGP_GG10_DEFAULT_FORMAT_REPLACEMENT "<span>"
-#define GGP_GG11_FORCE_COMPAT FALSE
-
-typedef struct
-{
-	enum
-	{
-		GGP_MESSAGE_GOT_TYPE_IM,
-		GGP_MESSAGE_GOT_TYPE_CHAT,
-		GGP_MESSAGE_GOT_TYPE_MULTILOGON
-	} type;
-
-	uin_t user;
-	gchar *text;
-	time_t time;
-	uint64_t chat_id;
-
-	PurpleConnection *gc;
-} ggp_message_got_data;
-
-typedef struct
-{
-	GRegex *re_html_tag;
-	GRegex *re_gg_img;
-} ggp_message_global_data;
-
-static ggp_message_global_data global_data;
-
-struct _ggp_message_session_data
-{
-};
-
-typedef struct
-{
-	int size;
-	gchar *face;
-	int color, bgcolor;
-	gboolean b, i, u, s;
-} ggp_font;
-
-static ggp_font * ggp_font_new(void);
-static ggp_font * ggp_font_clone(ggp_font *font);
-static void ggp_font_free(gpointer font);
-
-static PurpleConversation * ggp_message_get_conv(PurpleConnection *gc,
-	uin_t uin);
-static void ggp_message_got_data_free(ggp_message_got_data *msg);
-static void ggp_message_got_display(PurpleConnection *gc,
-	ggp_message_got_data *msg);
-static void ggp_message_format_from_gg(ggp_message_got_data *msg,
-	const gchar *text);
-
-/**************/
-
-void ggp_message_setup_global(void)
-{
-	global_data.re_html_tag = g_regex_new(
-		"<(/)?([a-zA-Z]+)( [^>]+)?>",
-		G_REGEX_OPTIMIZE, 0, NULL);
-	global_data.re_gg_img = g_regex_new(
-		"<img name=\"([0-9a-fA-F]+)\"/?>",
-		G_REGEX_OPTIMIZE, 0, NULL);
-}
-
-void ggp_message_cleanup_global(void)
-{
-	g_regex_unref(global_data.re_html_tag);
-	g_regex_unref(global_data.re_gg_img);
-}
-
-static inline ggp_message_session_data *
-ggp_message_get_sdata(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	return accdata->message_data;
-}
-
-void ggp_message_setup(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	ggp_message_session_data *sdata = g_new0(ggp_message_session_data, 1);
-
-	accdata->message_data = sdata;
-}
-
-void ggp_message_cleanup(PurpleConnection *gc)
-{
-	ggp_message_session_data *sdata = ggp_message_get_sdata(gc);
-
-	g_free(sdata);
-}
-
-static ggp_font * ggp_font_new(void)
-{
-	ggp_font *font;
-
-	font = g_new0(ggp_font, 1);
-	font->color = -1;
-	font->bgcolor = -1;
-
-	return font;
-}
-
-static ggp_font * ggp_font_clone(ggp_font * font)
-{
-	ggp_font *clone = g_new0(ggp_font, 1);
-
-	*clone = *font;
-	clone->face = g_strdup(font->face);
-
-	return clone;
-}
-
-static void ggp_font_free(gpointer _font)
-{
-	ggp_font *font = _font;
-
-	g_free(font->face);
-	g_free(font);
-}
-
-/**/
-
-static PurpleConversation * ggp_message_get_conv(PurpleConnection *gc,
-	uin_t uin)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	PurpleConversation *im;
-	PurpleConversationManager *manager;
-	const gchar *who = ggp_uin_to_str(uin);
-
-	manager = purple_conversation_manager_get_default();
-	im = purple_conversation_manager_find_im(manager, account, who);
-	if (im) {
-		return im;
-	}
-	im = purple_im_conversation_new(account, who);
-	return im;
-}
-
-static void ggp_message_got_data_free(ggp_message_got_data *msg)
-{
-	g_free(msg->text);
-	g_free(msg);
-}
-
-void ggp_message_got(PurpleConnection *gc, const struct gg_event_msg *ev)
-{
-	ggp_message_got_data *msg = g_new0(ggp_message_got_data, 1);
-
-	msg->gc = gc;
-	msg->time = ev->time;
-	msg->user = ev->sender;
-
-	if (ev->chat_id != 0) {
-		msg->type = GGP_MESSAGE_GOT_TYPE_CHAT;
-		msg->chat_id = ev->chat_id;
-	} else {
-		msg->type = GGP_MESSAGE_GOT_TYPE_IM;
-	}
-
-	ggp_message_format_from_gg(msg, ev->xhtml_message);
-
-	ggp_message_got_display(gc, msg);
-	ggp_message_got_data_free(msg);
-}
-
-void ggp_message_got_multilogon(PurpleConnection *gc,
-	const struct gg_event_msg *ev)
-{
-	ggp_message_got_data *msg = g_new0(ggp_message_got_data, 1);
-
-	msg->gc = gc;
-	msg->time = ev->time;
-	msg->user = ev->sender; /* not really a sender*/
-
-	if (ev->chat_id != 0) {
-		msg->type = GGP_MESSAGE_GOT_TYPE_CHAT;
-		msg->chat_id = ev->chat_id;
-	} else {
-		msg->type = GGP_MESSAGE_GOT_TYPE_MULTILOGON;
-	}
-
-	ggp_message_format_from_gg(msg, ev->xhtml_message);
-
-	ggp_message_got_display(gc, msg);
-	ggp_message_got_data_free(msg);
-}
-
-static void ggp_message_got_display(PurpleConnection *gc,
-	ggp_message_got_data *msg)
-{
-	if (msg->type == GGP_MESSAGE_GOT_TYPE_IM) {
-		purple_serv_got_im(gc, ggp_uin_to_str(msg->user), msg->text,
-			PURPLE_MESSAGE_RECV, msg->time);
-	} else if (msg->type == GGP_MESSAGE_GOT_TYPE_CHAT) {
-		ggp_chat_got_message(gc, msg->chat_id, msg->text, msg->time,
-			msg->user);
-	} else if (msg->type == GGP_MESSAGE_GOT_TYPE_MULTILOGON) {
-		GDateTime *dt = NULL;
-		PurpleAccount *account = NULL;
-		PurpleContactInfo *info = NULL;
-		PurpleConversation *im = ggp_message_get_conv(gc, msg->user);
-		PurpleMessage *pmsg;
-		const gchar *me = NULL;
-
-		account = purple_connection_get_account(gc);
-		info = PURPLE_CONTACT_INFO(account);
-		me = purple_contact_info_get_name_for_display(info);
-
-		pmsg = purple_message_new_outgoing(me, NULL, msg->text, 0);
-
-		dt = g_date_time_new_from_unix_local((gint64)msg->time);
-		purple_message_set_timestamp(pmsg, dt);
-		g_date_time_unref(dt);
-
-		purple_conversation_write_message(im, pmsg);
-
-		g_object_unref(pmsg);
-	} else {
-		purple_debug_error("gg", "ggp_message_got_display: "
-			"unexpected message type: %d\n", msg->type);
-	}
-}
-
-static gboolean ggp_message_format_from_gg_found_img(const GMatchInfo *info,
-	GString *res, gpointer data)
-{
-	ggp_message_got_data *msg = data;
-	gchar *name, *replacement;
-	int64_t id;
-	PurpleImage *image;
-	guint image_id;
-
-	name = g_match_info_fetch(info, 1);
-	if (sscanf(name, "%" G_GINT64_MODIFIER "x", &id) != 1)
-		id = 0;
-	g_free(name);
-	if (!id) {
-		/* TODO: stock broken image? */
-		g_string_append_printf(res, "[%s]", _("broken image"));
-		return FALSE;
-	}
-
-	image = ggp_image_request(msg->gc, msg->user, id);
-	if (!image) {
-		purple_debug_warning("gg", "ggp_message_format_from_gg_"
-			"found_img: couldn't request image");
-		g_string_append_printf(res, "[%s]", _("broken image"));
-		return FALSE;
-	}
-
-	image_id = purple_image_store_add_weak(image);
-	replacement = g_strdup_printf("<img src=\""
-		PURPLE_IMAGE_STORE_PROTOCOL "%u\">", image_id);
-	g_string_append(res, replacement);
-	g_free(replacement);
-
-	return FALSE;
-}
-
-static void ggp_message_format_from_gg(ggp_message_got_data *msg,
-	const gchar *text)
-{
-	gchar *text_new, *tmp;
-
-	if (text == NULL) {
-		msg->text = g_strdup("");
-		return;
-	}
-
-	text_new = g_strdup(text);
-	purple_str_strip_char(text_new, '\r');
-
-	tmp = text_new;
-	text_new = purple_strreplace(text_new, GGP_GG10_DEFAULT_FORMAT,
-		GGP_GG10_DEFAULT_FORMAT_REPLACEMENT);
-	g_free(tmp);
-
-	tmp = text_new;
-	text_new = g_regex_replace_eval(global_data.re_gg_img, text_new, -1, 0,
-		0, ggp_message_format_from_gg_found_img, msg, NULL);
-	g_free(tmp);
-
-	msg->text = text_new;
-}
-
-gchar *
-ggp_message_format_to_gg(PurpleConversation *conv, const gchar *text)
-{
-	gchar *text_new, *tmp;
-	GString *reformatted_text = NULL;
-	GMatchInfo *match;
-	guint pos = 0;
-	GString *pending_objects = NULL;
-	GList *font_stack = NULL;
-	static int html_sizes_pt[7] = { 7, 8, 9, 10, 12, 14, 16 };
-
-	ggp_font *font_new, *font_current, *font_base;
-	gboolean font_changed = FALSE;
-	gboolean in_any_tag = FALSE;
-
-	if (purple_debug_is_verbose())
-		purple_debug_info("gg", "ggp formatting text: [%s]", text);
-
-	/* default font */
-	font_base = ggp_font_new();
-	font_current = ggp_font_new();
-	font_new = ggp_font_new();
-
-	/* GG11 doesn't use nbsp, it just print spaces */
-	text_new = purple_strreplace(text, "&nbsp;", " ");
-
-	/* add end-of-message tag */
-	if (strstr(text_new, "<eom>") != NULL) {
-		tmp = text_new;
-		text_new = purple_strreplace(text_new, "<eom>", "");
-		g_free(tmp);
-		purple_debug_warning("gg", "ggp_message_format_to_gg: "
-			"unexpected <eom> tag\n");
-	}
-	tmp = text_new;
-	text_new = g_strdup_printf("%s<eom></eom>", text_new);
-	g_free(tmp);
-
-	reformatted_text = g_string_new(NULL);
-	pending_objects = g_string_new(NULL);
-	g_regex_match(global_data.re_html_tag, text_new, 0, &match);
-	while (g_match_info_matches(match)) {
-		int m_start, m_end, m_pos;
-		gboolean tag_close;
-		gchar *tag_str, *attribs_str;
-		ggp_html_tag tag;
-		gboolean text_before;
-
-		/* reading tag and its contents */
-		g_match_info_fetch_pos(match, 0, &m_start, &m_end);
-		g_assert(m_start >= 0 && m_end >= 0);
-		text_before = ((guint)m_start > pos);
-		g_match_info_fetch_pos(match, 1, &m_pos, NULL);
-		tag_close = (m_pos >= 0);
-		tag_str = g_match_info_fetch(match, 2);
-		tag = ggp_html_parse_tag(tag_str);
-		attribs_str = g_match_info_fetch(match, 3);
-		g_match_info_next(match, NULL);
-
-		if (tag == GGP_HTML_TAG_UNKNOWN) {
-			purple_debug_warning(
-				"gg",
-				"ggp_message_format_to_gg: unknown tag %s",
-				tag_str);
-		}
-
-		/* closing *all* formatting-related tags (GG11 weirdness)
-		 * and adding pending objects */
-		if ((text_before && (font_changed || pending_objects->len > 0)) ||
-		    (tag == GGP_HTML_TAG_EOM && tag_close)) {
-			font_changed = FALSE;
-			if (in_any_tag) {
-				in_any_tag = FALSE;
-				if (font_current->s && !GGP_GG11_FORCE_COMPAT) {
-					g_string_append(reformatted_text, "</s>");
-				}
-				if (font_current->u) {
-					g_string_append(reformatted_text, "</u>");
-				}
-				if (font_current->i) {
-					g_string_append(reformatted_text, "</i>");
-				}
-				if (font_current->b) {
-					g_string_append(reformatted_text, "</b>");
-				}
-				g_string_append(reformatted_text, "</span>");
-			}
-			if (pending_objects->len > 0) {
-				g_string_append(reformatted_text, pending_objects->str);
-				g_string_truncate(pending_objects, 0);
-			}
-		}
-
-		/* opening formatting-related tags again */
-		if (text_before && !in_any_tag) {
-			gboolean has_size = (font_new->size > 0 &&
-				font_new->size <= 7 && font_new->size != 3);
-			gboolean has_style =
-			        has_size || font_new->face ||
-			        (font_new->bgcolor >= 0 && !GGP_GG11_FORCE_COMPAT) ||
-			        font_new->color >= 0;
-
-			if (has_style) {
-				g_string_append(reformatted_text, "<span style=\"");
-
-				if (has_size) {
-					g_string_append_printf(reformatted_text, "font-size:%dpt;",
-					                       html_sizes_pt[font_new->size - 1]);
-				}
-				if (font_new->face) {
-					g_string_append_printf(reformatted_text, "font-family:%s;",
-					                       font_new->face);
-				}
-				if (font_new->bgcolor >= 0 && !GGP_GG11_FORCE_COMPAT) {
-					g_string_append_printf(reformatted_text,
-					                       "background-color:#%06x;",
-					                       font_new->bgcolor);
-				}
-				if (font_new->color >= 0) {
-					g_string_append_printf(reformatted_text, "color:#%06x;",
-					                       font_new->color);
-				}
-
-				g_string_append(reformatted_text, "\">");
-			} else {
-				g_string_append(reformatted_text, "<span>");
-			}
-
-			if (font_new->b) {
-				g_string_append(reformatted_text, "<b>");
-			}
-			if (font_new->i) {
-				g_string_append(reformatted_text, "<i>");
-			}
-			if (font_new->u) {
-				g_string_append(reformatted_text, "<u>");
-			}
-			if (font_new->s && !GGP_GG11_FORCE_COMPAT) {
-				g_string_append(reformatted_text, "<s>");
-			}
-
-			ggp_font_free(font_current);
-			font_current = font_new;
-			font_new = ggp_font_clone(font_current);
-
-			in_any_tag = TRUE;
-		}
-		if (text_before) {
-			g_string_append_len(reformatted_text, text_new + pos,
-			                    m_start - pos);
-		}
-
-		/* set formatting of a following text */
-		if (tag == GGP_HTML_TAG_B) {
-			font_changed |= (font_new->b != !tag_close);
-			font_new->b = !tag_close;
-		} else if (tag == GGP_HTML_TAG_I) {
-			font_changed |= (font_new->i != !tag_close);
-			font_new->i = !tag_close;
-		} else if (tag == GGP_HTML_TAG_U) {
-			font_changed |= (font_new->u != !tag_close);
-			font_new->u = !tag_close;
-		} else if (tag == GGP_HTML_TAG_S) {
-			font_changed |= (font_new->s != !tag_close);
-			font_new->s = !tag_close;
-		} else if (tag == GGP_HTML_TAG_IMG && !tag_close) {
-			GHashTable *attribs = ggp_html_tag_attribs(attribs_str);
-			gchar *val = NULL;
-			uint64_t id;
-			ggp_image_prepare_result res = -1;
-			PurpleImage *image = NULL;
-
-			val = g_hash_table_lookup(attribs, "src");
-			if (val)
-				image = purple_image_store_get_from_uri(val);
-
-			if (image != NULL)
-				res = ggp_image_prepare(conv, image, &id);
-
-			if (res == GGP_IMAGE_PREPARE_OK) {
-				g_string_append_printf(pending_objects,
-				                       "<img name=\"" GGP_IMAGE_ID_FORMAT "\">",
-				                       id);
-			} else if (res == GGP_IMAGE_PREPARE_TOO_BIG) {
-				purple_conversation_write_system_message(conv,
-					_("Image is too large, please try "
-					"smaller one."), PURPLE_MESSAGE_ERROR);
-			} else {
-				purple_conversation_write_system_message(conv,
-					_("Image cannot be sent."),
-					PURPLE_MESSAGE_ERROR);
-			}
-
-			g_hash_table_destroy(attribs);
-		} else if (tag == GGP_HTML_TAG_FONT && !tag_close) {
-			GHashTable *attribs = ggp_html_tag_attribs(attribs_str);
-			gchar *val = NULL;
-
-			font_stack = g_list_prepend(font_stack,
-				ggp_font_clone(font_new));
-
-			if ((val = g_hash_table_lookup(attribs, "size")) != NULL
-				&& val[0] >= '1' && val[0] <= '7' &&
-				val[1] == '\0')
-			{
-				int size = val[0] - '0';
-				font_changed |= (font_new->size != size);
-				font_new->size = size;
-			}
-
-			if ((val = g_hash_table_lookup(attribs, "face"))
-				!= NULL)
-			{
-				font_changed |=
-					(g_strcmp0(font_new->face, val) != 0);
-				g_free(font_new->face);
-				font_new->face = g_strdup(val);
-			}
-
-			if ((val = g_hash_table_lookup(attribs, "color"))
-				!= NULL && val[0] == '#' && strlen(val) == 7)
-			{
-				int color = ggp_html_decode_color(val);
-				font_changed |= (font_new->color != color);
-				font_new->color = color;
-			}
-
-			g_hash_table_destroy(attribs);
-		}
-		else if ((tag == GGP_HTML_TAG_SPAN || tag == GGP_HTML_TAG_DIV)
-			&& !tag_close)
-		{
-			GHashTable *attribs, *styles = NULL;
-			gchar *style = NULL;
-			gchar *val = NULL;
-
-			attribs = ggp_html_tag_attribs(attribs_str);
-
-			font_stack = g_list_prepend(font_stack,
-				ggp_font_clone(font_new));
-			if (tag == GGP_HTML_TAG_DIV) {
-				g_string_append(pending_objects, "<br>");
-			}
-
-			style = g_hash_table_lookup(attribs, "style");
-			if (style)
-				styles = ggp_html_css_attribs(style);
-
-			if (styles && (val = g_hash_table_lookup(styles,
-				"background-color")) != NULL)
-			{
-				int color = ggp_html_decode_color(val);
-				font_changed |= (font_new->bgcolor != color);
-				font_new->bgcolor = color;
-			}
-
-			if (styles && (val = g_hash_table_lookup(styles,
-				"color")) != NULL)
-			{
-				int color = ggp_html_decode_color(val);
-				font_changed |= (font_new->color != color);
-				font_new->color = color;
-			}
-
-			g_clear_pointer(&styles, g_hash_table_destroy);
-			g_hash_table_destroy(attribs);
-		}
-		else if ((tag == GGP_HTML_TAG_FONT || tag == GGP_HTML_TAG_SPAN
-			|| tag == GGP_HTML_TAG_DIV) && tag_close)
-		{
-			font_changed = TRUE;
-
-			ggp_font_free(font_new);
-			if (font_stack) {
-				font_new = (ggp_font*)font_stack->data;
-				font_stack = g_list_delete_link(
-					font_stack, font_stack);
-			}
-			else
-				font_new = ggp_font_clone(font_base);
-		} else if (tag == GGP_HTML_TAG_BR) {
-			g_string_append(pending_objects, "<br>");
-		} else if (tag == GGP_HTML_TAG_HR) {
-			g_string_append(pending_objects, "<br><span>---</span><br>");
-		} else if (tag == GGP_HTML_TAG_A || tag == GGP_HTML_TAG_EOM) {
-			/* do nothing */
-		} else if (tag == GGP_HTML_TAG_UNKNOWN) {
-			purple_debug_warning(
-				"gg",
-				"ggp_message_format_to_gg: unknown tag %s",
-				tag_str);
-		} else {
-			purple_debug_error("gg", "ggp_message_format_to_gg: "
-				"not handled tag %s\n", tag_str);
-		}
-
-		pos = m_end;
-		g_free(tag_str);
-		g_free(attribs_str);
-	}
-	g_match_info_free(match);
-
-	if (pos < strlen(text_new) || in_any_tag) {
-		purple_debug_error(
-		        "gg",
-		        "ggp_message_format_to_gg: end of message not reached");
-	}
-
-	/* releasing fonts resources */
-	ggp_font_free(font_new);
-	ggp_font_free(font_current);
-	ggp_font_free(font_base);
-	g_list_free_full(font_stack, ggp_font_free);
-
-	/* combining reformatted text info one string */
-	g_free(text_new);
-	g_string_free(pending_objects, TRUE);
-	text_new = g_string_free(reformatted_text, FALSE);
-
-	if (purple_debug_is_verbose())
-		purple_debug_info("gg", "reformatted text: [%s]", text_new);
-
-	return text_new;
-}
-
-int
-ggp_message_send_im(G_GNUC_UNUSED PurpleProtocolIM *pim,
-                    PurpleConnection *gc,
-                    G_GNUC_UNUSED PurpleConversation *conversation,
-                    PurpleMessage *msg)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	PurpleConversation *im;
-	PurpleConversationManager *manager;
-	ggp_buddy_data *buddy_data;
-	gchar *gg_msg;
-	gboolean succ;
-	const gchar *rcpt = purple_message_get_recipient(msg);
-
-	/* TODO: return -ENOTCONN, if not connected */
-
-	if (purple_message_is_empty(msg))
-		return 0;
-
-	buddy_data = ggp_buddy_get_data(purple_blist_find_buddy(
-		purple_connection_get_account(gc), rcpt));
-
-	if (buddy_data->blocked)
-		return -1;
-
-	manager = purple_conversation_manager_get_default();
-	im = purple_conversation_manager_find_im(manager,
-	                                         purple_connection_get_account(gc),
-	                                         rcpt);
-
-	gg_msg = ggp_message_format_to_gg(im,
-		purple_message_get_contents(msg));
-
-	/* TODO: splitting messages */
-	if (strlen(gg_msg) > GG_MSG_MAXSIZE) {
-		g_free(gg_msg);
-		return -E2BIG;
-	}
-
-	succ = (gg_send_message_html(info->session, GG_CLASS_CHAT,
-		ggp_str_to_uin(rcpt), (unsigned char *)gg_msg) >= 0);
-
-	g_free(gg_msg);
-
-	return succ ? 1 : -1;
-}
diff --git a/libpurple/protocols/gg/multilogon.h b/libpurple/protocols/gg/multilogon.h
deleted file mode 100644
--- a/libpurple/protocols/gg/multilogon.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_MULTILOGON_H
-#define PURPLE_GG_MULTILOGON_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-typedef struct _ggp_multilogon_session_data ggp_multilogon_session_data;
-
-void ggp_multilogon_setup(PurpleConnection *gc);
-void ggp_multilogon_cleanup(PurpleConnection *gc);
-
-void ggp_multilogon_info(PurpleConnection *gc,
-	struct gg_event_multilogon_info *msg);
-
-void ggp_multilogon_dialog(PurpleConnection *gc);
-
-#endif /* PURPLE_GG_MULTILOGON_H */
diff --git a/libpurple/protocols/gg/multilogon.c b/libpurple/protocols/gg/multilogon.c
deleted file mode 100644
--- a/libpurple/protocols/gg/multilogon.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "multilogon.h"
-
-#include <glib/gi18n-lib.h>
-
-#include "gg.h"
-#include "keymapper.h"
-#include "utils.h"
-#include "message-prpl.h"
-
-typedef struct
-{
-	uint64_t id;
-	uint32_t remote_addr;
-	gchar *name;
-	GDateTime *logon_time;
-} ggp_multilogon_session_info;
-
-struct _ggp_multilogon_session_data
-{
-	int session_count;
-	ggp_multilogon_session_info *sessions;
-	PurpleRequestDatasheet *sheet_handle;
-	gpointer dialog_handle;
-	ggp_keymapper *sid_mapper;
-};
-
-static inline ggp_multilogon_session_data *
-ggp_multilogon_get_mldata(PurpleConnection *gc);
-
-
-static inline ggp_multilogon_session_data *
-ggp_multilogon_get_mldata(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	return accdata->multilogon_data;
-}
-
-void
-ggp_multilogon_setup(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-
-	ggp_multilogon_session_data *mldata =
-		g_new0(ggp_multilogon_session_data, 1);
-	accdata->multilogon_data = mldata;
-
-	mldata->sid_mapper = ggp_keymapper_new();
-}
-
-static void
-ggp_multilogon_free_sessions(PurpleConnection *gc)
-{
-	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
-	int i;
-
-	for (i = 0; i < mldata->session_count; i++) {
-		g_free(mldata->sessions[i].name);
-		g_clear_pointer(&mldata->sessions[i].logon_time, g_date_time_unref);
-	}
-	g_free(mldata->sessions);
-
-	mldata->sessions = NULL;
-	mldata->session_count = 0;
-}
-
-void
-ggp_multilogon_cleanup(PurpleConnection *gc)
-{
-	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
-
-	if (mldata->dialog_handle) {
-		purple_request_close(PURPLE_REQUEST_FIELDS,
-			mldata->dialog_handle);
-		mldata->dialog_handle = NULL;
-	}
-
-	ggp_multilogon_free_sessions(gc);
-	ggp_keymapper_free(mldata->sid_mapper);
-	g_free(mldata);
-}
-
-static uint64_t
-ggp_multilogon_sid_from_libgadu(gg_multilogon_id_t lsid)
-{
-	uint64_t sid;
-
-	memcpy(&sid, lsid.id, sizeof(uint64_t));
-
-	return sid;
-}
-
-static void
-ggp_multilogon_sid_to_libgadu(uint64_t sid, gg_multilogon_id_t *lsid)
-{
-	g_return_if_fail(lsid != NULL);
-
-	memcpy(lsid->id, &sid, sizeof(uint64_t));
-}
-
-static void
-ggp_multilogon_fill_sessions(PurpleRequestDatasheet *sheet,
-	PurpleConnection *gc)
-{
-	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
-	ggp_keymapper *km = mldata->sid_mapper;
-	int i;
-
-	purple_request_datasheet_record_mark_all_for_rem(sheet);
-
-	for (i = 0; i < mldata->session_count; i++) {
-		ggp_multilogon_session_info *sess = &mldata->sessions[i];
-		PurpleRequestDatasheetRecord *rec;
-		gchar *tmp = NULL;
-
-		rec = purple_request_datasheet_record_add(sheet,
-			ggp_keymapper_to_key(km, sess->id));
-
-		purple_request_datasheet_record_set_string_data(rec, 0,
-			ggp_ipv4_to_str(sess->remote_addr));
-
-		tmp = g_date_time_format(sess->logon_time, "%c");
-		purple_request_datasheet_record_set_string_data(rec, 1, tmp);
-		g_free(tmp);
-
-		purple_request_datasheet_record_set_string_data(rec, 2, sess->name);
-	}
-
-	purple_request_datasheet_record_remove_marked(sheet);
-}
-
-void
-ggp_multilogon_info(PurpleConnection *gc, struct gg_event_multilogon_info *info)
-{
-	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
-	int i;
-
-	ggp_multilogon_free_sessions(gc);
-
-	purple_debug_info("gg", "ggp_multilogon_info: session list changed "
-		"(count now: %d)\n", info->count);
-
-	mldata->sessions = g_new(ggp_multilogon_session_info, info->count);
-	for (i = 0; i < info->count; i++) {
-		struct gg_multilogon_session *lsess = &info->sessions[i];
-		ggp_multilogon_session_info *psess = &mldata->sessions[i];
-
-		psess->id = ggp_multilogon_sid_from_libgadu(lsess->id);
-		psess->remote_addr = lsess->remote_addr;
-		psess->name = g_strdup(lsess->name);
-		psess->logon_time = g_date_time_new_from_unix_local(lsess->logon_time);
-	}
-
-	mldata->session_count = info->count;
-
-	if (mldata->sheet_handle != NULL)
-		ggp_multilogon_fill_sessions(mldata->sheet_handle, gc);
-}
-
-static void
-ggp_multilogon_disconnect(PurpleRequestDatasheetRecord *rec, gpointer _gc)
-{
-	PurpleConnection *gc = _gc;
-	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	uint64_t sid;
-	gpointer key;
-	gg_multilogon_id_t lsid;
-
-	key = purple_request_datasheet_record_get_key(rec);
-	sid = ggp_keymapper_from_key(mldata->sid_mapper, key);
-
-	ggp_multilogon_sid_to_libgadu(sid, &lsid);
-	gg_multilogon_disconnect(accdata->session, lsid);
-
-	purple_request_datasheet_record_remove(
-		purple_request_datasheet_record_get_datasheet(rec), key);
-}
-
-static void
-ggp_multilogin_close_request(ggp_multilogon_session_data *mldata)
-{
-	mldata->sheet_handle = NULL;
-	mldata->dialog_handle = NULL;
-}
-
-void
-ggp_multilogon_dialog(PurpleConnection *gc)
-{
-	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
-	PurpleRequestField *field;
-	PurpleRequestPage *page;
-	PurpleRequestGroup *group;
-	PurpleRequestCommonParameters *cpar;
-	PurpleRequestDatasheet *sheet;
-	PurpleRequestDatasheetAction *action;
-	gpointer dialog_handle;
-
-	if (mldata->dialog_handle != NULL)
-		return;
-
-	page = purple_request_page_new();
-	group = purple_request_group_new(NULL);
-	purple_request_page_add_group(page, group);
-
-	sheet = purple_request_datasheet_new();
-	purple_request_datasheet_add_column(sheet,
-		PURPLE_REQUEST_DATASHEET_COLUMN_STRING, _("IP"));
-	purple_request_datasheet_add_column(sheet,
-		PURPLE_REQUEST_DATASHEET_COLUMN_STRING, _("Logon time"));
-	purple_request_datasheet_add_column(sheet,
-		PURPLE_REQUEST_DATASHEET_COLUMN_STRING, _("Session"));
-
-	action = purple_request_datasheet_action_new();
-	purple_request_datasheet_action_set_label(action, _("Disconnect"));
-	purple_request_datasheet_action_set_cb(action,
-		ggp_multilogon_disconnect, gc);
-	purple_request_datasheet_add_action(sheet, action);
-	ggp_multilogon_fill_sessions(sheet, gc);
-
-	field = purple_request_field_datasheet_new("sessions", NULL, sheet);
-	purple_request_group_add_field(group, field);
-
-	cpar = purple_request_cpar_new();
-	purple_request_cpar_set_icon(cpar, PURPLE_REQUEST_ICON_DIALOG);
-
-	dialog_handle = purple_request_fields(gc,
-		_("Other Gadu-Gadu sessions"), NULL, NULL, page,
-		NULL, NULL, _("Close"), NULL,
-		cpar, NULL);
-	mldata->sheet_handle = sheet;
-	mldata->dialog_handle = dialog_handle;
-
-	purple_request_add_close_notify(dialog_handle,
-		(GDestroyNotify)ggp_multilogin_close_request, mldata);
-}
diff --git a/libpurple/protocols/gg/oauth/oauth-purple.h b/libpurple/protocols/gg/oauth/oauth-purple.h
deleted file mode 100644
--- a/libpurple/protocols/gg/oauth/oauth-purple.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 _GGP_OAUTH_PURPLE_H
-#define _GGP_OAUTH_PURPLE_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-typedef void (*ggp_oauth_request_cb)(PurpleConnection *gc, const gchar *token,
-	gpointer user_data);
-
-void ggp_oauth_request(PurpleConnection *gc, ggp_oauth_request_cb callback,
-	gpointer user_data, const gchar *sign_method, const gchar *sign_url);
-
-#endif /* _GGP_OAUTH_PURPLE_H */
diff --git a/libpurple/protocols/gg/oauth/oauth-purple.c b/libpurple/protocols/gg/oauth/oauth-purple.c
deleted file mode 100644
--- a/libpurple/protocols/gg/oauth/oauth-purple.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "oauth-purple.h"
-#include "gg.h"
-
-#include "oauth.h"
-#include "../utils.h"
-#include "../xml.h"
-
-#include <purple.h>
-
-#define GGP_OAUTH_RESPONSE_MAX 10240
-
-typedef struct
-{
-	SoupMessage *msg;
-	PurpleConnection *gc;
-	ggp_oauth_request_cb callback;
-	gpointer user_data;
-	gchar *token;
-	gchar *token_secret;
-
-	gchar *sign_method, *sign_url;
-} ggp_oauth_data;
-
-static void ggp_oauth_data_free(ggp_oauth_data *data)
-{
-	g_object_unref(data->msg);
-	g_free(data->token);
-	g_free(data->token_secret);
-	g_free(data->sign_method);
-	g_free(data->sign_url);
-	g_free(data);
-}
-
-static void
-ggp_oauth_access_token_got(GObject *source, GAsyncResult *result,
-                           gpointer user_data)
-{
-	ggp_oauth_data *data = user_data;
-	GBytes *response_body = NULL;
-	const char *buffer = NULL;
-	gsize size = 0;
-	gchar *token = NULL, *token_secret = NULL;
-	PurpleXmlNode *xml;
-	gboolean succ = TRUE;
-	GError *error = NULL;
-
-	response_body = soup_session_send_and_read_finish(SOUP_SESSION(source),
-	                                                  result, &error);
-	if(response_body == NULL) {
-		purple_debug_error("gg", "ggp_oauth_access_token_got: failed: %s",
-		                   error->message);
-		ggp_oauth_data_free(data);
-		g_error_free(error);
-		return;
-	}
-
-	buffer = g_bytes_get_data(response_body, &size);
-	xml = purple_xmlnode_from_str(buffer, size);
-	g_bytes_unref(response_body);
-
-	if (xml == NULL) {
-		purple_debug_error("gg", "ggp_oauth_access_token_got: invalid xml");
-		ggp_oauth_data_free(data);
-		return;
-	}
-
-	succ &= ggp_xml_get_string(xml, "oauth_token", &token);
-	succ &= ggp_xml_get_string(xml, "oauth_token_secret", &token_secret);
-	purple_xmlnode_free(xml);
-	if (!succ || strlen(token) < 10) {
-		purple_debug_error("gg", "ggp_oauth_access_token_got: invalid xml - "
-		                         "token is not present");
-		g_free(token);
-		g_free(token_secret);
-		ggp_oauth_data_free(data);
-		return;
-	}
-
-	if (data->sign_url) {
-		PurpleAccount *account;
-		PurpleContactInfo *info = NULL;
-		gchar *auth;
-
-		purple_debug_misc("gg", "ggp_oauth_access_token_got: got access token, "
-		                        "returning signed url");
-
-		account = purple_connection_get_account(data->gc);
-		info = PURPLE_CONTACT_INFO(account);
-		auth = gg_oauth_generate_header(
-		        data->sign_method, data->sign_url,
-		        purple_contact_info_get_username(info),
-		        purple_connection_get_password(data->gc), token, token_secret);
-		data->callback(data->gc, auth, data->user_data);
-	} else {
-		purple_debug_misc(
-		        "gg",
-		        "ggp_oauth_access_token_got: got access token, returning it");
-		data->callback(data->gc, token, data->user_data);
-	}
-
-	g_free(token);
-	g_free(token_secret);
-	ggp_oauth_data_free(data);
-}
-
-static void
-ggp_oauth_authorization_done(GObject *source,
-                             G_GNUC_UNUSED GAsyncResult *result,
-                             gpointer user_data)
-{
-	ggp_oauth_data *data = user_data;
-	PurpleAccount *account;
-	PurpleContactInfo *info = NULL;
-	SoupStatus status_code;
-	char *auth;
-	SoupMessage *msg = NULL;
-	const char *method = "POST";
-	const char *url = "http://api.gadu-gadu.pl/access_token";
-
-	PURPLE_ASSERT_CONNECTION_IS_VALID(data->gc);
-
-	account = purple_connection_get_account(data->gc);
-	info = PURPLE_CONTACT_INFO(account);
-
-	status_code = soup_message_get_status(data->msg);
-	if (status_code != 302) {
-		purple_debug_error("gg",
-		                   "ggp_oauth_authorization_done: failed (code = %d)",
-		                   status_code);
-		ggp_oauth_data_free(data);
-		return;
-	}
-
-	purple_debug_misc("gg", "ggp_oauth_authorization_done: authorization done, "
-	                        "requesting access token...");
-
-	auth = gg_oauth_generate_header(method, url,
-	                                purple_contact_info_get_username(info),
-	                                purple_connection_get_password(data->gc),
-	                                data->token, data->token_secret);
-
-	g_clear_object(&data->msg);
-	data->msg = msg = soup_message_new(method, url);
-	// purple_http_request_set_max_len(req, GGP_OAUTH_RESPONSE_MAX);
-	soup_message_headers_replace(soup_message_get_request_headers(msg),
-	                             "Authorization", auth);
-	soup_session_send_and_read_async(SOUP_SESSION(source), msg,
-	                                 G_PRIORITY_DEFAULT, NULL,
-	                                 ggp_oauth_access_token_got, data);
-
-	g_free(auth);
-}
-
-static void
-ggp_oauth_request_token_got(GObject *source, GAsyncResult *result,
-                            gpointer user_data)
-{
-	SoupSession *session = SOUP_SESSION(source);
-	ggp_oauth_data *data = user_data;
-	GBytes *response_body = NULL;
-	const char *buffer = NULL;
-	gsize size = 0;
-	PurpleAccount *account;
-	PurpleXmlNode *xml;
-	SoupMessage *msg = NULL;
-	gchar *request_data;
-	GBytes *body = NULL;
-	gboolean succ = TRUE;
-	GError *error = NULL;
-
-	PURPLE_ASSERT_CONNECTION_IS_VALID(data->gc);
-
-	account = purple_connection_get_account(data->gc);
-
-	if(!SOUP_STATUS_IS_SUCCESSFUL(soup_message_get_status(data->msg))) {
-		purple_debug_error("gg", "ggp_oauth_request_token_got: "
-			"requested token not received\n");
-		ggp_oauth_data_free(data);
-		return;
-	}
-
-	response_body = soup_session_send_and_read_finish(session, result, &error);
-	if(response_body == NULL) {
-		purple_debug_error("gg", "ggp_oauth_access_token_got: failed: %s",
-		                   error->message);
-		ggp_oauth_data_free(data);
-		g_error_free(error);
-		return;
-	}
-
-	purple_debug_misc("gg", "ggp_oauth_request_token_got: "
-		"got request token, doing authorization...\n");
-
-	buffer = g_bytes_get_data(response_body, &size);
-	xml = purple_xmlnode_from_str(buffer, size);
-	g_bytes_unref(response_body);
-
-	if (xml == NULL) {
-		purple_debug_error("gg", "ggp_oauth_request_token_got: "
-			"invalid xml\n");
-		ggp_oauth_data_free(data);
-		return;
-	}
-
-	succ &= ggp_xml_get_string(xml, "oauth_token", &data->token);
-	succ &= ggp_xml_get_string(xml, "oauth_token_secret",
-		&data->token_secret);
-	purple_xmlnode_free(xml);
-	if (!succ) {
-		purple_debug_error("gg", "ggp_oauth_request_token_got: "
-			"invalid xml - token is not present\n");
-		ggp_oauth_data_free(data);
-		return;
-	}
-
-	request_data = g_strdup_printf(
-		"callback_url=http://www.mojageneracja.pl&request_token=%s&"
-		"uin=%s&password=%s", data->token,
-		purple_contact_info_get_username(PURPLE_CONTACT_INFO(account)),
-		purple_connection_get_password(data->gc));
-
-	g_clear_object(&data->msg);
-	data->msg = msg = soup_message_new("POST",
-	                                   "https://login.gadu-gadu.pl/authorize");
-	// purple_http_request_set_max_len(msg, GGP_OAUTH_RESPONSE_MAX);
-	/* we don't need any results, nor 302 redirection */
-	soup_message_set_flags(msg, SOUP_MESSAGE_NO_REDIRECT);
-	body = g_bytes_new_take(request_data, strlen(request_data));
-	soup_message_set_request_body_from_bytes(msg,
-	                                         "application/x-www-form-urlencoded",
-	                                         body);
-	g_bytes_unref(body);
-	soup_session_send_and_read_async(session, msg, G_PRIORITY_DEFAULT, NULL,
-	                                 ggp_oauth_authorization_done, data);
-}
-
-void
-ggp_oauth_request(PurpleConnection *gc, ggp_oauth_request_cb callback,
-                  gpointer user_data, const gchar *sign_method,
-                  const gchar *sign_url)
-{
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	PurpleAccount *account = purple_connection_get_account(gc);
-	SoupMessage *msg;
-	char *auth;
-	const char *method = "POST";
-	const char *url = "http://api.gadu-gadu.pl/request_token";
-	ggp_oauth_data *data;
-
-	purple_debug_misc("gg", "ggp_oauth_request: requesting token...\n");
-
-	auth = gg_oauth_generate_header(
-	        method, url,
-	        purple_contact_info_get_username(PURPLE_CONTACT_INFO(account)),
-	        purple_connection_get_password(gc), NULL, NULL);
-
-	data = g_new0(ggp_oauth_data, 1);
-	data->gc = gc;
-	data->callback = callback;
-	data->user_data = user_data;
-	data->sign_method = g_strdup(sign_method);
-	data->sign_url = g_strdup(sign_url);
-
-	data->msg = msg = soup_message_new(method, url);
-	// purple_http_request_set_max_len(req, GGP_OAUTH_RESPONSE_MAX);
-	soup_message_headers_replace(soup_message_get_request_headers(msg),
-	                             "Authorization", auth);
-	soup_session_send_and_read_async(info->http, msg, G_PRIORITY_DEFAULT, NULL,
-	                                 ggp_oauth_request_token_got, data);
-
-	g_free(auth);
-}
diff --git a/libpurple/protocols/gg/oauth/oauth.h b/libpurple/protocols/gg/oauth/oauth.h
deleted file mode 100644
--- a/libpurple/protocols/gg/oauth/oauth.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* 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.
- *
- * Code adapted from libgadu (C) 2008 Wojtek Kaniewski <wojtekka@irc.pl>
- * (http://toxygen.net/libgadu/) during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * 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 _GGP_OAUTH_H
-#define _GGP_OAUTH_H
-
-#include <libgadu.h>
-
-char * gg_oauth_generate_header(const char *method, const char *url,
-	const char *consumer_key, const char *consumer_secret,
-	const char *token, const char *token_secret);
-
-#endif /* _GGP_OAUTH_H */
diff --git a/libpurple/protocols/gg/oauth/oauth.c b/libpurple/protocols/gg/oauth/oauth.c
deleted file mode 100644
--- a/libpurple/protocols/gg/oauth/oauth.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/* 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.
- *
- * Code adapted from libgadu (C) 2008 Wojtek Kaniewski <wojtekka@irc.pl>
- * (http://toxygen.net/libgadu/) during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * 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 "oauth.h"
-
-#include <time.h>
-
-#include <glib.h>
-
-char *gg_oauth_static_nonce;		/* dla unit testów */
-char *gg_oauth_static_timestamp;	/* dla unit testów */
-
-static char *gg_oauth_generate_request(gboolean header, ...) G_GNUC_NULL_TERMINATED;
-
-static void gg_oauth_generate_nonce(char *buf, int len)
-{
-	const char charset[] = "0123456789";
-
-	if (buf == NULL || len < 1)
-		return;
-
-	while (len > 1) {
-		*buf++ = charset[(unsigned) (((float) sizeof(charset) - 1.0) * g_random_int() / (RAND_MAX + 1.0))];
-		len--;
-	}
-
-	*buf = 0;
-}
-
-/* Returns a comma separated header value if header is true,
- * or a url-encoded request otherwise
- */
-static char *
-gg_oauth_generate_request(gboolean header, ...)
-{
-	GString *res = g_string_new(NULL);
-	va_list params;
-	const gchar *key;
-	gboolean truncate = FALSE;
-
-	if(header) {
-		res = g_string_append(res, "OAuth ");
-	}
-
-	va_start(params, header);
-	while((key = va_arg(params, const gchar *))) {
-		const gchar *value = va_arg(params, const gchar *);
-		gchar *escaped = g_uri_escape_string(value, NULL, FALSE);
-
-		if(header) {
-			g_string_append_printf(res, "%s=\"%s\",", key, escaped);
-		} else {
-			g_string_append_printf(res, "%s=%s&", key, escaped);
-		}
-
-		g_free(escaped);
-
-		truncate = TRUE;
-	}
-	va_end(params);
-
-	if(truncate) {
-		/* remove trailing separator */
-		res = g_string_truncate(res, res->len - 1);
-	}
-
-	return g_string_free(res, FALSE);
-}
-
-static gchar *gg_hmac_sha1(const char *key, const char *message)
-{
-	GHmac *hmac;
-	guchar digest[20];
-	gsize digest_len = 20;
-
-	hmac = g_hmac_new(G_CHECKSUM_SHA1, (guchar *)key, strlen(key));
-	g_hmac_update(hmac, (guchar *)message, -1);
-	g_hmac_get_digest(hmac, digest, &digest_len);
-	g_hmac_unref(hmac);
-
-	return g_base64_encode(digest, sizeof(digest));
-}
-
-static char *
-gg_oauth_generate_signature(const char *method, const char *url,
-	const char *request, const char *consumer_secret,
-	const char *token_secret)
-{
-	char *text, *key, *res;
-	gchar *url_e, *request_e, *consumer_secret_e, *token_secret_e;
-
-	url_e = g_uri_escape_string(url, "?", FALSE);
-	g_strdelimit(url_e, "?", '\0');
-	request_e = g_uri_escape_string(request, NULL, FALSE);
-	text = g_strdup_printf("%s&%s&%s", method, url_e, request_e);
-	g_free(url_e);
-	g_free(request_e);
-
-	consumer_secret_e = g_uri_escape_string(consumer_secret, NULL, FALSE);
-	token_secret_e = token_secret ? g_uri_escape_string(token_secret, NULL, FALSE) : NULL;
-	key = g_strdup_printf("%s&%s", consumer_secret_e, token_secret ? token_secret_e : "");
-	g_free(consumer_secret_e);
-	g_free(token_secret_e);
-
-	res = gg_hmac_sha1(key, text);
-
-	g_free(key);
-	g_free(text);
-
-	return res;
-}
-
-char *
-gg_oauth_generate_header(const char *method, const char *url,
-	const char *consumer_key, const char *consumer_secret,
-	const char *token, const char *token_secret)
-{
-	char *request, *signature, *res;
-	char nonce[80], timestamp[16];
-
-	if (gg_oauth_static_nonce == NULL)
-		gg_oauth_generate_nonce(nonce, sizeof(nonce));
-	else {
-		strncpy(nonce, gg_oauth_static_nonce, sizeof(nonce) - 1);
-		nonce[sizeof(nonce) - 1] = 0;
-	}
-
-	if (gg_oauth_static_timestamp == NULL) {
-		g_snprintf(timestamp, sizeof(timestamp), "%ld", time(NULL));
-	} else {
-		strncpy(timestamp, gg_oauth_static_timestamp, sizeof(timestamp) - 1);
-		timestamp[sizeof(timestamp) - 1] = 0;
-	}
-
-	request = gg_oauth_generate_request(FALSE,
-	                                    "oauth_consumer_key", consumer_key,
-	                                    "oauth_nonce", nonce,
-	                                    "oauth_signature_method", "HMAC-SHA1",
-	                                    "oauth_timestamp", timestamp,
-	                                    "oauth_token", token,
-	                                    "oauth_version", "1.0",
-	                                    NULL);
-
-	signature = gg_oauth_generate_signature(method, url, request, consumer_secret, token_secret);
-
-	g_free(request);
-
-	if (signature == NULL)
-		return NULL;
-
-	res = gg_oauth_generate_request(TRUE,
-	                                "oauth_version", "1.0",
-	                                "oauth_nonce", nonce,
-	                                "oauth_timestamp", timestamp,
-	                                "oauth_consumer_key", consumer_key,
-	                                "oauth_token", token,
-	                                "oauth_signature_method", "HMAC-SHA1",
-	                                "oauth_signature", signature,
-	                                NULL);
-	g_free(signature);
-
-	return res;
-}
diff --git a/libpurple/protocols/gg/pubdir-prpl.h b/libpurple/protocols/gg/pubdir-prpl.h
deleted file mode 100644
--- a/libpurple/protocols/gg/pubdir-prpl.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_PUBDIR_PRPL_H
-#define PURPLE_GG_PUBDIR_PRPL_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-typedef enum
-{
-	GGP_PUBDIR_GENDER_UNSPECIFIED,
-	GGP_PUBDIR_GENDER_FEMALE,
-	GGP_PUBDIR_GENDER_MALE,
-} ggp_pubdir_gender;
-
-typedef struct
-{
-	uin_t uin;
-	gchar *label;
-	gchar *nickname;
-	gchar *first_name;
-	gchar *last_name;
-	ggp_pubdir_gender gender;
-	gchar *city;
-	unsigned int province;
-	GDateTime *birth;
-	unsigned int age;
-} ggp_pubdir_record;
-
-typedef struct _ggp_pubdir_search_form ggp_pubdir_search_form;
-
-typedef void (*ggp_pubdir_request_cb)(PurpleConnection *gc, int records_count,
-	const ggp_pubdir_record *records, int next_offset, void *user_data);
-
-void ggp_pubdir_get_info(PurpleConnection *gc, uin_t uin,
-	ggp_pubdir_request_cb cb, void *user_data);
-
-void ggp_pubdir_get_info_protocol(PurpleProtocolServer *protocol_server, PurpleConnection *gc, const char *name);
-void ggp_pubdir_request_buddy_alias(PurpleConnection *gc, PurpleBuddy *buddy);
-
-void ggp_pubdir_search(PurpleConnection *gc,
-	const ggp_pubdir_search_form *form);
-
-void ggp_pubdir_set_info(PurpleConnection *gc);
-
-#endif /* PURPLE_GG_PUBDIR_PRPL_H */
diff --git a/libpurple/protocols/gg/pubdir-prpl.c b/libpurple/protocols/gg/pubdir-prpl.c
deleted file mode 100644
--- a/libpurple/protocols/gg/pubdir-prpl.c
+++ /dev/null
@@ -1,1025 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "pubdir-prpl.h"
-#include "gg.h"
-
-#include "oauth/oauth-purple.h"
-#include "xml.h"
-#include "utils.h"
-#include "status.h"
-
-typedef struct
-{
-	PurpleConnection *gc;
-	ggp_pubdir_request_cb cb;
-	void *user_data;
-	enum
-	{
-		GGP_PUBDIR_REQUEST_TYPE_INFO,
-		GGP_PUBDIR_REQUEST_TYPE_SEARCH,
-	} type;
-	union
-	{
-		struct
-		{
-			uin_t uin;
-		} user_info;
-		ggp_pubdir_search_form *search_form;
-	} params;
-} ggp_pubdir_request;
-
-/* Searching for buddies. */
-
-#define GGP_PUBDIR_SEARCH_TITLE _("Gadu-Gadu Public Directory")
-#define GGP_PUBDIR_SEARCH_PER_PAGE 20
-
-struct _ggp_pubdir_search_form
-{
-	gchar *nick, *city;
-	ggp_pubdir_gender gender;
-	int offset;
-	int limit;
-
-	void *display_handle;
-};
-
-/* For ggp_pubdir_search_results_next, which is called by this. */
-static void ggp_pubdir_search_results_display(PurpleConnection *gc,
-	int records_count, const ggp_pubdir_record *records, int next_offset,
-	void *user_data);
-
-/******************************************************************************/
-
-static const gchar *ggp_pubdir_provinces[] =
-{
-	N_("Not specified"),
-	"dolnośląskie",
-	"kujawsko-pomorskie",
-	"lubelskie",
-	"lubuskie",
-	"łódzkie",
-	"małopolskie",
-	"mazowieckie",
-	"opolskie",
-	"podkarpackie",
-	"podlaskie",
-	"pomorskie",
-	"śląskie",
-	"świętokrzyskie",
-	"warmińsko-mazurskie",
-	"wielkopolskie",
-	"zachodniopomorskie",
-};
-
-static gsize ggp_pubdir_provinces_count = sizeof(ggp_pubdir_provinces)/sizeof(gchar*);
-
-/******************************************************************************/
-
-static void
-ggp_pubdir_record_free(ggp_pubdir_record *records, int count)
-{
-	int i;
-	for (i = 0; i < count; i++) {
-		g_free(records[i].label);
-		g_free(records[i].nickname);
-		g_free(records[i].first_name);
-		g_free(records[i].last_name);
-		g_free(records[i].city);
-		g_date_time_unref(records[i].birth);
-	}
-	g_free(records);
-}
-
-static void
-ggp_pubdir_search_form_free(ggp_pubdir_search_form *form)
-{
-	g_free(form->nick);
-	g_free(form->city);
-	g_free(form);
-}
-
-static void
-ggp_pubdir_request_free(ggp_pubdir_request *request)
-{
-	if (request->type == GGP_PUBDIR_REQUEST_TYPE_SEARCH)
-		ggp_pubdir_search_form_free(request->params.search_form);
-	g_free(request);
-}
-
-static void
-ggp_pubdir_got_data(GObject *source, GAsyncResult *result, gpointer data) {
-	ggp_pubdir_request *request = data;
-	PurpleConnection *gc = request->gc;
-	GBytes *response_body = NULL;
-	gboolean succ = TRUE;
-	PurpleXmlNode *xml;
-	const char *xml_raw = NULL;
-	gsize xml_size = 0;
-	unsigned int status, next_offset;
-	int record_count, i;
-	ggp_pubdir_record *records;
-	GError *error = NULL;
-
-	response_body = soup_session_send_and_read_finish(SOUP_SESSION(source),
-	                                                  result, &error);
-	if (response_body == NULL) {
-		purple_debug_error("gg", "ggp_pubdir_got_data: %s", error->message);
-		request->cb(gc, -1, NULL, 0, request->user_data);
-		ggp_pubdir_request_free(request);
-		g_error_free(error);
-		return;
-	}
-
-	xml_raw = g_bytes_unref_to_data(response_body, &xml_size);
-
-	if (purple_debug_is_verbose() && purple_debug_is_unsafe()) {
-		purple_debug_misc("gg", "ggp_pubdir_got_data: xml=[%.*s]",
-		                  (int)xml_size, xml_raw);
-	}
-
-	xml = purple_xmlnode_from_str(xml_raw, xml_size);
-	if (xml == NULL) {
-		purple_debug_error("gg", "ggp_pubdir_got_data: "
-			"invalid xml\n");
-		request->cb(gc, -1, NULL, 0, request->user_data);
-		ggp_pubdir_request_free(request);
-		return;
-	}
-
-	succ &= ggp_xml_get_uint(xml, "status", &status);
-	if (!ggp_xml_get_uint(xml, "nextOffset", &next_offset))
-		next_offset = 0;
-	xml = purple_xmlnode_get_child(xml, "users");
-	if (!succ || status != 0 || !xml) {
-		purple_debug_error("gg", "ggp_pubdir_got_data: "
-			"invalid reply\n");
-		request->cb(gc, -1, NULL, 0, request->user_data);
-		ggp_pubdir_request_free(request);
-		return;
-	}
-
-	record_count = ggp_xml_child_count(xml, "user");
-	records = g_new0(ggp_pubdir_record, record_count);
-
-	xml = purple_xmlnode_get_child(xml, "user");
-	i = 0;
-	while (xml) {
-		ggp_pubdir_record *record = &records[i++];
-		gchar *city = NULL, *birth_s = NULL;
-		unsigned int gender = 0;
-		const gchar *uin_s;
-
-		g_assert(i <= record_count);
-
-		record->uin = ggp_str_to_uin(purple_xmlnode_get_attrib(xml, "uin"));
-		if (record->uin == 0)
-			ggp_xml_get_uint(xml, "uin", &record->uin);
-		if (record->uin == 0)
-			purple_debug_error("gg", "ggp_pubdir_got_data:"
-				" invalid uin\n");
-		uin_s = ggp_uin_to_str(record->uin);
-
-		ggp_xml_get_string(xml, "label", &record->label);
-		ggp_xml_get_string(xml, "nick", &record->nickname);
-		ggp_xml_get_string(xml, "name", &record->first_name);
-		ggp_xml_get_string(xml, "surname", &record->last_name);
-		ggp_xml_get_string(xml, "city", &city);
-		ggp_xml_get_string(xml, "birth", &birth_s);
-		ggp_xml_get_uint(xml, "gender", &gender);
-		ggp_xml_get_uint(xml, "age", &record->age);
-		ggp_xml_get_uint(xml, "province", &record->province);
-
-		record->label = ggp_free_if_equal(record->label, uin_s);
-		record->label = ggp_free_if_equal(record->label, "");
-		record->nickname = ggp_free_if_equal(record->nickname, uin_s);
-		record->nickname = ggp_free_if_equal(record->nickname, "");
-		record->first_name = ggp_free_if_equal(record->first_name, "");
-		record->last_name = ggp_free_if_equal(record->last_name, "");
-		g_clear_pointer(&record->birth, g_date_time_unref);
-
-		if (record->label) {}
-		else if (record->nickname)
-			record->label = g_strdup(record->nickname);
-		else if (record->first_name && record->last_name)
-			record->label = g_strdup_printf("%s %s",
-				record->first_name, record->last_name);
-		else if (record->first_name)
-			record->label = g_strdup(record->first_name);
-		else if (record->last_name)
-			record->label = g_strdup(record->last_name);
-		if (record->label)
-			g_strstrip(record->label);
-		if (record->nickname)
-			g_strstrip(record->nickname);
-
-		if (gender == 1)
-			record->gender = GGP_PUBDIR_GENDER_FEMALE;
-		else if (gender == 2)
-			record->gender = GGP_PUBDIR_GENDER_MALE;
-		else
-			record->gender = GGP_PUBDIR_GENDER_UNSPECIFIED;
-
-		if (city && city[0] != '\0')
-			record->city = g_strdup(city);
-		if (record->city)
-			g_strstrip(record->city);
-		if (!record->city) {
-			g_free(record->city);
-			record->city = NULL;
-		}
-
-		record->birth = g_date_time_new_from_iso8601(birth_s, NULL);
-		/*TODO: calculate age from birth */
-
-		if (purple_debug_is_verbose()) {
-			purple_debug_misc("gg", "ggp_pubdir_got_data: [uin:%d] "
-				"[label:%s] [nick:%s] [first name:%s] "
-				"[last name:%s] [city:%s] [gender:%d] [age:%d] "
-				"[birth:%lu]\n", record->uin, record->label,
-				record->nickname, record->first_name,
-				record->last_name, record->city, record->gender,
-				record->age, g_date_time_to_unix(record->birth));
-		}
-
-		g_clear_pointer(&city, g_free);
-		g_clear_pointer(&birth_s, g_free);
-
-		xml = purple_xmlnode_get_next_twin(xml);
-	}
-
-	request->cb(gc, record_count, records, next_offset, request->user_data);
-
-	ggp_pubdir_request_free(request);
-	ggp_pubdir_record_free(records, record_count);
-}
-
-static void
-ggp_pubdir_get_info_got_token(PurpleConnection *gc, const gchar *token,
-                              gpointer _request)
-{
-	GGPInfo *info = NULL;
-	gchar *url;
-	SoupMessage *msg;
-	ggp_pubdir_request *request = _request;
-
-	PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
-
-	if (!token) {
-		request->cb(gc, -1, NULL, 0, request->user_data);
-		ggp_pubdir_request_free(request);
-		return;
-	}
-
-	info = purple_connection_get_protocol_data(gc);
-
-	url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u",
-	                      request->params.user_info.uin);
-	msg = soup_message_new("GET", url);
-	g_free(url);
-	soup_message_headers_replace(soup_message_get_request_headers(msg),
-	                             "Authorization", token);
-	soup_session_send_and_read_async(info->http, msg, G_PRIORITY_DEFAULT, NULL,
-	                                 ggp_pubdir_got_data, request);
-	g_object_unref(msg);
-}
-
-void
-ggp_pubdir_get_info(PurpleConnection *gc, uin_t uin, ggp_pubdir_request_cb cb,
-                    void *user_data)
-{
-	ggp_pubdir_request *request = g_new0(ggp_pubdir_request, 1);
-	gchar *url;
-
-	request->type = GGP_PUBDIR_REQUEST_TYPE_INFO;
-	request->gc = gc;
-	request->cb = cb;
-	request->user_data = user_data;
-	request->params.user_info.uin = uin;
-
-	url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u", uin);
-	ggp_oauth_request(gc, ggp_pubdir_get_info_got_token, request, "GET", url);
-	g_free(url);
-}
-
-static void
-ggp_pubdir_get_info_protocol_got(PurpleConnection *gc, int records_count,
-                                 const ggp_pubdir_record *records,
-                                 G_GNUC_UNUSED int next_offset, void *_uin_p)
-{
-	uin_t uin = *((uin_t*)_uin_p);
-	PurpleNotifyUserInfo *info = purple_notify_user_info_new();
-	const ggp_pubdir_record *record = &records[0];
-	PurpleBuddy *buddy;
-
-	g_free(_uin_p);
-
-	if (records_count < 1) {
-		purple_debug_error("gg", "ggp_pubdir_get_info_protocol_got: "
-			"couldn't get info for %u\n", uin);
-		purple_notify_user_info_add_pair_plaintext(info, NULL,
-			_("Cannot get user information"));
-		purple_notify_userinfo(gc, ggp_uin_to_str(uin), info,
-			NULL, NULL);
-		purple_notify_user_info_destroy(info);
-		return;
-	}
-
-	purple_debug_info("gg", "ggp_pubdir_get_info_protocol_got: %u\n", uin);
-	g_assert(uin == record->uin);
-	g_assert(records_count == 1);
-
-	buddy = purple_blist_find_buddy(purple_connection_get_account(gc),
-		ggp_uin_to_str(uin));
-	if (buddy) {
-		const char *alias;
-		PurpleStatus *status;
-		gchar *status_message;
-
-		alias = purple_buddy_get_alias_only(buddy);
-		if (alias)
-			purple_notify_user_info_add_pair_plaintext(info,
-				_("Alias"), alias);
-
-		status = purple_presence_get_active_status(
-			purple_buddy_get_presence(buddy));
-		ggp_status_from_purplestatus(status, &status_message);
-		purple_notify_user_info_add_pair_plaintext(info, _("Status"),
-			purple_status_get_name(status));
-		if (status_message) {
-			purple_notify_user_info_add_pair_plaintext(info,
-				_("Message"), status_message);
-		}
-	}
-
-	if (record->nickname) {
-		purple_notify_user_info_add_pair_plaintext(info,
-			_("Nickname"), record->nickname);
-	}
-	if (record->first_name) {
-		purple_notify_user_info_add_pair_plaintext(info,
-			_("First name"), record->first_name);
-	}
-	if (record->last_name) {
-		purple_notify_user_info_add_pair_plaintext(info,
-			_("Last name"), record->last_name);
-	}
-	if (record->gender != GGP_PUBDIR_GENDER_UNSPECIFIED) {
-		purple_notify_user_info_add_pair_plaintext(info, _("Gender"),
-			record->gender == GGP_PUBDIR_GENDER_FEMALE ?
-			_("Female") : _("Male"));
-	}
-	if (record->city) {
-		purple_notify_user_info_add_pair_plaintext(info, _("City"),
-			record->city);
-	}
-	if (record->birth) {
-		gchar *bday = g_date_time_format(record->birth, "%Y-%m-%d");
-
-		purple_notify_user_info_add_pair_plaintext(info, _("Birthday"), bday);
-
-		g_free(bday);
-	} else if (record->age) {
-		gchar *age_s = g_strdup_printf("%d", record->age);
-		purple_notify_user_info_add_pair_plaintext(info, _("Age"),
-			age_s);
-		g_free(age_s);
-	}
-
-	purple_notify_userinfo(gc, ggp_uin_to_str(uin), info, NULL, NULL);
-	purple_notify_user_info_destroy(info);
-}
-
-void
-ggp_pubdir_get_info_protocol(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                             PurpleConnection *gc, const gchar *name)
-{
-	uin_t uin = ggp_str_to_uin(name);
-	uin_t *uin_p = g_new0(uin_t, 1);
-
-	*uin_p = uin;
-
-	purple_debug_info("gg", "ggp_pubdir_get_info_protocol: %u", uin);
-
-	ggp_pubdir_get_info(gc, uin, ggp_pubdir_get_info_protocol_got, uin_p);
-}
-
-static void
-ggp_pubdir_request_buddy_alias_got(PurpleConnection *gc, int records_count,
-                                   const ggp_pubdir_record *records,
-                                   G_GNUC_UNUSED int next_offset,
-                                   G_GNUC_UNUSED gpointer data)
-{
-	uin_t uin;
-	const gchar *alias;
-
-	if (records_count < 0) {
-		purple_debug_error("gg", "ggp_pubdir_request_buddy_alias_got: "
-			"couldn't get info for user\n");
-		return;
-	}
-	uin = records[0].uin;
-
-	alias = records[0].label;
-	if (!alias) {
-		purple_debug_info("gg", "ggp_pubdir_request_buddy_alias_got: "
-			"public alias for %u is not available\n", uin);
-		return;
-	}
-
-	purple_debug_info("gg", "ggp_pubdir_request_buddy_alias_got: "
-		"public alias for %u is \"%s\"\n", uin, alias);
-
-	purple_serv_got_alias(gc, ggp_uin_to_str(uin), alias);
-}
-
-void
-ggp_pubdir_request_buddy_alias(PurpleConnection *gc, PurpleBuddy *buddy)
-{
-	uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy));
-
-	purple_debug_info("gg", "ggp_pubdir_request_buddy_alias: %u", uin);
-
-	ggp_pubdir_get_info(gc, uin, ggp_pubdir_request_buddy_alias_got, NULL);
-}
-
-/*******************************************************************************
- * Searching for buddies.
- ******************************************************************************/
-
-static ggp_pubdir_search_form *
-ggp_pubdir_search_form_clone(const ggp_pubdir_search_form *form)
-{
-	ggp_pubdir_search_form *dup = g_new(ggp_pubdir_search_form, 1);
-
-	dup->nick = g_strdup(form->nick);
-	dup->city = g_strdup(form->city);
-	dup->gender = form->gender;
-	dup->offset = form->offset;
-	dup->limit = form->limit;
-
-	dup->display_handle = form->display_handle;
-
-	return dup;
-}
-
-static gchar * ggp_pubdir_search_make_query(const ggp_pubdir_search_form *form)
-{
-	gchar *nick, *city, *gender;
-	gchar *query;
-
-	if (form->nick && form->nick[0] != '\0') {
-		gchar *nick_e = g_uri_escape_string(form->nick, NULL, FALSE);
-		nick = g_strdup_printf("&nick=%s", nick_e);
-		g_free(nick_e);
-	} else
-		nick = g_strdup("");
-
-	if (form->city && form->city[0] != '\0') {
-		gchar *city_e = g_uri_escape_string(form->city, NULL, FALSE);
-		city = g_strdup_printf("&city=%s", city_e);
-		g_free(city_e);
-	} else
-		city = g_strdup("");
-
-	if (form->gender != GGP_PUBDIR_GENDER_UNSPECIFIED) {
-		gender = g_strdup_printf("&gender=%d",
-			form->gender == GGP_PUBDIR_GENDER_MALE ? 2 : 1);
-	} else
-		gender = g_strdup("");
-
-	query = g_strdup_printf("/users.xml?offset=%d&limit=%d%s%s%s",
-		form->offset, form->limit, nick, city, gender);
-
-	g_free(nick);
-	g_free(city);
-	g_free(gender);
-
-	return query;
-}
-
-static void ggp_pubdir_search_got_token(PurpleConnection *gc,
-	const gchar *token, gpointer _request)
-{
-	GGPInfo *info = NULL;
-	gchar *url;
-	SoupMessage *msg;
-	ggp_pubdir_request *request = _request;
-	gchar *query;
-
-	PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
-
-	if (!token) {
-		request->cb(gc, -1, NULL, 0, request->user_data);
-		ggp_pubdir_request_free(request);
-		return;
-	}
-
-	purple_debug_misc("gg", "ggp_pubdir_search_got_token\n");
-
-	query = ggp_pubdir_search_make_query(request->params.search_form);
-
-	info = purple_connection_get_protocol_data(gc);
-
-	url = g_strdup_printf("http://api.gadu-gadu.pl%s", query);
-	msg = soup_message_new("GET", url);
-	soup_message_headers_replace(soup_message_get_request_headers(msg),
-	                             "Authorization", token);
-	soup_session_send_and_read_async(info->http, msg, G_PRIORITY_DEFAULT, NULL,
-	                                 ggp_pubdir_got_data, request);
-
-	g_object_unref(msg);
-	g_free(url);
-	g_free(query);
-}
-
-static void
-ggp_pubdir_search_execute(PurpleConnection *gc,
-                          const ggp_pubdir_search_form *form,
-                          ggp_pubdir_request_cb cb, void *user_data)
-{
-	ggp_pubdir_request *request = g_new0(ggp_pubdir_request, 1);
-	gchar *url;
-	ggp_pubdir_search_form *local_form = ggp_pubdir_search_form_clone(form);
-	gchar *query;
-
-	request->type = GGP_PUBDIR_REQUEST_TYPE_SEARCH;
-	request->gc = gc;
-	request->cb = cb;
-	request->user_data = user_data;
-	request->params.search_form = local_form;
-
-	query = ggp_pubdir_search_make_query(form);
-	purple_debug_misc("gg", "ggp_pubdir_search_execute: %s", query);
-	url = g_strdup_printf("http://api.gadu-gadu.pl%s", query);
-	ggp_oauth_request(gc, ggp_pubdir_search_got_token, request, "GET", url);
-	g_free(query);
-	g_free(url);
-}
-
-static void
-ggp_pubdir_search_results_new(PurpleConnection *gc, G_GNUC_UNUSED GList *row,
-                              gpointer _form)
-{
-	ggp_pubdir_search_form *form = _form;
-	ggp_pubdir_search(gc, form);
-}
-
-static void
-ggp_pubdir_search_results_close(gpointer _form)
-{
-	ggp_pubdir_search_form *form = _form;
-	ggp_pubdir_search_form_free(form);
-}
-
-static void
-ggp_pubdir_search_results_next(PurpleConnection *gc, G_GNUC_UNUSED GList *row,
-                               gpointer _form)
-{
-	ggp_pubdir_search_form *form = _form;
-	ggp_pubdir_search_execute(gc, form, ggp_pubdir_search_results_display,
-	                          form);
-}
-
-static void
-ggp_pubdir_search_results_add(PurpleConnection *gc, GList *row,
-                              G_GNUC_UNUSED gpointer form)
-{
-	purple_blist_request_add_buddy(purple_connection_get_account(gc),
-	                               g_list_nth_data(row, 0), NULL,
-	                               g_list_nth_data(row, 1));
-}
-
-static void
-ggp_pubdir_search_results_im(PurpleConnection *gc, GList *row,
-                             G_GNUC_UNUSED gpointer form)
-{
-	purple_conversation_present(PURPLE_CONVERSATION(purple_im_conversation_new(
-	        purple_connection_get_account(gc), g_list_nth_data(row, 0))));
-}
-
-static void
-ggp_pubdir_search_results_info(PurpleConnection *gc, GList *row,
-                               G_GNUC_UNUSED gpointer form)
-{
-	ggp_pubdir_get_info_protocol(NULL, gc, g_list_nth_data(row, 0));
-}
-
-static void
-ggp_pubdir_search_results_display(PurpleConnection *gc, int records_count,
-                                  const ggp_pubdir_record *records,
-                                  int next_offset, void *_form)
-{
-	ggp_pubdir_search_form *form = _form;
-	PurpleNotifySearchResults *results;
-	int i;
-
-	purple_debug_info("gg", "ggp_pubdir_search_results_display: "
-		"got %d records (next offset: %d)\n",
-		records_count, next_offset);
-
-	if (records_count < 0 ||
-		(records_count == 0 && form->offset != 0))
-	{
-		purple_notify_error(gc, GGP_PUBDIR_SEARCH_TITLE,
-			_("Error while searching for buddies"), NULL,
-			purple_request_cpar_from_connection(gc));
-		ggp_pubdir_search_form_free(form);
-		return;
-	}
-
-	if (records_count == 0) {
-		purple_notify_info(gc, GGP_PUBDIR_SEARCH_TITLE,
-			_("No matching users found"),
-			_("There are no users matching your search criteria."),
-			purple_request_cpar_from_connection(gc));
-		ggp_pubdir_search_form_free(form);
-		return;
-	}
-
-	form->offset = next_offset;
-
-	results = purple_notify_searchresults_new();
-
-	purple_notify_searchresults_column_add(results,
-		purple_notify_searchresults_column_new(_("GG Number")));
-	purple_notify_searchresults_column_add(results,
-		purple_notify_searchresults_column_new(_("Name")));
-	purple_notify_searchresults_column_add(results,
-		purple_notify_searchresults_column_new(_("City")));
-	purple_notify_searchresults_column_add(results,
-		purple_notify_searchresults_column_new(_("Gender")));
-	purple_notify_searchresults_column_add(results,
-		purple_notify_searchresults_column_new(_("Age")));
-
-	for (i = 0; i < records_count; i++) {
-		GList *row = NULL;
-		const ggp_pubdir_record *record = &records[i];
-		gchar *gender = NULL, *age = NULL;
-
-		if (record->gender == GGP_PUBDIR_GENDER_MALE)
-			gender = g_strdup("male");
-		else if (record->gender == GGP_PUBDIR_GENDER_FEMALE)
-			gender = g_strdup("female");
-
-		if (record->age)
-			age = g_strdup_printf("%d", record->age);
-
-		row = g_list_append(row, g_strdup(ggp_uin_to_str(record->uin)));
-		row = g_list_append(row, g_strdup(record->label));
-		row = g_list_append(row, g_strdup(record->city));
-		row = g_list_append(row, gender);
-		row = g_list_append(row, age);
-		purple_notify_searchresults_row_add(results, row);
-	}
-
-	purple_notify_searchresults_button_add(results,
-		PURPLE_NOTIFY_BUTTON_ADD, ggp_pubdir_search_results_add);
-	purple_notify_searchresults_button_add(results,
-		PURPLE_NOTIFY_BUTTON_IM, ggp_pubdir_search_results_im);
-	purple_notify_searchresults_button_add(results,
-		PURPLE_NOTIFY_BUTTON_INFO, ggp_pubdir_search_results_info);
-	purple_notify_searchresults_button_add_labeled(results, _("New search"),
-		ggp_pubdir_search_results_new);
-	if (next_offset != 0)
-		purple_notify_searchresults_button_add(results,
-			PURPLE_NOTIFY_BUTTON_CONTINUE,
-			ggp_pubdir_search_results_next);
-
-	if (!form->display_handle)
-		form->display_handle = purple_notify_searchresults(gc,
-			GGP_PUBDIR_SEARCH_TITLE, _("Search results"), NULL,
-			results, ggp_pubdir_search_results_close, form);
-	else
-		purple_notify_searchresults_new_rows(gc, results,
-			form->display_handle);
-	g_assert(form->display_handle);
-}
-
-static void
-ggp_pubdir_search_request(PurpleConnection *gc, PurpleRequestPage *page) {
-	ggp_pubdir_search_form *form = g_new0(ggp_pubdir_search_form, 1);
-
-	purple_debug_info("gg", "ggp_pubdir_search_request");
-
-	form->nick = g_strdup(purple_request_page_get_string(page, "name"));
-	form->city = g_strdup(purple_request_page_get_string(page, "city"));
-	form->gender =
-	        GPOINTER_TO_INT(purple_request_page_get_choice(page, "gender"));
-	form->offset = 0;
-	form->limit = GGP_PUBDIR_SEARCH_PER_PAGE;
-
-	ggp_pubdir_search_execute(gc, form, ggp_pubdir_search_results_display,
-	                          form);
-}
-
-void
-ggp_pubdir_search(PurpleConnection *gc, const ggp_pubdir_search_form *form)
-{
-	PurpleRequestPage *page;
-	PurpleRequestGroup *group;
-	PurpleRequestField *field;
-	PurpleRequestFieldChoice *choice;
-
-	purple_debug_info("gg", "ggp_pubdir_search");
-
-	page = purple_request_page_new();
-	group = purple_request_group_new(NULL);
-	purple_request_page_add_group(page, group);
-
-	field = purple_request_field_string_new("name", _("Name"),
-	                                        form ? form->nick : NULL, FALSE);
-	purple_request_group_add_field(group, field);
-
-	field = purple_request_field_string_new("city", _("City"),
-	                                        form ? form->city : NULL, FALSE);
-	purple_request_group_add_field(group, field);
-
-	field = purple_request_field_choice_new(
-	        "gender", _("Gender"), form ? GINT_TO_POINTER(form->gender) : NULL);
-	choice = PURPLE_REQUEST_FIELD_CHOICE(field);
-	purple_request_field_choice_add(choice, _("Male or female"), NULL);
-	purple_request_field_choice_add(choice, _("Male"),
-	                                GINT_TO_POINTER(GGP_PUBDIR_GENDER_MALE));
-	purple_request_field_choice_add(choice, _("Female"),
-	                                GINT_TO_POINTER(GGP_PUBDIR_GENDER_FEMALE));
-	purple_request_group_add_field(group, field);
-
-	purple_request_fields(gc, _("Find buddies"), _("Find buddies"),
-	                      _("Please, enter your search criteria below"), page,
-	                      _("OK"), G_CALLBACK(ggp_pubdir_search_request),
-	                      _("Cancel"), NULL,
-	                      purple_request_cpar_from_connection(gc), gc);
-}
-
-/*******************************************************************************
- * Own profile.
- ******************************************************************************/
-
-static void
-ggp_pubdir_set_info_got_response(GObject *source, GAsyncResult *result,
-                                 gpointer data)
-{
-	SoupMessage *msg = data;
-	GBytes *response_body = NULL;
-	const char *buffer = NULL;
-	gsize size = 0;
-	GError *error = NULL;
-
-	if (!SOUP_STATUS_IS_SUCCESSFUL(soup_message_get_status(msg))) {
-		purple_debug_error("gg", "ggp_pubdir_set_info_got_response: failed");
-		g_object_unref(msg);
-		return;
-	}
-	g_clear_object(&msg);
-
-	response_body = soup_session_send_and_read_finish(SOUP_SESSION(source),
-	                                                  result, &error);
-	if (response_body == NULL) {
-		purple_debug_error("gg",
-		                   "ggp_pubdir_set_info_got_response: failed: %s",
-		                   error->message);
-		g_error_free(error);
-		return;
-	}
-
-	buffer = g_bytes_get_data(response_body, &size);
-	purple_debug_info("gg", "ggp_pubdir_set_info_got_response: [%.*s]",
-	                  (int)size, buffer);
-	/* <result><status>0</status></result> */
-
-	/* TODO: notify about failure */
-
-	g_bytes_unref(response_body);
-}
-
-static void ggp_pubdir_set_info_got_token(PurpleConnection *gc,
-	const gchar *token, gpointer _record)
-{
-	ggp_pubdir_record *record = _record;
-	GGPInfo *info = NULL;
-	SoupMessage *msg;
-	GBytes *body = NULL;
-	gchar *url;
-	gchar *request_data;
-	gchar *name, *surname, *city;
-	gchar *bday;
-	uin_t uin = record->uin;
-
-	PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
-
-	if (!token) {
-		/* TODO: notify about failure */
-		ggp_pubdir_record_free(record, 1);
-		return;
-	}
-
-	info = purple_connection_get_protocol_data(gc);
-
-	name = g_uri_escape_string(record->first_name, NULL, FALSE);
-	surname = g_uri_escape_string(record->last_name, NULL, FALSE);
-	city = g_uri_escape_string(record->city, NULL, FALSE);
-	bday = g_date_time_format(record->birth, "%Y-%m-%d");
-
-	request_data = g_strdup_printf(
-		"name=%s&"
-		"surname=%s&"
-		"birth=%sT10:00:00%%2B00:00&"
-		"birth_priv=2&"
-		"gender=%d&"
-		"gender_priv=2&"
-		"city=%s&"
-		"province=%d",
-		name, surname,
-		bday,
-		record->gender,
-		city,
-		record->province);
-
-	g_free(name);
-	g_free(surname);
-	g_free(city);
-	g_free(bday);
-
-	if (purple_debug_is_verbose() && purple_debug_is_unsafe()) {
-		purple_debug_misc("gg", "ggp_pubdir_set_info_got_token: "
-			"query [%s]\n", request_data);
-	}
-
-	url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u.xml", uin);
-	msg = soup_message_new("PUT", url);
-	soup_message_headers_replace(soup_message_get_request_headers(msg),
-	                             "Authorization", token);
-	body = g_bytes_new_take(request_data, strlen(request_data));
-	soup_message_set_request_body_from_bytes(msg,
-	                                         "application/x-www-form-urlencoded",
-	                                         body);
-	g_bytes_unref(body);
-	soup_session_send_and_read_async(info->http, msg, G_PRIORITY_DEFAULT, NULL,
-	                                 ggp_pubdir_set_info_got_response, msg);
-
-	g_free(url);
-	ggp_pubdir_record_free(record, 1);
-}
-
-static void
-ggp_pubdir_set_info_request(PurpleConnection *gc, PurpleRequestPage *page)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
-	gchar *url;
-	uin_t uin = ggp_str_to_uin(purple_contact_info_get_username(info));
-	ggp_pubdir_record *record = g_new0(ggp_pubdir_record, 1);
-	gchar *birth_s;
-
-	purple_debug_info("gg", "ggp_pubdir_set_info_request");
-
-	record->uin = uin;
-	record->first_name = g_strdup(purple_request_page_get_string(page,
-	                                                             "first_name"));
-	record->last_name = g_strdup(purple_request_page_get_string(page,
-	                                                            "last_name"));
-	record->gender = GPOINTER_TO_INT(purple_request_page_get_choice(page,
-	                                                                "gender"));
-	record->city = g_strdup(purple_request_page_get_string(page, "city"));
-	record->province = GPOINTER_TO_INT(purple_request_page_get_choice(page,
-	                                                                  "province"));
-
-	birth_s = g_strdup_printf("%sT10:00:00+00:00",
-	                          purple_request_page_get_string(page, "birth_date"));
-	record->birth = g_date_time_new_from_iso8601(birth_s, NULL);
-	g_free(birth_s);
-	purple_debug_info("gg", "ggp_pubdir_set_info_request: birth [%lu][%s]",
-	                  g_date_time_to_unix(record->birth),
-	                  purple_request_page_get_string(page, "birth_date"));
-
-	url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u.xml", uin);
-	ggp_oauth_request(gc, ggp_pubdir_set_info_got_token, record, "PUT", url);
-	g_free(url);
-}
-
-static void
-ggp_pubdir_set_info_dialog(PurpleConnection *gc, int records_count,
-                           const ggp_pubdir_record *records,
-                           G_GNUC_UNUSED int next_offset,
-                           G_GNUC_UNUSED gpointer data)
-{
-	PurpleRequestPage *page;
-	PurpleRequestGroup *group;
-	PurpleRequestField *field;
-	PurpleRequestFieldChoice *choice;
-	gchar *bday = NULL;
-	gsize i;
-	const ggp_pubdir_record *record;
-
-	purple_debug_info("gg", "ggp_pubdir_set_info_dialog (record: %d)",
-	                  records_count);
-
-	record = (records_count == 1 ? &records[0] : NULL);
-
-	page = purple_request_page_new();
-	group = purple_request_group_new(NULL);
-	purple_request_page_add_group(page, group);
-
-	field = purple_request_field_string_new("first_name", _("First name"),
-	                                        record ? record->first_name : NULL,
-	                                        FALSE);
-	purple_request_group_add_field(group, field);
-
-	field = purple_request_field_string_new("last_name", _("Last name"),
-	                                        record ? record->last_name : NULL,
-	                                        FALSE);
-	purple_request_group_add_field(group, field);
-
-	field = purple_request_field_choice_new(
-	        "gender", _("Gender"),
-	        record ? GINT_TO_POINTER(record->gender)
-	               : GGP_PUBDIR_GENDER_UNSPECIFIED);
-	choice = PURPLE_REQUEST_FIELD_CHOICE(field);
-	purple_request_field_set_required(field, TRUE);
-	purple_request_field_choice_add(choice, _("Male"),
-	                                GINT_TO_POINTER(GGP_PUBDIR_GENDER_MALE));
-	purple_request_field_choice_add(choice, _("Female"),
-	                                GINT_TO_POINTER(GGP_PUBDIR_GENDER_FEMALE));
-	purple_request_group_add_field(group, field);
-
-	if(record != NULL && record->birth != NULL) {
-		bday = g_date_time_format(record->birth, "%Y-%m-%d");
-	}
-
-	field = purple_request_field_string_new(
-	        "birth_date", _("Birth Day"), bday,
-	        FALSE);
-	g_free(bday);
-	purple_request_field_set_required(field, TRUE);
-	purple_request_group_add_field(group, field);
-
-	field = purple_request_field_string_new(
-	        "city", _("City"), record ? record->city : NULL, FALSE);
-	purple_request_group_add_field(group, field);
-
-	/* Translators: This word is basically used to describe a Polish
-	   province. Gadu-Gadu users outside of Poland might choose to enter some
-	   equivalent value for themselves. For example, users in the USA might
-	   use their state (e.g. New York). If there is an equivalent term for
-	   your language, feel free to use it. Otherwise it's probably acceptable
-	   to leave it changed or transliterate it into your alphabet. */
-	field = purple_request_field_choice_new("province", _("Voivodeship"), 0);
-	choice = PURPLE_REQUEST_FIELD_CHOICE(field);
-	purple_request_group_add_field(group, field);
-	for (i = 0; i < ggp_pubdir_provinces_count; i++) {
-		purple_request_field_choice_add(choice, ggp_pubdir_provinces[i],
-		                                GINT_TO_POINTER(i));
-		if (record && i == record->province) {
-			purple_request_field_choice_set_value(choice, GINT_TO_POINTER(i));
-			purple_request_field_choice_set_default_value(choice,
-			                                              GINT_TO_POINTER(i));
-		}
-	}
-
-	purple_request_fields(gc, _("Set User Info"), _("Set User Info"), NULL,
-	                      page, _("OK"),
-	                      G_CALLBACK(ggp_pubdir_set_info_request), _("Cancel"),
-	                      NULL, purple_request_cpar_from_connection(gc), gc);
-}
-
-void
-ggp_pubdir_set_info(PurpleConnection *gc)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
-
-	ggp_pubdir_get_info(gc,
-	                    ggp_str_to_uin(purple_contact_info_get_username(info)),
-	                    ggp_pubdir_set_info_dialog, NULL);
-}
diff --git a/libpurple/protocols/gg/purplew.h b/libpurple/protocols/gg/purplew.h
deleted file mode 100644
--- a/libpurple/protocols/gg/purplew.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_PURPLEW_H
-#define PURPLE_GG_PURPLEW_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-/**
- * Adds an input handler in purple event loop for http request.
- *
- * @see purple_input_add
- *
- * @param http_req  Http connection to watch.
- * @param func      The callback function for data.
- * @param user_data User-specified data.
- *
- * @return The resulting handle (will be greater than 0).
- */
-guint ggp_purplew_http_input_add(struct gg_http *http_req,
-	PurpleInputFunction func, gpointer user_data);
-
-typedef void (*ggp_purplew_request_processing_cancel_cb)(PurpleConnection *gc,
-	void *user_data);
-
-typedef struct
-{
-	PurpleConnection *gc;
-	ggp_purplew_request_processing_cancel_cb cancel_cb;
-	void *request_handle;
-	void *user_data;
-} ggp_purplew_request_processing_handle;
-
-ggp_purplew_request_processing_handle * ggp_purplew_request_processing(
-	PurpleConnection *gc, const gchar *msg, void *user_data,
-	ggp_purplew_request_processing_cancel_cb oncancel);
-
-void ggp_purplew_request_processing_done(
-	ggp_purplew_request_processing_handle *handle);
-
-/* ignores default group */
-PurpleGroup * ggp_purplew_buddy_get_group_only(PurpleBuddy *buddy);
-
-GList * ggp_purplew_group_get_buddies(PurpleGroup *group, PurpleAccount *account);
-
-/* you must g_free returned list */
-GList * ggp_purplew_account_get_groups(PurpleAccount *account, gboolean exclusive);
-
-#endif /* PURPLE_GG_PURPLEW_H */
diff --git a/libpurple/protocols/gg/purplew.c b/libpurple/protocols/gg/purplew.c
deleted file mode 100644
--- a/libpurple/protocols/gg/purplew.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "purplew.h"
-
-#include "tcpsocket.h"
-
-#include <glib/gi18n-lib.h>
-
-guint ggp_purplew_http_input_add(struct gg_http *http_req,
-	PurpleInputFunction func, gpointer user_data)
-{
-	if (purple_debug_is_verbose()) {
-		purple_debug_misc("gg", "ggp_purplew_http_input_add: "
-			"[req=%p, fd=%d, cond=%d]\n",
-			http_req, http_req->fd, http_req->check);
-	}
-	return purple_input_add(http_req->fd,
-		ggp_tcpsocket_inputcond_gg_to_purple(http_req->check),
-		func, user_data);
-}
-
-static void
-ggp_purplew_request_processing_cancel(ggp_purplew_request_processing_handle *handle,
-                                      G_GNUC_UNUSED gint id)
-{
-	handle->cancel_cb(handle->gc, handle->user_data);
-	g_free(handle);
-}
-
-ggp_purplew_request_processing_handle * ggp_purplew_request_processing(
-	PurpleConnection *gc, const gchar *msg, void *user_data,
-	ggp_purplew_request_processing_cancel_cb cancel_cb)
-{
-	ggp_purplew_request_processing_handle *handle =
-		g_new(ggp_purplew_request_processing_handle, 1);
-
-	handle->gc = gc;
-	handle->cancel_cb = cancel_cb;
-	handle->user_data = user_data;
-	handle->request_handle = purple_request_action(gc, _("Please wait..."),
-		(msg ? msg : _("Please wait...")), NULL,
-		PURPLE_DEFAULT_ACTION_NONE,
-		purple_request_cpar_from_connection(gc), handle, 1,
-		_("Cancel"), G_CALLBACK(ggp_purplew_request_processing_cancel));
-
-	return handle;
-}
-
-void ggp_purplew_request_processing_done(
-	ggp_purplew_request_processing_handle *handle)
-{
-	purple_request_close(PURPLE_REQUEST_ACTION, handle->request_handle);
-	g_free(handle);
-}
-
-PurpleGroup * ggp_purplew_buddy_get_group_only(PurpleBuddy *buddy)
-{
-	PurpleGroup *group = purple_buddy_get_group(buddy);
-	if (!group)
-		return NULL;
-	if (0 == g_strcmp0(PURPLE_BLIST_DEFAULT_GROUP_NAME,
-		purple_group_get_name(group)))
-	{
-		return NULL;
-	}
-	if (0 == g_strcmp0("Buddies", purple_group_get_name(group)))
-		return NULL;
-	return group;
-}
-
-GList * ggp_purplew_group_get_buddies(PurpleGroup *group, PurpleAccount *account)
-{
-	GList *buddies = NULL;
-	PurpleBlistNode *gnode, *cnode, *bnode;
-
-	g_return_val_if_fail(group != NULL, NULL);
-
-	gnode = PURPLE_BLIST_NODE(group);
-	for (cnode = gnode->child; cnode; cnode = cnode->next) {
-		if (!PURPLE_IS_META_CONTACT(cnode))
-			continue;
-		for (bnode = cnode->child; bnode; bnode = bnode->next) {
-			PurpleBuddy *buddy;
-			if (!PURPLE_IS_BUDDY(bnode))
-				continue;
-
-			buddy = PURPLE_BUDDY(bnode);
-			if (account == NULL ||
-				purple_buddy_get_account(buddy) == account)
-			{
-				buddies = g_list_append(buddies, buddy);
-			}
-		}
-	}
-
-	return buddies;
-}
-
-GList * ggp_purplew_account_get_groups(PurpleAccount *account, gboolean exclusive)
-{
-	PurpleBlistNode *bnode;
-	GList *groups = NULL;
-	for (bnode = purple_blist_get_default_root(); bnode;
-	     bnode = bnode->next) {
-		PurpleGroup *group;
-		GSList *accounts;
-		gboolean have_specified = FALSE, have_others = FALSE;
-
-		if (!PURPLE_IS_GROUP(bnode))
-			continue;
-
-		group = PURPLE_GROUP(bnode);
-		for (accounts = purple_group_get_accounts(group); accounts;
-			accounts = g_slist_delete_link(accounts, accounts))
-		{
-			if (accounts->data == account)
-				have_specified = TRUE;
-			else
-				have_others = TRUE;
-		}
-
-		if (have_specified && (!exclusive || !have_others))
-			groups = g_list_append(groups, group);
-	}
-	return groups;
-}
diff --git a/libpurple/protocols/gg/resolver-purple.h b/libpurple/protocols/gg/resolver-purple.h
deleted file mode 100644
--- a/libpurple/protocols/gg/resolver-purple.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_RESOLVER_PURPLE_H
-#define PURPLE_GG_RESOLVER_PURPLE_H
-
-/**
- * Registers custom resolver for libgadu, that uses libpurple for DNS queries.
- */
-void ggp_resolver_purple_setup(void);
-
-#endif /* PURPLE_GG_RESOLVER_PURPLE_H */
diff --git a/libpurple/protocols/gg/resolver-purple.c b/libpurple/protocols/gg/resolver-purple.c
deleted file mode 100644
--- a/libpurple/protocols/gg/resolver-purple.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "libpurple/glibcompat.h"
-
-#include <libgadu.h>
-#include "resolver-purple.h"
-
-#include <gio/gio.h>
-
-static int ggp_resolver_purple_start(int *fd, void **private_data,
-	const char *hostname);
-
-static void ggp_resolver_purple_cleanup(void **private_data, int force);
-
-static void ggp_resolver_purple_cb(GObject *sender, GAsyncResult *res, gpointer data);
-
-typedef struct
-{
-	GCancellable *cancellable;
-
-	/**
-	 * File descriptors:
-	 *  pipes[0] - for reading
-	 *  pipes[1] - for writing
-	 */
-	int pipes[2];
-} ggp_resolver_purple_data;
-
-
-extern void ggp_resolver_purple_setup(void)
-{
-	if (gg_global_set_custom_resolver(ggp_resolver_purple_start,
-		ggp_resolver_purple_cleanup) != 0)
-	{
-		purple_debug_error("gg", "failed to set custom resolver\n");
-	}
-}
-
-void ggp_resolver_purple_cb(GObject *sender, GAsyncResult *res, gpointer cbdata) {
-	GList *addresses = NULL, *in_addrs = NULL, *l = NULL;
-	GError *error = NULL;
-	gsize native_size = 0; /* this is kind of dirty, but it'll be initialized before we use it */
-
-	ggp_resolver_purple_data *data = (ggp_resolver_purple_data*)cbdata;
-	const int fd = data->pipes[1];
-
-	addresses = g_resolver_lookup_by_name_finish(G_RESOLVER(sender),
-			res, &error);
-	if(addresses == NULL) {
-		purple_debug_error("gg", "ggp_resolver_purple_cb failed: %s\n",
-			error->message);
-
-		g_error_free(error);
-	} else {
-		purple_debug_misc("gg", "ggp_resolver_purple_cb succeeded: (%p, %p)\n",
-			addresses, cbdata);
-	}
-
-	g_object_unref(data->cancellable);
-	data->cancellable = NULL;
-
-	for(l = addresses; l; l = l->next) {
-		GInetAddress *inet_address = G_INET_ADDRESS(l->data);
-		GSocketFamily family = G_SOCKET_FAMILY_INVALID;
-		gchar *ip_address = g_inet_address_to_string(inet_address);
-
-		family = g_inet_address_get_family(inet_address);
-
-		switch(family) {
-			case G_SOCKET_FAMILY_IPV4:
-				purple_debug_misc("gg", "ggp_resolver_purple_cb "
-					"ipv4: %s\n", ip_address);
-
-				native_size = g_inet_address_get_native_size(inet_address);
-				in_addrs = g_list_append(in_addrs, g_memdup2(g_inet_address_to_bytes(inet_address), native_size));
-
-				break;
-			case G_SOCKET_FAMILY_IPV6:
-				purple_debug_misc("gg", "ggp_resolver_purple_cb "
-					"ipv6 (ignore): %s\n", ip_address);
-
-				break;
-			default:
-				purple_debug_warning("gg", "ggp_resolver_purple_cb "
-					"unexpected sa_family: %d\n",
-					family);
-
-				break;
-		}
-
-		g_free(ip_address);
-	}
-
-	for(l = in_addrs; l; l = l->next) {
-		gint write_size = native_size;
-		if(write(fd, l->data, write_size) != write_size) {
-			purple_debug_error("gg",
-				"ggp_resolver_purple_cb write error on %p\n", l->data);
-		}
-
-		g_free(l->data);
-	}
-
-	g_list_free(in_addrs);
-	g_resolver_free_addresses(addresses);
-}
-
-int ggp_resolver_purple_start(int *fd, void **private_data,
-	const char *hostname)
-{
-	ggp_resolver_purple_data *data;
-	GResolver *resolver;
-
-	purple_debug_misc("gg", "ggp_resolver_purple_start(%p, %p, \"%s\")\n",
-		fd, private_data, hostname);
-
-	data = g_new0(ggp_resolver_purple_data, 1);
-	*private_data = (void*)data;
-	data->cancellable = NULL;
-	data->pipes[0] = 0;
-	data->pipes[1] = 0;
-
-	if (purple_input_pipe(data->pipes) != 0) {
-		purple_debug_error("gg", "ggp_resolver_purple_start: "
-			"unable to create pipe\n");
-		ggp_resolver_purple_cleanup(private_data, 0);
-		return -1;
-	}
-
-	*fd = data->pipes[0];
-
-	/* account and port is unknown in this context */
-	data->cancellable = g_cancellable_new();
-
-	resolver = g_resolver_get_default();
-	g_resolver_lookup_by_name_async(resolver,
-	                                hostname,
-	                                data->cancellable,
-	                                ggp_resolver_purple_cb,
-	                                (gpointer)data);
-	g_object_unref(resolver);
-
-	if (!data->cancellable) {
-		purple_debug_error("gg", "ggp_resolver_purple_start: "
-			"unable to call purple_dnsquery_a\n");
-		ggp_resolver_purple_cleanup(private_data, 0);
-		return -1;
-	}
-
-	return 0;
-}
-
-void ggp_resolver_purple_cleanup(void **private_data, int force)
-{
-	ggp_resolver_purple_data *data =
-		(ggp_resolver_purple_data*)(*private_data);
-
-	purple_debug_misc("gg", "ggp_resolver_purple_cleanup(%p, %d)\n",
-		private_data, force);
-
-	if (!data)
-		return;
-	*private_data = NULL;
-
-	if (G_IS_CANCELLABLE(data->cancellable)) {
-		g_cancellable_cancel(data->cancellable);
-
-		g_object_unref(data->cancellable);
-	}
-
-	if (data->pipes[0])
-		close(data->pipes[0]);
-	if (data->pipes[1])
-		close(data->pipes[1]);
-
-	g_free(data);
-}
diff --git a/libpurple/protocols/gg/resources/gg.gresource.xml b/libpurple/protocols/gg/resources/gg.gresource.xml
deleted file mode 100644
--- a/libpurple/protocols/gg/resources/gg.gresource.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<gresources>
-  <gresource prefix="/im/pidgin/libpurple/gg">
-    <file>icons/16x16/apps/im-gadu-gadu.png</file>
-    <file>icons/16x16/apps/scalable/im-gadu-gadu.svg</file>
-    <file>icons/22x22/apps/im-gadu-gadu.png</file>
-    <file>icons/22x22/apps/scalable/im-gadu-gadu.svg</file>
-    <file>icons/48x48/apps/im-gadu-gadu.png</file>
-    <file>icons/scalable/apps/im-gadu-gadu.svg</file>
-  </gresource>
-</gresources>
diff --git a/libpurple/protocols/gg/resources/icons/16x16/apps/im-gadu-gadu.png b/libpurple/protocols/gg/resources/icons/16x16/apps/im-gadu-gadu.png
deleted file mode 100644
index a7f02acc7478691110249cadd7c1844524a5f187..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/libpurple/protocols/gg/resources/icons/16x16/apps/scalable/im-gadu-gadu.svg b/libpurple/protocols/gg/resources/icons/16x16/apps/scalable/im-gadu-gadu.svg
deleted file mode 100644
--- a/libpurple/protocols/gg/resources/icons/16x16/apps/scalable/im-gadu-gadu.svg
+++ /dev/null
@@ -1,365 +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="svg10335"
-   sodipodi:version="0.32"
-   inkscape:version="0.46"
-   sodipodi:docname="emote-select.svg"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape"
-   inkscape:export-filename="/home/hbons/Bureaublad/gadu-gadu.png"
-   inkscape:export-xdpi="90"
-   inkscape:export-ydpi="90">
-  <defs
-     id="defs10337">
-    <linearGradient
-       id="linearGradient8687"
-       inkscape:collect="always">
-      <stop
-         id="stop8689"
-         offset="0"
-         style="stop-color:#f57575;stop-opacity:1" />
-      <stop
-         id="stop8691"
-         offset="1"
-         style="stop-color:#fea523;stop-opacity:0;" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient8653">
-      <stop
-         style="stop-color:#a40000;stop-opacity:1;"
-         offset="0"
-         id="stop8655" />
-      <stop
-         style="stop-color:#ef2929;stop-opacity:1"
-         offset="1"
-         id="stop8657" />
-    </linearGradient>
-    <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="perspective44" />
-    <linearGradient
-       id="linearGradient11170"
-       inkscape:collect="always">
-      <stop
-         id="stop11172"
-         offset="0"
-         style="stop-color:#000000;stop-opacity:1" />
-      <stop
-         id="stop11174"
-         offset="1"
-         style="stop-color:#2e3436;stop-opacity:0;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient11164"
-       inkscape:collect="always">
-      <stop
-         id="stop11166"
-         offset="0"
-         style="stop-color:#000000;stop-opacity:1" />
-      <stop
-         id="stop11168"
-         offset="1"
-         style="stop-color:#2e3436;stop-opacity:0;" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient22870">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop22872" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop22874" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient22870"
-       id="linearGradient20933"
-       gradientUnits="userSpaceOnUse"
-       x1="-11.187567"
-       y1="-14.181667"
-       x2="31.90255"
-       y2="35.477989" />
-    <linearGradient
-       id="linearGradient11461"
-       inkscape:collect="always">
-      <stop
-         id="stop11463"
-         offset="0"
-         style="stop-color:#fbfeac;stop-opacity:1" />
-      <stop
-         id="stop11465"
-         offset="1"
-         style="stop-color:#eedb3c;stop-opacity:0;" />
-    </linearGradient>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient11461"
-       id="radialGradient20931"
-       gradientUnits="userSpaceOnUse"
-       cx="11.806158"
-       cy="10.04414"
-       fx="11.88395"
-       fy="6.1128922"
-       r="10.561975"
-       gradientTransform="matrix(1.9034559,3.0329373e-8,-4.2282289e-8,2.6533656,-10.666343,-17.069444)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient22526"
-       id="linearGradient20942"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.8000001,0,0,0.8980646,-0.6999993,-2.2354831)"
-       x1="8.5062485"
-       y1="9.7487373"
-       x2="8.7451591"
-       y2="10.765122" />
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient22526">
-      <stop
-         style="stop-color:#f57575;stop-opacity:1"
-         offset="0"
-         id="stop22528" />
-      <stop
-         style="stop-color:#fea523;stop-opacity:0;"
-         offset="1"
-         id="stop22530" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient8687"
-       id="linearGradient20915"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(7.000002,1)"
-       x1="9.2937651"
-       y1="8.8493233"
-       x2="8.7171106"
-       y2="10" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient11164"
-       id="linearGradient11158"
-       gradientUnits="userSpaceOnUse"
-       x1="9.432662"
-       y1="9.6526775"
-       x2="10.732871"
-       y2="9.6526775" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient11170"
-       id="linearGradient11160"
-       gradientUnits="userSpaceOnUse"
-       x1="9.432662"
-       y1="9.6526775"
-       x2="10.732871"
-       y2="9.6526775" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient8653"
-       id="linearGradient8659"
-       x1="14.605568"
-       y1="14.845765"
-       x2="9.3490162"
-       y2="3.9909718"
-       gradientUnits="userSpaceOnUse" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="31.392433"
-     inkscape:cx="15.513311"
-     inkscape:cy="8.506005"
-     inkscape:current-layer="layer1"
-     showgrid="true"
-     inkscape:grid-bbox="true"
-     inkscape:document-units="px"
-     inkscape:snap-nodes="false"
-     inkscape:snap-bbox="true"
-     objecttolerance="10"
-     gridtolerance="10"
-     inkscape:window-width="1440"
-     inkscape:window-height="847"
-     inkscape:window-x="0"
-     inkscape:window-y="0">
-    <inkscape:grid
-       type="xygrid"
-       id="grid10376"
-       visible="true"
-       enabled="true" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata10340">
-    <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">
-    <rect
-       style="opacity:1;fill:#a40000;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="rect8683"
-       width="2.0000002"
-       height="2"
-       x="12"
-       y="12"
-       rx="1"
-       ry="1" />
-    <rect
-       style="opacity:1;fill:#a40000;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="rect8685"
-       width="2.0000002"
-       height="2"
-       x="2"
-       y="12"
-       rx="1"
-       ry="1" />
-    <rect
-       style="opacity:1;fill:#ef2929;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="rect8681"
-       width="2.0000002"
-       height="2"
-       x="12"
-       y="2"
-       rx="1"
-       ry="1" />
-    <rect
-       style="opacity:1;fill:#ef2929;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="rect8679"
-       width="2.0000002"
-       height="2"
-       x="1.9999998"
-       y="2"
-       rx="1"
-       ry="1" />
-    <rect
-       style="opacity:1;fill:#a40000;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="rect8675"
-       width="2.0000002"
-       height="2"
-       x="14"
-       y="7"
-       rx="1"
-       ry="1" />
-    <rect
-       style="opacity:1;fill:#ef2929;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="rect8671"
-       width="2.0000002"
-       height="2"
-       x="-2.3841858e-07"
-       y="7"
-       rx="1"
-       ry="1" />
-    <rect
-       style="opacity:1;fill:#a40000;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="rect8665"
-       width="2.0000002"
-       height="2"
-       x="7"
-       y="14"
-       rx="1"
-       ry="1" />
-    <rect
-       style="opacity:1;fill:#ef2929;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="rect8663"
-       width="2.0000002"
-       height="2"
-       x="7"
-       y="0"
-       rx="1"
-       ry="1" />
-    <rect
-       inkscape:label="22x22"
-       y="-0.90471238"
-       x="-0.90471238"
-       height="17.809425"
-       width="17.809425"
-       id="rect6749"
-       style="opacity:0;fill:#d3d7cf;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-    <path
-       transform="matrix(0.651488,0,0,0.651488,0.30843,0.8446922)"
-       d="M 21.781414,10.983024 A 9.975256,9.975256 0 1 1 1.8309021,10.983024 A 9.975256,9.975256 0 1 1 21.781414,10.983024 z"
-       sodipodi:ry="9.975256"
-       sodipodi:rx="9.975256"
-       sodipodi:cy="10.983024"
-       sodipodi:cx="11.806158"
-       id="path17960"
-       style="opacity:1;fill:#fcaf3e;fill-opacity:1;stroke:url(#linearGradient8659);stroke-width:1.53875661000000008;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;enable-background:new"
-       sodipodi:type="arc" />
-    <path
-       transform="matrix(0.5513643,0,0,0.5513643,1.490506,1.944353)"
-       d="M 21.781414,10.983024 A 9.975256,9.975256 0 1 1 1.8309021,10.983024 A 9.975256,9.975256 0 1 1 21.781414,10.983024 z"
-       sodipodi:ry="9.975256"
-       sodipodi:rx="9.975256"
-       sodipodi:cy="10.983024"
-       sodipodi:cx="11.806158"
-       id="path17964"
-       style="opacity:1;fill:url(#radialGradient20931);fill-opacity:1;stroke:url(#linearGradient20933);stroke-width:1.81368327;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;enable-background:new"
-       sodipodi:type="arc" />
-    <path
-       id="path17966"
-       d="M 8.5000005,6.7451615 C 8.5000005,7.9844904 7.604002,8.9903231 6.500001,8.9903231 C 5.3959999,8.9903231 4.5000001,7.9844904 4.5000001,6.7451615 C 4.5000001,5.5058325 5.3959999,4.5000005 6.500001,4.5000005 C 7.604002,4.5000005 8.5000005,5.5058325 8.5000005,6.7451615 z"
-       style="opacity:1;fill:#eeeeec;fill-opacity:1;stroke:url(#linearGradient20942);stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;display:inline;enable-background:new" />
-    <path
-       sodipodi:nodetypes="cscsc"
-       id="path17974"
-       d="M 11,10 C 10.887023,11.226829 9.4422911,12 8.0000003,12 C 6.5577095,12 5.2085418,11.396721 5,10 C 5.6322481,10.739405 6.7426661,11.065616 8.0000003,11.065616 C 9.2573337,11.065616 10.367752,10.739405 11,10 z"
-       style="opacity:1;fill:#b40c0c;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;enable-background:new" />
-    <a
-       style="opacity:1;display:inline;enable-background:new"
-       id="a22276"
-       transform="matrix(0.8295523,0,0,0.9130993,-3.698956,-3.261344)">
-      <path
-         style="opacity:1;fill:#eeeeec;fill-opacity:1;stroke:url(#linearGradient20915);stroke-width:1.14899766;stroke-miterlimit:4;stroke-opacity:1;display:inline;enable-background:new"
-         d="M 18.5,11 C 18.5,12.38 17.380001,13.5 16,13.5 C 14.62,13.5 13.5,12.38 13.5,11 C 13.5,9.62 14.62,8.5 16,8.5 C 17.380001,8.5 18.5,9.62 18.5,11 z"
-         id="path22835" />
-    </a>
-    <path
-       transform="matrix(0.9747196,0,0,0.5150957,-2.4615398,2.0279474)"
-       d="M 10.732871,9.6526775 A 1.0259361,1.9413869 0 1 1 8.6809988,9.6526775 A 1.0259361,1.9413869 0 1 1 10.732871,9.6526775 z"
-       sodipodi:ry="1.9413869"
-       sodipodi:rx="1.0259361"
-       sodipodi:cy="9.6526775"
-       sodipodi:cx="9.7069349"
-       id="path17968"
-       style="opacity:1;fill:url(#linearGradient11160);fill-opacity:1;stroke:none;stroke-width:0.98640186;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;enable-background:new"
-       sodipodi:type="arc" />
-    <path
-       transform="matrix(-0.9747196,0,0,0.5150957,18.46154,2.0279474)"
-       d="M 10.732871,9.6526775 A 1.0259361,1.9413869 0 1 1 8.6809988,9.6526775 A 1.0259361,1.9413869 0 1 1 10.732871,9.6526775 z"
-       sodipodi:ry="1.9413869"
-       sodipodi:rx="1.0259361"
-       sodipodi:cy="9.6526775"
-       sodipodi:cx="9.7069349"
-       id="path11156"
-       style="opacity:1;fill:url(#linearGradient11158);fill-opacity:1;stroke:none;stroke-width:0.98640186;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;enable-background:new"
-       sodipodi:type="arc" />
-  </g>
-</svg>
diff --git a/libpurple/protocols/gg/resources/icons/22x22/apps/im-gadu-gadu.png b/libpurple/protocols/gg/resources/icons/22x22/apps/im-gadu-gadu.png
deleted file mode 100644
index 388256c9053cc4ab532ca3bfe7615a8029f45495..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/libpurple/protocols/gg/resources/icons/22x22/apps/scalable/im-gadu-gadu.svg b/libpurple/protocols/gg/resources/icons/22x22/apps/scalable/im-gadu-gadu.svg
deleted file mode 100644
--- a/libpurple/protocols/gg/resources/icons/22x22/apps/scalable/im-gadu-gadu.svg
+++ /dev/null
@@ -1,206 +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/GUI/Tango/Gaim Refresh/protocols/22/scalable"
-   sodipodi:docname="gadu-gadu.svg"
-   inkscape:export-filename="/home/hbons/GUI/Tango/Gaim Refresh/protocols/22/gadu-gadu.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,0,0,-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="16.146337"
-     inkscape:cy="13.950539"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="true"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     fill="#fce94f"
-     inkscape:window-width="1268"
-     inkscape:window-height="971"
-     inkscape:window-x="6"
-     inkscape:window-y="25" />
-  <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">
-    <rect
-       style="opacity:1;fill:#c00;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2235"
-       width="2.0000005"
-       height="3.000001"
-       x="-0.29289341"
-       y="7.3639612"
-       transform="matrix(0.707107,-0.707107,0.707107,0.707107,-1,1)" />
-    <rect
-       style="opacity:1;fill:#c00;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2239"
-       width="2.0000033"
-       height="3.0000048"
-       x="-17.970564"
-       y="8.0710697"
-       transform="matrix(-0.707107,-0.707107,0.707107,-0.707107,-1,1)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.4;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.429666,0,0,1.267135,-3.866981,6.748756)" />
-    <rect
-       style="opacity:1;fill:#db2424;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2192"
-       width="1.9907103"
-       height="3"
-       x="12"
-       y="1"
-       transform="translate(-1,1)" />
-    <rect
-       style="opacity:1;fill:#db2424;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2203"
-       width="2"
-       height="3"
-       x="12"
-       y="18"
-       transform="translate(-1,1)" />
-    <rect
-       style="opacity:1;fill:#db2424;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2211"
-       width="2"
-       height="3.4306233"
-       x="-12"
-       y="3"
-       transform="matrix(0,-1,1,0,-1,1)" />
-    <rect
-       style="opacity:1;fill:#db2424;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2213"
-       width="2"
-       height="3"
-       x="-12"
-       y="20"
-       transform="matrix(0,-1,1,0,-1,1)" />
-    <rect
-       style="opacity:1;fill:#c00;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2237"
-       width="2.0000019"
-       height="3.0000029"
-       x="-0.29289412"
-       y="23.57716"
-       transform="matrix(0.707107,-0.707107,0.707107,0.707107,-1,1)" />
-    <rect
-       style="opacity:1;fill:#c00;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2241"
-       width="2.0000048"
-       height="3.0000067"
-       x="-17.970566"
-       y="-8.24265"
-       transform="matrix(-0.707107,-0.707107,0.707107,-0.707107,-1,1)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#fce94f;fill-opacity:1;stroke:#c00;stroke-width:0.73921776;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2217"
-       sodipodi:cx="8.0702047"
-       sodipodi:cy="8.0363102"
-       sodipodi:rx="5.5372205"
-       sodipodi:ry="5.5372205"
-       d="M 13.607425 8.0363102 A 5.5372205 5.5372205 0 1 1  2.5329843,8.0363102 A 5.5372205 5.5372205 0 1 1  13.607425 8.0363102 z"
-       transform="matrix(1.354195,0,0,1.35137,1.070845,1.157102)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.7;fill:none;fill-opacity:1;stroke:#c4a000;stroke-width:0.85407299;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.4848485"
-       id="path2222"
-       sodipodi:cx="8.0702047"
-       sodipodi:cy="8.0363102"
-       sodipodi:rx="5.5372205"
-       sodipodi:ry="5.5372205"
-       d="M 13.607425 8.0363102 A 5.5372205 5.5372205 0 1 1  2.5329843,8.0363102 A 5.5372205 5.5372205 0 1 1  13.607425 8.0363102 z"
-       transform="matrix(1.171277,0,0,1.170443,2.525066,2.61184)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2243"
-       sodipodi:cx="9.8489876"
-       sodipodi:cy="10.583912"
-       sodipodi:rx="1.2626907"
-       sodipodi:ry="1.0417198"
-       d="M 11.111678 10.583912 A 1.2626907 1.0417198 0 1 1  8.5862969,10.583912 A 1.2626907 1.0417198 0 1 1  11.111678 10.583912 z"
-       transform="matrix(0,1.18426,-0.959955,0,20.16009,-1.168408)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2245"
-       sodipodi:cx="9.8489876"
-       sodipodi:cy="10.583912"
-       sodipodi:rx="1.2626907"
-       sodipodi:ry="1.0417198"
-       d="M 11.111678 10.583912 A 1.2626907 1.0417198 0 1 1  8.5862969,10.583912 A 1.2626907 1.0417198 0 1 1  11.111678 10.583912 z"
-       transform="matrix(0,-1.187938,0.959951,0,3.839963,22.19998)" />
-    <path
-       style="opacity:1;fill:#555753;fill-opacity:1;stroke:none;stroke-width:1.10482609;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       d="M 17.0113,10.955978 C 17.0113,13.182328 15.218558,14.007827 13,14.007827 C 10.819611,14.007827 9.0496187,13.101106 8.9887006,10.913915 L 8,10.942262 C 8.0756746,13.659262 10.29145,15 13,15 C 15.758926,15 17.999999,13.724591 18,10.955978 L 17.0113,10.955978 z "
-       id="path2247"
-       sodipodi:nodetypes="csccscc"
-       transform="translate(-1,1)" />
-  </g>
-</svg>
diff --git a/libpurple/protocols/gg/resources/icons/48x48/apps/im-gadu-gadu.png b/libpurple/protocols/gg/resources/icons/48x48/apps/im-gadu-gadu.png
deleted file mode 100644
index cc2660dc78c3d13fa7721b1452e327d9862e9076..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/libpurple/protocols/gg/resources/icons/scalable/apps/im-gadu-gadu.svg b/libpurple/protocols/gg/resources/icons/scalable/apps/im-gadu-gadu.svg
deleted file mode 100644
--- a/libpurple/protocols/gg/resources/icons/scalable/apps/im-gadu-gadu.svg
+++ /dev/null
@@ -1,215 +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="48px"
-   height="48px"
-   id="svg1307"
-   sodipodi:version="0.32"
-   inkscape:version="0.46"
-   sodipodi:docbase="/home/hbons/Desktop/Gaim Refresh/protocols/48/scalable"
-   sodipodi:docname="gadu-gadu.svg"
-   inkscape:export-filename="/home/hbons/Desktop/Gaim Refresh/protocols/48/gadu-gadu.png"
-   inkscape:export-xdpi="90"
-   inkscape:export-ydpi="90"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape">
-  <defs
-     id="defs1309">
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient2447">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop2449" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop2451" />
-    </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.842757,5.698892e-16,-4.565819e-9,-0.35721,19.80716,14.19321)"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient2233">
-      <stop
-         style="stop-color:#eeeeec;stop-opacity:1;"
-         offset="0"
-         id="stop2235" />
-      <stop
-         style="stop-color:#eeeeec;stop-opacity:0;"
-         offset="1"
-         id="stop2237" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2233"
-       id="linearGradient2279"
-       gradientUnits="userSpaceOnUse"
-       x1="24.450865"
-       y1="5.1375499"
-       x2="24.450865"
-       y2="31.487988" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2447"
-       id="linearGradient2453"
-       x1="24.5"
-       y1="0.33943355"
-       x2="24.5"
-       y2="19.724688"
-       gradientUnits="userSpaceOnUse" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="15.004828"
-     inkscape:cx="40.53287"
-     inkscape:cy="23.900599"
-     inkscape:current-layer="layer1"
-     showgrid="true"
-     inkscape:grid-bbox="true"
-     inkscape:document-units="px"
-     fill="#ef2929"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     inkscape:window-width="1268"
-     inkscape:window-height="972"
-     inkscape:window-x="6"
-     inkscape:window-y="21" />
-  <metadata
-     id="metadata1312">
-    <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
-       sodipodi:type="arc"
-       style="opacity:0.5;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.160314,0,0,2.745459,-9.969125,9.788968)" />
-    <path
-       style="opacity:1;fill:#ef2929;fill-opacity:1;fill-rule:evenodd;stroke:#a40000;stroke-width:0.9999997;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       d="M 22.5,4.5130623 L 22.5,8.6366327 C 19.782905,9.0005399 17.277282,10.079925 15.21875,11.698071 L 12.0625,8.5116761 L 9.5,11.073287 L 12.6875,14.259683 C 11.068793,16.317502 9.9577835,18.791017 9.59375,21.50717 L 5.5,21.50717 L 5.5,25.505784 L 9.59375,25.505784 C 9.9535644,28.234089 11.062591,30.718808 12.6875,32.78451 L 9.5,35.970906 L 12.0625,38.501278 L 15.21875,35.346123 C 17.277282,36.964269 19.782905,38.043654 22.5,38.407561 L 22.5,42.499891 L 26.5,42.499891 L 26.5,38.407561 C 29.229107,38.042044 31.717452,36.944842 33.78125,35.314883 L 36.96875,38.501278 L 39.5,35.970906 L 36.3125,32.78451 C 37.936789,30.719597 39.014761,28.232873 39.375,25.505784 L 43.5,25.505784 L 43.5,21.50717 L 39.375,21.50717 C 39.010966,18.791018 37.931208,16.317502 36.3125,14.259683 L 39.5,11.073287 L 36.96875,8.5116761 L 33.78125,11.698071 L 33.75,11.698071 C 31.691468,10.079924 29.217095,9.0005401 26.5,8.6366327 L 26.5,4.5130623 L 22.5,4.5130623 z M 23.8125,11.354441 C 24.033452,11.344807 24.274977,11.354441 24.5,11.354441 C 31.700731,11.354441 36.65625,16.339482 36.65625,23.537717 C 36.656248,30.735953 31.700731,35.689753 24.5,35.689753 C 17.29927,35.689754 12.502002,30.735951 12.502002,23.537717 C 12.502002,16.564428 16.962974,11.653081 23.8125,11.354441 z "
-       id="path2394"
-       sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccssssc" />
-    <path
-       sodipodi:type="inkscape:offset"
-       inkscape:radius="-1"
-       inkscape:original="M 22.5 4.5 L 22.5 8.625 C 19.782905 8.988907 17.277282 10.069354 15.21875 11.6875 L 12.0625 8.5 L 9.5 11.0625 L 12.6875 14.25 C 11.068793 16.307819 9.9577835 18.783847 9.59375 21.5 L 5.5 21.5 L 5.5 25.5 L 9.59375 25.5 C 9.9535644 28.228306 11.062591 30.715548 12.6875 32.78125 L 9.5 35.96875 L 12.0625 38.5 L 15.21875 35.34375 C 17.277282 36.961896 19.782905 38.042343 22.5 38.40625 L 22.5 42.5 L 26.5 42.5 L 26.5 38.40625 C 29.229107 38.040732 31.717452 36.942459 33.78125 35.3125 L 36.96875 38.5 L 39.5 35.96875 L 36.3125 32.78125 C 37.936789 30.716335 39.014761 28.227089 39.375 25.5 L 43.5 25.5 L 43.5 21.5 L 39.375 21.5 C 39.010966 18.783848 37.931208 16.307819 36.3125 14.25 L 39.5 11.0625 L 36.96875 8.5 L 33.78125 11.6875 L 33.75 11.6875 C 31.691468 10.069353 29.217095 8.9889074 26.5 8.625 L 26.5 4.5 L 22.5 4.5 z M 23.8125 11.34375 C 24.033452 11.334116 24.274977 11.34375 24.5 11.34375 C 31.700731 11.34375 36.65625 16.333015 36.65625 23.53125 C 36.656248 30.729485 31.700731 35.6875 24.5 35.6875 C 17.29927 35.6875 12.5 30.729484 12.5 23.53125 C 12.5 16.55796 16.962974 11.64239 23.8125 11.34375 z "
-       xlink:href="#path2394"
-       style="opacity:0.2;fill:url(#linearGradient2453);fill-opacity:1.0;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.9999997;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2445"
-       inkscape:href="#path2394"
-       d="M 23.5,5.5 L 23.5,8.625 C 23.503929,9.1319208 23.127956,9.5616039 22.625,9.625 C 20.085855,9.9650737 17.762357,10.960594 15.84375,12.46875 C 15.44664,12.797268 14.864902,12.77021 14.5,12.40625 L 12.0625,9.9375 L 10.9375,11.0625 L 13.40625,13.53125 C 13.77021,13.896152 13.797268,14.47789 13.46875,14.875 C 11.953567,16.801212 10.932828,19.095048 10.59375,21.625 C 10.530354,22.127956 10.100671,22.503929 9.59375,22.5 L 6.5,22.5 L 6.5,24.5 L 9.59375,24.5 C 10.100671,24.496071 10.530354,24.872044 10.59375,25.375 C 10.929039,27.917339 11.948302,30.223346 13.46875,32.15625 C 13.797268,32.55336 13.77021,33.135098 13.40625,33.5 L 10.9375,35.96875 L 12.03125,37.09375 L 14.5,34.625 C 14.864902,34.26104 15.44664,34.233982 15.84375,34.5625 C 17.762357,36.070656 20.085855,37.066176 22.625,37.40625 C 23.127956,37.469646 23.503929,37.899329 23.5,38.40625 L 23.5,41.5 L 25.5,41.5 L 25.5,38.40625 C 25.496071,37.899329 25.872044,37.469646 26.375,37.40625 C 28.92215,37.065102 31.227806,36.054308 33.15625,34.53125 C 33.55336,34.202732 34.135098,34.22979 34.5,34.59375 L 36.96875,37.0625 L 38.0625,35.96875 L 35.59375,33.5 C 35.22979,33.135098 35.202732,32.55336 35.53125,32.15625 C 37.047015,30.229299 38.038333,27.923642 38.375,25.375 C 38.438396,24.872044 38.868079,24.496071 39.375,24.5 L 42.5,24.5 L 42.5,22.5 L 39.375,22.5 C 38.868079,22.503929 38.438396,22.127956 38.375,21.625 C 38.034921,19.087581 37.042567,16.796296 35.53125,14.875 C 35.202732,14.47789 35.22979,13.896152 35.59375,13.53125 L 38.09375,11.03125 L 36.96875,9.9375 L 34.5,12.40625 C 34.307701,12.592396 34.048815,12.693699 33.78125,12.6875 L 33.75,12.6875 C 33.522871,12.68767 33.302449,12.610522 33.125,12.46875 C 31.202527,10.957555 28.913145,9.9649402 26.375,9.625 C 25.872044,9.5616039 25.496071,9.1319208 25.5,8.625 L 25.5,5.5 L 23.5,5.5 z M 23.78125,10.34375 C 24.062872,10.331471 24.303519,10.34375 24.5,10.34375 C 32.162653,10.34375 37.65625,15.874058 37.65625,23.53125 C 37.656248,31.188442 32.15976,36.6875 24.5,36.6875 C 20.67012,36.6875 17.391923,35.341265 15.09375,33 C 12.795577,30.658735 11.5,27.35261 11.5,23.53125 C 11.5,16.131287 16.473536,10.662367 23.78125,10.34375 z " />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#edd400;fill-opacity:1;fill-rule:evenodd;stroke:#a40000;stroke-width:1.08146787;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2198"
-       sodipodi:cx="24.450865"
-       sodipodi:cy="23.959385"
-       sodipodi:rx="14.03053"
-       sodipodi:ry="14.03053"
-       d="M 38.481395 23.959385 A 14.03053 14.03053 0 1 1  10.420335,23.959385 A 14.03053 14.03053 0 1 1  38.481395 23.959385 z"
-       transform="matrix(0.924879,0,0,0.924459,1.889957,1.34006)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:url(#linearGradient2279);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.12198293;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2277"
-       sodipodi:cx="24.450865"
-       sodipodi:cy="23.959385"
-       sodipodi:rx="14.03053"
-       sodipodi:ry="14.03053"
-       d="M 38.481395 23.959385 A 14.03053 14.03053 0 1 1  10.420335,23.959385 A 14.03053 14.03053 0 1 1  38.481395 23.959385 z"
-       transform="matrix(0.890914,0,0,0.891279,2.716374,2.14037)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2200"
-       sodipodi:cx="10.54341"
-       sodipodi:cy="-2.7068274"
-       sodipodi:rx="2.4204714"
-       sodipodi:ry="1.7230475"
-       d="M 12.963882 -2.7068274 A 2.4204714 1.7230475 0 1 1  8.1229389,-2.7068274 A 2.4204714 1.7230475 0 1 1  12.963882 -2.7068274 z"
-       transform="matrix(0.827565,0,0,0.87352,11.27774,22.85935)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2202"
-       sodipodi:cx="10.54341"
-       sodipodi:cy="-2.7068274"
-       sodipodi:rx="2.4204714"
-       sodipodi:ry="1.7230475"
-       d="M 12.963882 -2.7068274 A 2.4204714 1.7230475 0 1 1  8.1229389,-2.7068274 A 2.4204714 1.7230475 0 1 1  12.963882 -2.7068274 z"
-       transform="matrix(0.827567,0,0,0.87352,20.27772,22.86958)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#2e3436;stroke-width:4.5851903;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2204"
-       sodipodi:cx="24.450865"
-       sodipodi:cy="23.959385"
-       sodipodi:rx="14.03053"
-       sodipodi:ry="14.03053"
-       d="M 36.657066,30.877796 A 14.03053,14.03053 0 0 1 11.928959,30.288496"
-       transform="matrix(0.453563,0,0,0.419476,13.51464,14.26249)"
-       sodipodi:start="0.51564596"
-       sodipodi:end="2.6736"
-       sodipodi:open="true" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.5;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.75245398;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="path2465"
-       sodipodi:cx="26.658085"
-       sodipodi:cy="20.675463"
-       sodipodi:rx="9.863492"
-       sodipodi:ry="8.2640066"
-       d="M 36.521577 20.675463 A 9.863492 8.2640066 0 1 1  16.794593,20.675463 A 9.863492 8.2640066 0 1 1  36.521577 20.675463 z"
-       transform="matrix(1.216989,0,0,1.451287,-7.948546,-6.503855)" />
-  </g>
-</svg>
diff --git a/libpurple/protocols/gg/roster.h b/libpurple/protocols/gg/roster.h
deleted file mode 100644
--- a/libpurple/protocols/gg/roster.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_ROSTER_H
-#define PURPLE_GG_ROSTER_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-typedef struct
-{
-	gpointer content;
-	gboolean is_updating;
-
-	GList *sent_updates;
-	GList *pending_updates;
-
-	guint timer;
-} ggp_roster_session_data;
-
-/* setup */
-gboolean ggp_roster_enabled(void);
-void ggp_roster_setup(PurpleConnection *gc);
-void ggp_roster_cleanup(PurpleConnection *gc);
-
-/* synchronization control */
-void ggp_roster_request_update(PurpleConnection *gc);
-
-/* libgadu callbacks */
-void ggp_roster_reply(PurpleConnection *gc,
-	struct gg_event_userlist100_reply *reply);
-void ggp_roster_version(PurpleConnection *gc,
-	struct gg_event_userlist100_version *version);
-
-/* libpurple callbacks */
-void ggp_roster_alias_buddy(PurpleProtocolServer *protocol_server, PurpleConnection *gc, const char *who,
-	const char *alias);
-void ggp_roster_group_buddy(PurpleProtocolServer *protocol_server, PurpleConnection *gc, const char *who,
-	const char *old_group, const char *new_group);
-void ggp_roster_rename_group(PurpleProtocolServer *protocol_server, PurpleConnection *, const char *old_name,
-	PurpleGroup *group, GList *moved_buddies);
-void ggp_roster_add_buddy(PurpleProtocolServer *protocol_server, PurpleConnection *gc, PurpleBuddy *buddy,
-	PurpleGroup *group, const char *message);
-void ggp_roster_remove_buddy(PurpleProtocolServer *protocol_server, PurpleConnection *gc, PurpleBuddy *buddy,
-	PurpleGroup *group);
-
-#endif /* PURPLE_GG_ROSTER_H */
diff --git a/libpurple/protocols/gg/roster.c b/libpurple/protocols/gg/roster.c
deleted file mode 100644
--- a/libpurple/protocols/gg/roster.c
+++ /dev/null
@@ -1,1092 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "roster.h"
-
-#include <glib/gi18n-lib.h>
-
-#include "gg.h"
-#include "xml.h"
-#include "utils.h"
-#include "purplew.h"
-
-#define GGP_ROSTER_SYNC_SETT "gg-synchronized"
-#define GGP_ROSTER_DEBUG 0
-#define GGP_ROSTER_GROUPID_DEFAULT "00000000-0000-0000-0000-000000000000"
-#define GGP_ROSTER_GROUPID_BOTS "0b345af6-0001-0000-0000-000000000004"
-
-/* TODO: ignored contacts synchronization (?) */
-
-typedef struct
-{
-	int version;
-
-	PurpleXmlNode *xml;
-
-	PurpleXmlNode *groups_node, *contacts_node;
-
-	/**
-	 * Key: (uin_t) user identifier
-	 * Value: (PurpleXmlNode*) xml node for contact
-	 */
-	GHashTable *contact_nodes;
-
-	/**
-	 * Key: (gchar*) group id
-	 * Value: (PurpleXmlNode*) xml node for group
-	 */
-	GHashTable *group_nodes;
-
-	/**
-	 * Key: (gchar*) group name
-	 * Value: (gchar*) group id
-	 */
-	GHashTable *group_ids;
-
-	/**
-	 * Key: (gchar*) group id
-	 * Value: (gchar*) group name
-	 */
-	GHashTable *group_names;
-
-	gchar *bots_group_id;
-
-	gboolean needs_update;
-} ggp_roster_content;
-
-typedef struct
-{
-	enum
-	{
-		GGP_ROSTER_CHANGE_CONTACT_UPDATE,
-		GGP_ROSTER_CHANGE_CONTACT_REMOVE,
-		GGP_ROSTER_CHANGE_GROUP_RENAME,
-	} type;
-	union
-	{
-		uin_t uin;
-		struct
-		{
-			gchar *old_name;
-			gchar *new_name;
-		} group_rename;
-	} data;
-} ggp_roster_change;
-
-static inline ggp_roster_session_data *
-ggp_roster_get_rdata(PurpleConnection *gc);
-static void ggp_roster_content_free(ggp_roster_content *content);
-static void ggp_roster_change_free(gpointer change);
-static int ggp_roster_get_version(PurpleConnection *gc);
-static gboolean ggp_roster_timer_cb(gpointer _gc);
-#if GGP_ROSTER_DEBUG
-static void ggp_roster_dump(ggp_roster_content *content);
-#endif
-
-/* synchronization control */
-static gboolean ggp_roster_is_synchronized(PurpleBuddy *buddy);
-static void ggp_roster_set_synchronized(PurpleConnection *gc,
-	PurpleBuddy *buddy, gboolean synchronized);
-
-/* buddy list import */
-static gboolean ggp_roster_reply_list_read_group(PurpleXmlNode *node,
-	ggp_roster_content *content);
-static gboolean ggp_roster_reply_list_read_buddy(PurpleConnection *gc,
-	PurpleXmlNode *node, ggp_roster_content *content, GHashTable *remove_buddies);
-static void ggp_roster_reply_list(PurpleConnection *gc, uint32_t version,
-	const char *reply);
-
-/* buddy list export */
-static const gchar * ggp_roster_send_update_group_add(
-	ggp_roster_content *content, PurpleGroup *group);
-static gboolean ggp_roster_send_update_contact_update(PurpleConnection *gc,
-	ggp_roster_change *change);
-static gboolean ggp_roster_send_update_contact_remove(PurpleConnection *gc,
-	ggp_roster_change *change);
-static gboolean ggp_roster_send_update_group_rename(PurpleConnection *gc,
-	ggp_roster_change *change);
-static void ggp_roster_send_update(PurpleConnection *gc);
-static void ggp_roster_reply_ack(PurpleConnection *gc, uint32_t version);
-static void ggp_roster_reply_reject(PurpleConnection *gc, uint32_t version);
-
-/******************************************************************************/
-
-static inline ggp_roster_session_data *
-ggp_roster_get_rdata(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	return &accdata->roster_data;
-}
-
-static void ggp_roster_content_free(ggp_roster_content *content)
-{
-	if (content == NULL)
-		return;
-	g_clear_pointer(&content->xml, purple_xmlnode_free);
-	g_clear_pointer(&content->contact_nodes, g_hash_table_destroy);
-	g_clear_pointer(&content->group_nodes, g_hash_table_destroy);
-	g_clear_pointer(&content->group_ids, g_hash_table_destroy);
-	g_clear_pointer(&content->group_names, g_hash_table_destroy);
-	g_free(content->bots_group_id);
-	g_free(content);
-}
-
-static void ggp_roster_change_free(gpointer _change)
-{
-	ggp_roster_change *change = _change;
-
-	if (change->type == GGP_ROSTER_CHANGE_GROUP_RENAME) {
-		g_free(change->data.group_rename.old_name);
-		g_free(change->data.group_rename.new_name);
-	}
-
-	g_free(change);
-}
-
-static int ggp_roster_get_version(PurpleConnection *gc)
-{
-	ggp_roster_content *content = ggp_roster_get_rdata(gc)->content;
-	if (content == NULL)
-		return 0;
-	return content->version;
-}
-
-static gboolean ggp_roster_timer_cb(gpointer _gc)
-{
-	PurpleConnection *gc = _gc;
-
-	PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
-
-	ggp_roster_send_update(gc);
-
-	return TRUE;
-}
-
-#if GGP_ROSTER_DEBUG
-static void ggp_roster_dump(ggp_roster_content *content)
-{
-	char *str;
-	int len;
-
-	g_return_if_fail(content != NULL);
-	g_return_if_fail(content->xml != NULL);
-
-	str = purple_xmlnode_to_formatted_str(content->xml, &len);
-	purple_debug_misc("gg", "ggp_roster_dump: [%s]\n", str);
-	g_free(str);
-}
-#endif
-
-/*******************************************************************************
- * Setup.
- ******************************************************************************/
-
-gboolean ggp_roster_enabled(void)
-{
-	static gboolean checked = FALSE;
-	static gboolean enabled;
-
-	if (!checked) {
-		enabled = gg_libgadu_check_feature(
-			GG_LIBGADU_FEATURE_USERLIST100);
-		checked = TRUE;
-	}
-	return enabled;
-}
-
-void ggp_roster_setup(PurpleConnection *gc)
-{
-	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
-
-	rdata->content = NULL;
-	rdata->sent_updates = NULL;
-	rdata->pending_updates = NULL;
-	rdata->timer = 0;
-	rdata->is_updating = FALSE;
-
-	if (ggp_roster_enabled())
-		rdata->timer = g_timeout_add_seconds(2,
-			ggp_roster_timer_cb, gc);
-}
-
-void ggp_roster_cleanup(PurpleConnection *gc)
-{
-	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
-
-	g_clear_handle_id(&rdata->timer, g_source_remove);
-	ggp_roster_content_free(rdata->content);
-	g_list_free_full(rdata->sent_updates, ggp_roster_change_free);
-	g_list_free_full(rdata->pending_updates, ggp_roster_change_free);
-}
-
-/*******************************************************************************
- * Synchronization control.
- ******************************************************************************/
-
-static gboolean ggp_roster_is_synchronized(PurpleBuddy *buddy)
-{
-	gboolean ret = purple_blist_node_get_bool(PURPLE_BLIST_NODE(buddy),
-		GGP_ROSTER_SYNC_SETT);
-	return ret;
-}
-
-static void ggp_roster_set_synchronized(PurpleConnection *gc,
-	PurpleBuddy *buddy, gboolean synchronized)
-{
-	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
-	uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy));
-	ggp_roster_change *change;
-
-	purple_blist_node_set_bool(PURPLE_BLIST_NODE(buddy),
-		GGP_ROSTER_SYNC_SETT, synchronized);
-	if (!synchronized) {
-		change = g_new0(ggp_roster_change, 1);
-		change->type = GGP_ROSTER_CHANGE_CONTACT_UPDATE;
-		change->data.uin = uin;
-		rdata->pending_updates =
-			g_list_append(rdata->pending_updates, change);
-	}
-}
-
-void ggp_roster_request_update(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	int local_version = ggp_roster_get_version(gc);
-
-	if (!ggp_roster_enabled()) {
-		purple_debug_warning("gg", "ggp_roster_request_update: "
-			"feature disabled\n");
-		return;
-	}
-
-	purple_debug_info("gg", "ggp_roster_request_update: local=%u\n",
-		local_version);
-
-	gg_userlist100_request(accdata->session, GG_USERLIST100_GET,
-		local_version, GG_USERLIST100_FORMAT_TYPE_GG100, NULL);
-}
-
-/*******************************************************************************
- * Libgadu callbacks.
- ******************************************************************************/
-
-void ggp_roster_reply(PurpleConnection *gc,
-	struct gg_event_userlist100_reply *reply)
-{
-	if (GG_USERLIST100_FORMAT_TYPE_GG100 != reply->format_type) {
-		purple_debug_warning("gg", "ggp_roster_reply: "
-			"unsupported format type (%x)\n", reply->format_type);
-		return;
-	}
-
-	if (reply->type == GG_USERLIST100_REPLY_LIST)
-		ggp_roster_reply_list(gc, reply->version, reply->reply);
-	else if (reply->type == 0x01) /* list up to date (TODO: push to libgadu) */
-		purple_debug_info("gg", "ggp_roster_reply: list up to date\n");
-	else if (reply->type == GG_USERLIST100_REPLY_ACK)
-		ggp_roster_reply_ack(gc, reply->version);
-	else if (reply->type == GG_USERLIST100_REPLY_REJECT)
-		ggp_roster_reply_reject(gc, reply->version);
-	else
-		purple_debug_error("gg", "ggp_roster_reply: "
-			"unsupported reply (%x)\n", reply->type);
-}
-
-void ggp_roster_version(PurpleConnection *gc,
-	struct gg_event_userlist100_version *version)
-{
-	int local_version = ggp_roster_get_version(gc);
-	int remote_version = version->version;
-
-	purple_debug_info("gg", "ggp_roster_version: local=%u, remote=%u\n",
-		local_version, remote_version);
-
-	if (local_version < remote_version)
-		ggp_roster_request_update(gc);
-}
-
-/*******************************************************************************
- * Libpurple callbacks.
- ******************************************************************************/
-
-void
-ggp_roster_alias_buddy(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                       PurpleConnection *gc, const gchar *who,
-                       const gchar *alias)
-{
-	PurpleBuddy *buddy;
-
-	g_return_if_fail(who != NULL);
-
-	if (!ggp_roster_enabled())
-		return;
-
-	purple_debug_misc("gg", "ggp_roster_alias_buddy(\"%s\", \"%s\")\n",
-		who, alias);
-
-	buddy = purple_blist_find_buddy(purple_connection_get_account(gc), who);
-	g_return_if_fail(buddy != NULL);
-
-	ggp_roster_set_synchronized(gc, buddy, FALSE);
-}
-
-void
-ggp_roster_group_buddy(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                       PurpleConnection *gc, const gchar *who,
-                       const gchar *old_group, const gchar *new_group)
-{
-	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
-	ggp_roster_change *change;
-
-	if (!ggp_roster_enabled())
-		return;
-	if (rdata->is_updating)
-		return;
-
-	purple_debug_misc("gg", "ggp_roster_group_buddy: "
-		"who=\"%s\", group=\"%s\" -> \"%s\")\n",
-		who, old_group, new_group);
-
-	/* purple_blist_find_buddy(..., who) is not accessible at this moment */
-	change = g_new0(ggp_roster_change, 1);
-	change->type = GGP_ROSTER_CHANGE_CONTACT_UPDATE;
-	change->data.uin = ggp_str_to_uin(who);
-	rdata->pending_updates = g_list_append(rdata->pending_updates, change);
-}
-
-void
-ggp_roster_rename_group(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                        PurpleConnection *gc, const gchar *old_name,
-                        PurpleGroup *group, G_GNUC_UNUSED GList *moved_buddies)
-{
-	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
-	ggp_roster_change *change;
-
-	if (!ggp_roster_enabled())
-		return;
-
-	change = g_new0(ggp_roster_change, 1);
-	change->type = GGP_ROSTER_CHANGE_GROUP_RENAME;
-	change->data.group_rename.old_name = g_strdup(old_name);
-	change->data.group_rename.new_name =
-		g_strdup(purple_group_get_name(group));
-	rdata->pending_updates = g_list_append(rdata->pending_updates, change);
-}
-
-void
-ggp_roster_add_buddy(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                     PurpleConnection *gc, PurpleBuddy *buddy,
-                     G_GNUC_UNUSED PurpleGroup *group,
-                     G_GNUC_UNUSED const gchar *message)
-{
-	g_return_if_fail(gc != NULL);
-	g_return_if_fail(buddy != NULL);
-
-	if (!ggp_roster_enabled())
-		return;
-
-	ggp_roster_set_synchronized(gc, buddy, FALSE);
-}
-
-void
-ggp_roster_remove_buddy(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                        PurpleConnection *gc, PurpleBuddy *buddy,
-                        G_GNUC_UNUSED PurpleGroup *group)
-{
-	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
-	ggp_roster_change *change;
-
-	if (!ggp_roster_enabled())
-		return;
-
-	change = g_new0(ggp_roster_change, 1);
-	change->type = GGP_ROSTER_CHANGE_CONTACT_REMOVE;
-	change->data.uin = ggp_str_to_uin(purple_buddy_get_name(buddy));
-	rdata->pending_updates = g_list_append(rdata->pending_updates, change);
-}
-
-/*******************************************************************************
- * Buddy list import.
- ******************************************************************************/
-
-static gboolean ggp_roster_reply_list_read_group(PurpleXmlNode *node,
-	ggp_roster_content *content)
-{
-	char *name, *id;
-	gboolean removable;
-	gboolean succ = TRUE, is_bot, is_default;
-
-	succ &= ggp_xml_get_string(node, "Id", &id);
-	succ &= ggp_xml_get_string(node, "Name", &name);
-	succ &= ggp_xml_get_bool(node, "IsRemovable", &removable);
-
-	if (!succ) {
-		g_free(id);
-		g_free(name);
-		g_return_val_if_reached(FALSE);
-	}
-
-	is_bot = (strcmp(id, GGP_ROSTER_GROUPID_BOTS) == 0 ||
-		g_strcmp0(name, "Pomocnicy") == 0);
-	is_default = (strcmp(id, GGP_ROSTER_GROUPID_DEFAULT) == 0 ||
-		g_strcmp0(name, PURPLE_BLIST_DEFAULT_GROUP_NAME) == 0 ||
-		g_strcmp0(name, "[default]") == 0);
-
-	if (!content->bots_group_id && is_bot)
-		content->bots_group_id = g_strdup(id);
-
-	if (!removable || is_bot || is_default) {
-		g_free(id);
-		g_free(name);
-		return TRUE;
-	}
-
-	g_hash_table_insert(content->group_nodes, g_strdup(id), node);
-	g_hash_table_insert(content->group_ids, g_strdup(name), g_strdup(id));
-	g_hash_table_insert(content->group_names, id, name);
-
-	return TRUE;
-}
-
-static gboolean ggp_roster_reply_list_read_buddy(PurpleConnection *gc,
-	PurpleXmlNode *node, ggp_roster_content *content, GHashTable *remove_buddies)
-{
-	gchar *alias, *group_name = NULL;
-	uin_t uin;
-	gboolean succ = TRUE;
-	PurpleXmlNode *group_list, *group_elem;
-	PurpleBuddy *buddy = NULL;
-	PurpleGroup *group = NULL;
-	PurpleGroup *currentGroup;
-	gboolean alias_changed;
-	PurpleAccount *account = purple_connection_get_account(gc);
-
-	succ &= ggp_xml_get_string(node, "ShowName", &alias);
-	succ &= ggp_xml_get_uint(node, "GGNumber", &uin);
-
-	group_list = purple_xmlnode_get_child(node, "Groups");
-	succ &= (group_list != NULL);
-
-	if (!succ) {
-		g_free(alias);
-		g_return_val_if_reached(FALSE);
-	}
-
-	g_hash_table_insert(content->contact_nodes, GINT_TO_POINTER(uin), node);
-
-	/* check, if alias is set */
-	if (*alias == '\0' ||
-		strcmp(alias, ggp_uin_to_str(uin)) == 0)
-	{
-		g_free(alias);
-		alias = NULL;
-	}
-
-	/* getting (eventually creating) group */
-	group_elem = purple_xmlnode_get_child(group_list, "GroupId");
-	while (group_elem != NULL) {
-		gchar *id;
-		gboolean isbot;
-
-		if (!ggp_xml_get_string(group_elem, NULL, &id))
-			continue;
-		isbot = (0 == g_strcmp0(id, content->bots_group_id));
-		group_name = g_hash_table_lookup(content->group_names, id);
-		g_free(id);
-
-		/* we don't want to import bots;
-		 * they are inserted to roster by default
-		 */
-		if (isbot) {
-			g_free(alias);
-			return TRUE;
-		}
-
-		if (group_name != NULL)
-			break;
-
-		group_elem = purple_xmlnode_get_next_twin(group_elem);
-	}
-	if (group_name) {
-		group = purple_blist_find_group(group_name);
-		if (!group) {
-			group = purple_group_new(group_name);
-			purple_blist_add_group(group, NULL);
-		}
-	}
-
-	/* add buddy, if doesn't exists */
-	buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin));
-	g_hash_table_remove(remove_buddies, GINT_TO_POINTER(uin));
-	if (!buddy) {
-		purple_debug_info("gg", "ggp_roster_reply_list_read_buddy: "
-			"adding %u (%s) to buddy list\n", uin, alias);
-		buddy = purple_buddy_new(account, ggp_uin_to_str(uin), alias);
-		purple_blist_add_buddy(buddy, NULL, group, NULL);
-		ggp_roster_set_synchronized(gc, buddy, TRUE);
-
-		g_free(alias);
-		return TRUE;
-	}
-
-	/* buddy exists, but is not synchronized - local list has priority */
-	if (!ggp_roster_is_synchronized(buddy)) {
-		purple_debug_misc("gg", "ggp_roster_reply_list_read_buddy: "
-			"ignoring not synchronized %u (%s)\n",
-			uin, purple_buddy_get_name(buddy));
-		g_free(alias);
-		return TRUE;
-	}
-
-	currentGroup = ggp_purplew_buddy_get_group_only(buddy);
-	alias_changed =
-		(0 != g_strcmp0(alias, purple_buddy_get_alias_only(buddy)));
-
-	if (currentGroup == group && !alias_changed) {
-		g_free(alias);
-		return TRUE;
-	}
-
-	purple_debug_misc("gg", "ggp_roster_reply_list_read_buddy: "
-		"updating %u (%s) - alias=\"%s\"->\"%s\", group=%p->%p (%s)\n",
-		uin, purple_buddy_get_name(buddy),
-		purple_buddy_get_alias(buddy), alias,
-		currentGroup, group, group_name);
-	if (alias_changed)
-		purple_buddy_set_local_alias(buddy, alias);
-	if (currentGroup != group)
-		purple_blist_add_buddy(buddy, NULL, group, NULL);
-
-	g_free(alias);
-	return TRUE;
-}
-
-static void ggp_roster_reply_list(PurpleConnection *gc, uint32_t version,
-	const char *data)
-{
-	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
-	PurpleXmlNode *xml, *xml_it;
-	PurpleAccount *account;
-	GSList *local_buddies;
-	GHashTable *remove_buddies;
-	GList *update_buddies = NULL, *local_groups, *it, *table_values;
-	ggp_roster_content *content;
-
-	g_return_if_fail(gc != NULL);
-	g_return_if_fail(data != NULL);
-
-	account = purple_connection_get_account(gc);
-
-	purple_debug_info("gg", "ggp_roster_reply_list: got list, version=%u\n",
-		version);
-
-	xml = purple_xmlnode_from_str(data, -1);
-	if (xml == NULL) {
-		purple_debug_warning("gg", "ggp_roster_reply_list: "
-			"invalid xml\n");
-		return;
-	}
-
-	ggp_roster_content_free(rdata->content);
-	rdata->content = NULL;
-	rdata->is_updating = TRUE;
-	content = g_new0(ggp_roster_content, 1);
-	content->version = version;
-	content->xml = xml;
-	content->contact_nodes = g_hash_table_new(NULL, NULL);
-	content->group_nodes = g_hash_table_new_full(
-		g_str_hash, g_str_equal, g_free, NULL);
-	content->group_ids = g_hash_table_new_full(
-		g_str_hash, g_str_equal, g_free, g_free);
-	content->group_names = g_hash_table_new_full(
-		g_str_hash, g_str_equal, g_free, g_free);
-
-#if GGP_ROSTER_DEBUG
-	ggp_roster_dump(content);
-#endif
-
-	/* reading groups */
-	content->groups_node = purple_xmlnode_get_child(xml, "Groups");
-	if (content->groups_node == NULL) {
-		ggp_roster_content_free(content);
-		g_return_if_reached();
-	}
-	xml_it = purple_xmlnode_get_child(content->groups_node, "Group");
-	while (xml_it != NULL) {
-		if (!ggp_roster_reply_list_read_group(xml_it, content)) {
-			ggp_roster_content_free(content);
-			g_return_if_reached();
-		}
-
-		xml_it = purple_xmlnode_get_next_twin(xml_it);
-	}
-
-	/* dumping current group list */
-	local_groups = ggp_purplew_account_get_groups(account, TRUE);
-
-	/* dumping current buddy list
-	 * we will:
-	 * - remove synchronized ones, if not found in list at server
-	 * - upload not synchronized ones
-	 */
-	local_buddies = purple_blist_find_buddies(account, NULL);
-	remove_buddies = g_hash_table_new(g_direct_hash, g_direct_equal);
-	while (local_buddies) {
-		PurpleBuddy *buddy = local_buddies->data;
-		uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy));
-		local_buddies =
-			g_slist_delete_link(local_buddies, local_buddies);
-
-		if (!uin)
-			continue;
-
-		if (ggp_roster_is_synchronized(buddy))
-			g_hash_table_insert(remove_buddies,
-				GINT_TO_POINTER(uin), buddy);
-		else
-			update_buddies = g_list_append(update_buddies, buddy);
-	}
-
-	/* reading buddies */
-	content->contacts_node = purple_xmlnode_get_child(xml, "Contacts");
-	if (content->contacts_node == NULL) {
-		g_hash_table_destroy(remove_buddies);
-		g_list_free(update_buddies);
-		ggp_roster_content_free(content);
-		g_return_if_reached();
-	}
-	xml_it = purple_xmlnode_get_child(content->contacts_node, "Contact");
-	while (xml_it != NULL) {
-		if (!ggp_roster_reply_list_read_buddy(gc, xml_it, content,
-			remove_buddies))
-		{
-			g_hash_table_destroy(remove_buddies);
-			g_list_free(update_buddies);
-			ggp_roster_content_free(content);
-			g_return_if_reached();
-		}
-
-		xml_it = purple_xmlnode_get_next_twin(xml_it);
-	}
-
-	/* removing buddies, which are not present in roster */
-	table_values = g_hash_table_get_values(remove_buddies);
-	it = g_list_first(table_values);
-	while (it) {
-		PurpleBuddy *buddy = it->data;
-		it = g_list_next(it);
-		if (!ggp_roster_is_synchronized(buddy))
-			continue;
-		purple_debug_info("gg", "ggp_roster_reply_list: "
-			"removing %s from buddy list\n",
-			purple_buddy_get_name(buddy));
-		purple_blist_remove_buddy(buddy);
-	}
-	g_list_free(table_values);
-	g_hash_table_destroy(remove_buddies);
-
-	/* remove groups, which are empty, but had contacts before
-	 * synchronization
-	 */
-	it = g_list_first(local_groups);
-	while (it) {
-		PurpleGroup *group = it->data;
-		it = g_list_next(it);
-		if (purple_counting_node_get_total_size(PURPLE_COUNTING_NODE(group)) != 0)
-			continue;
-		purple_debug_info("gg", "ggp_roster_reply_list: "
-			"removing group %s\n", purple_group_get_name(group));
-		purple_blist_remove_group(group);
-	}
-	g_list_free(local_groups);
-
-	/* adding not synchronized buddies */
-	it = g_list_first(update_buddies);
-	while (it) {
-		PurpleBuddy *buddy = it->data;
-		uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy));
-		ggp_roster_change *change;
-
-		it = g_list_next(it);
-		g_assert(uin > 0);
-
-		purple_debug_misc("gg", "ggp_roster_reply_list: "
-			"adding change of %u for roster\n", uin);
-		change = g_new0(ggp_roster_change, 1);
-		change->type = GGP_ROSTER_CHANGE_CONTACT_UPDATE;
-		change->data.uin = uin;
-		rdata->pending_updates =
-			g_list_append(rdata->pending_updates, change);
-	}
-	g_list_free(update_buddies);
-
-	rdata->content = content;
-	rdata->is_updating = FALSE;
-	purple_debug_info("gg", "ggp_roster_reply_list: "
-		"import done, version=%u\n", version);
-}
-
-/*******************************************************************************
- * Buddy list export.
- ******************************************************************************/
-
-static const gchar * ggp_roster_send_update_group_add(
-	ggp_roster_content *content, PurpleGroup *group)
-{
-	gchar *id;
-	const char *id_existing, *group_name;
-	PurpleXmlNode *group_node;
-	gboolean succ = TRUE;
-
-	if (group) {
-		group_name = purple_group_get_name(group);
-		id_existing =
-			g_hash_table_lookup(content->group_ids, group_name);
-	} else
-		id_existing = GGP_ROSTER_GROUPID_DEFAULT;
-	if (id_existing)
-		return id_existing;
-
-	purple_debug_info("gg", "ggp_roster_send_update_group_add: adding %s\n",
-		purple_group_get_name(group));
-
-	id = g_uuid_string_random();
-
-	group_node = purple_xmlnode_new_child(content->groups_node, "Group");
-	succ &= ggp_xml_set_string(group_node, "Id", id);
-	succ &= ggp_xml_set_string(group_node, "Name", group_name);
-	succ &= ggp_xml_set_string(group_node, "IsExpanded", "true");
-	succ &= ggp_xml_set_string(group_node, "IsRemovable", "true");
-	content->needs_update = TRUE;
-
-	g_hash_table_insert(content->group_ids, g_strdup(group_name),
-		g_strdup(id));
-	g_hash_table_replace(content->group_nodes, id, group_node);
-
-	g_return_val_if_fail(succ, NULL);
-
-	return id;
-}
-
-static gboolean ggp_roster_send_update_contact_update(PurpleConnection *gc,
-	ggp_roster_change *change)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	ggp_roster_content *content = ggp_roster_get_rdata(gc)->content;
-	uin_t uin = change->data.uin;
-	PurpleBuddy *buddy;
-	PurpleXmlNode *buddy_node, *contact_groups;
-	gboolean succ = TRUE;
-	const gchar *group_id;
-	gchar *guid;
-
-	g_return_val_if_fail(change->type == GGP_ROSTER_CHANGE_CONTACT_UPDATE,
-		FALSE);
-
-	buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin));
-	if (!buddy)
-		return TRUE;
-	buddy_node = g_hash_table_lookup(content->contact_nodes,
-		GINT_TO_POINTER(uin));
-
-	group_id = ggp_roster_send_update_group_add(content,
-		ggp_purplew_buddy_get_group_only(buddy));
-
-	if (buddy_node) { /* update existing */
-		purple_debug_misc("gg", "ggp_roster_send_update_contact_update:"
-			" updating %u...\n", uin);
-
-		succ &= ggp_xml_set_string(buddy_node, "ShowName",
-			purple_buddy_get_alias(buddy));
-
-		contact_groups = purple_xmlnode_get_child(buddy_node, "Groups");
-		g_assert(contact_groups);
-		ggp_xmlnode_remove_children(contact_groups);
-		succ &= ggp_xml_set_string(contact_groups, "GroupId", group_id);
-
-		g_return_val_if_fail(succ, FALSE);
-
-		return TRUE;
-	}
-
-	/* add new */
-	guid = g_uuid_string_random();
-	purple_debug_misc("gg", "ggp_roster_send_update_contact_update: "
-		"adding %u...\n", uin);
-	buddy_node = purple_xmlnode_new_child(content->contacts_node, "Contact");
-	succ &= ggp_xml_set_string(buddy_node, "Guid", guid);
-	succ &= ggp_xml_set_uint(buddy_node, "GGNumber", uin);
-	succ &= ggp_xml_set_string(buddy_node, "ShowName",
-		purple_buddy_get_alias(buddy));
-
-	contact_groups = purple_xmlnode_new_child(buddy_node, "Groups");
-	g_assert(contact_groups);
-	succ &= ggp_xml_set_string(contact_groups, "GroupId", group_id);
-
-	purple_xmlnode_new_child(buddy_node, "Avatars");
-	succ &= ggp_xml_set_bool(buddy_node, "FlagBuddy", TRUE);
-	succ &= ggp_xml_set_bool(buddy_node, "FlagNormal", TRUE);
-	succ &= ggp_xml_set_bool(buddy_node, "FlagFriend", TRUE);
-
-	/* we don't use Guid, so update is not needed
-	 * content->needs_update = TRUE;
-	 */
-	g_free(guid);
-
-	g_hash_table_insert(content->contact_nodes, GINT_TO_POINTER(uin),
-		buddy_node);
-
-	g_return_val_if_fail(succ, FALSE);
-
-	return TRUE;
-}
-
-static gboolean ggp_roster_send_update_contact_remove(PurpleConnection *gc,
-	ggp_roster_change *change)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	ggp_roster_content *content = ggp_roster_get_rdata(gc)->content;
-	uin_t uin = change->data.uin;
-	PurpleBuddy *buddy;
-	PurpleXmlNode *buddy_node;
-
-	g_return_val_if_fail(change->type == GGP_ROSTER_CHANGE_CONTACT_REMOVE,
-		FALSE);
-
-	buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin));
-	if (buddy) {
-		purple_debug_info("gg", "ggp_roster_send_update_contact_remove:"
-			" contact %u re-added\n", uin);
-		return TRUE;
-	}
-
-	buddy_node = g_hash_table_lookup(content->contact_nodes,
-		GINT_TO_POINTER(uin));
-	if (!buddy_node) /* already removed */
-		return TRUE;
-
-	purple_debug_info("gg", "ggp_roster_send_update_contact_remove: "
-		"removing %u\n", uin);
-	purple_xmlnode_free(buddy_node);
-	g_hash_table_remove(content->contact_nodes, GINT_TO_POINTER(uin));
-
-	return TRUE;
-}
-
-static gboolean ggp_roster_send_update_group_rename(PurpleConnection *gc,
-	ggp_roster_change *change)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	ggp_roster_content *content = ggp_roster_get_rdata(gc)->content;
-	const char *old_name = change->data.group_rename.old_name;
-	const char *new_name = change->data.group_rename.new_name;
-	PurpleXmlNode *group_node;
-	const char *group_id;
-
-	g_return_val_if_fail(change->type == GGP_ROSTER_CHANGE_GROUP_RENAME,
-		FALSE);
-
-	purple_debug_misc("gg", "ggp_roster_send_update_group_rename: "
-		"\"%s\"->\"%s\"\n", old_name, new_name);
-
-	/* moving to or from default group instead of renaming it */
-	if (0 == g_strcmp0(old_name, PURPLE_BLIST_DEFAULT_GROUP_NAME) ||
-		0 == g_strcmp0(new_name, PURPLE_BLIST_DEFAULT_GROUP_NAME))
-	{
-		PurpleGroup *group;
-		GList *group_buddies;
-		group = purple_blist_find_group(new_name);
-		if (!group)
-			return TRUE;
-		purple_debug_info("gg", "ggp_roster_send_update_group_rename: "
-			"invalidating buddies in default group\n");
-		group_buddies = ggp_purplew_group_get_buddies(group, account);
-		while (group_buddies) {
-			ggp_roster_set_synchronized(gc, group_buddies->data,
-				FALSE);
-			group_buddies = g_list_delete_link(group_buddies,
-				group_buddies);
-		}
-		return TRUE;
-	}
-	group_id = g_hash_table_lookup(content->group_ids, old_name);
-	if (!group_id) {
-		purple_debug_info("gg", "ggp_roster_send_update_group_rename: "
-			"%s is not present at roster\n", old_name);
-		return TRUE;
-	}
-
-	group_node = g_hash_table_lookup(content->group_nodes, group_id);
-	if (!group_node) {
-		purple_debug_error("gg", "ggp_roster_send_update_group_rename: "
-			"node for %s not found, id=%s\n", old_name, group_id);
-		g_hash_table_remove(content->group_ids, old_name);
-		return TRUE;
-	}
-
-	g_hash_table_remove(content->group_ids, old_name);
-	g_hash_table_insert(content->group_ids, g_strdup(new_name),
-		g_strdup(group_id));
-	g_hash_table_insert(content->group_nodes, g_strdup(group_id),
-		group_node);
-	return ggp_xml_set_string(group_node, "Name", new_name);
-}
-
-static void ggp_roster_send_update(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
-	ggp_roster_content *content = rdata->content;
-	GList *updates_it;
-	gchar *str;
-	int len;
-
-	/* an update is running now */
-	if (rdata->sent_updates)
-		return;
-
-	/* no pending updates found */
-	if (!rdata->pending_updates)
-		return;
-
-	/* not initialized */
-	if (!content)
-		return;
-
-	purple_debug_info("gg", "ggp_roster_send_update: "
-		"pending updates found\n");
-
-	rdata->sent_updates = rdata->pending_updates;
-	rdata->pending_updates = NULL;
-
-	updates_it = g_list_first(rdata->sent_updates);
-	while (updates_it) {
-		ggp_roster_change *change = updates_it->data;
-		gboolean succ = FALSE;
-		updates_it = g_list_next(updates_it);
-
-		if (change->type == GGP_ROSTER_CHANGE_CONTACT_UPDATE) {
-			succ = ggp_roster_send_update_contact_update(gc, change);
-		} else if (change->type == GGP_ROSTER_CHANGE_CONTACT_REMOVE) {
-			succ = ggp_roster_send_update_contact_remove(gc, change);
-		} else if (change->type == GGP_ROSTER_CHANGE_GROUP_RENAME) {
-			succ = ggp_roster_send_update_group_rename(gc, change);
-		} else {
-			purple_debug_error("gg", "ggp_roster_send_update: not handled");
-		}
-		g_return_if_fail(succ);
-	}
-
-#if GGP_ROSTER_DEBUG
-	ggp_roster_dump(content);
-#endif
-
-	str = purple_xmlnode_to_str(content->xml, &len);
-	gg_userlist100_request(accdata->session, GG_USERLIST100_PUT,
-		content->version, GG_USERLIST100_FORMAT_TYPE_GG100, str);
-	g_free(str);
-}
-
-static void ggp_roster_reply_ack(PurpleConnection *gc, uint32_t version)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
-	ggp_roster_content *content = rdata->content;
-	GList *updates_it;
-
-	purple_debug_info("gg", "ggp_roster_reply_ack: version=%u\n", version);
-
-	/* set synchronization flag for all buddies, that were updated at roster */
-	updates_it = g_list_first(rdata->sent_updates);
-	while (updates_it) {
-		ggp_roster_change *change = updates_it->data;
-		PurpleBuddy *buddy;
-		updates_it = g_list_next(updates_it);
-
-		if (change->type != GGP_ROSTER_CHANGE_CONTACT_UPDATE)
-			continue;
-
-		buddy = purple_blist_find_buddy(account,
-			ggp_uin_to_str(change->data.uin));
-		if (buddy)
-			ggp_roster_set_synchronized(gc, buddy, TRUE);
-	}
-
-	/* we need to remove "synchronized" flag for all contacts, that have
-	 * been modified between roster update start and now
-	 */
-	updates_it = g_list_first(rdata->pending_updates);
-	while (updates_it) {
-		ggp_roster_change *change = updates_it->data;
-		PurpleBuddy *buddy;
-		updates_it = g_list_next(updates_it);
-
-		if (change->type != GGP_ROSTER_CHANGE_CONTACT_UPDATE)
-			continue;
-
-		buddy = purple_blist_find_buddy(account,
-			ggp_uin_to_str(change->data.uin));
-		if (buddy && ggp_roster_is_synchronized(buddy))
-			ggp_roster_set_synchronized(gc, buddy, FALSE);
-	}
-
-	g_clear_list(&rdata->sent_updates, ggp_roster_change_free);
-
-	/* bump roster version or update it, if needed */
-	g_return_if_fail(content != NULL);
-	if (content->needs_update) {
-		ggp_roster_content_free(rdata->content);
-		rdata->content = NULL;
-		/* we have to wait for gg_event_userlist100_version
-		 * ggp_roster_request_update(gc);
-		 */
-	}
-	else
-		content->version = version;
-}
-
-static void ggp_roster_reply_reject(PurpleConnection *gc, uint32_t version)
-{
-	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
-
-	purple_debug_info("gg", "ggp_roster_reply_reject: version=%u\n",
-		version);
-
-	g_return_if_fail(rdata->sent_updates);
-
-	rdata->pending_updates = g_list_concat(rdata->pending_updates,
-		rdata->sent_updates);
-	rdata->sent_updates = NULL;
-
-	ggp_roster_content_free(rdata->content);
-	rdata->content = NULL;
-	ggp_roster_request_update(gc);
-}
-
-/******************************************************************************/
diff --git a/libpurple/protocols/gg/servconn.h b/libpurple/protocols/gg/servconn.h
deleted file mode 100644
--- a/libpurple/protocols/gg/servconn.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_SERVCONN_H
-#define PURPLE_GG_SERVCONN_H
-
-#include <purple.h>
-
-void ggp_servconn_setup(PurpleAccountOption *server_option);
-void ggp_servconn_cleanup(void);
-
-void ggp_servconn_add_server(const gchar *server);
-GSList * ggp_servconn_get_servers(void);
-void ggp_servconn_remote_disconnect(PurpleConnection *gc);
-
-#endif /* PURPLE_GG_SERVCONN_H */
diff --git a/libpurple/protocols/gg/servconn.c b/libpurple/protocols/gg/servconn.c
deleted file mode 100644
--- a/libpurple/protocols/gg/servconn.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "servconn.h"
-
-#include "utils.h"
-
-#define GGP_SERVCONN_HISTORY_PREF "/plugins/prpl/gg/server_history"
-#define GGP_SERVCONN_HISTORY_MAXLEN 15
-
-typedef struct
-{
-	GList *server_history;
-	PurpleAccountOption *server_option;
-} ggp_servconn_global_data;
-
-static ggp_servconn_global_data global_data;
-
-void ggp_servconn_setup(PurpleAccountOption *server_option)
-{
-	GList *extra;
-	purple_prefs_add_string_list(GGP_SERVCONN_HISTORY_PREF, NULL);
-
-	global_data.server_option = server_option;
-	global_data.server_history =
-	        purple_prefs_get_string_list(GGP_SERVCONN_HISTORY_PREF);
-	extra = g_list_nth(global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN);
-	if (extra != NULL) {
-		/* Truncate the list to the maximum. */
-		extra->prev->next = NULL;
-		g_list_free_full(extra, g_free);
-	}
-
-	if(server_option != NULL) {
-		purple_account_option_string_set_hints(global_data.server_option,
-			ggp_servconn_get_servers());
-	}
-}
-
-void ggp_servconn_cleanup(void)
-{
-	g_clear_list(&global_data.server_history, g_free);
-}
-
-void ggp_servconn_add_server(const gchar *server)
-{
-	GList *old_entry;
-
-	old_entry = g_list_find_custom(global_data.server_history, server,
-		(GCompareFunc)g_strcmp0);
-	if (old_entry) {
-		g_free(old_entry->data);
-		global_data.server_history = g_list_delete_link(
-			global_data.server_history, old_entry);
-	}
-
-	global_data.server_history = g_list_prepend(global_data.server_history,
-		g_strdup(server));
-	old_entry =
-	        g_list_nth(global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN);
-	if (old_entry != NULL) {
-		/* Truncate the list to the maximum. */
-		old_entry->prev->next = NULL;
-		g_list_free_full(old_entry, g_free);
-	}
-
-	purple_prefs_set_string_list(GGP_SERVCONN_HISTORY_PREF,
-	                             global_data.server_history);
-	purple_account_option_string_set_hints(global_data.server_option,
-		ggp_servconn_get_servers());
-}
-
-GSList *
-ggp_servconn_get_servers(void)
-{
-	GSList *new_list = NULL;
-	GList *it;
-
-	it = g_list_first(global_data.server_history);
-	while (it) {
-		new_list = g_slist_append(new_list, g_strdup(it->data));
-		it = g_list_next(it);
-	}
-	return new_list;
-}
-
-void
-ggp_servconn_remote_disconnect(PurpleConnection *gc)
-{
-	purple_debug_info("gg", "Server remotely closes connection");
-	purple_account_disconnect(purple_connection_get_account(gc));
-}
diff --git a/libpurple/protocols/gg/status.h b/libpurple/protocols/gg/status.h
deleted file mode 100644
--- a/libpurple/protocols/gg/status.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_STATUS_H
-#define PURPLE_GG_STATUS_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-typedef struct _ggp_status_session_data ggp_status_session_data;
-
-void ggp_status_setup(PurpleConnection *gc);
-void ggp_status_cleanup(PurpleConnection *gc);
-
-GList *ggp_status_types(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleAccount *account);
-int ggp_status_from_purplestatus(PurpleStatus *status, gchar **message);
-const gchar * ggp_status_to_purplestatus(int status);
-const gchar * ggp_status_get_name(const gchar *purple_status);
-
-/* own status */
-
-void ggp_status_set_initial(PurpleConnection *gc, struct gg_login_params *glp);
-
-gboolean ggp_status_set(PurpleAccount *account, int status, const gchar* msg);
-void ggp_status_set_purplestatus(PurpleProtocolServer *protocol_server, PurpleAccount *account, PurpleStatus *status);
-void ggp_status_set_disconnected(PurpleAccount *account);
-void ggp_status_fake_to_self(PurpleConnection *gc);
-
-gboolean ggp_status_get_status_broadcasting(PurpleConnection *gc);
-void ggp_status_set_status_broadcasting(PurpleConnection *gc,
-	gboolean broadcasting);
-void ggp_status_broadcasting_dialog(PurpleConnection *gc);
-
-/* buddy status */
-
-void ggp_status_got_others(PurpleConnection *gc, struct gg_event *ev);
-
-#endif /* PURPLE_GG_STATUS_H */
diff --git a/libpurple/protocols/gg/status.c b/libpurple/protocols/gg/status.c
deleted file mode 100644
--- a/libpurple/protocols/gg/status.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 <libgadu.h>
-
-#include "status.h"
-
-#include "gg.h"
-#include "utils.h"
-
-struct _ggp_status_session_data
-{
-	gboolean status_broadcasting;
-	gchar *current_description;
-};
-
-static inline ggp_status_session_data *
-ggp_status_get_ssdata(PurpleConnection *gc);
-
-static gchar * ggp_status_validate_description(const gchar* msg);
-
-static inline ggp_status_session_data *
-ggp_status_get_ssdata(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	return accdata->status_data;
-}
-
-void ggp_status_setup(PurpleConnection *gc)
-{
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	PurpleAccount *account = purple_connection_get_account(gc);
-
-	ggp_status_session_data *ssdata = g_new0(ggp_status_session_data, 1);
-	accdata->status_data = ssdata;
-
-	ssdata->status_broadcasting =
-		purple_account_get_bool(account, "status_broadcasting", TRUE);
-}
-
-void ggp_status_cleanup(PurpleConnection *gc)
-{
-	ggp_status_session_data *ssdata = ggp_status_get_ssdata(gc);
-	g_free(ssdata->current_description);
-	g_free(ssdata);
-}
-
-static gchar * ggp_status_validate_description(const gchar* msg)
-{
-	if (msg == NULL || msg[0] == '\0')
-		return NULL;
-
-	return ggp_utf8_strndup(msg, GG_STATUS_DESCR_MAXSIZE);
-}
-
-GList *
-ggp_status_types(G_GNUC_UNUSED PurpleProtocol *protocol,
-                 G_GNUC_UNUSED PurpleAccount *account)
-{
-	GList *types = NULL;
-
-	types = g_list_append(types, purple_status_type_new_with_attrs(
-		PURPLE_STATUS_AVAILABLE, NULL, NULL,
-		TRUE, TRUE, FALSE, "message", _("Message"),
-		purple_value_new(G_TYPE_STRING), NULL));
-
-	types = g_list_append(types, purple_status_type_new_with_attrs(
-		PURPLE_STATUS_AVAILABLE, "freeforchat", _("Chatty"),
-		TRUE, TRUE, FALSE, "message", _("Message"),
-		purple_value_new(G_TYPE_STRING), NULL));
-
-	types = g_list_append(types, purple_status_type_new_with_attrs(
-		PURPLE_STATUS_AWAY, NULL, NULL,
-		TRUE, TRUE, FALSE, "message", _("Message"),
-		purple_value_new(G_TYPE_STRING), NULL));
-
-	types = g_list_append(types, purple_status_type_new_with_attrs(
-		PURPLE_STATUS_UNAVAILABLE, NULL, NULL,
-		TRUE, TRUE, FALSE, "message", _("Message"),
-		purple_value_new(G_TYPE_STRING), NULL));
-
-	types = g_list_append(types, purple_status_type_new_with_attrs(
-		PURPLE_STATUS_INVISIBLE, NULL, NULL,
-		TRUE, TRUE, FALSE, "message", _("Message"),
-		purple_value_new(G_TYPE_STRING), NULL));
-
-	types = g_list_append(types, purple_status_type_new_with_attrs(
-		PURPLE_STATUS_OFFLINE, NULL, NULL,
-		TRUE, TRUE, FALSE, "message", _("Message"),
-		purple_value_new(G_TYPE_STRING), NULL));
-
-	return types;
-}
-
-int ggp_status_from_purplestatus(PurpleStatus *status, gchar **message)
-{
-	const char *status_id = purple_status_get_id(status);
-	const char *status_message =
-		purple_status_get_attr_string(status, "message");
-
-	g_return_val_if_fail(message != NULL, 0);
-
-	*message = NULL;
-	if (status_message) {
-		gchar *stripped = purple_markup_strip_html(status_message);
-		g_strstrip(stripped);
-		*message = ggp_status_validate_description(stripped);
-		g_free(stripped);
-	}
-
-	if (0 == strcmp(status_id, "available"))
-		return status_message ? GG_STATUS_AVAIL_DESCR : GG_STATUS_AVAIL;
-	if (0 == strcmp(status_id, "freeforchat"))
-		return status_message ? GG_STATUS_FFC_DESCR : GG_STATUS_FFC;
-	if (0 == strcmp(status_id, "away"))
-		return status_message ? GG_STATUS_BUSY_DESCR : GG_STATUS_BUSY;
-	if (0 == strcmp(status_id, "unavailable"))
-		return status_message ? GG_STATUS_DND_DESCR : GG_STATUS_DND;
-	if (0 == strcmp(status_id, "invisible"))
-		return status_message ?
-			GG_STATUS_INVISIBLE_DESCR : GG_STATUS_INVISIBLE;
-	if (0 == strcmp(status_id, "offline"))
-		return status_message ?
-			GG_STATUS_NOT_AVAIL_DESCR : GG_STATUS_NOT_AVAIL;
-
-	purple_debug_error("gg", "ggp_status_from_purplestatus: "
-		"unknown status requested (%s)\n", status_id);
-	return status_message ? GG_STATUS_AVAIL_DESCR : GG_STATUS_AVAIL;
-}
-
-const gchar * ggp_status_to_purplestatus(int status)
-{
-	switch (status)
-	{
-		case GG_STATUS_NOT_AVAIL:
-		case GG_STATUS_NOT_AVAIL_DESCR:
-		case GG_STATUS_BLOCKED:
-		case GG_STATUS_UNKNOWN:
-			return purple_primitive_get_id_from_type(
-				PURPLE_STATUS_OFFLINE);
-		case GG_STATUS_FFC:
-		case GG_STATUS_FFC_DESCR:
-			return "freeforchat";
-		case GG_STATUS_AVAIL:
-		case GG_STATUS_AVAIL_DESCR:
-			return purple_primitive_get_id_from_type(
-				PURPLE_STATUS_AVAILABLE);
-		case GG_STATUS_BUSY:
-		case GG_STATUS_BUSY_DESCR:
-			return purple_primitive_get_id_from_type(
-				PURPLE_STATUS_AWAY);
-		case GG_STATUS_INVISIBLE:
-		case GG_STATUS_INVISIBLE_DESCR:
-			return purple_primitive_get_id_from_type(
-				PURPLE_STATUS_INVISIBLE);
-		case GG_STATUS_DND:
-		case GG_STATUS_DND_DESCR:
-			return purple_primitive_get_id_from_type(
-				PURPLE_STATUS_UNAVAILABLE);
-		default:
-			purple_debug_warning("gg", "ggp_status_to_purplestatus: unknown status %#02x\n", status);
-			return purple_primitive_get_id_from_type(
-				PURPLE_STATUS_AVAILABLE);
-	}
-}
-
-const gchar * ggp_status_get_name(const gchar *purple_status)
-{
-	if (g_strcmp0(purple_status, "freeforchat") == 0)
-		return _("Chatty");
-	return purple_primitive_get_name_from_type(
-		purple_primitive_get_type_from_id(purple_status));
-}
-
-/*******************************************************************************
- * Own status.
- ******************************************************************************/
-
-void ggp_status_set_initial(PurpleConnection *gc, struct gg_login_params *glp)
-{
-	ggp_status_session_data *ssdata = ggp_status_get_ssdata(gc);
-	PurpleAccount *account = purple_connection_get_account(gc);
-
-	glp->status = ggp_status_from_purplestatus(
-		purple_account_get_active_status(account), &glp->status_descr);
-	if (!ggp_status_get_status_broadcasting(gc))
-		glp->status |= GG_STATUS_FRIENDS_MASK;
-	ssdata->current_description = g_strdup(glp->status_descr);
-}
-
-gboolean ggp_status_set(PurpleAccount *account, int status, const gchar* msg)
-{
-	PurpleConnection *gc = purple_account_get_connection(account);
-	ggp_status_session_data *ssdata = ggp_status_get_ssdata(gc);
-	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	gchar *new_description = ggp_status_validate_description(msg);
-
-	if (!ssdata->status_broadcasting)
-		status |= GG_STATUS_FRIENDS_MASK;
-
-	if ((status == GG_STATUS_NOT_AVAIL ||
-		status == GG_STATUS_NOT_AVAIL_DESCR) &&
-		0 == g_strcmp0(ssdata->current_description, new_description))
-	{
-		purple_debug_info("gg", "ggp_status_set: new status doesn't "
-			"differ when closing connection - ignore\n");
-		g_free(new_description);
-		return FALSE;
-	}
-	g_free(ssdata->current_description);
-	ssdata->current_description = new_description;
-
-	if (msg == NULL)
-		gg_change_status(accdata->session, status);
-	else
-		gg_change_status_descr(accdata->session, status, new_description);
-
-	return TRUE;
-}
-
-void
-ggp_status_set_purplestatus(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
-                            PurpleAccount *account, PurpleStatus *status)
-{
-	int status_gg;
-	gchar *msg = NULL;
-
-	if (!purple_status_is_active(status))
-		return;
-
-	status_gg = ggp_status_from_purplestatus(status, &msg);
-	ggp_status_set(account, status_gg, msg);
-	g_free(msg);
-}
-
-void ggp_status_set_disconnected(PurpleAccount *account)
-{
-	gchar *msg = NULL;
-
-	ggp_status_from_purplestatus(purple_account_get_active_status(account),
-		&msg);
-	if (!ggp_status_set(account,
-		msg ? GG_STATUS_NOT_AVAIL_DESCR : GG_STATUS_NOT_AVAIL, msg))
-	{
-		g_free(msg);
-		return;
-	}
-
-	/*
-	struct gg_event *ev;
-	guint64 wait_start = ggp_microtime(), now;
-	int sleep_time = 5000;
-	while ((ev = gg_watch_fd(info->session)) != NULL)
-	{
-		if (ev->type == GG_EVENT_DISCONNECT_ACK)
-			break;
-		now = ggp_microtime();
-		if (now - wait_start + sleep_time >= 100000)
-			break;
-		usleep(sleep_time);
-		sleep_time *= 2;
-	}
-	*/
-	g_usleep(100000);
-
-	g_free(msg);
-}
-
-void ggp_status_fake_to_self(PurpleConnection *gc)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
-	PurpleStatus *status = purple_presence_get_active_status(
-		purple_account_get_presence(account));
-	const char *status_msg = purple_status_get_attr_string(status,
-		"message");
-	gchar *status_msg_gg = NULL;
-
-	if (status_msg != NULL && status_msg[0] != '\0') {
-		status_msg_gg = g_new0(gchar, GG_STATUS_DESCR_MAXSIZE + 1);
-		g_utf8_strncpy(status_msg_gg, status_msg,
-			GG_STATUS_DESCR_MAXSIZE);
-	}
-
-	purple_protocol_got_user_status(account,
-		purple_contact_info_get_username(info),
-		purple_status_get_id(status),
-		status_msg_gg ? "message" : NULL, status_msg_gg, NULL);
-
-	g_free(status_msg_gg);
-}
-
-gboolean ggp_status_get_status_broadcasting(PurpleConnection *gc)
-{
-	return ggp_status_get_ssdata(gc)->status_broadcasting;
-}
-
-void ggp_status_set_status_broadcasting(PurpleConnection *gc,
-	gboolean broadcasting)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-
-	ggp_status_get_ssdata(gc)->status_broadcasting = broadcasting;
-	purple_account_set_bool(account, "status_broadcasting", broadcasting);
-	ggp_status_set_purplestatus(NULL, account,
-		purple_account_get_active_status(account));
-}
-
-static void
-ggp_status_broadcasting_dialog_ok(PurpleConnection *gc,
-                                  PurpleRequestPage *page)
-{
-	gboolean buddies_only = purple_request_page_get_bool(page, "buddies_only");
-	ggp_status_set_status_broadcasting(gc, !buddies_only);
-}
-
-void ggp_status_broadcasting_dialog(PurpleConnection *gc)
-{
-	PurpleRequestPage *page;
-	PurpleRequestGroup *group;
-	PurpleRequestField *field;
-
-	page = purple_request_page_new();
-	group = purple_request_group_new(NULL);
-	purple_request_page_add_group(page, group);
-
-	field = purple_request_field_bool_new("buddies_only",
-		_("Show status only for buddies"),
-		!ggp_status_get_status_broadcasting(gc));
-	purple_request_group_add_field(group, field);
-
-	purple_request_fields(gc,
-		_("Change status broadcasting"),
-		_("Please, select who can see your status"),
-		NULL,
-		page,
-		_("OK"), G_CALLBACK(ggp_status_broadcasting_dialog_ok),
-		_("Cancel"), NULL,
-		purple_request_cpar_from_connection(gc), gc);
-}
-
-/*******************************************************************************
- * Buddy status.
- ******************************************************************************/
-
-void ggp_status_got_others_buddy(PurpleConnection *gc, uin_t uin, int status,
-	const char *descr);
-
-/******************************************************************************/
-
-void ggp_status_got_others(PurpleConnection *gc, struct gg_event *ev)
-{
-	if (ev->type == GG_EVENT_NOTIFY60) {
-		struct gg_event_notify60 *notify = ev->event.notify60;
-		int i;
-		for (i = 0; notify[i].uin; i++)
-			ggp_status_got_others_buddy(gc, notify[i].uin,
-				GG_S(notify[i].status), notify[i].descr);
-	} else if (ev->type == GG_EVENT_STATUS60) {
-		struct gg_event_status60 *notify = &ev->event.status60;
-		ggp_status_got_others_buddy(gc, notify->uin,
-			GG_S(notify->status), notify->descr);
-	} else {
-		purple_debug_error("gg", "ggp_status_got_others: unexpected event %d",
-		                   ev->type);
-	}
-}
-
-void ggp_status_got_others_buddy(PurpleConnection *gc, uin_t uin, int status,
-	const char *descr)
-{
-	PurpleAccount *account = purple_connection_get_account(gc);
-	PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
-	PurpleBuddy *buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin));
-	const gchar *purple_status = ggp_status_to_purplestatus(status);
-	gchar *status_message = NULL;
-	gboolean is_own;
-
-	is_own = (!g_strcmp0(ggp_uin_to_str(uin),
-	                     purple_contact_info_get_username(info)));
-
-	if (!buddy) {
-		if (!is_own) {
-			purple_debug_warning("gg",
-				"ggp_status_got_others_buddy: "
-				"buddy %u not found\n", uin);
-		}
-		return;
-	}
-	ggp_buddy_get_data(buddy)->blocked = (status == GG_STATUS_BLOCKED);
-	ggp_buddy_get_data(buddy)->not_a_friend = (status == GG_STATUS_UNKNOWN);
-
-	if (descr != NULL) {
-		status_message = g_strdup(descr);
-		g_strstrip(status_message);
-		if (status_message[0] == '\0') {
-			g_free(status_message);
-			status_message = NULL;
-		}
-	}
-
-	if (uin == ggp_str_to_uin(purple_contact_info_get_username(info))) {
-		purple_debug_info("gg", "ggp_status_got_others_buddy: "
-			"own status changed to %s [%s]\n",
-			purple_status, status_message ? status_message : "");
-	} else if (purple_debug_is_verbose()) {
-		purple_debug_misc("gg", "ggp_status_got_others_buddy: "
-			"status of %u changed to %s [%s]\n", uin,
-			purple_status, status_message ? status_message : "");
-	}
-
-	if (status_message) {
-		purple_protocol_got_user_status(account, ggp_uin_to_str(uin),
-			purple_status, "message", status_message, NULL);
-	} else {
-		purple_protocol_got_user_status(account, ggp_uin_to_str(uin),
-			purple_status, NULL);
-	}
-
-	g_free(status_message);
-}
diff --git a/libpurple/protocols/gg/tcpsocket.h b/libpurple/protocols/gg/tcpsocket.h
deleted file mode 100644
--- a/libpurple/protocols/gg/tcpsocket.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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_GG_TCPSOCKET_H
-#define PURPLE_GG_TCPSOCKET_H
-
-#include <purple.h>
-#include <libgadu.h>
-
-void
-ggp_tcpsocket_setup(PurpleConnection *gc, struct gg_login_params *glp);
-
-PurpleInputCondition
-ggp_tcpsocket_inputcond_gg_to_purple(enum gg_check_t check);
-
-#endif /* PURPLE_GG_TCPSOCKET_H */
diff --git a/libpurple/protocols/gg/tcpsocket.c b/libpurple/protocols/gg/tcpsocket.c
deleted file mode 100644
--- a/libpurple/protocols/gg/tcpsocket.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/* 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.
- *
- * Component written by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * This file is dual-licensed under the GPL2+ and the X11 (MIT) licences.
- * As a recipient of this file you may choose, which license to receive the
- * code under. As a contributor, you have to ensure the new code is
- * compatible with both.
- *
- * 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 <errno.h>
-
-#include <purple.h>
-
-#include "tcpsocket.h"
-
-#include "gg.h"
-
-
-typedef struct {
-	GSocketConnection *conn;
-	GCancellable *cancellable;
-	PurpleConnection *gc;
-	gpointer priv_gg;
-} GGPTcpSocketData;
-
-static void
-ggp_tcp_socket_data_free(GGPTcpSocketData *data)
-{
-	g_return_if_fail(data != NULL);
-
-	if (data->cancellable != NULL) {
-		g_cancellable_cancel(data->cancellable);
-		g_clear_object(&data->cancellable);
-	}
-
-	if (data->conn != NULL) {
-		purple_gio_graceful_close(G_IO_STREAM(data->conn), NULL, NULL);
-		g_clear_object(&data->conn);
-	}
-
-	g_free(data);
-}
-
-static void
-ggp_tcpsocket_connected(GObject *source, GAsyncResult *res, gpointer user_data)
-{
-	GGPTcpSocketData *data = user_data;
-	GSocketConnection *conn;
-	GSocket *socket;
-	int fd = -1;
-	GGPInfo *info;
-	GError *error = NULL;
-
-	conn = g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(source),
-			res, &error);
-
-	if (conn == NULL) {
-		if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-			/* The connection was already closed, return now */
-			g_clear_error(&error);
-			return;
-		}
-
-		purple_debug_error("gg", "socket failed to connect: %s",
-				error->message);
-		g_clear_error(&error);
-	} else {
-		data->conn = conn;
-
-		socket = g_socket_connection_get_socket(data->conn);
-
-		if (socket != NULL) {
-			fd = g_socket_get_fd(socket);
-		}
-	}
-
-	/* XXX: For some reason if you try to connect and then immediately
-	 * disconnect, this gets into a state where ggp_tcpsocket_close()
-	 * isn't called. The cancellable is therefore not cancelled, and
-	 * the connection is never closed. Guard against that state here.
-	 */
-	if (data->gc == NULL ||
-			!g_list_find(purple_connections_get_all(), data->gc)) {
-		purple_debug_error("gg",
-				"disconnected without closing connection: %p",
-				data);
-		ggp_tcp_socket_data_free(data);
-		return;
-	}
-
-	if (!gg_socket_manager_connected(data, data->priv_gg, fd)) {
-		purple_debug_error("gg", "socket not handled");
-		ggp_tcp_socket_data_free(data);
-		return;
-	}
-
-	info = purple_connection_get_protocol_data(data->gc);
-
-	g_clear_handle_id(&info->inpa, g_source_remove);
-
-	if (info->session->fd < 0)
-		return;
-
-	/* XXX: This works, but not recommended to use GSocket FDs directly */
-	info->inpa = purple_input_add(info->session->fd,
-		ggp_tcpsocket_inputcond_gg_to_purple(info->session->check),
-		ggp_async_login_handler, data->gc);
-}
-
-static void*
-ggp_tcpsocket_connect(void *_gc, const char *host, int port, int is_tls,
-	int is_async, void *priv)
-{
-	PurpleConnection *gc = _gc;
-	GGPTcpSocketData *data;
-	GSocketClient *client;
-	GError *error = NULL;
-
-	PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
-
-	g_return_val_if_fail(host != NULL, NULL);
-	g_return_val_if_fail(is_async, NULL);
-
-	purple_debug_misc("gg", "ggp_tcpsocket_connect(%p, %s:%d, %s, %p)",
-		gc, host, port, is_tls ? "tls" : "tcp", priv);
-
-	client = purple_gio_socket_client_new(
-			purple_connection_get_account(gc), &error);
-
-	if (client == NULL) {
-		purple_debug_error("gg", "unable to connect: %s",
-				error->message);
-		g_clear_error(&error);
-		return NULL;
-	}
-
-	g_socket_client_set_tls(client, is_tls);
-
-	data = g_new0(GGPTcpSocketData, 1);
-	data->cancellable = g_cancellable_new();
-	data->gc = gc;
-	data->priv_gg = priv;
-
-	g_socket_client_connect_to_host_async(client, host, port,
-			data->cancellable, ggp_tcpsocket_connected, data);
-	g_object_unref(client);
-
-	return data;
-}
-
-static void
-ggp_tcpsocket_close(G_GNUC_UNUSED void *_gc, void *_data) {
-	GGPTcpSocketData *data = _data;
-
-	ggp_tcp_socket_data_free(data);
-}
-
-static ssize_t
-ggp_tcpsocket_read(G_GNUC_UNUSED void *_gc, void *_data,
-                   unsigned char *buffer, size_t bufsize)
-{
-	GGPTcpSocketData *data = _data;
-	GPollableInputStream *input;
-	gssize ret;
-	GError *error = NULL;
-
-	if (data->conn == NULL) {
-		return -1;
-	}
-
-	input = G_POLLABLE_INPUT_STREAM(
-			g_io_stream_get_input_stream(G_IO_STREAM(data->conn)));
-	ret = g_pollable_input_stream_read_nonblocking(input,
-			buffer, bufsize, NULL, &error);
-
-	if (ret < 0) {
-		if (g_error_matches(error,
-				G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
-			errno = EAGAIN;
-		} else {
-			purple_debug_error("gg", "socket read error: %s",
-					error->message);
-		}
-
-		g_clear_error(&error);
-	}
-
-	return ret;
-}
-
-static ssize_t
-ggp_tcpsocket_write(G_GNUC_UNUSED void *_gc, void *_data,
-                    const unsigned char *data_buf, size_t len)
-{
-	GGPTcpSocketData *data = _data;
-	GPollableOutputStream *output;
-	gssize ret;
-	GError *error = NULL;
-
-	if (data->conn == NULL) {
-		return -1;
-	}
-
-	output = G_POLLABLE_OUTPUT_STREAM(
-			g_io_stream_get_output_stream(G_IO_STREAM(data->conn)));
-	ret = g_pollable_output_stream_write_nonblocking(output,
-			data_buf, len, NULL, &error);
-
-	if (ret < 0) {
-		if (g_error_matches(error,
-				G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
-			errno = EAGAIN;
-		} else {
-			purple_debug_error("gg", "socket write error: %s",
-					error->message);
-		}
-
-		g_clear_error(&error);
-	}
-
-	return ret;
-}
-
-void
-ggp_tcpsocket_setup(PurpleConnection *gc, struct gg_login_params *glp)
-{
-	glp->socket_manager_type = GG_SOCKET_MANAGER_TYPE_TLS;
-	glp->socket_manager.cb_data = gc;
-	glp->socket_manager.connect_cb = ggp_tcpsocket_connect;
-	glp->socket_manager.close_cb = ggp_tcpsocket_close;
-	glp->socket_manager.read_cb = ggp_tcpsocket_read;
-	glp->socket_manager.write_cb = ggp_tcpsocket_write;
-}
-
-PurpleInputCondition
-ggp_tcpsocket_inputcond_gg_to_purple(enum gg_check_t check)
-{
-	PurpleInputCondition cond = 0;
-
-	if (check & GG_CHECK_READ)
-		cond |= PURPLE_INPUT_READ;
-	if (check & GG_CHECK_WRITE)
-		cond |= PURPLE_INPUT_WRITE;
-
-	return cond;
-}
diff --git a/libpurple/protocols/gg/utils.h b/libpurple/protocols/gg/utils.h
deleted file mode 100644
--- a/libpurple/protocols/gg/utils.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_UTILS_H
-#define PURPLE_GG_UTILS_H
-
-#include <libgadu.h>
-#include <json-glib/json-glib.h>
-
-#include <purple.h>
-
-/**
- * Converts stringified UIN to uin_t.
- *
- * @param str The string to convert.
- *
- * @return Converted UIN or 0 if an error occurred.
- */
-uin_t ggp_str_to_uin(const char *str);
-
-/**
- * Stringifies UIN.
- *
- * @param uin UIN to stringify.
- *
- * @return Stringified UIN.
- */
-const char * ggp_uin_to_str(uin_t uin);
-
-/**
- * Gets UIN for the account.
- *
- * @param gc The connection, in which account is connected.
- * @return UIN for this account.
- */
-uin_t ggp_get_my_uin(PurpleConnection *gc);
-
-/**
- * Converts encoding of a given string from UTF-8 to CP1250.
- *
- * @param src Input string.
- *
- * @return Converted string (must be freed with g_free). If src is NULL,
- * then NULL is returned.
- */
-gchar * ggp_convert_to_cp1250(const gchar *src);
-
-/**
- * Converts encoding of a given string from CP1250 to UTF-8.
- *
- * @param src Input string.
- *
- * @return Converted string (must be freed with g_free). If src is NULL,
- * then NULL is returned.
- */
-gchar * ggp_convert_from_cp1250(const gchar *src);
-
-gchar * ggp_utf8_strndup(const gchar *str, gsize n);
-
-const gchar * ggp_ipv4_to_str(uint32_t raw_ip);
-
-gchar * ggp_free_if_equal(gchar *str, const gchar *pattern);
-
-uint64_t * ggp_uint64dup(uint64_t val);
-
-JsonParser * ggp_json_parse(const gchar *data);
-
-#endif /* PURPLE_GG_UTILS_H */
diff --git a/libpurple/protocols/gg/utils.c b/libpurple/protocols/gg/utils.c
deleted file mode 100644
--- a/libpurple/protocols/gg/utils.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 <errno.h>
-#include <netinet/in.h>
-
-#include <purple.h>
-
-#include "utils.h"
-
-#include "gg.h"
-
-uin_t ggp_str_to_uin(const char *str)
-{
-	char *endptr;
-	uin_t uin;
-
-	if (!str || str[0] < '0' || str[0] > '9')
-		return 0;
-
-	errno = 0;
-	uin = strtoul(str, &endptr, 10);
-
-	if (errno == ERANGE || endptr[0] != '\0')
-		return 0;
-
-	return uin;
-}
-
-const char * ggp_uin_to_str(uin_t uin)
-{
-	static char buff[GGP_UIN_LEN_MAX + 1];
-
-	g_snprintf(buff, GGP_UIN_LEN_MAX + 1, "%u", uin);
-
-	return buff;
-}
-
-uin_t
-ggp_get_my_uin(PurpleConnection *gc) {
-	PurpleAccount *account = purple_connection_get_account(gc);
-	PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
-
-	g_return_val_if_fail(gc != NULL, 0);
-
-	return ggp_str_to_uin(purple_contact_info_get_username(info));
-}
-
-static gchar * ggp_convert(const gchar *src, const char *srcenc,
-	const char *dstenc)
-{
-	gchar *dst;
-	GError *err = NULL;
-
-	if (src == NULL)
-		return NULL;
-
-	dst = g_convert_with_fallback(src, strlen(src), dstenc, srcenc, "?",
-		NULL, NULL, &err);
-	if (err != NULL) {
-		purple_debug_error("gg", "error converting from %s to %s: %s\n",
-			srcenc, dstenc, err->message);
-		g_error_free(err);
-	}
-
-	if (dst == NULL)
-		dst = g_strdup(src);
-
-	return dst;
-}
-
-gchar * ggp_convert_to_cp1250(const gchar *src)
-{
-	return ggp_convert(src, "UTF-8", "CP1250");
-}
-
-gchar * ggp_convert_from_cp1250(const gchar *src)
-{
-	return ggp_convert(src, "CP1250", "UTF-8");
-}
-
-gchar * ggp_utf8_strndup(const gchar *str, gsize n)
-{
-	size_t raw_len;
-	gchar *end_ptr;
-	if (str == NULL)
-		return NULL;
-	raw_len = strlen(str);
-	if (raw_len <= n)
-		return g_strdup(str);
-
-	end_ptr = g_utf8_offset_to_pointer(str, g_utf8_pointer_to_offset(str, &str[n]));
-	raw_len = end_ptr - str;
-
-	if (raw_len > n) {
-		end_ptr = g_utf8_prev_char(end_ptr);
-		raw_len = end_ptr - str;
-	}
-
-	g_assert(raw_len <= n);
-
-	return g_strndup(str, raw_len);
-}
-
-const gchar * ggp_ipv4_to_str(uint32_t raw_ip)
-{
-	static gchar buff[INET_ADDRSTRLEN];
-	buff[0] = '\0';
-
-	g_snprintf(buff, sizeof(buff), "%d.%d.%d.%d",
-		((raw_ip >>  0) & 0xFF),
-		((raw_ip >>  8) & 0xFF),
-		((raw_ip >> 16) & 0xFF),
-		((raw_ip >> 24) & 0xFF));
-
-	return buff;
-}
-
-gchar * ggp_free_if_equal(gchar *str, const gchar *pattern)
-{
-	if (g_strcmp0(str, pattern) == 0) {
-		g_free(str);
-		return NULL;
-	}
-	return str;
-}
-
-uint64_t * ggp_uint64dup(uint64_t val)
-{
-	uint64_t *ptr = g_new(uint64_t, 1);
-	*ptr = val;
-	return ptr;
-}
-
-JsonParser * ggp_json_parse(const gchar *data)
-{
-	JsonParser *parser;
-
-	parser = json_parser_new();
-	if (json_parser_load_from_data(parser, data, -1, NULL))
-		return parser;
-
-	if (purple_debug_is_unsafe())
-		purple_debug_warning("gg", "Invalid JSON: %s\n", data);
-	return NULL;
-}
diff --git a/libpurple/protocols/gg/validator.h b/libpurple/protocols/gg/validator.h
deleted file mode 100644
--- a/libpurple/protocols/gg/validator.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_VALIDATOR_H
-#define PURPLE_GG_VALIDATOR_H
-
-#include <purple.h>
-
-gboolean ggp_validator_password(PurpleRequestField *field, gchar **errmsg,
-	void *user_data);
-
-gboolean ggp_validator_password_equal(PurpleRequestField *field, gchar **errmsg,
-	void *field2);
-
-#endif /* PURPLE_GG_VALIDATOR_H */
diff --git a/libpurple/protocols/gg/validator.c b/libpurple/protocols/gg/validator.c
deleted file mode 100644
--- a/libpurple/protocols/gg/validator.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 "validator.h"
-
-#include "utils.h"
-
-#include <glib/gi18n-lib.h>
-
-gboolean
-ggp_validator_password(PurpleRequestField *field, gchar **errmsg,
-                       G_GNUC_UNUSED gpointer data)
-{
-	const char *value;
-
-	g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field), FALSE);
-
-	value = purple_request_field_string_get_value(PURPLE_REQUEST_FIELD_STRING(field));
-
-	if (value != NULL) {
-		size_t len = strlen(value);
-		if (6 <= len && len <= 15) {
-			if (g_regex_match_simple(
-			            "^[ a-zA-Z0-9~`!@#$%^&*()_+=[\\]{};':\",./?<>\\\\|-]+$",
-			            value, 0, 0)) {
-				return TRUE;
-			}
-		}
-	}
-
-	if (errmsg)
-		*errmsg = g_strdup(_("Password can contain 6-15 alphanumeric characters"));
-	return FALSE;
-}
-
-gboolean ggp_validator_password_equal(PurpleRequestField *field, gchar **errmsg,
-	void *field2_p)
-{
-	const char *value1, *value2;
-	PurpleRequestField *field2 = field2_p;
-
-	g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field), FALSE);
-	g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field2), FALSE);
-
-	value1 = purple_request_field_string_get_value(PURPLE_REQUEST_FIELD_STRING(field));
-	value2 = purple_request_field_string_get_value(PURPLE_REQUEST_FIELD_STRING(field2));
-
-	if (g_strcmp0(value1, value2) == 0)
-		return TRUE;
-
-	if (errmsg)
-		*errmsg = g_strdup(_("Passwords do not match"));
-	return FALSE;
-}
diff --git a/libpurple/protocols/gg/xml.h b/libpurple/protocols/gg/xml.h
deleted file mode 100644
--- a/libpurple/protocols/gg/xml.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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_GG_XML_H
-#define PURPLE_GG_XML_H
-
-#include <purple.h>
-
-gboolean ggp_xml_get_string(const PurpleXmlNode *xml, const gchar *childName, gchar **var);
-gboolean ggp_xml_get_bool(const PurpleXmlNode *xml, const gchar *childName, gboolean *var);
-gboolean ggp_xml_get_uint(const PurpleXmlNode *xml, const gchar *childName, unsigned int *var);
-
-gboolean ggp_xml_set_string(PurpleXmlNode *xml, const gchar *childName, const gchar *val);
-gboolean ggp_xml_set_bool(PurpleXmlNode *xml, const gchar *childName, gboolean val);
-gboolean ggp_xml_set_uint(PurpleXmlNode *xml, const gchar *childName, unsigned int val);
-
-void ggp_xmlnode_remove_children(PurpleXmlNode *xml);
-
-unsigned int ggp_xml_child_count(PurpleXmlNode *xml, const gchar *childName);
-
-#endif /* PURPLE_GG_XML_H */
diff --git a/libpurple/protocols/gg/xml.c b/libpurple/protocols/gg/xml.c
deleted file mode 100644
--- a/libpurple/protocols/gg/xml.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/* 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.
- *
- * Rewritten from scratch during Google Summer of Code 2012
- * by Tomek Wasilczyk (http://www.wasilczyk.pl).
- *
- * Previously implemented by:
- *  - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
- *  - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
- *  - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
- *
- * 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 <errno.h>
-
-#include "xml.h"
-
-gboolean
-ggp_xml_get_string(const PurpleXmlNode *xml, const gchar *childName, gchar **var)
-{
-	char *str;
-
-	g_return_val_if_fail(xml != NULL, FALSE);
-	g_return_val_if_fail(var != NULL, FALSE);
-
-	if (childName != NULL) {
-		xml = purple_xmlnode_get_child(xml, childName);
-		if (xml == NULL)
-			return FALSE;
-	}
-
-	str = purple_xmlnode_get_data(xml);
-	if (str == NULL)
-		return FALSE;
-
-	*var = str;
-	return TRUE;
-}
-
-gboolean
-ggp_xml_get_bool(const PurpleXmlNode *xml, const gchar *childName, gboolean *var)
-{
-	char *str;
-	gboolean succ;
-
-	succ = ggp_xml_get_string(xml, childName, &str);
-	if (!succ)
-		return FALSE;
-
-	*var = (strcmp(str, "true") == 0 ||
-		strcmp(str, "True") == 0 ||
-		strcmp(str, "TRUE") == 0 ||
-		strcmp(str, "1") == 0);
-	g_free(str);
-
-	return TRUE;
-}
-
-gboolean
-ggp_xml_get_uint(const PurpleXmlNode *xml, const gchar *childName, unsigned int *var)
-{
-	char *str, *endptr;
-	gboolean succ;
-	unsigned int val;
-
-	succ = ggp_xml_get_string(xml, childName, &str);
-	if (!succ)
-		return FALSE;
-
-	errno = 0;
-	val = strtoul(str, &endptr, 10);
-
-	succ = (errno != ERANGE && endptr[0] == '\0');
-	g_free(str);
-
-	if (succ)
-		*var = val;
-	return succ;
-}
-
-gboolean
-ggp_xml_set_string(PurpleXmlNode *xml, const gchar *childName, const gchar *val)
-{
-	g_return_val_if_fail(xml != NULL, FALSE);
-	g_return_val_if_fail(val != NULL, FALSE);
-
-	if (childName != NULL) {
-		PurpleXmlNode *child = purple_xmlnode_get_child(xml, childName);
-		if (child == NULL)
-			child = purple_xmlnode_new_child(xml, childName);
-		xml = child;
-	}
-
-	ggp_xmlnode_remove_children(xml);
-	purple_xmlnode_insert_data(xml, val, -1);
-
-	return TRUE;
-}
-
-gboolean
-ggp_xml_set_bool(PurpleXmlNode *xml, const gchar *childName, gboolean val)
-{
-	return ggp_xml_set_string(xml, childName, val ? "true" : "false");
-}
-
-gboolean
-ggp_xml_set_uint(PurpleXmlNode *xml, const gchar *childName, unsigned int val)
-{
-	gchar buff[20];
-	g_snprintf(buff, sizeof(buff), "%u", val);
-	return ggp_xml_set_string(xml, childName, buff);
-}
-
-void ggp_xmlnode_remove_children(PurpleXmlNode *xml)
-{
-	PurpleXmlNode *child = xml->child;
-	while (child) {
-		PurpleXmlNode *next = child->next;
-		if (child->type != PURPLE_XMLNODE_TYPE_ATTRIB)
-			purple_xmlnode_free(child);
-		child = next;
-	}
-}
-
-unsigned int ggp_xml_child_count(PurpleXmlNode *xml, const gchar *childName)
-{
-	PurpleXmlNode *child;
-	unsigned int count = 0;
-
-	g_return_val_if_fail(xml != NULL, 0);
-
-	if (childName) {
-		child = purple_xmlnode_get_child(xml, childName);
-		while (child) {
-			child = purple_xmlnode_get_next_twin(child);
-			count++;
-		}
-	} else {
-		child = xml->child;
-		while (child) {
-			child = child->next;
-			count++;
-		}
-	}
-
-	return count;
-}
diff --git a/libpurple/protocols/meson.build b/libpurple/protocols/meson.build
--- a/libpurple/protocols/meson.build
+++ b/libpurple/protocols/meson.build
@@ -1,3 +1,2 @@
 subdir('bonjour')
-subdir('gg')
 subdir('jabber')
diff --git a/meson.build b/meson.build
--- a/meson.build
+++ b/meson.build
@@ -276,35 +276,13 @@
 endif
 
 #######################################################################
-# Check for Gadu-Gadu protocol library (libgadu)
-#######################################################################
-
-libgadu = dependency('libgadu', version : '>= 1.12.0', required : get_option('libgadu'))
-
-if libgadu.found()
-	if not compiler.has_function('gg_is_gpl_compliant', dependencies : libgadu)
-		if get_option('libgadu').auto()
-			libgadu = disabler()
-		else
-			message('''
-libgadu is not compatible with the GPL when compiled with OpenSSL support.
-
-To link against libgadu, please recompile it using:
-./configure --with-openssl=no
-Then rerun this Meson build
-			''')
-		endif
-	endif
-endif
-
-#######################################################################
 # Check for Xeme XMPP Library
 #######################################################################
 xeme = dependency('xeme')
 
 dependency('shoes', required : false)
 
-DEFAULT_PRPLS = ['bonjour', 'demo', 'gg', 'ircv3', 'jabber', 'xmpp']
+DEFAULT_PRPLS = ['bonjour', 'demo', 'ircv3', 'jabber', 'xmpp']
 
 dynamic_list = get_option('dynamic-prpls').split(',')
 if dynamic_list == ['all']
@@ -316,8 +294,6 @@
 		# The list was empty; do nothing.
 	elif prpl == 'bonjour' and not enable_avahi
 		# Do nothing.
-	elif prpl == 'gg' and not libgadu.found()
-		# Do nothing.
 	elif prpl == 'xmpp' and not xeme.found()
 		# Do nothing.
 	else
@@ -327,7 +303,6 @@
 
 DYNAMIC_BONJOUR = DYNAMIC_PRPLS.contains('bonjour')
 DYNAMIC_DEMO = DYNAMIC_PRPLS.contains('demo')
-DYNAMIC_GG  = DYNAMIC_PRPLS.contains('gg')
 DYNAMIC_IRCV3 = DYNAMIC_PRPLS.contains('ircv3')
 DYNAMIC_JABBER = DYNAMIC_PRPLS.contains('jabber')
 DYNAMIC_XMPP = DYNAMIC_PRPLS.contains('xmpp')
