# HG changeset patch
# Node ID 66ce8fd431d9
# Parent  d57c56146156
diff --git a/libpurple/meson.build b/libpurple/meson.build
--- a/libpurple/meson.build
+++ b/libpurple/meson.build
@@ -96,7 +96,6 @@
 	'signals.c',
 	'status.c',
 	'stun.c',
-	'trie.c',
 	'upnp.c',
 	'util.c',
 	'version.c',
@@ -201,7 +200,6 @@
 	'status.h',
 	'stun.h',
 	'tests.h',
-	'trie.h',
 	'upnp.h',
 	'util.h',
 	'xfer.h',
diff --git a/libpurple/tests/meson.build b/libpurple/tests/meson.build
--- a/libpurple/tests/meson.build
+++ b/libpurple/tests/meson.build
@@ -17,7 +17,6 @@
     'protocol_xfer',
     'purplepath',
     'queued_output_stream',
-    'trie',
     'util',
     'whiteboard_manager',
     'xmlnode',
diff --git a/libpurple/tests/test_trie.c b/libpurple/tests/test_trie.c
deleted file mode 100644
--- a/libpurple/tests/test_trie.c
+++ /dev/null
@@ -1,372 +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
- *
- * 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 <purple.h>
-
-static gint find_sum;
-
-static gboolean
-test_trie_replace_cb(GString *out, const gchar *word, gpointer word_data,
-	gpointer user_data)
-{
-	/* the "test" word for the test_trie_replace test */
-	if ((gintptr)word_data == 0x1001)
-		return FALSE;
-
-	g_string_append_printf(out, "[%d:%x]",
-		(int)(gintptr)user_data, (int)(gintptr)word_data);
-
-	return TRUE;
-}
-
-static gboolean
-test_trie_find_cb(const gchar *word, gpointer word_data,
-	gpointer user_data)
-{
-	if ((gintptr)word_data == 0x7004)
-		return FALSE;
-
-	find_sum += (gintptr)word_data;
-	find_sum -= (gintptr)user_data * 0x1000;
-
-	return TRUE;
-}
-
-static void
-test_trie_replace_normal(void) {
-	PurpleTrie *trie;
-	const gchar *in;
-	gchar *out;
-
-	trie = purple_trie_new();
-	purple_trie_set_reset_on_match(trie, FALSE);
-
-	purple_trie_add(trie, "test", (gpointer)0x1001);
-	purple_trie_add(trie, "testing", (gpointer)0x1002);
-	purple_trie_add(trie, "overtested", (gpointer)0x1003);
-	purple_trie_add(trie, "trie", (gpointer)0x1004);
-	purple_trie_add(trie, "tree", (gpointer)0x1005);
-	purple_trie_add(trie, "implement", (gpointer)0x1006);
-	purple_trie_add(trie, "implementation", (gpointer)0x1007);
-
-	in = "Alice is testing her trie implementation, "
-		"but she's far away from making test tree overtested";
-
-	out = purple_trie_replace(trie, in, test_trie_replace_cb, (gpointer)1);
-
-	g_assert_cmpstr(
-		"Alice is [1:1002] her [1:1004] [1:1006]ation,"
-		" but she's far away from making test [1:1005] [1:1003]",
-		==,
-		out
-	);
-
-	g_object_unref(trie);
-	g_free(out);
-}
-
-static void
-test_trie_replace_whole(void) {
-	PurpleTrie *trie;
-	const gchar *in;
-	gchar *out;
-
-	trie = purple_trie_new();
-
-	purple_trie_add(trie, "test", (gpointer)0x2002);
-
-	in = "test";
-
-	out = purple_trie_replace(trie, in, test_trie_replace_cb, (gpointer)2);
-
-	g_assert_cmpstr("[2:2002]", ==, out);
-
-	g_object_unref(trie);
-	g_free(out);
-}
-
-static void
-test_trie_replace_inner(void) {
-	PurpleTrie *trie;
-	const gchar *in;
-	gchar *out;
-
-	trie = purple_trie_new();
-
-	purple_trie_add(trie, "est", (gpointer)0x3001);
-	purple_trie_add(trie, "tester", (gpointer)0x3002);
-
-	in = "the test!";
-
-	out = purple_trie_replace(trie, in, test_trie_replace_cb, (gpointer)3);
-
-	g_assert_cmpstr("the t[3:3001]!", ==, out);
-
-	g_object_unref(trie);
-	g_free(out);
-}
-
-
-static void
-test_trie_replace_empty(void) {
-	PurpleTrie *trie;
-	const gchar *in;
-	gchar *out;
-
-	trie = purple_trie_new();
-
-	purple_trie_add(trie, "test", (gpointer)0x4001);
-
-	in = "";
-
-	out = purple_trie_replace(trie, in, test_trie_replace_cb, (gpointer)4);
-
-	g_assert_cmpstr("", ==, out);
-
-	g_object_unref(trie);
-	g_free(out);
-}
-
-static void
-test_trie_multi_replace(void) {
-	PurpleTrie *trie1, *trie2, *trie3;
-	GSList *tries = NULL;
-	const gchar *in;
-	gchar *out;
-
-	trie1 = purple_trie_new();
-	trie2 = purple_trie_new();
-	trie3 = purple_trie_new();
-
-	/* appending is not efficient, but we have only 3 elements */
-	tries = g_slist_append(tries, trie1);
-	tries = g_slist_append(tries, trie2);
-	tries = g_slist_append(tries, trie3);
-
-	purple_trie_add(trie1, "test", (gpointer)0x5011);
-	purple_trie_add(trie1, "trie1", (gpointer)0x5012);
-	purple_trie_add(trie1, "Alice", (gpointer)0x5013);
-
-	purple_trie_add(trie2, "test", (gpointer)0x5021);
-	purple_trie_add(trie2, "trie2", (gpointer)0x5022);
-	purple_trie_add(trie2, "example", (gpointer)0x5023);
-	purple_trie_add(trie2, "Ali", (gpointer)0x5024);
-
-	/* "tester" without last (accepting) letter of "test" */
-	purple_trie_add(trie3, "teser", (gpointer)0x5031);
-	purple_trie_add(trie3, "trie3", (gpointer)0x5032);
-	purple_trie_add(trie3, "tester", (gpointer)0x5033);
-	purple_trie_add(trie3, "example", (gpointer)0x5034);
-	purple_trie_add(trie3, "Al", (gpointer)0x5035);
-
-	in = "test tester trie trie1 trie2 trie3 example Alice";
-
-	out = purple_trie_multi_replace(tries, in,
-		test_trie_replace_cb, (gpointer)5);
-
-	g_assert_cmpstr(
-		"[5:5011] [5:5011]er trie [5:5012] [5:5022] "
-		"[5:5032] [5:5023] [5:5035]ice",
-		==,
-		out
-	);
-
-	g_slist_free_full(tries, g_object_unref);
-	g_free(out);
-}
-
-static void
-test_trie_remove(void) {
-	PurpleTrie *trie;
-	const gchar *in;
-	gchar *out;
-
-	trie = purple_trie_new();
-
-	purple_trie_add(trie, "alice", (gpointer)0x6001);
-	purple_trie_add(trie, "bob", (gpointer)0x6002);
-	purple_trie_add(trie, "cherry", (gpointer)0x6003);
-
-	purple_trie_remove(trie, "bob");
-
-	in = "alice bob cherry";
-
-	out = purple_trie_replace(trie, in, test_trie_replace_cb, (gpointer)6);
-
-	g_assert_cmpstr("[6:6001] bob [6:6003]", ==, out);
-
-	g_object_unref(trie);
-	g_free(out);
-}
-
-static void
-test_trie_find_normal(void) {
-	PurpleTrie *trie;
-	const gchar *in;
-	gint out;
-
-	trie = purple_trie_new();
-
-	purple_trie_add(trie, "alice", (gpointer)0x7001);
-	purple_trie_add(trie, "bob", (gpointer)0x7002);
-	purple_trie_add(trie, "cherry", (gpointer)0x7003);
-	purple_trie_add(trie, "al", (gpointer)0x7004); /* not accepted */
-
-	in = "test alice bob test cherry alice";
-
-	find_sum = 0;
-	out = purple_trie_find(trie, in, test_trie_find_cb, (gpointer)7);
-
-	g_assert_cmpint(4, ==, out);
-	g_assert_cmpint(2 * 1 + 2 + 3, ==, find_sum);
-
-	g_object_unref(trie);
-}
-
-static void
-test_trie_find_reset(void) {
-	PurpleTrie *trie;
-	const gchar *in;
-	gint out;
-
-	trie = purple_trie_new();
-	purple_trie_set_reset_on_match(trie, TRUE);
-
-	purple_trie_add(trie, "alice", (gpointer)0x8001);
-	purple_trie_add(trie, "ali", (gpointer)0x8002);
-	purple_trie_add(trie, "al", (gpointer)0x8003);
-
-	in = "al ali alice";
-
-	find_sum = 0;
-	out = purple_trie_find(trie, in, test_trie_find_cb, (gpointer)8);
-
-	g_assert_cmpint(3, ==, out);
-	g_assert_cmpint(3 * 3, ==, find_sum);
-
-	g_object_unref(trie);
-}
-
-static void
-test_trie_find_noreset(void) {
-	PurpleTrie *trie;
-	const gchar *in;
-	gint out;
-
-	trie = purple_trie_new();
-	purple_trie_set_reset_on_match(trie, FALSE);
-
-	purple_trie_add(trie, "alice", (gpointer)0x9001);
-	purple_trie_add(trie, "ali", (gpointer)0x9002);
-	purple_trie_add(trie, "al", (gpointer)0x9003);
-
-	in = "al ali alice";
-
-	find_sum = 0;
-	out = purple_trie_find(trie, in, test_trie_find_cb, (gpointer)9);
-
-	g_assert_cmpint(6, ==, out);
-	g_assert_cmpint(3 * 3 + 2 * 2 + 1, ==, find_sum);
-
-	g_object_unref(trie);
-}
-
-static void
-test_trie_multi_find(void) {
-	PurpleTrie *trie1, *trie2, *trie3;
-	GSList *tries = NULL;
-	const gchar *in;
-	int out;
-
-	trie1 = purple_trie_new();
-	trie2 = purple_trie_new();
-	trie3 = purple_trie_new();
-	purple_trie_set_reset_on_match(trie1, FALSE);
-	purple_trie_set_reset_on_match(trie2, TRUE);
-	purple_trie_set_reset_on_match(trie3, FALSE);
-
-	/* appending is not efficient, but we have only 3 elements */
-	tries = g_slist_append(tries, trie1);
-	tries = g_slist_append(tries, trie2);
-	tries = g_slist_append(tries, trie3);
-
-	purple_trie_add(trie1, "test", (gpointer)0x10011);
-	purple_trie_add(trie1, "trie1", (gpointer)0x10012);
-	purple_trie_add(trie1, "Alice", (gpointer)0x10013);
-
-	purple_trie_add(trie2, "test", (gpointer)0x10021);
-	purple_trie_add(trie2, "trie2", (gpointer)0x10022);
-	purple_trie_add(trie2, "example", (gpointer)0x10023);
-	purple_trie_add(trie2, "Ali", (gpointer)0x10024);
-
-	/* "tester" without last (accepting) letter of "test" */
-	purple_trie_add(trie3, "teser", (gpointer)0x10031);
-	purple_trie_add(trie3, "trie3", (gpointer)0x10032);
-	purple_trie_add(trie3, "tester", (gpointer)0x10033);
-	purple_trie_add(trie3, "example", (gpointer)0x10034);
-	purple_trie_add(trie3, "Al", (gpointer)0x10035);
-
-	in = "test tester trie trie1 trie2 trie3 example Alice";
-
-	out = purple_trie_multi_find(tries, in,
-		test_trie_find_cb, (gpointer)0x10);
-
-	g_assert_cmpint(9, ==, out);
-	g_assert_cmpint(2 * 0x11 + 0x33 + 0x12 + 0x22 +
-		0x32 + 0x23 + 0x35 + 0x13, ==, find_sum);
-
-	g_slist_free_full(tries, g_object_unref);
-}
-
-gint
-main(gint argc, gchar **argv) {
-	g_test_init(&argc, &argv, NULL);
-
-	g_test_add_func("/trie/replace/normal",
-	                test_trie_replace_normal);
-	g_test_add_func("/trie/replace/whole",
-	                test_trie_replace_whole);
-	g_test_add_func("/trie/replace/inner",
-	                test_trie_replace_inner);
-	g_test_add_func("/trie/replace/empty",
-	                test_trie_replace_empty);
-
-	g_test_add_func("/trie/multi_replace",
-	                test_trie_multi_replace);
-
-	g_test_add_func("/trie/remove",
-	                test_trie_remove);
-
-	g_test_add_func("/trie/find/normal",
-	                test_trie_find_normal);
-	g_test_add_func("/trie/find/reset",
-	                test_trie_find_reset);
-	g_test_add_func("/trie/find/noreset",
-	                test_trie_find_noreset);
-
-	g_test_add_func("/trie/multi_find",
-	                test_trie_multi_find);
-
-	return g_test_run();
-}
diff --git a/libpurple/trie.h b/libpurple/trie.h
deleted file mode 100644
--- a/libpurple/trie.h
+++ /dev/null
@@ -1,271 +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
- *
- * 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
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_TRIE_H
-#define PURPLE_TRIE_H
-
-#include <glib-object.h>
-
-/**
- * PURPLE_TYPE_TRIE:
- *
- * The standard _get_type macro for #PurpleTrie.
- */
-#define PURPLE_TYPE_TRIE purple_trie_get_type()
-
-/**
- * PurpleTrieReplaceCb:
- * @out: currently built output string, append replacement to it.
- * @word: found word.
- * @word_data: the user data bound with this word, when added with
- *             #purple_trie_add.
- * @user_data: the user supplied data passed when calling #purple_trie_replace.
- *
- * A function called on every matching substring to be replaced.
- *
- * If you decide to replace the word, append your text to @out and return %TRUE.
- * Otherwise, you must not touch @out. In both cases, you must not do any
- * operations on @out other than appending text to it.
- *
- * Returns: %TRUE if the word was replaced, %FALSE otherwise.
- */
-typedef gboolean (*PurpleTrieReplaceCb)(GString *out, const gchar *word,
-	gpointer word_data, gpointer user_data);
-
-/**
- * PurpleTrieFindCb:
- * @word: found word.
- * @word_data: the user data bound with this word, when added with
- *             #purple_trie_add.
- * @user_data: the user data passed when calling #purple_trie_find.
- *
- * A function called on every matching substring.
- *
- * You can decide to count the match or not (for the total number of found
- * words, that is returned by #purple_trie_find). In both cases you can
- * obviously do some processing outside the #PurpleTrie object.
- *
- * If you decide to count the word and #PurpleTrie:reset-on-match property
- * is set, no overlapping words will be found - the processing will skip after
- * the end of this word.
- *
- * Returns: %TRUE if the word should be counter, %FALSE otherwise.
- */
-typedef gboolean (*PurpleTrieFindCb)(const gchar *word, gpointer word_data,
-	gpointer user_data);
-
-G_BEGIN_DECLS
-
-/**
- * PurpleTrie:
- *
- * A #PurpleTrie is a structure for quick searching of multiple phrases within
- * a text. It's intended for repeated searches of the same set of patterns
- * within multiple source texts (or a single, big one).
- *
- * It's preparation time is <literal>O(p)</literal>, where <literal>p</literal>
- * is the total length of searched phrases. In current implementation, the
- * internal structure is invalidated after every modification of the
- * #PurpleTrie's contents, so it's not efficient to do alternating modifications
- * and searches. Search time does not depend on patterns being stored within
- * a trie and is always <literal>O(n)</literal>, where <literal>n</literal> is
- * the size of a text.
- *
- * Its main drawback is a significant memory usage - every internal trie node
- * needs about 1kB of memory on 32-bit machine and 2kB on 64-bit. Fortunately,
- * the trie grows slower when more words (with common prefixes) are added.
- * We could avoid invalidating the whole tree when altering it, but it would
- * require figuring out, how to update <literal>longest_suffix</literal> fields
- * in satisfying time.
- */
-
-/**
- * purple_trie_get_type:
- *
- * Returns: the #GType for a #PurpleTrie.
- */
-G_DECLARE_FINAL_TYPE(PurpleTrie, purple_trie, PURPLE, TRIE, GObject)
-
-/**
- * purple_trie_new:
- *
- * Creates a new trie.
- *
- * Returns: the new #PurpleTrie.
- */
-PurpleTrie *
-purple_trie_new(void);
-
-/**
- * purple_trie_get_reset_on_match:
- * @trie: the trie.
- *
- * Checks, if the trie will reset its internal state after every match.
- *
- * Returns: %TRUE, if trie will reset, %FALSE otherwise.
- */
-gboolean
-purple_trie_get_reset_on_match(PurpleTrie *trie);
-
-/**
- * purple_trie_set_reset_on_match:
- * @trie: the trie.
- * @reset: %TRUE, if trie should reset, %FALSE otherwise.
- *
- * Enables or disables a feature of resetting trie's state after every match.
- * When enabled, it will not search for overlapping matches.
- *
- * It's well defined for #purple_trie_find, but not for replace operations.
- * Thus, for the latter, it's better to stay with this option enabled, because
- * its behavior may be changed in future.
- */
-void
-purple_trie_set_reset_on_match(PurpleTrie *trie, gboolean reset);
-
-/**
- * purple_trie_add:
- * @trie: the trie.
- * @word: the word.
- * @data: the word-related data (may be %NULL).
- *
- * Adds a word to the trie. Current implementation doesn't allow for duplicates,
- * so please avoid adding those.
- *
- * Please note, that altering a trie invalidates its internal structure, so by
- * the occasion of next search, it will be rebuilt. It's done in
- * <literal>O(n)</literal>, where n is the total length of strings
- * in #PurpleTrie.
- *
- * Returns: %TRUE if succeeded, %FALSE otherwise.
- */
-gboolean
-purple_trie_add(PurpleTrie *trie, const gchar *word, gpointer data);
-
-/**
- * purple_trie_remove:
- * @trie: the trie.
- * @word: the word.
- *
- * Removes a word from the trie. Depending on used memory pool, this may not
- * free allocated memory (that will be freed when destroying the whole
- * collection), so use it wisely. See #purple_memory_pool_free.
- *
- * Please note, that altering a trie invalidates its internal structure.
- * See #purple_trie_add.
- */
-void
-purple_trie_remove(PurpleTrie *trie, const gchar *word);
-
-/**
- * purple_trie_get_size:
- * @trie: the trie.
- *
- * Returns the number of elements contained in the #PurpleTrie.
- *
- * Returns: the number of stored words in @trie.
- */
-guint
-purple_trie_get_size(PurpleTrie *trie);
-
-/**
- * purple_trie_replace:
- * @trie: the trie.
- * @src: the source string.
- * @replace_cb: (scope call): the replacement function.
- * @user_data: custom data to be passed to @replace_cb.
- *
- * Processes @src string and replaces all occuriences of words added to @trie.
- * It's <literal>O(strlen(src))</literal>, if @replace_cb runs in
- * <literal>O(strlen(word))</literal> and #PurpleTrie:reset-on-match is set.
- *
- * Returns: resulting string. Must be #g_free'd when you are done using it.
- */
-gchar *
-purple_trie_replace(PurpleTrie *trie, const gchar *src,
-	PurpleTrieReplaceCb replace_cb, gpointer user_data);
-
-/**
- * purple_trie_multi_replace:
- * @tries: (element-type PurpleTrie): the list of tries.
- * @src: the source string.
- * @replace_cb: (scope call): the replacement function.
- * @user_data: custom data to be passed to @replace_cb.
- *
- * Processes @src and replaces all occuriences of words added to tries in list
- * @tries. Entries added to tries on the beginning of the list have higher
- * priority, than ones added further.
- *
- * Different #GSList's can be combined to possess common parts, so you can create
- * a "tree of tries".
- *
- * Returns: resulting string. Must be #g_free'd when you are done using it.
- */
-gchar *
-purple_trie_multi_replace(const GSList *tries, const gchar *src,
-	PurpleTrieReplaceCb replace_cb, gpointer user_data);
-
-/**
- * purple_trie_find:
- * @trie: the trie.
- * @src: the source string.
- * @find_cb: (nullable) (scope call): the callback for the found entries (may be %NULL).
- * @user_data: custom data to be passed to @find_cb.
- *
- * Processes @src string and finds all occuriences of words added to @trie.
- * It's <literal>O(strlen(src))</literal>, if find_cb runs
- * in <literal>O(1)</literal>.
- *
- * The word is counted as found if it's found and the callback returns %TRUE.
- *
- * Returns: the number of found words.
- */
-gulong
-purple_trie_find(PurpleTrie *trie, const gchar *src,
-	PurpleTrieFindCb find_cb, gpointer user_data);
-
-/**
- * purple_trie_multi_find:
- * @tries: (element-type PurpleTrie): the list of tries.
- * @src: the source string.
- * @find_cb: (nullable) (scope call): the callback for the found entries (may be %NULL).
- * @user_data: custom data to be passed to @find_cb.
- *
- * Processes @src and replaces all occuriences of words added to tries in
- * list @tries. Entries added to tries on the beginning of the list have higher
- * priority, than ones added further.
- *
- * Different #GSList's can be combined to possess common parts, so you can create
- * a "tree of tries".
- *
- * Returns: the number of found words.
- */
-gulong
-purple_trie_multi_find(const GSList *tries, const gchar *src,
-	PurpleTrieFindCb find_cb, gpointer user_data);
-
-G_END_DECLS
-
-#endif /* PURPLE_MEMORY_POOL_H */
diff --git a/libpurple/trie.c b/libpurple/trie.c
deleted file mode 100644
--- a/libpurple/trie.c
+++ /dev/null
@@ -1,853 +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
- *
- * 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 "trie.h"
-
-#include <string.h>
-
-#include "debug.h"
-#include "memorypool.h"
-
-/* A single internal (that don't have any children) consists
- * of 256 + 4 pointers. That's 1040 bytes on 32-bit machine or 2080 bytes
- * on 64-bit.
- *
- * Thus, in 10500-byte pool block we can hold about 5-10 internal states.
- * Threshold of 100 states means, we'd need 10-20 "small" blocks before
- * switching to ~1-2 large blocks.
- */
-#define PURPLE_TRIE_LARGE_THRESHOLD 100
-#define PURPLE_TRIE_STATES_SMALL_POOL_BLOCK_SIZE 10880
-#define PURPLE_TRIE_STATES_LARGE_POOL_BLOCK_SIZE 102400
-
-typedef struct _PurpleTrieRecord PurpleTrieRecord;
-typedef struct _PurpleTrieState PurpleTrieState;
-typedef struct _PurpleTrieRecordList PurpleTrieRecordList;
-
-struct _PurpleTrie
-{
-	GObject parent;
-};
-
-typedef struct
-{
-	gboolean reset_on_match;
-
-	PurpleMemoryPool *records_str_mempool;
-	PurpleMemoryPool *records_obj_mempool;
-	PurpleTrieRecordList *records;
-	GHashTable *records_map;
-	gsize records_total_size;
-
-	PurpleMemoryPool *states_mempool;
-	PurpleTrieState *root_state;
-} PurpleTriePrivate;
-
-struct _PurpleTrieRecord
-{
-	gchar *word;
-	guint word_len;
-	gpointer data;
-};
-
-struct _PurpleTrieRecordList
-{
-	PurpleTrieRecord *rec;
-	PurpleTrieRecordList *next;
-	PurpleTrieRecordList *prev;
-
-	gpointer extra_data;
-};
-
-struct _PurpleTrieState
-{
-	PurpleTrieState *parent;
-	PurpleTrieState **children;
-
-	PurpleTrieState *longest_suffix;
-
-	PurpleTrieRecord *found_word;
-};
-
-typedef struct
-{
-	PurpleTrieState *state;
-
-	PurpleTrieState *root_state;
-	gboolean reset_on_match;
-
-	PurpleTrieReplaceCb replace_cb;
-	PurpleTrieFindCb find_cb;
-	gpointer user_data;
-} PurpleTrieMachine;
-
-/* TODO: an option to make it eager or lazy (now, it's eager) */
-enum
-{
-	PROP_ZERO,
-	PROP_RESET_ON_MATCH,
-	PROP_LAST
-};
-
-static GParamSpec *properties[PROP_LAST];
-
-G_DEFINE_TYPE_WITH_PRIVATE(PurpleTrie, purple_trie, G_TYPE_OBJECT);
-
-/*******************************************************************************
- * Records list
- ******************************************************************************/
-
-static PurpleTrieRecordList *
-purple_record_list_new(PurpleMemoryPool *mpool, PurpleTrieRecord *rec)
-{
-	PurpleTrieRecordList *node;
-
-	node = purple_memory_pool_alloc0(mpool,
-		sizeof(PurpleTrieRecordList), sizeof(gpointer));
-	g_return_val_if_fail(node != NULL, NULL);
-
-	node->rec = rec;
-
-	return node;
-}
-
-static PurpleTrieRecordList *
-purple_record_list_prepend(PurpleMemoryPool *mpool,
-	PurpleTrieRecordList *old_head, PurpleTrieRecord *rec)
-{
-	PurpleTrieRecordList *new_head;
-
-	new_head = purple_record_list_new(mpool, rec);
-	g_return_val_if_fail(new_head != NULL, NULL);
-
-	new_head->next = old_head;
-	if (old_head)
-		old_head->prev = new_head;
-
-	return new_head;
-}
-
-static PurpleTrieRecordList *
-purple_record_list_copy(PurpleMemoryPool *mpool,
-	const PurpleTrieRecordList *head)
-{
-	PurpleTrieRecordList *new_head = NULL, *new_tail = NULL;
-
-	while (head) {
-		PurpleTrieRecordList *node;
-
-		node = purple_record_list_new(mpool, head->rec);
-		g_return_val_if_fail(node != NULL, NULL); /* there is no leak */
-
-		node->prev = new_tail;
-		if (new_tail)
-			new_tail->next = node;
-		new_tail = node;
-		if (!new_head)
-			new_head = node;
-
-		head = head->next;
-	}
-
-	return new_head;
-}
-
-static PurpleTrieRecordList *
-purple_record_list_remove(PurpleTrieRecordList *head,
-	PurpleTrieRecordList *node)
-{
-	g_return_val_if_fail(head != NULL, NULL);
-	g_return_val_if_fail(node != NULL, head);
-	g_return_val_if_fail(head->prev == NULL, NULL);
-
-	if (head == node) {
-		if (head->next != NULL)
-			head->next->prev = NULL;
-		return head->next;
-	} else {
-		g_return_val_if_fail(node->prev != NULL, NULL);
-		node->prev->next = node->next;
-		if (node->next != NULL)
-			node->next->prev = node->prev;
-		return head;
-	}
-}
-
-
-/*******************************************************************************
- * States management
- ******************************************************************************/
-
-static void
-purple_trie_states_cleanup(PurpleTriePrivate *priv)
-{
-	if (priv->root_state != NULL) {
-		purple_memory_pool_cleanup(priv->states_mempool);
-		priv->root_state = NULL;
-	}
-}
-
-/* Allocates a state and binds it to the parent. */
-static PurpleTrieState *
-purple_trie_state_new(PurpleTriePrivate *priv, PurpleTrieState *parent,
-                      guchar character)
-{
-	PurpleTrieState *state;
-
-	state = purple_memory_pool_alloc0(priv->states_mempool,
-		sizeof(PurpleTrieState), sizeof(gpointer));
-	g_return_val_if_fail(state != NULL, NULL);
-
-	if (parent == NULL)
-		return state;
-
-	state->parent = parent;
-	if (parent->children == NULL) {
-		parent->children = purple_memory_pool_alloc0(
-			priv->states_mempool,
-			/* PurpleTrieState *children[G_MAXUCHAR + 1] */
-			256 * sizeof(gpointer),
-			sizeof(gpointer));
-	}
-
-	if (parent->children == NULL) {
-		purple_memory_pool_free(priv->states_mempool, state);
-		g_warn_if_reached();
-		return NULL;
-	}
-
-	parent->children[character] = state;
-
-	return state;
-}
-
-static gboolean
-purple_trie_states_build(PurpleTriePrivate *priv)
-{
-	PurpleTrieState *root;
-	PurpleMemoryPool *reclist_mpool;
-	PurpleTrieRecordList *reclist, *it;
-	gulong cur_len;
-
-	if (priv->root_state != NULL)
-		return TRUE;
-
-	if (priv->records_total_size < PURPLE_TRIE_LARGE_THRESHOLD) {
-		purple_memory_pool_set_block_size(priv->states_mempool,
-			PURPLE_TRIE_STATES_SMALL_POOL_BLOCK_SIZE);
-	} else {
-		purple_memory_pool_set_block_size(priv->states_mempool,
-			PURPLE_TRIE_STATES_LARGE_POOL_BLOCK_SIZE);
-	}
-
-	priv->root_state = root = purple_trie_state_new(priv, NULL, '\0');
-	g_return_val_if_fail(root != NULL, FALSE);
-	g_assert(root->longest_suffix == NULL);
-
-	/* reclist is a list of words not yet added to the trie. Shorter words
-	 * are removed from the list, when they are fully added to the trie. */
-	reclist_mpool = purple_memory_pool_new();
-	reclist = purple_record_list_copy(reclist_mpool, priv->records);
-
-	/* extra_data on every element of reclist will be a pointer to a trie
-	 * node -- the prefix of the word with len of cur_len */
-	for (it = reclist; it != NULL; it = it->next) {
-		it->extra_data = root;
-	}
-
-	/* Iterate over indexes of words -- every loop iteration checks certain
-	 * index of all remaining words. Loop finishes when there are no words
-	 * longer than cur_len. */
-	for (cur_len = 0; reclist != NULL; cur_len++) {
-		for (it = reclist; it; it = it->next) {
-			PurpleTrieRecord *rec = it->rec;
-			guchar character = rec->word[cur_len];
-			PurpleTrieState *prefix = it->extra_data;
-			PurpleTrieState *lon_suf_parent;
-
-			g_assert(character != '\0');
-
-			if (prefix->children && prefix->children[character]) {
-				/* Word's prefix is already in the trie, added
-				 * by the other word. */
-				prefix = prefix->children[character];
-			} else {
-				/* We need to create a new branch of trie. */
-				prefix = purple_trie_state_new(priv, prefix,
-				                               character);
-				if (!prefix) {
-					g_warn_if_reached();
-					g_object_unref(reclist_mpool);
-					return FALSE;
-				}
-			}
-			it->extra_data = prefix;
-			/* prefix is now of length increased by one character. */
-
-			/* The whole word is now added to the trie. */
-			if (rec->word[cur_len + 1] == '\0') {
-				if (prefix->found_word == NULL)
-					prefix->found_word = rec;
-				else {
-					purple_debug_warning("trie", "found "
-						"a collision of \"%s\" words",
-						rec->word);
-				}
-
-				/* "it" is not modified here, so it->next is
-				 * still valid */
-				reclist = purple_record_list_remove(reclist, it);
-			}
-
-			/* We need to fill the longest_suffix field -- a longest
-			 * complete suffix of the prefix we created. We look for
-			 * that suffix in any path starting in root and ending
-			 * in the (cur_len - 1) level of trie. */
-			if (prefix->longest_suffix != NULL)
-				continue;
-			lon_suf_parent = prefix->parent->longest_suffix;
-			while (lon_suf_parent) {
-				if (lon_suf_parent->children &&
-					lon_suf_parent->children[character])
-				{
-					prefix->longest_suffix = lon_suf_parent->
-						children[character];
-					break;
-				}
-				lon_suf_parent = lon_suf_parent->longest_suffix;
-			}
-			if (prefix->longest_suffix == NULL)
-				prefix->longest_suffix = root;
-			if (prefix->found_word == NULL) {
-				prefix->found_word =
-					prefix->longest_suffix->found_word;
-			}
-		}
-	}
-
-	g_object_unref(reclist_mpool);
-
-	return TRUE;
-}
-
-/*******************************************************************************
- * Searching
- ******************************************************************************/
-
-static void
-purple_trie_advance(PurpleTrieMachine *m, const guchar character)
-{
-	/* change state after processing a character */
-	while (TRUE) {
-		/* Perfect fit - next character is the same, as the child of the
-		 * prefix we reached so far. */
-		if (m->state->children && m->state->children[character]) {
-			m->state = m->state->children[character];
-			break;
-		}
-
-		/* We reached root, that's a pity. */
-		if (m->state == m->root_state)
-			break;
-
-		/* Let's try a bit shorter suffix. */
-		m->state = m->state->longest_suffix;
-	}
-}
-
-static gboolean
-purple_trie_replace_do_replacement(PurpleTrieMachine *m, GString *out)
-{
-	gboolean was_replaced = FALSE;
-	gsize str_old_len;
-
-	/* if we reached a "found" state, let's process it */
-	if (!m->state->found_word)
-		return FALSE;
-
-	/* let's get back to the beginning of the word */
-	g_assert(out->len >= m->state->found_word->word_len - 1);
-	str_old_len = out->len;
-	out->len -= m->state->found_word->word_len - 1;
-
-	was_replaced = m->replace_cb(out, m->state->found_word->word,
-		m->state->found_word->data, m->user_data);
-
-	/* output was untouched, revert to the previous position */
-	if (!was_replaced)
-		out->len = str_old_len;
-
-	/* XXX */
-	if (was_replaced || m->reset_on_match)
-		m->state = m->root_state;
-
-	return was_replaced;
-}
-
-static gboolean
-purple_trie_find_do_discovery(PurpleTrieMachine *m)
-{
-	gboolean was_accepted;
-
-	/* if we reached a "found" state, let's process it */
-	if (!m->state->found_word)
-		return FALSE;
-
-	if (m->find_cb) {
-		was_accepted = m->find_cb(m->state->found_word->word,
-			m->state->found_word->data, m->user_data);
-	} else {
-		was_accepted = TRUE;
-	}
-
-	if (was_accepted && m->reset_on_match)
-		m->state = m->root_state;
-
-	return was_accepted;
-}
-
-gchar *
-purple_trie_replace(PurpleTrie *trie, const gchar *src,
-	PurpleTrieReplaceCb replace_cb, gpointer user_data)
-{
-	PurpleTriePrivate *priv = NULL;
-	PurpleTrieMachine machine;
-	GString *out;
-	gsize i;
-
-	if (src == NULL)
-		return NULL;
-
-	g_return_val_if_fail(replace_cb != NULL, g_strdup(src));
-	g_return_val_if_fail(PURPLE_IS_TRIE(trie), NULL);
-
-	priv = purple_trie_get_instance_private(trie);
-
-	purple_trie_states_build(priv);
-
-	machine.state = priv->root_state;
-	machine.root_state = priv->root_state;
-	machine.reset_on_match = priv->reset_on_match;
-	machine.replace_cb = replace_cb;
-	machine.user_data = user_data;
-
-	out = g_string_new(NULL);
-	i = 0;
-	while (src[i] != '\0') {
-		guchar character = src[i++];
-		gboolean was_replaced;
-
-		purple_trie_advance(&machine, character);
-		was_replaced = purple_trie_replace_do_replacement(&machine, out);
-
-		/* We skipped a character without finding any records,
-		 * let's just copy it to the output. */
-		if (!was_replaced)
-			g_string_append_c(out, character);
-	}
-
-	return g_string_free(out, FALSE);
-}
-
-gchar *
-purple_trie_multi_replace(const GSList *tries, const gchar *src,
-	PurpleTrieReplaceCb replace_cb, gpointer user_data)
-{
-	guint tries_count, m_idx;
-	PurpleTrieMachine *machines;
-	GString *out;
-	gsize i;
-
-	if (src == NULL)
-		return NULL;
-
-	g_return_val_if_fail(replace_cb != NULL, g_strdup(src));
-
-	tries_count = g_slist_length((GSList*)tries);
-	if (tries_count == 0)
-		return g_strdup(src);
-
-	/* Initialize all machines. */
-	machines = g_new(PurpleTrieMachine, tries_count);
-	for (i = 0; i < tries_count; i++, tries = tries->next) {
-		PurpleTrie *trie = tries->data;
-		PurpleTriePrivate *priv = NULL;
-
-		if (!PURPLE_TRIE(trie)) {
-			g_warn_if_reached();
-			g_free(machines);
-			return NULL;
-		}
-
-		priv = purple_trie_get_instance_private(trie);
-
-		purple_trie_states_build(priv);
-
-		machines[i].state = priv->root_state;
-		machines[i].root_state = priv->root_state;
-		machines[i].reset_on_match = priv->reset_on_match;
-		machines[i].replace_cb = replace_cb;
-		machines[i].user_data = user_data;
-	}
-
-	out = g_string_new(NULL);
-	i = 0;
-	while (src[i] != '\0') {
-		guchar character = src[i++];
-		gboolean was_replaced = FALSE;
-
-		/* Advance every machine and possibly perform a replacement. */
-		for (m_idx = 0; m_idx < tries_count; m_idx++) {
-			purple_trie_advance(&machines[m_idx], character);
-			if (was_replaced)
-				continue;
-			was_replaced = purple_trie_replace_do_replacement(
-				&machines[m_idx], out);
-		}
-
-		/* We skipped a character without finding any records,
-		 * let's just copy it to the output. */
-		if (!was_replaced)
-			g_string_append_c(out, character);
-
-		/* If we replaced a word, reset _all_ machines */
-		if (was_replaced) {
-			for (m_idx = 0; m_idx < tries_count; m_idx++) {
-				machines[m_idx].state =
-					machines[m_idx].root_state;
-			}
-		}
-	}
-
-	g_free(machines);
-	return g_string_free(out, FALSE);
-}
-
-gulong
-purple_trie_find(PurpleTrie *trie, const gchar *src,
-	PurpleTrieFindCb find_cb, gpointer user_data)
-{
-	PurpleTriePrivate *priv = NULL;
-	PurpleTrieMachine machine;
-	gulong found_count = 0;
-	gsize i;
-
-	if (src == NULL)
-		return 0;
-
-	g_return_val_if_fail(PURPLE_IS_TRIE(trie), 0);
-
-	priv = purple_trie_get_instance_private(trie);
-
-	purple_trie_states_build(priv);
-
-	machine.state = priv->root_state;
-	machine.root_state = priv->root_state;
-	machine.reset_on_match = priv->reset_on_match;
-	machine.find_cb = find_cb;
-	machine.user_data = user_data;
-
-	i = 0;
-	while (src[i] != '\0') {
-		guchar character = src[i++];
-		gboolean was_found;
-
-		purple_trie_advance(&machine, character);
-
-		was_found = purple_trie_find_do_discovery(&machine);
-
-		if (was_found)
-			found_count++;
-	}
-
-	return found_count;
-}
-
-gulong
-purple_trie_multi_find(const GSList *tries, const gchar *src,
-	PurpleTrieFindCb find_cb, gpointer user_data)
-{
-	guint tries_count, m_idx;
-	PurpleTrieMachine *machines;
-	gulong found_count = 0;
-	gsize i;
-
-	if (src == NULL)
-		return 0;
-
-	tries_count = g_slist_length((GSList*)tries);
-	if (tries_count == 0)
-		return 0;
-
-	/* Initialize all machines. */
-	machines = g_new(PurpleTrieMachine, tries_count);
-	for (i = 0; i < tries_count; i++, tries = tries->next) {
-		PurpleTrie *trie = tries->data;
-		PurpleTriePrivate *priv = NULL;
-
-		if (!PURPLE_IS_TRIE(trie)) {
-			g_warn_if_reached();
-			g_free(machines);
-			return 0;
-		}
-
-		priv = purple_trie_get_instance_private(trie);
-
-		purple_trie_states_build(priv);
-
-		machines[i].state = priv->root_state;
-		machines[i].root_state = priv->root_state;
-		machines[i].reset_on_match = priv->reset_on_match;
-		machines[i].find_cb = find_cb;
-		machines[i].user_data = user_data;
-	}
-
-	i = 0;
-	while (src[i] != '\0') {
-		guchar character = src[i++];
-		gboolean was_found = FALSE;
-
-		/* Advance every machine and possibly perform a replacement. */
-		for (m_idx = 0; m_idx < tries_count; m_idx++) {
-			purple_trie_advance(&machines[m_idx], character);
-			if (was_found)
-				continue;
-			was_found =
-				purple_trie_find_do_discovery(&machines[m_idx]);
-			if (was_found)
-				found_count++;
-		}
-
-		/* If we replaced a word, reset _all_ machines */
-		if (was_found) {
-			for (m_idx = 0; m_idx < tries_count; m_idx++) {
-				if (!machines[m_idx].reset_on_match)
-					continue;
-				machines[m_idx].state =
-					machines[m_idx].root_state;
-			}
-		}
-	}
-
-	g_free(machines);
-	return found_count;
-}
-
-
-/*******************************************************************************
- * Records
- ******************************************************************************/
-
-gboolean
-purple_trie_add(PurpleTrie *trie, const gchar *word, gpointer data)
-{
-	PurpleTriePrivate *priv = NULL;
-	PurpleTrieRecord *rec;
-
-	g_return_val_if_fail(PURPLE_IS_TRIE(trie), FALSE);
-	g_return_val_if_fail(word != NULL, FALSE);
-	g_return_val_if_fail(word[0] != '\0', FALSE);
-
-	priv = purple_trie_get_instance_private(trie);
-
-	if (g_hash_table_lookup(priv->records_map, word) != NULL) {
-		purple_debug_warning("trie", "record exists: %s", word);
-		return FALSE;
-	}
-
-	/* Every change in a trie invalidates longest_suffix map.
-	 * These prefixes could be updated instead of cleaning the whole graph.
-	 */
-	purple_trie_states_cleanup(priv);
-
-	rec = purple_memory_pool_alloc(priv->records_obj_mempool,
-		sizeof(PurpleTrieRecord), sizeof(gpointer));
-	rec->word = purple_memory_pool_strdup(priv->records_str_mempool, word);
-	rec->word_len = strlen(word);
-	g_assert(rec->word_len > 0);
-	rec->data = data;
-
-	priv->records_total_size += rec->word_len;
-	priv->records = purple_record_list_prepend(priv->records_obj_mempool,
-		priv->records, rec);
-	g_hash_table_insert(priv->records_map, rec->word, priv->records);
-
-	return TRUE;
-}
-
-void
-purple_trie_remove(PurpleTrie *trie, const gchar *word)
-{
-	PurpleTriePrivate *priv = NULL;
-	PurpleTrieRecordList *it;
-
-	g_return_if_fail(PURPLE_IS_TRIE(trie));
-	g_return_if_fail(word != NULL);
-	g_return_if_fail(word[0] != '\0');
-
-	priv = purple_trie_get_instance_private(trie);
-
-	it = g_hash_table_lookup(priv->records_map, word);
-	if (it == NULL)
-		return;
-
-	/* see purple_trie_add */
-	purple_trie_states_cleanup(priv);
-
-	priv->records_total_size -= it->rec->word_len;
-	priv->records = purple_record_list_remove(priv->records, it);
-	g_hash_table_remove(priv->records_map, it->rec->word);
-
-	purple_memory_pool_free(priv->records_str_mempool, it->rec->word);
-	purple_memory_pool_free(priv->records_obj_mempool, it->rec);
-	purple_memory_pool_free(priv->records_obj_mempool, it);
-}
-
-guint
-purple_trie_get_size(PurpleTrie *trie)
-{
-	PurpleTriePrivate *priv = NULL;
-
-	g_return_val_if_fail(PURPLE_IS_TRIE(trie), 0);
-
-	priv = purple_trie_get_instance_private(trie);
-	return g_hash_table_size(priv->records_map);
-}
-
-
-/*******************************************************************************
- * API implementation
- ******************************************************************************/
-
-gboolean
-purple_trie_get_reset_on_match(PurpleTrie *trie)
-{
-	PurpleTriePrivate *priv = NULL;
-
-	g_return_val_if_fail(PURPLE_IS_TRIE(trie), FALSE);
-
-	priv = purple_trie_get_instance_private(trie);
-	return priv->reset_on_match;
-}
-
-void
-purple_trie_set_reset_on_match(PurpleTrie *trie, gboolean reset)
-{
-	PurpleTriePrivate *priv = NULL;
-
-	g_return_if_fail(PURPLE_IS_TRIE(trie));
-
-	priv = purple_trie_get_instance_private(trie);
-	priv->reset_on_match = reset;
-	g_object_notify_by_pspec(G_OBJECT(trie), properties[PROP_RESET_ON_MATCH]);
-}
-
-/*******************************************************************************
- * Object stuff
- ******************************************************************************/
-
-PurpleTrie *
-purple_trie_new(void)
-{
-	return g_object_new(PURPLE_TYPE_TRIE, NULL);
-}
-
-static void
-purple_trie_init(PurpleTrie *trie)
-{
-	PurpleTriePrivate *priv = purple_trie_get_instance_private(trie);
-
-	priv->records_obj_mempool = purple_memory_pool_new();
-	priv->records_str_mempool = purple_memory_pool_new();
-	priv->states_mempool = purple_memory_pool_new();
-	purple_memory_pool_set_block_size(priv->states_mempool,
-		PURPLE_TRIE_STATES_SMALL_POOL_BLOCK_SIZE);
-
-	priv->records_map = g_hash_table_new(g_str_hash, g_str_equal);
-}
-
-static void
-purple_trie_finalize(GObject *obj)
-{
-	PurpleTriePrivate *priv =
-			purple_trie_get_instance_private(PURPLE_TRIE(obj));
-
-	g_hash_table_destroy(priv->records_map);
-	g_object_unref(priv->records_obj_mempool);
-	g_object_unref(priv->records_str_mempool);
-	g_object_unref(priv->states_mempool);
-
-	G_OBJECT_CLASS(purple_trie_parent_class)->finalize(obj);
-}
-
-static void
-purple_trie_get_property(GObject *obj, guint param_id, GValue *value,
-	GParamSpec *pspec)
-{
-	PurpleTrie *trie = PURPLE_TRIE(obj);
-	PurpleTriePrivate *priv = purple_trie_get_instance_private(trie);
-
-	switch (param_id) {
-		case PROP_RESET_ON_MATCH:
-			g_value_set_boolean(value, priv->reset_on_match);
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-	}
-}
-
-static void
-purple_trie_set_property(GObject *obj, guint param_id,
-	const GValue *value, GParamSpec *pspec)
-{
-	PurpleTrie *trie = PURPLE_TRIE(obj);
-	PurpleTriePrivate *priv = purple_trie_get_instance_private(trie);
-
-	switch (param_id) {
-		case PROP_RESET_ON_MATCH:
-			priv->reset_on_match = g_value_get_boolean(value);
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-	}
-}
-
-static void
-purple_trie_class_init(PurpleTrieClass *klass)
-{
-	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-
-	obj_class->finalize = purple_trie_finalize;
-	obj_class->get_property = purple_trie_get_property;
-	obj_class->set_property = purple_trie_set_property;
-
-	properties[PROP_RESET_ON_MATCH] = g_param_spec_boolean("reset-on-match",
-		"Reset on match", "Determines, if the search state machine "
-		"should be reset to the initial state on every match. This "
-		"ensures, that every match is distinct from each other. "
-		"Please note, that it's not well-defined for a replace "
-		"operation, so it's better to leave this value default, unless "
-		"you perform only find operations.", TRUE,
-		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
-	g_object_class_install_properties(obj_class, PROP_LAST, properties);
-}
diff --git a/po/POTFILES.in b/po/POTFILES.in
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -303,12 +303,10 @@
 libpurple/tests/test_protocol_xfer.c
 libpurple/tests/test_purplepath.c
 libpurple/tests/test_queued_output_stream.c
-libpurple/tests/test_trie.c
 libpurple/tests/test_ui.c
 libpurple/tests/test_util.c
 libpurple/tests/test_whiteboard_manager.c
 libpurple/tests/test_xmlnode.c
-libpurple/trie.c
 libpurple/upnp.c
 libpurple/util.c
 libpurple/version.c
