plugins/spellchk.c

changeset 14253
b63ebf84c42b
parent 14252
d10dda2777a9
child 14254
77edc7a6191a
--- a/plugins/spellchk.c	Sat Aug 19 00:24:14 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2367 +0,0 @@
-/*
- * Gaim - Replace certain misspelled words with their correct form.
- *
- * Signification changes were made by Benjamin Kahn ("xkahn") and
- * Richard Laager ("rlaager") in April 2005--you may want to contact
- * them if you have questions.
- *
- * Gaim 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-/*
- * A lot of this code (especially the config code) was taken directly
- * or nearly directly from xchat, version 1.4.2 by Peter Zelezny and others.
- */
-
-#include "internal.h"
-#include "gtkgaim.h"
-
-#include "debug.h"
-#include "notify.h"
-#include "signals.h"
-#include "util.h"
-#include "version.h"
-
-#include "gtkplugin.h"
-#include "gtkprefs.h"
-#include "gtkutils.h"
-
-#include <stdio.h>
-#include <string.h>
-#ifndef _WIN32
-#include <strings.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#define SPELLCHECK_PLUGIN_ID "gtk-spellcheck"
-#define SPELLCHK_OBJECT_KEY "spellchk"
-
-enum {
-	BAD_COLUMN,
-	GOOD_COLUMN,
-	WORD_ONLY_COLUMN,
-	CASE_SENSITIVE_COLUMN,
-	N_COLUMNS
-};
-
-struct _spellchk {
-	GtkTextView *view;
-	GtkTextMark *mark_insert_start;
-	GtkTextMark *mark_insert_end;
-
-	const gchar *word;
-	gboolean inserting;
-	gboolean ignore_correction;
-	gboolean ignore_correction_on_send;
-	gint pos;
-};
-
-typedef struct _spellchk spellchk;
-
-static GtkListStore *model;
-
-static gboolean
-is_word_uppercase(const gchar *word)
-{
-	for (; word[0] != '\0'; word = g_utf8_find_next_char (word, NULL)) {
-		gunichar c = g_utf8_get_char(word);
-
-		if (!(g_unichar_isupper(c) ||
-		      g_unichar_ispunct(c) ||
-		      g_unichar_isspace(c)))
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-static gboolean
-is_word_lowercase(const gchar *word)
-{
-	for (; word[0] != '\0'; word = g_utf8_find_next_char(word, NULL)) {
-		gunichar c = g_utf8_get_char(word);
-
-		if (!(g_unichar_islower(c) ||
-		      g_unichar_ispunct(c) ||
-		      g_unichar_isspace(c)))
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-static gboolean
-is_word_proper(const gchar *word)
-{
-	if (word[0] == '\0')
-		return FALSE;
-
-	if (!g_unichar_isupper(g_utf8_get_char_validated(word, -1)))
-		return FALSE;
-
-	return is_word_lowercase(g_utf8_offset_to_pointer(word, 1));
-}
-
-static gchar *
-make_word_proper(const gchar *word)
-{
-	char buf[7];
-	gchar *lower = g_utf8_strdown(word, -1);
-	gint bytes;
-	gchar *ret;
-
-	bytes = g_unichar_to_utf8(g_unichar_toupper(g_utf8_get_char(word)), buf);
-	buf[MIN(bytes, sizeof(buf) - 1)] = '\0';
-
-	ret = g_strconcat(buf, g_utf8_offset_to_pointer(lower, 1), NULL);
-	g_free(lower);
-
-	return ret;
-}
-
-static gboolean
-substitute_simple_buffer(GtkTextBuffer *buffer)
-{
-	GtkTextIter start;
-	GtkTextIter end;
-	GtkTreeIter treeiter;
-	gchar *text = NULL;
-
-	gtk_text_buffer_get_iter_at_offset(buffer, &start, 0);
-	gtk_text_buffer_get_iter_at_offset(buffer, &end, 0);
-	gtk_text_iter_forward_to_end(&end);
-
-	text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
-
-	if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &treeiter) && text) {
-		do {
-			GValue val1;
-			const gchar *bad;
-			gchar *cursor;
-			glong char_pos;
-
-			val1.g_type = 0;
-			gtk_tree_model_get_value(GTK_TREE_MODEL(model), &treeiter, WORD_ONLY_COLUMN, &val1);
-			if (g_value_get_boolean(&val1))
-			{
-				g_value_unset(&val1);
-				continue;
-			}
-			g_value_unset(&val1);
-
-			gtk_tree_model_get_value(GTK_TREE_MODEL(model), &treeiter, BAD_COLUMN, &val1);
-			bad = g_value_get_string(&val1);
-
-			/* using g_utf8_* to get /character/ offsets instead of byte offsets for buffer */
-			if ((cursor = g_strrstr(text, bad)))
-			{
-				GValue val2;
-				const gchar *good;
-
-				val2.g_type = 0;
-				gtk_tree_model_get_value(GTK_TREE_MODEL(model), &treeiter, GOOD_COLUMN, &val2);
-				good = g_value_get_string(&val2);
-
-				char_pos = g_utf8_pointer_to_offset(text, cursor);
-				gtk_text_buffer_get_iter_at_offset(buffer, &start, char_pos);
-				gtk_text_buffer_get_iter_at_offset(buffer, &end, char_pos + g_utf8_strlen(bad, -1));
-				gtk_text_buffer_delete(buffer, &start, &end);
-
-				gtk_text_buffer_get_iter_at_offset(buffer, &start, char_pos);
-				gtk_text_buffer_insert(buffer, &start, good, -1);
-
-				g_value_unset(&val2);
-				g_free(text);
-
-				g_value_unset(&val1);
-				return TRUE;
-			}
-
-			g_value_unset(&val1);
-		} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &treeiter));
-	}
-
-	g_free(text);
-	return FALSE;
-}
-
-static gchar *
-substitute_word(gchar *word)
-{
-	GtkTreeIter iter;
-	gchar *outword;
-	gchar *lowerword;
-	gchar *foldedword;
-
-	if (word == NULL)
-		return NULL;
-
-	lowerword = g_utf8_strdown(word, -1);
-	foldedword = g_utf8_casefold(word, -1);
-
-	if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) {
-		do {
-			GValue val1;
-			gboolean case_sensitive;
-			const char *bad;
-			gchar *tmpbad = NULL;
-
-			val1.g_type = 0;
-			gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, WORD_ONLY_COLUMN, &val1);
-			if (!g_value_get_boolean(&val1)) {
-				g_value_unset(&val1);
-				continue;
-			}
-			g_value_unset(&val1);
-
-			gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, CASE_SENSITIVE_COLUMN, &val1);
-			case_sensitive = g_value_get_boolean(&val1);
-			g_value_unset(&val1);
-
-			gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, BAD_COLUMN, &val1);
-			bad = g_value_get_string(&val1);
-
-			if ((case_sensitive && !strcmp(bad, word)) ||
-			    (!case_sensitive && (!strcmp(bad, lowerword) ||
-			                        (!is_word_lowercase(bad) &&
-			                         !strcmp((tmpbad = g_utf8_casefold(bad, -1)), foldedword)))))
-			{
-				GValue val2;
-				const char *good;
-
-				g_free(tmpbad);
-
-				val2.g_type = 0;
-				gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, GOOD_COLUMN, &val2);
-				good = g_value_get_string(&val2);
-
-				if (!case_sensitive && is_word_lowercase(bad) && is_word_lowercase(good))
-				{
-					if (is_word_uppercase(word))
-						outword = g_utf8_strup(good, -1);
-					else if (is_word_proper(word))
-						outword = make_word_proper(good);
-					else
-						outword = g_strdup(good);
-				}
-				else
-					outword = g_strdup(good);
-
-				g_value_unset(&val1);
-				g_value_unset(&val2);
-
-				g_free(foldedword);
-				return outword;
-			}
-
-			g_value_unset(&val1);
-			g_free(tmpbad);
-
-		} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter));
-	}
-	g_free(foldedword);
-
-	return NULL;
-}
-
-static void
-spellchk_free(spellchk *spell)
-{
-	GtkTextBuffer *buffer;
-
-	g_return_if_fail(spell != NULL);
-
-	buffer = gtk_text_view_get_buffer(spell->view);
-
-	g_signal_handlers_disconnect_matched(buffer,
-			G_SIGNAL_MATCH_DATA,
-			0, 0, NULL, NULL,
-			spell);
-	g_free(spell);
-}
-
-/* Pango doesn't know about the "'" character.  Let's fix that. */
-static gboolean
-spellchk_inside_word(GtkTextIter *iter)
-{
-	gunichar ucs4_char = gtk_text_iter_get_char(iter);
-	gchar *utf8_str;
-	gchar c = 0;
-	gboolean result;
-	gboolean output;
-
-	utf8_str = g_ucs4_to_utf8(&ucs4_char, 1, NULL, NULL, NULL);
-	if (utf8_str != NULL)
-	{
-		c = utf8_str[0];
-		g_free(utf8_str);
-	}
-
-	/* Hack because otherwise typing things like U.S. gets difficult
-	 * if you have 'u' -> 'you' set as a correction...
-	 *
-	 * Part 1 of 2: This marks . as being an inside-word character. */
-	if (c == '.')
-		return TRUE;
-
-	/* Avoid problems with \r, for example (SF #1289031). */
-	if (c == '\\')
-		return TRUE;
-
-	if (gtk_text_iter_inside_word (iter) == TRUE)
-		return TRUE;
-
-	if (c == '\'') {
-		result = gtk_text_iter_backward_char(iter);
-		output = gtk_text_iter_inside_word(iter);
-
-		if (result)
-			gtk_text_iter_forward_char(iter);
-
-		return output;
-	}
-
-	return FALSE;
-
-}
-
-static gboolean
-spellchk_backward_word_start(GtkTextIter *iter)
-{
-	int output;
-	int result;
-
-	output = gtk_text_iter_backward_word_start(iter);
-
-	/* It didn't work...  */
-	if (!output)
-		return FALSE;
-
-	while (spellchk_inside_word(iter)) {
-		result = gtk_text_iter_backward_char(iter);
-
-		/* We can't go backwards anymore?  We're at the beginning of the word. */
-		if (!result)
-			return TRUE;
-
-		if (!spellchk_inside_word(iter)) {
-			gtk_text_iter_forward_char(iter);
-			return TRUE;
-		}
-
-		output = gtk_text_iter_backward_word_start(iter);
-		if (!output)
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-static gboolean
-check_range(spellchk *spell, GtkTextBuffer *buffer,
-				GtkTextIter start, GtkTextIter end, gboolean sending)
-{
-	gboolean replaced;
-	gboolean result;
-	gchar *tmp;
-	int period_count = 0;
-	gchar *word;
-	GtkTextMark *mark;
-	GtkTextIter pos;
-
-	if ((replaced = substitute_simple_buffer(buffer)))
-	{
-		mark = gtk_text_buffer_get_insert(buffer);
-		gtk_text_buffer_get_iter_at_mark(buffer, &pos, mark);
-		spell->pos = gtk_text_iter_get_offset(&pos);
-
-		gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
-		gtk_text_buffer_get_iter_at_mark(buffer, &end, mark);
-	}
-
-	if (!sending)
-	{
-		/* We need to go backwords to find out if we are inside a word or not. */
-		gtk_text_iter_backward_char(&end);
-
-		if (spellchk_inside_word(&end))
-		{
-			gtk_text_iter_forward_char(&end);
-			return replaced;  /* We only pay attention to whole words. */
-		}
-	}
-
-	/* We could be in the middle of a whitespace block.  Check for that. */
-	result = gtk_text_iter_backward_char(&end);
-
-	if (!spellchk_inside_word(&end))
-	{
-		if (result)
-			gtk_text_iter_forward_char(&end);
-		return replaced;
-	}
-
-	if (result)
-		gtk_text_iter_forward_char(&end);
-
-	/* Move backwards to the beginning of the word. */
-	spellchk_backward_word_start(&start);
-
-	spell->word = gtk_text_iter_get_text(&start, &end);
-
-	/* Hack because otherwise typing things like U.S. gets difficult
-	 * if you have 'u' -> 'you' set as a correction...
-	 *
-	 * Part 2 of 2: This chops periods off the end of the word so
-	 * the right substitution entry is found. */
-	tmp = g_strdup(spell->word);
-	if (tmp != NULL && *tmp != '\0') {
-		gchar *c;
-		for (c = tmp + strlen(tmp) - 1 ; c != tmp ; c--) {
-			if (*c == '.') {
-				*c = '\0';
-				period_count++;
-			} else
-				break;
-		}
-	}
-
-	if ((word = substitute_word(tmp))) {
-		GtkTextMark *mark;
-		GtkTextIter pos;
-		gchar *tmp2;
-		int i;
-
-		for (i = 1 ; i <= period_count ; i++) {
-			tmp2 = g_strconcat(word, ".", NULL);
-			g_free(word);
-			word = tmp2;
-		}
-
-		gtk_text_buffer_delete(buffer, &start, &end);
-		gtk_text_buffer_insert(buffer, &start, word, -1);
-
-		mark = gtk_text_buffer_get_insert(buffer);
-		gtk_text_buffer_get_iter_at_mark(buffer, &pos, mark);
-		spell->pos = gtk_text_iter_get_offset(&pos);
-
-		g_free(word);
-		g_free(tmp);
-		return TRUE;
-	}
-	g_free(tmp);
-
-	spell->word = NULL;
-
-	return replaced;
-}
-
-/* insertion works like this:
- *  - before the text is inserted, we mark the position in the buffer.
- *  - after the text is inserted, we see where our mark is and use that and
- *    the current position to check the entire range of inserted text.
- *
- * this may be overkill for the common case (inserting one character). */
-static void
-insert_text_before(GtkTextBuffer *buffer, GtkTextIter *iter,
-					gchar *text, gint len, spellchk *spell)
-{
-	if (spell->inserting == TRUE)
-		return;
-
-	spell->inserting = TRUE;
-
-	spell->word = NULL;
-
-	gtk_text_buffer_move_mark(buffer, spell->mark_insert_start, iter);
-}
-
-static void
-insert_text_after(GtkTextBuffer *buffer, GtkTextIter *iter,
-					gchar *text, gint len, spellchk *spell)
-{
-	GtkTextIter start, end;
-	GtkTextMark *mark;
-
-	spell->ignore_correction_on_send = FALSE;
-
-	if (spell->ignore_correction) {
-		spell->ignore_correction = FALSE;
-		return;
-	}
-
-	/* we need to check a range of text. */
-	gtk_text_buffer_get_iter_at_mark(buffer, &start, spell->mark_insert_start);
-
-	if (len == 1)
-		check_range(spell, buffer, start, *iter, FALSE);
-
-	/* if check_range modified the buffer, iter has been invalidated */
-	mark = gtk_text_buffer_get_insert(buffer);
-	gtk_text_buffer_get_iter_at_mark(buffer, &end, mark);
-	gtk_text_buffer_move_mark(buffer, spell->mark_insert_end, &end);
-
-	spell->inserting = FALSE;
-}
-
-static void
-delete_range_after(GtkTextBuffer *buffer,
-					GtkTextIter *start, GtkTextIter *end, spellchk *spell)
-{
-	GtkTextIter start2, end2;
-	GtkTextMark *mark;
-	GtkTextIter pos;
-	gint place;
-
-	spell->ignore_correction_on_send = FALSE;
-
-	if (!spell->word)
-		return;
-
-	if (spell->inserting == TRUE)
-		return;
-
-	spell->inserting = TRUE;
-
-	mark = gtk_text_buffer_get_insert(buffer);
-	gtk_text_buffer_get_iter_at_mark(buffer, &pos, mark);
-	place = gtk_text_iter_get_offset(&pos);
-
-	if ((place + 1) != spell->pos) {
-		spell->word = NULL;
-		return;
-	}
-
-	gtk_text_buffer_get_iter_at_mark(buffer, &start2, spell->mark_insert_start);
-	gtk_text_buffer_get_iter_at_mark(buffer, &end2, spell->mark_insert_end);
-
-	gtk_text_buffer_delete(buffer, &start2, &end2);
-	gtk_text_buffer_insert(buffer, &start2, spell->word, -1);
-	spell->ignore_correction = TRUE;
-	spell->ignore_correction_on_send = TRUE;
-
-	spell->inserting = FALSE;
-	spell->word = NULL;
-}
-
-static void
-message_send_cb(GtkWidget *widget, spellchk *spell)
-{
-	GtkTextBuffer *buffer;
-	GtkTextIter start, end;
-	GtkTextMark *mark;
-	gboolean replaced;
-
-	if (spell->ignore_correction_on_send)
-	{
-		spell->ignore_correction_on_send = FALSE;
-		return;
-	}
-
-#if 0
-	if (!gaim_prefs_get_bool("/plugins/gtk/spellchk/last_word_replace"))
-		return;
-#endif
-
-	buffer = gtk_text_view_get_buffer(spell->view);
-
-	gtk_text_buffer_get_end_iter(buffer, &start);
-	gtk_text_buffer_get_end_iter(buffer, &end);
-	spell->inserting = TRUE;
-	replaced = check_range(spell, buffer, start, end, TRUE);
-	spell->inserting = FALSE;
-
-	/* if check_range modified the buffer, iter has been invalidated */
-	mark = gtk_text_buffer_get_insert(buffer);
-	gtk_text_buffer_get_iter_at_mark(buffer, &end, mark);
-	gtk_text_buffer_move_mark(buffer, spell->mark_insert_end, &end);
-
-	if (replaced)
-	{
-		g_signal_stop_emission_by_name(widget, "message_send");
-		spell->ignore_correction_on_send = TRUE;
-	}
-}
-
-static void
-spellchk_new_attach(GaimConversation *conv)
-{
-	spellchk *spell;
-	GtkTextBuffer *buffer;
-	GtkTextIter start, end;
-	GaimGtkConversation *gtkconv;
-	GtkTextView *view;
-
-	gtkconv = GAIM_GTK_CONVERSATION(conv);
-
-	view = GTK_TEXT_VIEW(gtkconv->entry);
-
-	spell = g_object_get_data(G_OBJECT(view), SPELLCHK_OBJECT_KEY);
-	if (spell != NULL)
-		return;
-
-	/* attach to the widget */
-	spell = g_new0(spellchk, 1);
-	spell->view = view;
-
-	g_object_set_data_full(G_OBJECT(view), SPELLCHK_OBJECT_KEY, spell,
-			(GDestroyNotify)spellchk_free);
-
-	buffer = gtk_text_view_get_buffer(view);
-
-	/* we create the mark here, but we don't use it until text is
-	 * inserted, so we don't really care where iter points.  */
-	gtk_text_buffer_get_bounds(buffer, &start, &end);
-	spell->mark_insert_start = gtk_text_buffer_create_mark(buffer,
-			"spellchk-insert-start",
-			&start, TRUE);
-	spell->mark_insert_end = gtk_text_buffer_create_mark(buffer,
-			"spellchk-insert-end",
-			&start, TRUE);
-
-	g_signal_connect_after(G_OBJECT(buffer),
-			"delete-range",
-			G_CALLBACK(delete_range_after), spell);
-	g_signal_connect(G_OBJECT(buffer),
-			"insert-text",
-			G_CALLBACK(insert_text_before), spell);
-	g_signal_connect_after(G_OBJECT(buffer),
-			"insert-text",
-			G_CALLBACK(insert_text_after), spell);
-
-	g_signal_connect(G_OBJECT(gtkconv->entry), "message_send",
-	                 G_CALLBACK(message_send_cb), spell);
-	return;
-}
-
-static int buf_get_line(char *ibuf, char **buf, int *position, int len)
-{
-	int pos = *position;
-	int spos = pos;
-
-	if (pos == len)
-		return 0;
-
-	while (!(ibuf[pos] == '\n' ||
-	         (ibuf[pos] == '\r' && ibuf[pos + 1] != '\n')))
-	{
-		pos++;
-		if (pos == len)
-			return 0;
-	}
-
-	if (pos != 0 && ibuf[pos] == '\n' && ibuf[pos - 1] == '\r')
-		ibuf[pos - 1] = '\0';
-
-	ibuf[pos] = '\0';
-	*buf = &ibuf[spos];
-
-	pos++;
-	*position = pos;
-
-	return 1;
-}
-
-static void load_conf()
-{
-	/* Corrections to change "...", "(c)", "(r)", and "(tm)" to their
-	 * Unicode character equivalents were not added here even though
-	 * they existed in the source list(s). I think these corrections
-	 * would be more trouble than they're worth.
-	 */
-	const char * const defaultconf =
-			"BAD abbout\nGOOD about\n"
-			"BAD abotu\nGOOD about\n"
-			"BAD abouta\nGOOD about a\n"
-			"BAD aboutit\nGOOD about it\n"
-			"BAD aboutthe\nGOOD about the\n"
-			"BAD abscence\nGOOD absence\n"
-			"BAD accesories\nGOOD accessories\n"
-			"BAD accidant\nGOOD accident\n"
-			"BAD accomodate\nGOOD accommodate\n"
-			"BAD accordingto\nGOOD according to\n"
-			"BAD accross\nGOOD across\n"
-			"BAD acheive\nGOOD achieve\n"
-			"BAD acheived\nGOOD achieved\n"
-			"BAD acheiving\nGOOD achieving\n"
-			"BAD acn\nGOOD can\n"
-			"BAD acommodate\nGOOD accommodate\n"
-			"BAD acomodate\nGOOD accommodate\n"
-			"BAD actualyl\nGOOD actually\n"
-			"BAD additinal\nGOOD additional\n"
-			"BAD addtional\nGOOD additional\n"
-			"BAD adequit\nGOOD adequate\n"
-			"BAD adequite\nGOOD adequate\n"
-			"BAD adn\nGOOD and\n"
-			"BAD advanage\nGOOD advantage\n"
-			"BAD affraid\nGOOD afraid\n"
-			"BAD afterthe\nGOOD after the\n"
-			"COMPLETE 0\nBAD againstt he \nGOOD against the \n"
-			"BAD aganist\nGOOD against\n"
-			"BAD aggresive\nGOOD aggressive\n"
-			"BAD agian\nGOOD again\n"
-			"BAD agreemeent\nGOOD agreement\n"
-			"BAD agreemeents\nGOOD agreements\n"
-			"BAD agreemnet\nGOOD agreement\n"
-			"BAD agreemnets\nGOOD agreements\n"
-			"BAD agressive\nGOOD aggressive\n"
-			"BAD agressiveness\nGOOD aggressiveness\n"
-			"BAD ahd\nGOOD had\n"
-			"BAD ahold\nGOOD a hold\n"
-			"BAD ahppen\nGOOD happen\n"
-			"BAD ahve\nGOOD have\n"
-			"BAD allready\nGOOD already\n"
-			"BAD allwasy\nGOOD always\n"
-			"BAD allwyas\nGOOD always\n"
-			"BAD almots\nGOOD almost\n"
-			"BAD almsot\nGOOD almost\n"
-			"BAD alomst\nGOOD almost\n"
-			"BAD alot\nGOOD a lot\n"
-			"BAD alraedy\nGOOD already\n"
-			"BAD alreayd\nGOOD already\n"
-			"BAD alreday\nGOOD already\n"
-			"BAD alwasy\nGOOD always\n"
-			"BAD alwats\nGOOD always\n"
-			"BAD alway\nGOOD always\n"
-			"BAD alwyas\nGOOD always\n"
-			"BAD amde\nGOOD made\n"
-			"BAD Ameria\nGOOD America\n"
-			"BAD amke\nGOOD make\n"
-			"BAD amkes\nGOOD makes\n"
-			"BAD anbd\nGOOD and\n"
-			"BAD andone\nGOOD and one\n"
-			"BAD andteh\nGOOD and the\n"
-			"BAD andthe\nGOOD and the\n"
-			"COMPLETE 0\nBAD andt he \nGOOD and the \n"
-			"BAD anothe\nGOOD another\n"
-			"BAD anual\nGOOD annual\n"
-			"BAD any1\nGOOD anyone\n"
-			"BAD apparant\nGOOD apparent\n"
-			"BAD apparrent\nGOOD apparent\n"
-			"BAD appearence\nGOOD appearance\n"
-			"BAD appeares\nGOOD appears\n"
-			"BAD applicaiton\nGOOD application\n"
-			"BAD applicaitons\nGOOD applications\n"
-			"BAD applyed\nGOOD applied\n"
-			"BAD appointiment\nGOOD appointment\n"
-			"BAD approrpiate\nGOOD appropriate\n"
-			"BAD approrpriate\nGOOD appropriate\n"
-			"BAD aquisition\nGOOD acquisition\n"
-			"BAD aquisitions\nGOOD acquisitions\n"
-			"BAD arent\nGOOD aren't\n"
-			"COMPLETE 0\nBAD aren;t \nGOOD aren't \n"
-			"BAD arguement\nGOOD argument\n"
-			"BAD arguements\nGOOD arguments\n"
-			"COMPLETE 0\nBAD arn't \nGOOD aren't \n"
-			"BAD arond\nGOOD around\n"
-			"BAD artical\nGOOD article\n"
-			"BAD articel\nGOOD article\n"
-			"BAD asdvertising\nGOOD advertising\n"
-			"COMPLETE 0\nBAD askt he \nGOOD ask the \n"
-			"BAD assistent\nGOOD assistant\n"
-			"BAD asthe\nGOOD as the\n"
-			"BAD atention\nGOOD attention\n"
-			"BAD atmospher\nGOOD atmosphere\n"
-			"BAD attentioin\nGOOD attention\n"
-			"BAD atthe\nGOOD at the\n"
-			"BAD audeince\nGOOD audience\n"
-			"BAD audiance\nGOOD audience\n"
-			"BAD authentification\nGOOD authentication\n"
-			"BAD availalbe\nGOOD available\n"
-			"BAD awya\nGOOD away\n"
-			"BAD aywa\nGOOD away\n"
-			"BAD b4\nGOOD before\n"
-			"BAD bakc\nGOOD back\n"
-			"BAD balence\nGOOD balance\n"
-			"BAD ballance\nGOOD balance\n"
-			"BAD baout\nGOOD about\n"
-			"BAD bcak\nGOOD back\n"
-			"BAD bcuz\nGOOD because\n"
-			"BAD beacuse\nGOOD because\n"
-			"BAD becasue\nGOOD because\n"
-			"BAD becaus\nGOOD because\n"
-			"BAD becausea\nGOOD because a\n"
-			"BAD becauseof\nGOOD because of\n"
-			"BAD becausethe\nGOOD because the\n"
-			"BAD becauseyou\nGOOD because you\n"
-			"COMPLETE 0\nBAD beckon call\nGOOD beck and call\n"
-			"BAD becomeing\nGOOD becoming\n"
-			"BAD becomming\nGOOD becoming\n"
-			"BAD becuase\nGOOD because\n"
-			"BAD becuse\nGOOD because\n"
-			"BAD befoer\nGOOD before\n"
-			"BAD beggining\nGOOD beginning\n"
-			"BAD begining\nGOOD beginning\n"
-			"BAD beginining\nGOOD beginning\n"
-			"BAD beleiev\nGOOD believe\n"
-			"BAD beleieve\nGOOD believe\n"
-			"BAD beleif\nGOOD belief\n"
-			"BAD beleive\nGOOD believe\n"
-			"BAD beleived\nGOOD believed\n"
-			"BAD beleives\nGOOD believes\n"
-			"BAD belive\nGOOD believe\n"
-			"BAD belived\nGOOD believed\n"
-			"BAD belives\nGOOD believes\n"
-			"BAD benifit\nGOOD benefit\n"
-			"BAD benifits\nGOOD benefits\n"
-			"BAD betwen\nGOOD between\n"
-			"BAD beutiful\nGOOD beautiful\n"
-			"BAD blase\nGOOD blasé\n"
-			"BAD boxs\nGOOD boxes\n"
-			"BAD brodcast\nGOOD broadcast\n"
-			"BAD butthe\nGOOD but the\n"
-			"BAD bve\nGOOD be\n"
-			"COMPLETE 0\nBAD byt he \nGOOD by the \n"
-			"BAD cafe\nGOOD café\n"
-			"BAD caharcter\nGOOD character\n"
-			"BAD calcullated\nGOOD calculated\n"
-			"BAD calulated\nGOOD calculated\n"
-			"BAD candidtae\nGOOD candidate\n"
-			"BAD candidtaes\nGOOD candidates\n"
-			"COMPLETE 0\nBAD case and point\nGOOD case in point\n"
-			"BAD cant\nGOOD can't\n"
-			"COMPLETE 0\nBAD can;t \nGOOD can't \n"
-			"COMPLETE 0\nBAD can't of been\nGOOD can't have been\n"
-			"BAD catagory\nGOOD category\n"
-			"BAD categiory\nGOOD category\n"
-			"BAD certian\nGOOD certain\n"
-			"BAD challange\nGOOD challenge\n"
-			"BAD challanges\nGOOD challenges\n"
-			"BAD chaneg\nGOOD change\n"
-			"BAD chanegs\nGOOD changes\n"
-			"BAD changable\nGOOD changeable\n"
-			"BAD changeing\nGOOD changing\n"
-			"BAD changng\nGOOD changing\n"
-			"BAD charachter\nGOOD character\n"
-			"BAD charachters\nGOOD characters\n"
-			"BAD charactor\nGOOD character\n"
-			"BAD charecter\nGOOD character\n"
-			"BAD charector\nGOOD character\n"
-			"BAD cheif\nGOOD chief\n"
-			"BAD chekc\nGOOD check\n"
-			"BAD chnage\nGOOD change\n"
-			"BAD cieling\nGOOD ceiling\n"
-			"BAD circut\nGOOD circuit\n"
-			"BAD claer\nGOOD clear\n"
-			"BAD claered\nGOOD cleared\n"
-			"BAD claerly\nGOOD clearly\n"
-			"BAD cliant\nGOOD client\n"
-			"BAD cliche\nGOOD cliché\n"
-			"BAD cna\nGOOD can\n"
-			"BAD colection\nGOOD collection\n"
-			"BAD comanies\nGOOD companies\n"
-			"BAD comany\nGOOD company\n"
-			"BAD comapnies\nGOOD companies\n"
-			"BAD comapny\nGOOD company\n"
-			"BAD combintation\nGOOD combination\n"
-			"BAD comited\nGOOD committed\n"
-			"BAD comittee\nGOOD committee\n"
-			"BAD commadn\nGOOD command\n"
-			"BAD comming\nGOOD coming\n"
-			"BAD commitee\nGOOD committee\n"
-			"BAD committe\nGOOD committee\n"
-			"BAD committment\nGOOD commitment\n"
-			"BAD committments\nGOOD commitments\n"
-			"BAD committy\nGOOD committee\n"
-			"BAD comntain\nGOOD contain\n"
-			"BAD comntains\nGOOD contains\n"
-			"BAD compair\nGOOD compare\n"
-			"COMPLETE 0\nBAD company;s \nGOOD company's \n"
-			"BAD competetive\nGOOD competitive\n"
-			"BAD compleated\nGOOD completed\n"
-			"BAD compleatly\nGOOD completely\n"
-			"BAD compleatness\nGOOD completeness\n"
-			"BAD completly\nGOOD completely\n"
-			"BAD completness\nGOOD completeness\n"
-			"BAD composate\nGOOD composite\n"
-			"BAD comtain\nGOOD contain\n"
-			"BAD comtains\nGOOD contains\n"
-			"BAD comunicate\nGOOD communicate\n"
-			"BAD comunity\nGOOD community\n"
-			"BAD condolances\nGOOD condolences\n"
-			"BAD conected\nGOOD connected\n"
-			"BAD conferance\nGOOD conference\n"
-			"BAD confirmmation\nGOOD confirmation\n"
-			"BAD congradulations\nGOOD congratulations\n"
-			"BAD considerit\nGOOD considerate\n"
-			"BAD considerite\nGOOD considerate\n"
-			"BAD consonent\nGOOD consonant\n"
-			"BAD conspiricy\nGOOD conspiracy\n"
-			"BAD consultent\nGOOD consultant\n"
-			"BAD convertable\nGOOD convertible\n"
-			"BAD cooparate\nGOOD cooperate\n"
-			"BAD cooporate\nGOOD cooperate\n"
-			"BAD corproation\nGOOD corporation\n"
-			"BAD corproations\nGOOD corporations\n"
-			"BAD corruptable\nGOOD corruptible\n"
-			"BAD cotten\nGOOD cotton\n"
-			"BAD coudl\nGOOD could\n"
-			"COMPLETE 0\nBAD coudln't \nGOOD couldn't \n"
-			"COMPLETE 0\nBAD coudn't \nGOOD couldn't \n"
-			"BAD couldnt\nGOOD couldn't\n"
-			"COMPLETE 0\nBAD couldn;t \nGOOD couldn't \n"
-			"COMPLETE 0\nBAD could of been\nGOOD could have been\n"
-			"COMPLETE 0\nBAD could of had\nGOOD could have had\n"
-			"BAD couldthe\nGOOD could the\n"
-			"BAD couldve\nGOOD could've\n"
-			"BAD cpoy\nGOOD copy\n"
-			"BAD creme\nGOOD crème\n"
-			"BAD ctaegory\nGOOD category\n"
-			"BAD cu\nGOOD see you\n"
-			"BAD cusotmer\nGOOD customer\n"
-			"BAD cusotmers\nGOOD customers\n"
-			"BAD cutsomer\nGOOD customer\n"
-			"BAD cutsomers\nGOOD customer\n"
-			"BAD cuz\nGOOD because\n"
-			"BAD cxan\nGOOD can\n"
-			"BAD danceing\nGOOD dancing\n"
-			"BAD dcument\nGOOD document\n"
-			"BAD deatils\nGOOD details\n"
-			"BAD decison\nGOOD decision\n"
-			"BAD decisons\nGOOD decisions\n"
-			"BAD decor\nGOOD décor\n"
-			"BAD defendent\nGOOD defendant\n"
-			"BAD definately\nGOOD definitely\n"
-			"COMPLETE 0\nBAD deja vu\nGOOD déjà vu\n"
-			"BAD deptartment\nGOOD department\n"
-			"BAD desicion\nGOOD decision\n"
-			"BAD desicions\nGOOD decisions\n"
-			"BAD desision\nGOOD decision\n"
-			"BAD desisions\nGOOD decisions\n"
-			"BAD detente\nGOOD détente\n"
-			"BAD develeoprs\nGOOD developers\n"
-			"BAD devellop\nGOOD develop\n"
-			"BAD develloped\nGOOD developed\n"
-			"BAD develloper\nGOOD developer\n"
-			"BAD devellopers\nGOOD developers\n"
-			"BAD develloping\nGOOD developing\n"
-			"BAD devellopment\nGOOD development\n"
-			"BAD devellopments\nGOOD developments\n"
-			"BAD devellops\nGOOD develop\n"
-			"BAD develope\nGOOD develop\n"
-			"BAD developement\nGOOD development\n"
-			"BAD developements\nGOOD developments\n"
-			"BAD developor\nGOOD developer\n"
-			"BAD developors\nGOOD developers\n"
-			"BAD develpment\nGOOD development\n"
-			"BAD diaplay\nGOOD display\n"
-			"BAD didint\nGOOD didn't\n"
-			"BAD didnot\nGOOD did not\n"
-			"BAD didnt\nGOOD didn't\n"
-			"COMPLETE 0\nBAD didn;t \nGOOD didn't \n"
-			"BAD difefrent\nGOOD different\n"
-			"BAD diferences\nGOOD differences\n"
-			"BAD differance\nGOOD difference\n"
-			"BAD differances\nGOOD differences\n"
-			"BAD differant\nGOOD different\n"
-			"BAD differemt\nGOOD different\n"
-			"BAD differnt\nGOOD different\n"
-			"BAD diffrent\nGOOD different\n"
-			"BAD directer\nGOOD director\n"
-			"BAD directers\nGOOD directors\n"
-			"BAD directiosn\nGOOD direction\n"
-			"BAD disatisfied\nGOOD dissatisfied\n"
-			"BAD discoverd\nGOOD discovered\n"
-			"BAD disign\nGOOD design\n"
-			"BAD dispaly\nGOOD display\n"
-			"BAD dissonent\nGOOD dissonant\n"
-			"BAD distribusion\nGOOD distribution\n"
-			"BAD divsion\nGOOD division\n"
-			"BAD docuement\nGOOD documents\n"
-			"BAD docuemnt\nGOOD document\n"
-			"BAD documetn\nGOOD document\n"
-			"BAD documnet\nGOOD document\n"
-			"BAD documnets\nGOOD documents\n"
-			"COMPLETE 0\nBAD doens't \nGOOD doesn't \n"
-			"BAD doese\nGOOD does\n"
-			"COMPLETE 0\nBAD doe snot \nGOOD does not \n"
-			"BAD doesnt\nGOOD doesn't\n"
-			"COMPLETE 0\nBAD doesn;t \nGOOD doesn't \n"
-			"BAD doign\nGOOD doing\n"
-			"BAD doimg\nGOOD doing\n"
-			"BAD doind\nGOOD doing\n"
-			"BAD dollers\nGOOD dollars\n"
-			"BAD donig\nGOOD doing\n"
-			"BAD donno\nGOOD don't know\n"
-			"BAD dont\nGOOD don't\n"
-			"COMPLETE 0\nBAD do'nt \nGOOD don't \n"
-			"COMPLETE 0\nBAD don;t \nGOOD don't \n"
-			"COMPLETE 0\nBAD don't no \nGOOD don't know \n"
-			"COMPLETE 0\nBAD dosn't \nGOOD doesn't \n"
-			"BAD driveing\nGOOD driving\n"
-			"BAD drnik\nGOOD drink\n"
-			"BAD dunno\nGOOD don't know\n"
-			"BAD eclair\nGOOD éclair\n"
-			"BAD efel\nGOOD feel\n"
-			"BAD effecient\nGOOD efficient\n"
-			"BAD efort\nGOOD effort\n"
-			"BAD eforts\nGOOD efforts\n"
-			"BAD ehr\nGOOD her\n"
-			"BAD eligable\nGOOD eligible\n"
-			"BAD embarass\nGOOD embarrass\n"
-			"BAD emigre\nGOOD émigré\n"
-			"BAD enought\nGOOD enough\n"
-			"BAD entree\nGOOD entrée\n"
-			"BAD enuf\nGOOD enough\n"
-			"BAD equippment\nGOOD equipment\n"
-			"BAD equivalant\nGOOD equivalent\n"
-			"BAD esle\nGOOD else\n"
-			"BAD especally\nGOOD especially\n"
-			"BAD especialyl\nGOOD especially\n"
-			"BAD espesially\nGOOD especially\n"
-			"BAD essense\nGOOD essence\n"
-			"BAD excellance\nGOOD excellence\n"
-			"BAD excellant\nGOOD excellent\n"
-			"BAD excercise\nGOOD exercise\n"
-			"BAD exchagne\nGOOD exchange\n"
-			"BAD exchagnes\nGOOD exchanges\n"
-			"BAD excitment\nGOOD excitement\n"
-			"BAD exhcange\nGOOD exchange\n"
-			"BAD exhcanges\nGOOD exchanges\n"
-			"BAD experiance\nGOOD experience\n"
-			"BAD experienc\nGOOD experience\n"
-			"BAD exprience\nGOOD experience\n"
-			"BAD exprienced\nGOOD experienced\n"
-			"BAD eyt\nGOOD yet\n"
-			"BAD facade\nGOOD façade\n"
-			"BAD faeture\nGOOD feature\n"
-			"BAD faetures\nGOOD feature\n"
-			"BAD familair\nGOOD familiar\n"
-			"BAD familar\nGOOD familiar\n"
-			"BAD familliar\nGOOD familiar\n"
-			"BAD fammiliar\nGOOD familiar\n"
-			"BAD feild\nGOOD field\n"
-			"BAD feilds\nGOOD fields\n"
-			"BAD fianlly\nGOOD finally\n"
-			"BAD fidn\nGOOD find\n"
-			"BAD finalyl\nGOOD finally\n"
-			"BAD firends\nGOOD friends\n"
-			"BAD firts\nGOOD first\n"
-			"BAD follwo\nGOOD follow\n"
-			"BAD follwoing\nGOOD following\n"
-			"BAD fora\nGOOD for a\n"
-			"COMPLETE 0\nBAD for all intensive purposes\nfor all intents and purposes\n"
-			"BAD foriegn\nGOOD foreign\n"
-			"BAD forthe\nGOOD for the\n"
-			"BAD forwrd\nGOOD forward\n"
-			"BAD forwrds\nGOOD forwards\n"
-			"BAD foudn\nGOOD found\n"
-			"BAD foward\nGOOD forward\n"
-			"BAD fowards\nGOOD forwards\n"
-			"BAD freind\nGOOD friend\n"
-			"BAD freindly\nGOOD friendly\n"
-			"BAD freinds\nGOOD friends\n"
-			"BAD friday\nGOOD Friday\n"
-			"BAD frmo\nGOOD from\n"
-			"BAD fromthe\nGOOD from the\n"
-			"COMPLETE 0\nBAD fromt he \nGOOD from the \n"
-			"BAD furneral\nGOOD funeral\n"
-			"BAD fwe\nGOOD few\n"
-			"BAD garantee\nGOOD guarantee\n"
-			"BAD gaurd\nGOOD guard\n"
-			"BAD gemeral\nGOOD general\n"
-			"BAD gerat\nGOOD great\n"
-			"BAD geting\nGOOD getting\n"
-			"BAD gettin\nGOOD getting\n"
-			"BAD gievn\nGOOD given\n"
-			"BAD giveing\nGOOD giving\n"
-			"BAD gloabl\nGOOD global\n"
-			"BAD goign\nGOOD going\n"
-			"BAD gonig\nGOOD going\n"
-			"BAD govenment\nGOOD government\n"
-			"BAD goverment\nGOOD government\n"
-			"BAD gruop\nGOOD group\n"
-			"BAD gruops\nGOOD groups\n"
-			"BAD grwo\nGOOD grow\n"
-			"BAD guidlines\nGOOD guidelines\n"
-			"BAD hadbeen\nGOOD had been\n"
-			"BAD hadnt\nGOOD hadn't\n"
-			"COMPLETE 0\nBAD hadn;t \nGOOD hadn't \n"
-			"BAD haev\nGOOD have\n"
-			"BAD hapen\nGOOD happen\n"
-			"BAD hapened\nGOOD happened\n"
-			"BAD hapening\nGOOD happening\n"
-			"BAD hapens\nGOOD happens\n"
-			"BAD happend\nGOOD happened\n"
-			"BAD hasbeen\nGOOD has been\n"
-			"BAD hasnt\nGOOD hasn't\n"
-			"COMPLETE 0\nBAD hasn;t \nGOOD hasn't \n"
-			"BAD havebeen\nGOOD have been\n"
-			"BAD haveing\nGOOD having\n"
-			"BAD havent\nGOOD haven't\n"
-			"COMPLETE 0\nBAD haven;t \nGOOD haven't \n"
-			"BAD hda\nGOOD had\n"
-			"BAD hearign\nGOOD hearing\n"
-			"COMPLETE 0\nBAD he;d \nGOOD he'd \n"
-			"BAD heirarchy\nGOOD hierarchy\n"
-			"BAD hel\nGOOD he'll\n"
-			"COMPLETE 0\nBAD he;ll \nGOOD he'll \n"
-			"BAD helpfull\nGOOD helpful\n"
-			"BAD herat\nGOOD heart\n"
-			"BAD heres\nGOOD here's\n"
-			"COMPLETE 0\nBAD here;s \nGOOD here's \n"
-			"BAD hes\nGOOD he's\n"
-			"COMPLETE 0\nBAD he;s \nGOOD he's \n"
-			"BAD hesaid\nGOOD he said\n"
-			"BAD hewas\nGOOD he was\n"
-			"BAD hge\nGOOD he\n"
-			"BAD hismelf\nGOOD himself\n"
-			"BAD hlep\nGOOD help\n"
-			"BAD hott\nGOOD hot\n"
-			"BAD hows\nGOOD how's\n"
-			"BAD hsa\nGOOD has\n"
-			"BAD hse\nGOOD she\n"
-			"BAD hsi\nGOOD his\n"
-			"BAD hte\nGOOD the\n"
-			"BAD htere\nGOOD there\n"
-			"BAD htese\nGOOD these\n"
-			"BAD htey\nGOOD they\n"
-			"BAD hting\nGOOD thing\n"
-			"BAD htink\nGOOD think\n"
-			"BAD htis\nGOOD this\n"
-			"COMPLETE 0\nBAD htp:\nGOOD http:\n"
-			"COMPLETE 0\nBAD http:\\\\nGOOD http://\n"
-			"BAD httpL\nGOOD http:\n"
-			"BAD hvae\nGOOD have\n"
-			"BAD hvaing\nGOOD having\n"
-			"BAD hwich\nGOOD which\n"
-			"BAD i\nGOOD I\n"
-			"COMPLETE 0\nBAD i c \nGOOD I see \n"
-			"COMPLETE 0\nBAD i;d \nGOOD I'd \n"
-			"COMPLETE 0\nBAD i'd \nGOOD I'd \n"
-			"COMPLETE 0\nBAD I;d \nGOOD I'd \n"
-			"BAD idae\nGOOD idea\n"
-			"BAD idaes\nGOOD ideas\n"
-			"BAD identofy\nGOOD identify\n"
-			"BAD ihs\nGOOD his\n"
-			"BAD iits the\nGOOD it's the\n"
-			"COMPLETE 0\nBAD i'll \nGOOD I'll \n"
-			"COMPLETE 0\nBAD I;ll \nGOOD I'll \n"
-			"COMPLETE 0\nBAD i;m \nGOOD I'm \n"
-			"COMPLETE 0\nBAD i'm \nGOOD I'm \n"
-			"COMPLETE 0\nBAD I\"m \nGOOD I'm \n"
-			"BAD imediate\nGOOD immediate\n"
-			"BAD imediatly\nGOOD immediately\n"
-			"BAD immediatly\nGOOD immediately\n"
-			"BAD importent\nGOOD important\n"
-			"BAD importnat\nGOOD important\n"
-			"BAD impossable\nGOOD impossible\n"
-			"BAD improvemnt\nGOOD improvement\n"
-			"BAD improvment\nGOOD improvement\n"
-			"BAD includ\nGOOD include\n"
-			"BAD indecate\nGOOD indicate\n"
-			"BAD indenpendence\nGOOD independence\n"
-			"BAD indenpendent\nGOOD independent\n"
-			"BAD indepedent\nGOOD independent\n"
-			"BAD independance\nGOOD independence\n"
-			"BAD independant\nGOOD independent\n"
-			"BAD influance\nGOOD influence\n"
-			"BAD infomation\nGOOD information\n"
-			"BAD informatoin\nGOOD information\n"
-			"BAD inital\nGOOD initial\n"
-			"BAD instaleld\nGOOD installed\n"
-			"BAD insted\nGOOD instead\n"
-			"BAD insurence\nGOOD insurance\n"
-			"BAD inteh\nGOOD in the\n"
-			"BAD interum\nGOOD interim\n"
-			"BAD inthe\nGOOD in the\n"
-			"COMPLETE 0\nBAD int he \nGOOD in the \n"
-			"BAD inturn\nGOOD intern\n"
-			"BAD inwhich\nGOOD in which\n"
-			"COMPLETE 0\nBAD i snot \nGOOD is not \n"
-			"BAD isnt\nGOOD isn't\n"
-			"COMPLETE 0\nBAD isn;t \nGOOD isn't \n"
-			"BAD isthe\nGOOD is the\n"
-			"BAD itd\nGOOD it'd\n"
-			"COMPLETE 0\nBAD it;d \nGOOD it'd \n"
-			"BAD itis\nGOOD it is\n"
-			"BAD ititial\nGOOD initial\n"
-			"BAD itll\nGOOD it'll\n"
-			"COMPLETE 0\nBAD it;ll \nGOOD it'll \n"
-			"BAD itnerest\nGOOD interest\n"
-			"BAD itnerested\nGOOD interested\n"
-			"BAD itneresting\nGOOD interesting\n"
-			"BAD itnerests\nGOOD interests\n"
-			"COMPLETE 0\nBAD it;s \nGOOD it's \n"
-			"BAD itsa\nGOOD it's a\n"
-			"COMPLETE 0\nBAD  its a \nGOOD  it's a \n"
-			"COMPLETE 0\nBAD  it snot \nGOOD  it's not \n"
-			"COMPLETE 0\nBAD  it' snot \nGOOD  it's not \n"
-			"COMPLETE 0\nBAD  its the \nGOOD  it's the \n"
-			"BAD itwas\nGOOD it was\n"
-			"BAD ive\nGOOD I've\n"
-			"COMPLETE 0\nBAD i;ve \nGOOD I've \n"
-			"COMPLETE 0\nBAD i've \nGOOD I've \n"
-			"BAD iwll\nGOOD will\n"
-			"BAD iwth\nGOOD with\n"
-			"BAD jsut\nGOOD just\n"
-			"BAD jugment\nGOOD judgment\n"
-			"BAD kno\nGOOD know\n"
-			"BAD knowldge\nGOOD knowledge\n"
-			"BAD knowlege\nGOOD knowledge\n"
-			"BAD knwo\nGOOD know\n"
-			"BAD knwon\nGOOD known\n"
-			"BAD knwos\nGOOD knows\n"
-			"BAD konw\nGOOD know\n"
-			"BAD konwn\nGOOD known\n"
-			"BAD konws\nGOOD knows\n"
-			"BAD labratory\nGOOD laboratory\n"
-			"BAD labtop\nGOOD laptop\n"
-			"BAD lastyear\nGOOD last year\n"
-			"BAD laterz\nGOOD later\n"
-			"BAD learnign\nGOOD learning\n"
-			"BAD lenght\nGOOD length\n"
-			"COMPLETE 0\nBAD let;s \nGOOD let's \n"
-			"COMPLETE 0\nBAD let's him \nGOOD lets him \n"
-			"COMPLETE 0\nBAD let's it \nGOOD lets it \n"
-			"BAD levle\nGOOD level\n"
-			"BAD libary\nGOOD library\n"
-			"BAD librarry\nGOOD library\n"
-			"BAD librery\nGOOD library\n"
-			"BAD liek\nGOOD like\n"
-			"BAD liekd\nGOOD liked\n"
-			"BAD lieutenent\nGOOD lieutenant\n"
-			"BAD liev\nGOOD live\n"
-			"BAD likly\nGOOD likely\n"
-			"BAD lisense\nGOOD license\n"
-			"BAD littel\nGOOD little\n"
-			"BAD litttle\nGOOD little\n"
-			"BAD liuke\nGOOD like\n"
-			"BAD liveing\nGOOD living\n"
-			"BAD loev\nGOOD love\n"
-			"BAD lonly\nGOOD lonely\n"
-			"BAD lookign\nGOOD looking\n"
-			"BAD m\nGOOD am\n"
-			"BAD maintainence\nGOOD maintenance\n"
-			"BAD maintenence\nGOOD maintenance\n"
-			"BAD makeing\nGOOD making\n"
-			"BAD managment\nGOOD management\n"
-			"BAD mantain\nGOOD maintain\n"
-			"BAD marraige\nGOOD marriage\n"
-			"COMPLETE 0\nBAD may of been\nGOOD may have been\n"
-			"COMPLETE 0\nBAD may of had\nGOOD may have had\n"
-			"BAD memeber\nGOOD member\n"
-			"BAD merchent\nGOOD merchant\n"
-			"BAD mesage\nGOOD message\n"
-			"BAD mesages\nGOOD messages\n"
-			"COMPLETE 0\nBAD might of been\nGOOD might have been\n"
-			"COMPLETE 0\nBAD might of had\nGOOD might have had\n"
-			"BAD mispell\nGOOD misspell\n"
-			"BAD mispelling\nGOOD misspelling\n"
-			"BAD mispellings\nGOOD misspellings\n"
-			"BAD mkae\nGOOD make\n"
-			"BAD mkaes\nGOOD makes\n"
-			"BAD mkaing\nGOOD making\n"
-			"BAD moeny\nGOOD money\n"
-			"BAD monday\nGOOD Monday\n"
-			"BAD morgage\nGOOD mortgage\n"
-			"BAD mroe\nGOOD more\n"
-			"COMPLETE 0\nBAD must of been\nGOOD must have been\n"
-			"COMPLETE 0\nBAD must of had\nGOOD must have had\n"
-			"COMPLETE 0\nBAD mute point\nGOOD moot point\n"
-			"BAD mysefl\nGOOD myself\n"
-			"BAD myu\nGOOD my\n"
-			"BAD naive\nGOOD naïve\n"
-			"BAD ne1\nGOOD anyone\n"
-			"BAD neway\nGOOD anyway\n"
-			"BAD neways\nGOOD anyways\n"
-			"BAD necassarily\nGOOD necessarily\n"
-			"BAD necassary\nGOOD necessary\n"
-			"BAD neccessarily\nGOOD necessarily\n"
-			"BAD neccessary\nGOOD necessary\n"
-			"BAD necesarily\nGOOD necessarily\n"
-			"BAD necesary\nGOOD necessary\n"
-			"BAD negotiaing\nGOOD negotiating\n"
-			"BAD nkow\nGOOD know\n"
-			"BAD nothign\nGOOD nothing\n"
-			"BAD nto\nGOOD not\n"
-			"BAD nver\nGOOD never\n"
-			"BAD nwe\nGOOD new\n"
-			"BAD nwo\nGOOD now\n"
-			"BAD obediant\nGOOD obedient\n"
-			"BAD ocasion\nGOOD occasion\n"
-			"BAD occassion\nGOOD occasion\n"
-			"BAD occurance\nGOOD occurrence\n"
-			"BAD occured\nGOOD occurred\n"
-			"BAD occurence\nGOOD occurrence\n"
-			"BAD occurrance\nGOOD occurrence\n"
-			"BAD oclock\nGOOD o'clock\n"
-			"BAD oculd\nGOOD could\n"
-			"BAD ocur\nGOOD occur\n"
-			"BAD oeprator\nGOOD operator\n"
-			"BAD ofits\nGOOD of its\n"
-			"BAD ofthe\nGOOD of the\n"
-			"BAD oft he\nGOOD of the\n"
-			"BAD oging\nGOOD going\n"
-			"BAD ohter\nGOOD other\n"
-			"BAD omre\nGOOD more\n"
-			"BAD oneof\nGOOD one of\n"
-			"BAD onepoint\nGOOD one point\n"
-			"BAD onthe\nGOOD on the\n"
-			"COMPLETE 0\nBAD ont he \nGOOD on the \n"
-			"BAD onyl\nGOOD only\n"
-			"BAD oppasite\nGOOD opposite\n"
-			"BAD opperation\nGOOD operation\n"
-			"BAD oppertunity\nGOOD opportunity\n"
-			"BAD opposate\nGOOD opposite\n"
-			"BAD opposible\nGOOD opposable\n"
-			"BAD opposit\nGOOD opposite\n"
-			"BAD oppotunities\nGOOD opportunities\n"
-			"BAD oppotunity\nGOOD opportunity\n"
-			"BAD orginization\nGOOD organization\n"
-			"BAD orginized\nGOOD organized\n"
-			"BAD otehr\nGOOD other\n"
-			"BAD otu\nGOOD out\n"
-			"BAD outof\nGOOD out of\n"
-			"BAD overthe\nGOOD over the\n"
-			"BAD owrk\nGOOD work\n"
-			"BAD owuld\nGOOD would\n"
-			"BAD oxident\nGOOD oxidant\n"
-			"BAD papaer\nGOOD paper\n"
-			"BAD parliment\nGOOD parliament\n"
-			"BAD partof\nGOOD part of\n"
-			"BAD paymetn\nGOOD payment\n"
-			"BAD paymetns\nGOOD payments\n"
-			"BAD pciture\nGOOD picture\n"
-			"BAD peice\nGOOD piece\n"
-			"BAD peices\nGOOD pieces\n"
-			"BAD peolpe\nGOOD people\n"
-			"BAD peopel\nGOOD people\n"
-			"BAD percentof\nGOOD percent of\n"
-			"BAD percentto\nGOOD percent to\n"
-			"BAD performence\nGOOD performance\n"
-			"BAD perhasp\nGOOD perhaps\n"
-			"BAD perhpas\nGOOD perhaps\n"
-			"BAD permanant\nGOOD permanent\n"
-			"BAD perminent\nGOOD permanent\n"
-			"BAD personalyl\nGOOD personally\n"
-			"BAD pleasent\nGOOD pleasant\n"
-			"BAD pls\nGOOD please\n"
-			"BAD plz\nGOOD please\n"
-			"BAD poeple\nGOOD people\n"
-			"BAD porblem\nGOOD problem\n"
-			"BAD porblems\nGOOD problems\n"
-			"BAD porvide\nGOOD provide\n"
-			"BAD possable\nGOOD possible\n"
-			"BAD postition\nGOOD position\n"
-			"BAD potatoe\nGOOD potato\n"
-			"BAD potatos\nGOOD potatoes\n"
-			"BAD potentialy\nGOOD potentially\n"
-			"BAD ppl\nGOOD people\n"
-			"BAD pregnent\nGOOD pregnant\n"
-			"BAD presance\nGOOD presence\n"
-			"BAD primative\nGOOD primitive\n"
-			"BAD probally\nGOOD probably\n"
-			"BAD probelm\nGOOD problem\n"
-			"BAD probelms\nGOOD problems\n"
-			"BAD probly\nGOOD probably\n"
-			"BAD prolly\nGOOD probably\n"
-			"BAD proly\nGOOD probably\n"
-			"BAD prominant\nGOOD prominent\n"
-			"BAD proposterous\nGOOD preposterous\n"
-			"BAD protege\nGOOD protégé\n"
-			"BAD protoge\nGOOD protégé\n"
-			"BAD psoition\nGOOD position\n"
-			"BAD ptogress\nGOOD progress\n"
-			"BAD pursuade\nGOOD persuade\n"
-			"BAD puting\nGOOD putting\n"
-			"BAD pwoer\nGOOD power\n"
-			"BAD quater\nGOOD quarter\n"
-			"BAD quaters\nGOOD quarters\n"
-			"BAD quesion\nGOOD question\n"
-			"BAD quesions\nGOOD questions\n"
-			"BAD questioms\nGOOD questions\n"
-			"BAD questiosn\nGOOD questions\n"
-			"BAD questoin\nGOOD question\n"
-			"BAD quetion\nGOOD question\n"
-			"BAD quetions\nGOOD questions\n"
-			"BAD r\nGOOD are\n"
-			"BAD raeson\nGOOD reason\n"
-			"BAD realyl\nGOOD really\n"
-			"BAD reccomend\nGOOD recommend\n"
-			"BAD reccommend\nGOOD recommend\n"
-			"BAD receieve\nGOOD receive\n"
-			"BAD recieve\nGOOD receive\n"
-			"BAD recieved\nGOOD received\n"
-			"BAD recieving\nGOOD receiving\n"
-			"BAD recomend\nGOOD recommend\n"
-			"BAD recomendation\nGOOD recommendation\n"
-			"BAD recomendations\nGOOD recommendations\n"
-			"BAD recomended\nGOOD recommended\n"
-			"BAD reconize\nGOOD recognize\n"
-			"BAD recrod\nGOOD record\n"
-			"BAD rediculous\nGOOD ridiculous\n"
-			"BAD rediculus\nGOOD ridiculous\n"
-			"BAD reguard\nGOOD regard\n"
-			"BAD religous\nGOOD religious\n"
-			"BAD reluctent\nGOOD reluctant\n"
-			"BAD remeber\nGOOD remember\n"
-			"BAD reommend\nGOOD recommend\n"
-			"BAD representativs\nGOOD representatives\n"
-			"BAD representives\nGOOD representatives\n"
-			"BAD represetned\nGOOD represented\n"
-			"BAD represnt\nGOOD represent\n"
-			"BAD reserach\nGOOD research\n"
-			"BAD resollution\nGOOD resolution\n"
-			"BAD resorces\nGOOD resources\n"
-			"BAD respomd\nGOOD respond\n"
-			"BAD respomse\nGOOD response\n"
-			"BAD responce\nGOOD response\n"
-			"BAD responsability\nGOOD responsibility\n"
-			"BAD responsable\nGOOD responsible\n"
-			"BAD responsibile\nGOOD responsible\n"
-			"BAD responsiblity\nGOOD responsibility\n"
-			"BAD restaraunt\nGOOD restaurant\n"
-			"BAD restuarant\nGOOD restaurant\n"
-			"BAD reult\nGOOD result\n"
-			"BAD reveiw\nGOOD review\n"
-			"BAD reveiwing\nGOOD reviewing\n"
-			"BAD rumers\nGOOD rumors\n"
-			"BAD rwite\nGOOD write\n"
-			"BAD rythm\nGOOD rhythm\n"
-			"BAD saidhe\nGOOD said he\n"
-			"BAD saidit\nGOOD said it\n"
-			"BAD saidthat\nGOOD said that\n"
-			"BAD saidthe\nGOOD said the\n"
-			"COMPLETE 0\nBAD saidt he \nGOOD said the \n"
-			"BAD sandwhich\nGOOD sandwich\n"
-			"BAD sandwitch\nGOOD sandwich\n"
-			"BAD saturday\nGOOD Saturday\n"
-			"BAD scedule\nGOOD schedule\n"
-			"BAD sceduled\nGOOD scheduled\n"
-			"BAD seance\nGOOD séance\n"
-			"BAD secratary\nGOOD secretary\n"
-			"BAD sectino\nGOOD section\n"
-			"BAD seh\nGOOD she\n"
-			"BAD selectoin\nGOOD selection\n"
-			"BAD sence\nGOOD sense\n"
-			"BAD sentance\nGOOD sentence\n"
-			"BAD separeate\nGOOD separate\n"
-			"BAD seperate\nGOOD separate\n"
-			"BAD sercumstances\nGOOD circumstances\n"
-			"BAD shcool\nGOOD school\n"
-			"COMPLETE 0\nBAD she;d \nGOOD she'd \n"
-			"COMPLETE 0\nBAD she;ll \nGOOD she'll \n"
-			"BAD shes\nGOOD she's\n"
-			"COMPLETE 0\nBAD she;s \nGOOD she's \n"
-			"BAD shesaid\nGOOD she said\n"
-			"BAD shineing\nGOOD shining\n"
-			"BAD shiped\nGOOD shipped\n"
-			"BAD shoudl\nGOOD should\n"
-			"COMPLETE 0\nBAD shoudln't \nGOOD shouldn't \n"
-			"BAD shouldent\nGOOD shouldn't\n"
-			"BAD shouldnt\nGOOD shouldn't\n"
-			"COMPLETE 0\nBAD shouldn;t \nGOOD shouldn't \n"
-			"COMPLETE 0\nBAD should of been\nGOOD should have been\n"
-			"COMPLETE 0\nBAD should of had\nGOOD should have had\n"
-			"BAD shouldve\nGOOD should've\n"
-			"BAD showinf\nGOOD showing\n"
-			"BAD signifacnt\nGOOD significant\n"
-			"BAD simalar\nGOOD similar\n"
-			"BAD similiar\nGOOD similar\n"
-			"BAD simpyl\nGOOD simply\n"
-			"BAD sincerly\nGOOD sincerely\n"
-			"BAD sitll\nGOOD still\n"
-			"BAD smae\nGOOD same\n"
-			"BAD smoe\nGOOD some\n"
-			"BAD soem\nGOOD some\n"
-			"BAD sohw\nGOOD show\n"
-			"BAD soical\nGOOD social\n"
-			"BAD some1\nGOOD someone\n"
-			"BAD somethign\nGOOD something\n"
-			"BAD someting\nGOOD something\n"
-			"BAD somewaht\nGOOD somewhat\n"
-			"BAD somthing\nGOOD something\n"
-			"BAD somtimes\nGOOD sometimes\n"
-			"COMPLETE 0\nBAD sot hat \nGOOD so that \n"
-			"BAD soudn\nGOOD sound\n"
-			"BAD soudns\nGOOD sounds\n"
-			"BAD speach\nGOOD speech\n"
-			"BAD specificaly\nGOOD specifically\n"
-			"BAD specificalyl\nGOOD specifically\n"
-			"BAD spelt\nGOOD spelled\n"
-			"BAD sry\nGOOD sorry\n"
-			"COMPLETE 0\nBAD state of the ark\nGOOD state of the art\n"
-			"BAD statment\nGOOD statement\n"
-			"BAD statments\nGOOD statements\n"
-			"BAD stnad\nGOOD stand\n"
-			"BAD stopry\nGOOD story\n"
-			"BAD stoyr\nGOOD story\n"
-			"BAD stpo\nGOOD stop\n"
-			"BAD strentgh\nGOOD strength\n"
-			"BAD stroy\nGOOD story\n"
-			"BAD struggel\nGOOD struggle\n"
-			"BAD strugle\nGOOD struggle\n"
-			"BAD studnet\nGOOD student\n"
-			"BAD successfull\nGOOD successful\n"
-			"BAD successfuly\nGOOD successfully\n"
-			"BAD successfulyl\nGOOD successfully\n"
-			"BAD sucess\nGOOD success\n"
-			"BAD sucessfull\nGOOD successful\n"
-			"BAD sufficiant\nGOOD sufficient\n"
-			"BAD sum1\nGOOD someone\n"
-			"BAD sunday\nGOOD Sunday\n"
-			"BAD suposed\nGOOD supposed\n"
-			"BAD supposably\nGOOD supposedly\n"
-			"BAD suppossed\nGOOD supposed\n"
-			"BAD suprise\nGOOD surprise\n"
-			"BAD suprised\nGOOD surprised\n"
-			"BAD sux\nGOOD sucks\n"
-			"BAD swiming\nGOOD swimming\n"
-			"BAD tahn\nGOOD than\n"
-			"BAD taht\nGOOD that\n"
-			"COMPLETE 0\nBAD take it for granite\nGOOD take it for granted\n"
-			"COMPLETE 0\nBAD taken for granite\nGOOD taken for granted\n"
-			"BAD talekd\nGOOD talked\n"
-			"BAD talkign\nGOOD talking\n"
-			"BAD tath\nGOOD that\n"
-			"BAD tecnical\nGOOD technical\n"
-			"BAD teh\nGOOD the\n"
-			"BAD tehy\nGOOD they\n"
-			"COMPLETE 0\nBAD tellt he \nGOOD tell the \n"
-			"BAD termoil\nGOOD turmoil\n"
-			"BAD tets\nGOOD test\n"
-			"BAD tghe\nGOOD the\n"
-			"BAD tghis\nGOOD this\n"
-			"BAD thansk\nGOOD thanks\n"
-			"BAD thanx\nGOOD thanks\n"
-			"BAD thats\nGOOD that's\n"
-			"BAD thatthe\nGOOD that the\n"
-			"COMPLETE 0\nBAD thatt he \nGOOD that the \n"
-			"BAD thecompany\nGOOD the company\n"
-			"BAD thefirst\nGOOD the first\n"
-			"BAD thegovernment\nGOOD the government\n"
-			"COMPLETE 0\nBAD their are \nGOOD there are \n"
-			"COMPLETE 0\nBAD their aren't \nGOOD there aren't \n"
-			"COMPLETE 0\nBAD their is \nGOOD there is \n"
-			"BAD themself\nGOOD themselves\n"
-			"BAD themselfs\nGOOD themselves\n"
-			"BAD thenew\nGOOD the new\n"
-			"BAD theres\nGOOD there's\n"
-			"COMPLETE 0\nBAD there's is \nGOOD theirs is \n"
-			"COMPLETE 0\nBAD there's isn't \nGOOD theirs isn't \n"
-			"BAD theri\nGOOD their\n"
-			"BAD thesame\nGOOD the same\n"
-			"BAD thetwo\nGOOD the two\n"
-			"BAD theyd\nGOOD they'd\n"
-			"COMPLETE 0\nBAD they;d \nGOOD they'd \n"
-			"COMPLETE 0\nBAD they;l \nGOOD they'll \n"
-			"BAD theyll\nGOOD they'll\n"
-			"COMPLETE 0\nBAD they;ll \nGOOD they'll \n"
-			"COMPLETE 0\nBAD they;r \nGOOD they're \n"
-			"COMPLETE 0\nBAD theyre \nGOOD they're \n"
-			"COMPLETE 0\nBAD they;re \nGOOD they're \n"
-			"COMPLETE 0\nBAD they're are \nGOOD there are \n"
-			"COMPLETE 0\nBAD they're is \nGOOD there is \n"
-			"COMPLETE 0\nBAD they;v \nGOOD they've \n"
-			"BAD theyve\nGOOD they've\n"
-			"COMPLETE 0\nBAD they;ve \nGOOD they've \n"
-			"BAD thgat\nGOOD that\n"
-			"BAD thge\nGOOD the\n"
-			"BAD thier\nGOOD their \n"
-			"BAD thigsn\nGOOD things\n"
-			"BAD thisyear\nGOOD this year\n"
-			"BAD thme\nGOOD them\n"
-			"BAD thna\nGOOD than\n"
-			"BAD thne\nGOOD then\n"
-			"BAD thnig\nGOOD thing\n"
-			"BAD thnigs\nGOOD things\n"
-			"BAD tho\nGOOD though\n"
-			"BAD threatend\nGOOD threatened\n"
-			"BAD thsi\nGOOD this\n"
-			"BAD thsoe\nGOOD those\n"
-			"BAD thta\nGOOD that\n"
-			"BAD thursday\nGOOD Thursday\n"
-			"BAD thx\nGOOD thanks\n"
-			"BAD tihs\nGOOD this\n"
-			"BAD timne\nGOOD time\n"
-			"BAD tiogether\nGOOD together\n"
-			"BAD tje\nGOOD the\n"
-			"BAD tjhe\nGOOD the\n"
-			"BAD tkae\nGOOD take\n"
-			"BAD tkaes\nGOOD takes\n"
-			"BAD tkaing\nGOOD taking\n"
-			"BAD tlaking\nGOOD talking\n"
-			"BAD tnx\nGOOD thanks\n"
-			"BAD todya\nGOOD today\n"
-			"BAD togehter\nGOOD together\n"
-			"COMPLETE 0\nBAD toldt he \nGOOD told the \n"
-			"BAD tomorow\nGOOD tomorrow\n"
-			"BAD tongiht\nGOOD tonight\n"
-			"BAD tonihgt\nGOOD tonight\n"
-			"BAD tonite\nGOOD tonight\n"
-			"BAD totaly\nGOOD totally\n"
-			"BAD totalyl\nGOOD totally\n"
-			"BAD tothe\nGOOD to the\n"
-			"COMPLETE 0\nBAD tot he \nGOOD to the \n"
-			"BAD towrad\nGOOD toward\n"
-			"BAD traditionalyl\nGOOD traditionally\n"
-			"BAD transfered\nGOOD transferred\n"
-			"BAD truely\nGOOD truly\n"
-			"BAD truley\nGOOD truly\n"
-			"BAD tryed\nGOOD tried\n"
-			"BAD tthe\nGOOD the\n"
-			"BAD tuesday\nGOOD Tuesday\n"
-			"BAD tyhat\nGOOD that\n"
-			"BAD tyhe\nGOOD the\n"
-			"BAD u\nGOOD you\n"
-			"BAD udnerstand\nGOOD understand\n"
-			"BAD understnad\nGOOD understand\n"
-			"COMPLETE 0\nBAD undert he \nGOOD under the \n"
-			"BAD unforseen\nGOOD unforeseen\n"
-			"BAD UnitedStates\nGOOD United States\n"
-			"BAD unliek\nGOOD unlike\n"
-			"BAD unpleasently\nGOOD unpleasantly\n"
-			"BAD untill\nGOOD until\n"
-			"BAD untilll\nGOOD until\n"
-			"BAD ur\nGOOD you are\n"
-			"BAD useing\nGOOD using\n"
-			"BAD usualyl\nGOOD usually\n"
-			"BAD veyr\nGOOD very\n"
-			"BAD virtualyl\nGOOD virtually\n"
-			"BAD visavis\nGOOD vis-a-vis\n"
-			"COMPLETE 0\nBAD vis-a-vis\nGOOD vis-à-vis\n"
-			"BAD vrey\nGOOD very\n"
-			"BAD vulnerible\nGOOD vulnerable\n"
-			"BAD waht\nGOOD what\n"
-			"BAD warrent\nGOOD warrant\n"
-			"COMPLETE 0\nBAD wa snot \nGOOD was not \n"
-			"COMPLETE 0\nBAD wasnt \nGOOD wasn't \n"
-			"COMPLETE 0\nBAD wasn;t \nGOOD wasn't \n"
-			"BAD wat\nGOOD what\n"
-			"BAD watn\nGOOD want\n"
-			"COMPLETE 0\nBAD we;d \nGOOD we'd \n"
-			"BAD wednesday\nGOOD Wednesday\n"
-			"BAD wehn\nGOOD when\n"
-			"COMPLETE 0\nBAD we'l \nGOOD we'll \n"
-			"COMPLETE 0\nBAD we;ll \nGOOD we'll \n"
-			"COMPLETE 0\nBAD we;re \nGOOD we're \n"
-			"BAD werent\nGOOD weren't\n"
-			"COMPLETE 0\nBAD weren;t \nGOOD weren't \n"
-			"COMPLETE 0\nBAD wern't \nGOOD weren't \n"
-			"BAD werre\nGOOD were\n"
-			"BAD weve\nGOOD we've\n"
-			"COMPLETE 0\nBAD we;ve \nGOOD we've \n"
-			"BAD whats\nGOOD what's\n"
-			"COMPLETE 0\nBAD what;s \nGOOD what's \n"
-			"BAD whcih\nGOOD which\n"
-			"COMPLETE 0\nBAD whent he \nGOOD when the \n"
-			"BAD wheres\nGOOD where's\n"
-			"COMPLETE 0\nBAD where;s \nGOOD where's \n"
-			"BAD wherre\nGOOD where\n"
-			"BAD whic\nGOOD which\n"
-			"COMPLETE 0\nBAD whicht he \nGOOD which the \n"
-			"BAD whihc\nGOOD which\n"
-			"BAD wholl\nGOOD who'll\n"
-			"BAD whos\nGOOD who's\n"
-			"COMPLETE 0\nBAD who;s \nGOOD who's \n"
-			"BAD whove\nGOOD who've\n"
-			"COMPLETE 0\nBAD who;ve \nGOOD who've \n"
-			"BAD whta\nGOOD what\n"
-			"BAD whys\nGOOD why's\n"
-			"BAD wief\nGOOD wife\n"
-			"BAD wierd\nGOOD weird\n"
-			"BAD wihch\nGOOD which\n"
-			"BAD wiht\nGOOD with\n"
-			"BAD willbe\nGOOD will be\n"
-			"COMPLETE 0\nBAD will of been\nGOOD will have been\n"
-			"COMPLETE 0\nBAD will of had\nGOOD will have had\n"
-			"BAD windoes\nGOOD windows\n"
-			"BAD witha\nGOOD with a\n"
-			"BAD withdrawl\nGOOD withdrawal\n"
-			"BAD withe\nGOOD with\n"
-			"COMPLETE 0\nBAD withthe \nGOOD with the \n"
-			"BAD witht he\nGOOD with the\n"
-			"BAD wiull\nGOOD will\n"
-			"BAD wnat\nGOOD want\n"
-			"BAD wnated\nGOOD wanted\n"
-			"BAD wnats\nGOOD wants\n"
-			"BAD woh\nGOOD who\n"
-			"BAD wohle\nGOOD whole\n"
-			"BAD wokr\nGOOD work\n"
-			"BAD wont\nGOOD won't\n"
-			"COMPLETE 0\nBAD wo'nt \nGOOD won't \n"
-			"COMPLETE 0\nBAD won;t \nGOOD won't \n"
-			"BAD woudl\nGOOD would\n"
-			"COMPLETE 0\nBAD woudln't \nGOOD wouldn't \n"
-			"BAD wouldbe\nGOOD would be\n"
-			"BAD wouldnt\nGOOD wouldn't\n"
-			"COMPLETE 0\nBAD wouldn;t \nGOOD wouldn't \n"
-			"COMPLETE 0\nBAD would of been\nGOOD would have been\n"
-			"COMPLETE 0\nBAD would of had\nGOOD would have had\n"
-			"BAD wouldve\nGOOD would've\n"
-			"BAD wriet\nGOOD write\n"
-			"BAD writting\nGOOD writing\n"
-			"BAD wrod\nGOOD word\n"
-			"BAD wroet\nGOOD wrote\n"
-			"BAD wroking\nGOOD working\n"
-			"BAD wtih\nGOOD with\n"
-			"BAD wuould\nGOOD would\n"
-			"BAD wut\nGOOD what\n"
-			"BAD wya\nGOOD way\n"
-			"BAD y\nGOOD why\n"
-			"BAD yeh\nGOOD yeah\n"
-			"BAD yera\nGOOD year\n"
-			"BAD yeras\nGOOD years\n"
-			"BAD yersa\nGOOD years\n"
-			"BAD yoiu\nGOOD you\n"
-			"BAD youare\nGOOD you are\n"
-			"BAD youd\nGOOD you'd\n"
-			"COMPLETE 0\nBAD you;d \nGOOD you'd \n"
-			"BAD youll\nGOOD you'll\n"
-			"COMPLETE 0\nBAD your a \nGOOD you're a \n"
-			"COMPLETE 0\nBAD your an \nGOOD you're an \n"
-			"BAD youre\nGOOD you're\n"
-			"COMPLETE 0\nBAD you;re \nGOOD you're \n"
-			"COMPLETE 0\nBAD you're own \nGOOD your own \n"
-			"COMPLETE 0\nBAD your her \nGOOD you're her \n"
-			"COMPLETE 0\nBAD your here \nGOOD you're here \n"
-			"COMPLETE 0\nBAD your his \nGOOD you're his \n"
-			"COMPLETE 0\nBAD your my \nGOOD you're my \n"
-			"COMPLETE 0\nBAD your the \nGOOD you're the \n"
-			"COMPLETE 0\nBAD your their \nGOOD you're their \n"
-			"COMPLETE 0\nBAD your your \nGOOD you're your \n"
-			"BAD youve\nGOOD you've\n"
-			"COMPLETE 0\nBAD you;ve \nGOOD you've \n"
-			"BAD ytou\nGOOD you\n"
-			"BAD yuo\nGOOD you\n"
-			"BAD yuor\nGOOD your\n";
-	gchar *buf;
-	gchar *ibuf;
-	GHashTable *hashes;
-	char bad[82] = "";
-	char good[256] = "";
-	int pnt = 0;
-	gsize size;
-	gboolean complete = TRUE;
-	gboolean case_sensitive = FALSE;
-
-	buf = g_build_filename(gaim_user_dir(), "dict", NULL);
-	g_file_get_contents(buf, &ibuf, &size, NULL);
-	g_free(buf);
-	if (!ibuf) {
-		ibuf = g_strdup(defaultconf);
-		size = strlen(defaultconf);
-	}
-
-	model = gtk_list_store_new((gint)N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
-	hashes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
-
-	while (buf_get_line(ibuf, &buf, &pnt, size)) {
-		if (*buf != '#') {
-			if (!strncasecmp(buf, "BAD ", 4))
-			{
-				strncpy(bad, buf + 4, 81);
-			}
-			else if(!strncasecmp(buf, "CASE ", 5))
-			{
-				case_sensitive = *(buf+5) == '0' ? FALSE : TRUE;
-			}
-			else if(!strncasecmp(buf, "COMPLETE ", 9))
-			{
-				complete = *(buf+9) == '0' ? FALSE : TRUE;
-			}
-			else if (!strncasecmp(buf, "GOOD ", 5))
-			{
-				strncpy(good, buf + 5, 255);
-
-				if (*bad && *good && g_hash_table_lookup(hashes, bad) == NULL) {
-					GtkTreeIter iter;
-
-					/* We don't actually need to store the good string, since this
-					 * hash is just being used to eliminate duplicate bad strings.
-					 * The value has to be non-NULL so the lookup above will work.
-					 */
-					g_hash_table_insert(hashes, g_strdup(bad), GINT_TO_POINTER(1));
-
-					if (!complete)
-						case_sensitive = TRUE;
-
-					gtk_list_store_append(model, &iter);
-					gtk_list_store_set(model, &iter,
-						BAD_COLUMN, bad,
-						GOOD_COLUMN, good,
-						WORD_ONLY_COLUMN, complete,
-						CASE_SENSITIVE_COLUMN, case_sensitive,
-						-1);
-				}
-				bad[0] = '\0';
-				complete = TRUE;
-				case_sensitive = FALSE;
-			}
-		}
-	}
-	g_free(ibuf);
-	g_hash_table_destroy(hashes);
-
-	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),
-	                                     0, GTK_SORT_ASCENDING);
-}
-
-static GtkWidget *tree;
-static GtkWidget *bad_entry;
-static GtkWidget *good_entry;
-static GtkWidget *complete_toggle;
-static GtkWidget *case_toggle;
-
-static void save_list(void);
-
-static void on_edited(GtkCellRendererText *cellrenderertext,
-					  gchar *path, gchar *arg2, gpointer data)
-{
-	GtkTreeIter iter;
-	GValue val;
-
-	if (arg2[0] == '\0') {
-		gdk_beep();
-		return;
-	}
-
-	g_return_if_fail(gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(model), &iter, path));
-	val.g_type = 0;
-	gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, GPOINTER_TO_INT(data), &val);
-
-	if (strcmp(arg2, g_value_get_string(&val))) {
-		gtk_list_store_set(model, &iter, GPOINTER_TO_INT(data), arg2, -1);
-		save_list();
-	}
-	g_value_unset(&val);
-}
-
-
-static void word_only_toggled(GtkCellRendererToggle *cellrenderertoggle,
-						gchar *path, gpointer data){
-	GtkTreeIter iter;
-	gboolean enabled;
-
-	g_return_if_fail(gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(model), &iter, path));
-	gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
-					   WORD_ONLY_COLUMN, &enabled,
-					   -1);
-
-	gtk_list_store_set(GTK_LIST_STORE(model), &iter,
-					   WORD_ONLY_COLUMN, !enabled,
-					   -1);
-
-	/* I want to be sure that the above change has happened to the GtkTreeView first. */
-	gtk_list_store_set(GTK_LIST_STORE(model), &iter,
-					   CASE_SENSITIVE_COLUMN, enabled,
-					   -1);
-
-	save_list();
-}
-
-static void case_sensitive_toggled(GtkCellRendererToggle *cellrenderertoggle,
-						gchar *path, gpointer data){
-	GtkTreeIter iter;
-	gboolean enabled;
-
-	g_return_if_fail(gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(model), &iter, path));
-
-	/* Prevent the case sensitive column from changing on non-whole word replacements.
-	 * Ideally, the column would be set insensitive in the word_only_toggled callback. */
-	gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
-					   WORD_ONLY_COLUMN, &enabled,
-					   -1);
-	if (!enabled)
-		return;
-
-	gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
-					   CASE_SENSITIVE_COLUMN, &enabled,
-					   -1);
-
-	gtk_list_store_set(GTK_LIST_STORE(model), &iter,
-					   CASE_SENSITIVE_COLUMN, !enabled,
-					   -1);
-
-	save_list();
-}
-
-static void list_add_new()
-{
-	GtkTreeIter iter;
-	const char *word = gtk_entry_get_text(GTK_ENTRY(bad_entry));
-	gboolean case_sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(case_toggle));
-
-	if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) {
-		char *tmpword = g_utf8_casefold(word, -1);
-
-		do {
-			GValue bad_val;
-			gboolean match;
-
-			bad_val.g_type = 0;
-			gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, BAD_COLUMN, &bad_val);
-
-			if (case_sensitive)
-			{
-				GValue case_sensitive_val;
-				case_sensitive_val.g_type = 0;
-				gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, CASE_SENSITIVE_COLUMN, &case_sensitive_val);
-
-				/* If they're both case-sensitive, then compare directly.
-				 * Otherwise, they overlap. */
-				if (g_value_get_boolean(&case_sensitive_val))
-				{
-					match = !strcmp(g_value_get_string(&bad_val), word);
-				}
-				else
-				{
-					char *bad = g_utf8_casefold(g_value_get_string(&bad_val), -1);
-					match = !strcmp(bad, tmpword);
-					g_free(bad);
-				}
-				g_value_unset(&case_sensitive_val);
-			}
-			else
-			{
-				char *bad = g_utf8_casefold(g_value_get_string(&bad_val), -1);
-				match = !strcmp(bad, tmpword);
-				g_free(bad);
-			}
-
-			if (match) {
-				g_value_unset(&bad_val);
-				g_free(tmpword);
-
-				gaim_notify_error(NULL, _("Duplicate Correction"),
-					_("The specified word already exists in the correction list."),
-					gtk_entry_get_text(GTK_ENTRY(bad_entry)));
-				return;
-			}
-
-			g_value_unset(&bad_val);
-
-		} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter));
-
-		g_free(tmpword);
-	}
-
-
-	gtk_list_store_append(model, &iter);
-	gtk_list_store_set(model, &iter,
-		BAD_COLUMN, word,
-		GOOD_COLUMN, gtk_entry_get_text(GTK_ENTRY(good_entry)),
-		WORD_ONLY_COLUMN, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(complete_toggle)),
-		CASE_SENSITIVE_COLUMN, case_sensitive,
-		-1);
-
-	gtk_editable_delete_text(GTK_EDITABLE(bad_entry), 0, -1);
-	gtk_editable_delete_text(GTK_EDITABLE(good_entry), 0, -1);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(complete_toggle), TRUE);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(case_toggle), FALSE);
-	gtk_widget_grab_focus(bad_entry);
-
-	save_list();
-}
-
-static void add_selected_row_to_list(GtkTreeModel *model, GtkTreePath *path,
-	GtkTreeIter *iter, gpointer data)
-{
-	GtkTreeRowReference *row_reference;
-	GSList **list = (GSList **)data;
-	row_reference = gtk_tree_row_reference_new(model, path);
-	*list = g_slist_prepend(*list, row_reference);
-}
-
-static void remove_row(void *data1, gpointer data2)
-{
-	GtkTreeRowReference *row_reference;
-	GtkTreePath *path;
-	GtkTreeIter iter;
-
-	row_reference = (GtkTreeRowReference *)data1;
-	path = gtk_tree_row_reference_get_path(row_reference);
-
-	if (gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path))
-		gtk_list_store_remove(model, &iter);
-
-	gtk_tree_path_free(path);
-	gtk_tree_row_reference_free(row_reference);
-}
-
-static void list_delete()
-{
-	GtkTreeSelection *sel;
-	GSList *list = NULL;
-
-	sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
-	gtk_tree_selection_selected_foreach(sel, add_selected_row_to_list, &list);
-
-	g_slist_foreach(list, remove_row, NULL);
-	g_slist_free(list);
-
-	save_list();
-}
-
-static void save_list()
-{
-	GString *data;
-	GtkTreeIter iter;
-
-	data = g_string_new("");
-
-	if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) {
-		do {
-			GValue val0;
-			GValue val1;
-			GValue val2;
-			GValue val3;
-
-			val0.g_type = 0;
-			val1.g_type = 0;
-			val2.g_type = 0;
-			val3.g_type = 0;
-
-			gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, BAD_COLUMN, &val0);
-			gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, GOOD_COLUMN, &val1);
-			gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, WORD_ONLY_COLUMN, &val2);
-			gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, CASE_SENSITIVE_COLUMN, &val3);
-
-			g_string_append_printf(data, "COMPLETE %d\nCASE %d\nBAD %s\nGOOD %s\n\n",
-								   g_value_get_boolean(&val2),
-								   g_value_get_boolean(&val3),
-								   g_value_get_string(&val0),
-								   g_value_get_string(&val1));
-
-			g_value_unset(&val0);
-			g_value_unset(&val1);
-			g_value_unset(&val2);
-			g_value_unset(&val3);
-
-		} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter));
-	}
-
-	gaim_util_write_data_to_file("dict", data->str, -1);
-
-	g_string_free(data, TRUE);
-}
-
-static void
-check_if_something_is_selected(GtkTreeModel *model,
-	GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
-	*((gboolean*)data) = TRUE;
-}
-
-static void on_selection_changed(GtkTreeSelection *sel,
-	gpointer data)
-{
-	gboolean is = FALSE;
-	gtk_tree_selection_selected_foreach(sel, check_if_something_is_selected, &is);
-	gtk_widget_set_sensitive((GtkWidget*)data, is);
-}
-
-static gboolean non_empty(const char *s)
-{
-	while (*s && g_ascii_isspace(*s))
-		s++;
-	return *s;
-}
-
-static void on_entry_changed(GtkEditable *editable, gpointer data)
-{
-	gtk_widget_set_sensitive((GtkWidget*)data,
-		non_empty(gtk_entry_get_text(GTK_ENTRY(bad_entry))) &&
-		non_empty(gtk_entry_get_text(GTK_ENTRY(good_entry))));
-}
-
-/*
- *  EXPORTED FUNCTIONS
- */
-
-static gboolean
-plugin_load(GaimPlugin *plugin)
-{
-	void *conv_handle = gaim_conversations_get_handle();
-	GList *convs;
-
-	load_conf();
-
-	/* Attach to existing conversations */
-	for (convs = gaim_get_conversations(); convs != NULL; convs = convs->next)
-	{
-		spellchk_new_attach((GaimConversation *)convs->data);
-	}
-
-	gaim_signal_connect(conv_handle, "conversation-created",
-			    plugin, GAIM_CALLBACK(spellchk_new_attach), NULL);
-
-	return TRUE;
-}
-
-static gboolean
-plugin_unload(GaimPlugin *plugin)
-{
-	GList *convs;
-
-	/* Detach from existing conversations */
-	for (convs = gaim_get_conversations(); convs != NULL; convs = convs->next)
-	{
-		GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION((GaimConversation *)convs->data);
-		spellchk *spell = g_object_get_data(G_OBJECT(gtkconv->entry), SPELLCHK_OBJECT_KEY);
-
-		g_signal_handlers_disconnect_by_func(gtkconv->entry, message_send_cb, spell);
-		g_object_set_data(G_OBJECT(gtkconv->entry), SPELLCHK_OBJECT_KEY, NULL);
-	}
-
-	return TRUE;
-}
-
-static void whole_words_button_toggled(GtkToggleButton *complete_toggle, GtkToggleButton *case_toggle)
-{
-	gboolean enabled = gtk_toggle_button_get_active(complete_toggle);
-
-	gtk_toggle_button_set_active(case_toggle, !enabled);
-	gtk_widget_set_sensitive(GTK_WIDGET(case_toggle), enabled);
-}
-
-static GtkWidget *
-get_config_frame(GaimPlugin *plugin)
-{
-	GtkWidget *ret, *vbox, *win;
-	GtkWidget *hbox, *label;
-	GtkWidget *button;
-	GtkSizeGroup *sg;
-	GtkSizeGroup *sg2;
-	GtkCellRenderer *renderer;
-	GtkTreeViewColumn *column;
-	GtkWidget *vbox2;
-	GtkWidget *hbox2;
-	GtkWidget *vbox3;
-
-	ret = gtk_vbox_new(FALSE, GAIM_HIG_CAT_SPACE);
-	gtk_container_set_border_width (GTK_CONTAINER(ret), GAIM_HIG_BORDER);
-
-	vbox = gaim_gtk_make_frame(ret, _("Text Replacements"));
-	gtk_container_set_border_width(GTK_CONTAINER(vbox), 4);
-	gtk_widget_show(vbox);
-
-	win = gtk_scrolled_window_new(0, 0);
-	gtk_box_pack_start(GTK_BOX(vbox), win, TRUE, TRUE, 0);
-	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(win),
-										GTK_SHADOW_IN);
-	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(win),
-			GTK_POLICY_NEVER,
-			GTK_POLICY_ALWAYS);
-	gtk_widget_show(win);
-
-	tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
-	gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree), TRUE);
-	gtk_widget_set_size_request(tree, -1, 200);
-
-	renderer = gtk_cell_renderer_text_new();
-	g_object_set(G_OBJECT(renderer),
-		"editable", TRUE,
-		NULL);
-	g_signal_connect(G_OBJECT(renderer), "edited",
-		G_CALLBACK(on_edited), GINT_TO_POINTER(0));
-	column = gtk_tree_view_column_new_with_attributes(_("You type"), renderer,
-													  "text", BAD_COLUMN,
-													  NULL);
-	gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
-	gtk_tree_view_column_set_fixed_width(column, 150);
-	gtk_tree_view_column_set_resizable(column, TRUE);
-	gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
-
-	renderer = gtk_cell_renderer_text_new();
-	g_object_set(G_OBJECT(renderer),
-		"editable", TRUE,
-		NULL);
-	g_signal_connect(G_OBJECT(renderer), "edited",
-		G_CALLBACK(on_edited), GINT_TO_POINTER(1));
-	column = gtk_tree_view_column_new_with_attributes(_("You send"), renderer,
-													  "text", GOOD_COLUMN,
-													  NULL);
-	gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
-	gtk_tree_view_column_set_fixed_width(column, 150);
-	gtk_tree_view_column_set_resizable(column, TRUE);
-	gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
-
-	renderer = gtk_cell_renderer_toggle_new();
-	g_object_set(G_OBJECT(renderer),
-		"activatable", TRUE,
-		NULL);
-	g_signal_connect(G_OBJECT(renderer), "toggled",
-		G_CALLBACK(word_only_toggled), NULL);
-	column = gtk_tree_view_column_new_with_attributes(_("Whole words only"), renderer,
-													  "active", WORD_ONLY_COLUMN,
-													  NULL);
-	gtk_tree_view_column_set_resizable(column, TRUE);
-	gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
-
-	renderer = gtk_cell_renderer_toggle_new();
-	g_object_set(G_OBJECT(renderer),
-		"activatable", TRUE,
-		NULL);
-	g_signal_connect(G_OBJECT(renderer), "toggled",
-		G_CALLBACK(case_sensitive_toggled), NULL);
-	column = gtk_tree_view_column_new_with_attributes(_("Case sensitive"), renderer,
-													  "active", CASE_SENSITIVE_COLUMN,
-													  NULL);
-	gtk_tree_view_column_set_resizable(column, TRUE);
-	gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
-
-	gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)),
-		 GTK_SELECTION_MULTIPLE);
-	gtk_container_add(GTK_CONTAINER(win), tree);
-	gtk_widget_show(tree);
-
-	hbox = gtk_hbutton_box_new();
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-	gtk_widget_show(hbox);
-
-	button = gtk_button_new_from_stock(GTK_STOCK_DELETE);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			   G_CALLBACK(list_delete), NULL);
-	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
-	gtk_widget_set_sensitive(button, FALSE);
-
-	g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree))),
-		"changed", G_CALLBACK(on_selection_changed), button);
-
-	gtk_widget_show(button);
-
-	vbox = gaim_gtk_make_frame(ret, _("Add a new text replacement"));
-
-	hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
-	gtk_widget_show(hbox);
-	vbox2 = gtk_vbox_new(FALSE, GAIM_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0);
-	gtk_widget_show(vbox2);
-
-	sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
-	sg2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
-
-	hbox2 = gtk_hbox_new(FALSE, 2);
-	gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 0);
-	gtk_widget_show(hbox2);
-
-	label = gtk_label_new_with_mnemonic(_("You _type:"));
-	gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
-	gtk_size_group_add_widget(sg, label);
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
-
-	bad_entry = gtk_entry_new();
-	/* Set a minimum size. Since they're in a size group, the other entry will match up. */
-	gtk_widget_set_size_request(bad_entry, 350, -1);
-	gtk_box_pack_start(GTK_BOX(hbox2), bad_entry, TRUE, TRUE, 0);
-	gtk_size_group_add_widget(sg2, bad_entry);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), bad_entry);
-	gtk_widget_show(bad_entry);
-
-	hbox2 = gtk_hbox_new(FALSE, 2);
-	gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 0);
-	gtk_widget_show(hbox2);
-
-	label = gtk_label_new_with_mnemonic(_("You _send:"));
-	gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
-	gtk_size_group_add_widget(sg, label);
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
-
-	good_entry = gtk_entry_new();
-	gtk_box_pack_start(GTK_BOX(hbox2), good_entry, TRUE, TRUE, 0);
-	gtk_size_group_add_widget(sg2, good_entry);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), good_entry);
-	gtk_widget_show(good_entry);
-
-	/* Created here so it can be passed to whole_words_button_toggled. */
-	case_toggle = gtk_check_button_new_with_mnemonic(_("_Exact case match (uncheck for automatic case handling)"));
-
-	complete_toggle = gtk_check_button_new_with_mnemonic(_("Only replace _whole words"));
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(complete_toggle), TRUE);
-	g_signal_connect(G_OBJECT(complete_toggle), "clicked",
-                         G_CALLBACK(whole_words_button_toggled), case_toggle);
-	gtk_widget_show(complete_toggle);
-	gtk_box_pack_start(GTK_BOX(vbox2), complete_toggle, FALSE, FALSE, 0);
-
-	/* The button is created above so it can be passed to whole_words_button_toggled. */
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(case_toggle), FALSE);
-	gtk_widget_show(case_toggle);
-	gtk_box_pack_start(GTK_BOX(vbox2), case_toggle, FALSE, FALSE, 0);
-
-	button = gtk_button_new_from_stock(GTK_STOCK_ADD);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			   G_CALLBACK(list_add_new), NULL);
-	vbox3 = gtk_vbox_new(FALSE, 0);
-	gtk_box_pack_start(GTK_BOX(hbox), vbox3, TRUE, FALSE, 0);
-	gtk_widget_show(vbox3);
-	gtk_box_pack_end(GTK_BOX(vbox3), button, FALSE, FALSE, 0);
-	g_signal_connect(G_OBJECT(bad_entry), "changed", G_CALLBACK(on_entry_changed), button);
-	g_signal_connect(G_OBJECT(good_entry), "changed", G_CALLBACK(on_entry_changed), button);
-	gtk_widget_set_sensitive(button, FALSE);
-	gtk_widget_show(button);
-
-#if 0
-	vbox = gaim_gtk_make_frame(ret, _("General Text Replacement Options"));
-	gaim_gtk_prefs_checkbox(_("Enable replacement of last word on send"),
-	                        "/plugins/gtk/spellchk/last_word_replace", vbox);
-#endif
-
-	gtk_widget_show_all(ret);
-	return ret;
-}
-
-static GaimGtkPluginUiInfo ui_info =
-{
-	get_config_frame,
-	0 /* page_num (Reserved) */
-};
-
-static GaimPluginInfo info =
-{
-	GAIM_PLUGIN_MAGIC,
-	GAIM_MAJOR_VERSION,
-	GAIM_MINOR_VERSION,
-	GAIM_PLUGIN_STANDARD,
-	GAIM_GTK_PLUGIN_TYPE,
-	0,
-	NULL,
-	GAIM_PRIORITY_DEFAULT,
-	SPELLCHECK_PLUGIN_ID,
-	N_("Text replacement"),
-	VERSION,
-	N_("Replaces text in outgoing messages according to user-defined rules."),
-	N_("Replaces text in outgoing messages according to user-defined rules."),
-	"Eric Warmenhoven <eric@warmenhoven.org>",
-	GAIM_WEBSITE,
-	plugin_load,
-	plugin_unload,
-	NULL,
-	&ui_info,
-	NULL,
-	NULL,
-	NULL
-};
-
-static void
-init_plugin(GaimPlugin *plugin)
-{
-#if 0
-	gaim_prefs_add_none("/plugins");
-	gaim_prefs_add_none("/plugins/gtk");
-	gaim_prefs_add_none("/plugins/gtk/spellchk");
-	gaim_prefs_add_bool("/plugins/gtk/spellchk/last_word_replace", TRUE);
-#endif
-}
-
-GAIM_INIT_PLUGIN(spellcheck, init_plugin, info)

mercurial