diff --git a/ekg/commands.c b/ekg/commands.c
index 499c094..fb9d375 100644
--- a/ekg/commands.c
+++ b/ekg/commands.c
@@ -1044,7 +1044,7 @@ static COMMAND(cmd_help)
 					seeking_name = c->name;
 				}
 
-				while ((line = read_file_utf(f, 0))) {
+				while ((line = read_file(f, 0))) {
 					if (!xstrcasecmp(line, seeking_name)) {
 						found = 1;
 						break;
@@ -1057,7 +1057,7 @@ static COMMAND(cmd_help)
 					return -1;
 				}
 
-				line = read_file_utf(f, 0);
+				line = read_file(f, 0);
 
 				if ((tmp = xstrstr(line, (": "))))
 					params_help = xstrdup(tmp + 2);
@@ -1066,7 +1066,7 @@ static COMMAND(cmd_help)
 
 				params_help_s = strip_spaces(params_help);
 
-				line = read_file_utf(f, 0);
+				line = read_file(f, 0);
 
 				if ((tmp = xstrstr(line, (": "))))
 					brief = xstrdup(tmp + 2);
@@ -1093,7 +1093,7 @@ static COMMAND(cmd_help)
 				xfree(tmp);
 
 				s = string_init(NULL);
-				while ((line = read_file_utf(f, 0))) {
+				while ((line = read_file(f, 0))) {
 					if (line[0] != ('\t'))
 						break;
 					
@@ -1149,7 +1149,7 @@ static COMMAND(cmd_help)
 				seeking_name = c->name;
 			}
 
-			while ((line = read_file_utf(f, 0))) {
+			while ((line = read_file(f, 0))) {
 				if (!xstrcasecmp(line, seeking_name)) {
 					found = 1;
 					break;
@@ -1161,7 +1161,7 @@ static COMMAND(cmd_help)
 				continue;
 			}
 
-			line = read_file_utf(f, 0);
+			line = read_file(f, 0);
 		
 			if ((tmp = xstrstr(line, (": "))))
 			       params_help = xstrdup(tmp + 2);
@@ -1170,7 +1170,7 @@ static COMMAND(cmd_help)
 
 			params_help_s = strip_spaces(params_help);	
 
-			line = read_file_utf(f, 0);
+			line = read_file(f, 0);
 
 			if ((tmp = xstrstr(line, (": "))))
 			       brief = xstrdup(tmp + 2);
diff --git a/ekg/ekg.c b/ekg/ekg.c
index cf1da77..cb5fbac 100644
--- a/ekg/ekg.c
+++ b/ekg/ekg.c
@@ -684,6 +684,7 @@ int main(int argc, char **argv)
 #ifdef ENABLE_NLS
 	bindtextdomain("ekg2",LOCALEDIR);
 	textdomain("ekg2");
+	bind_textdomain_codeset("ekg2", "UTF-8");
 #endif
 	srand(time(NULL));
 
@@ -1174,7 +1175,6 @@ void ekg_exit()
 
 	/* free internal read_file() buffer */
 	read_file(NULL, -1);
-	read_file_utf(NULL, -1);
 
 /* windows: */
 	windows_destroy();
diff --git a/ekg/legacyconfig.c b/ekg/legacyconfig.c
index dae62da..96a2d8b 100644
--- a/ekg/legacyconfig.c
+++ b/ekg/legacyconfig.c
@@ -30,13 +30,6 @@
 void config_upgrade() {
 	const int current_config_version = 9;
 
-#if ! USE_UNICODE
-	if (!xstrcasecmp(config_console_charset, "UTF-8")) {
-		print("config_error", _("Warning, nl_langinfo(CODESET) reports that you are using utf-8 encoding, but you didn't compile ekg2 with (experimental/untested) --enable-unicode\n"
-			    "\tPlease compile ekg2 with --enable-unicode or change your enviroment setting to use not utf-8 but iso-8859-1 maybe? (LC_ALL/LC_CTYPE)\n"));
-	}
-#endif
-
 	if (xstrcasecmp(console_charset, config_console_charset)) 
 		print("console_charset_bad", console_charset, config_console_charset);
 	else if (config_version == 0 || config_version == -1)
diff --git a/ekg/recode.c b/ekg/recode.c
index 2facb89..be6673e 100644
--- a/ekg/recode.c
+++ b/ekg/recode.c
@@ -435,88 +435,10 @@ string_t ekg_convert_string_t_p(string_t s, void *ptr) {
 #endif
 }
 
-string_t ekg_convert_string_t(string_t s, const char *from, const char *to) {
-	string_t r;
-	void *p;
-
-	if (!s || !s->len) /* don't even init iconv if we've got NULL string */
-		return NULL;
-
-	p = ekg_convert_string_init(from, to, NULL);
-	r = ekg_convert_string_t_p(s, p);
-	ekg_convert_string_destroy(p);
-	return r;
-}
-
-struct ekg_recoder {
-	int count;
-	char *(*recode_from_locale)(struct ekg_recoder *, int, char *);
-	char *(*recode_to_locale)(struct ekg_recoder *, int, char *);
-	void *conv_in, *conv_out;
-	int is_utf;
-};
-
-static struct ekg_recoder cp_recoder;
-static struct ekg_recoder iso2_recoder;
-static struct ekg_recoder utf8_recoder;
-static struct ekg_recoder dummy_recoder;
-
-static void ekg_recode_init(struct ekg_recoder *rec);
-static void ekg_recode_deinit(struct ekg_recoder *rec);
-
-void changed_console_charset(const char *name) {
-	int all_ok = 1;
-
-	/* reinit, and display */
-#define REINIT_RECODER(strukt, name)	\
-	do {				\
-		int oldcount;		\
-		if ((oldcount = strukt.count)) {						\
-			/* int wasok = (strukt.recode_from_locale && strukt.recode_to_locale); */	\
-			ekg_recode_deinit(&strukt);						\
-			ekg_recode_init(&strukt);						\
-			strukt.count = oldcount;						\
-			if (!strukt.recode_from_locale || !strukt.recode_to_locale)		\
-				all_ok = 0;							\
-		}										\
-	} while (0);
-
-	REINIT_RECODER(iso2_recoder, "ISO-8859-2");
-	REINIT_RECODER(cp_recoder, "CP-1250");
-	REINIT_RECODER(utf8_recoder, "UTF-8");
-
-	if (!all_ok) {
-#ifdef HAVE_ICONV
-		// XXX, iconv_fail
-		print("generic_error", "ekg2 fail to (re)initialize charset conversion between some encodings. Check %Gconsole_charset%n variable, if it won't help inform ekg2 dev team and/or upgrade iconv");
-#else
-		print("generic_error", "ekg2 fail to (re)initialize charset conversion between some encodings. Check %Gconsole_charset%n variable, %rNOTE: console_charset other than: ISO-8859-2 and UTF-8 "
-			"require iconv, go and install some!");
-#endif
-	} else if (!in_autoexec && xstrcasecmp(console_charset, config_console_charset)) 
-		print("console_charset_bad", console_charset, config_console_charset);
-}
-
 int ekg_converters_display(int quiet) {
 #ifdef HAVE_ICONV
 	struct ekg_converter *c;
-#endif
-
-#define DISPLAY_RECODER(strukt, name)	\
-	do {				\
-		if (strukt.count)	\
-			printq( (strukt.recode_from_locale && strukt.recode_to_locale) ? 		\
-				"iconv_list" : "iconv_list_bad",					\
-				config_console_charset, name, itoa(strukt.count), itoa(strukt.count),"");\
-	} while(0);
-
-	DISPLAY_RECODER(iso2_recoder, "ISO-8859-2");
-	DISPLAY_RECODER(cp_recoder, "CP-1250");
-	DISPLAY_RECODER(utf8_recoder, "UTF-8");
 
-#undef DISPLAY_RECODER
-
-#ifdef HAVE_ICONV
 	for (c = ekg_converters; c; c = c->next) {
 		/* cd, rev, from, to, used, rev_used, is_utf */
 
@@ -531,7 +453,7 @@ int ekg_converters_display(int quiet) {
 #endif
 }
 
-static int ekg_utf8_helper(unsigned char *s, int n, unsigned short *ch) {
+static int ekg_utf8_helper(const unsigned char *s, int n, unsigned short *ch) {
 	unsigned char c = s[0];
 
 	if (c < 0x80) {
@@ -561,12 +483,12 @@ static int ekg_utf8_helper(unsigned char *s, int n, unsigned short *ch) {
 	}
 
 invalid:
-	*ch = '?';
+	*ch = RECANT;
 	return 1;
 }
 
-static char *ekg_from_utf8(char *b, const unsigned short *recode_table) {	/* sizeof(recode_table) = 0x100 ==> 0x80 items */
-	unsigned char *buf = (unsigned char *) b;
+static char *ekg_from_utf8(const char *b, const unsigned short *recode_table) {	/* sizeof(recode_table) = 0x100 ==> 0x80 items */
+	const unsigned char *buf = (const unsigned char *) b;
 
 	char *newbuf;
 	int newlen = 0;
@@ -596,6 +518,9 @@ static char *ekg_from_utf8(char *b, const unsigned short *recode_table) {	/* siz
 
 		newbuf[j] = '?';
 
+		if (znak == RECANT) 
+			continue;
+
 		for (k = 0; k < 0x80; k++) {
 			if (recode_table[k] == znak) {
 				newbuf[j] = (0x80 | k);
@@ -607,8 +532,8 @@ static char *ekg_from_utf8(char *b, const unsigned short *recode_table) {	/* siz
 	return newbuf;
 }
 
-static char *ekg_to_utf8(char *b, const unsigned short *recode_table) {		/* sizeof(recode_table) = 0x100 ==> 0x80 items */
-	unsigned char *buf = (unsigned char *) b;
+static char *ekg_to_utf8(const char *b, const unsigned short *recode_table) {		/* sizeof(recode_table) = 0x100 ==> 0x80 items */
+	const unsigned char *buf = (const unsigned char *) b;
 	char *newbuf;
 	int newlen = 0;
 	int i, j;
@@ -642,315 +567,122 @@ static char *ekg_to_utf8(char *b, const unsigned short *recode_table) {		/* size
 	return newbuf;
 }
 
-/*
- * iso_to_ascii()
- *
- * usuwa polskie litery z tekstu.
- *
- *  - c.
- */
-static char *iso_to_ascii(struct ekg_recoder *rec, int alloc_buf, char *b) {
-	unsigned char *buf;
-	
-	if (alloc_buf)
-		b = xstrdup(b);
-	buf = (unsigned char *) b;
-
-	while (*buf) {
-		if (*buf == (unsigned char)'�') *buf = 'a';
-		if (*buf == (unsigned char)'�') *buf = 'e';
-		if (*buf == (unsigned char)'�') *buf = 'c';
-		if (*buf == (unsigned char)'�') *buf = 'l';
-		if (*buf == (unsigned char)'�') *buf = 'n';
-		if (*buf == (unsigned char)'�') *buf = 'o';
-		if (*buf == (unsigned char)'�') *buf = 's';
-		if (*buf == (unsigned char)'�') *buf = 'z';
-		if (*buf == (unsigned char)'�') *buf = 'z';
-
-		if (*buf == (unsigned char)'�') *buf = 'A';
-		if (*buf == (unsigned char)'�') *buf = 'E';
-		if (*buf == (unsigned char)'�') *buf = 'C';
-		if (*buf == (unsigned char)'�') *buf = 'L';
-		if (*buf == (unsigned char)'�') *buf = 'N';
-		if (*buf == (unsigned char)'�') *buf = 'O';
-		if (*buf == (unsigned char)'�') *buf = 'S';
-		if (*buf == (unsigned char)'�') *buf = 'Z';
-		if (*buf == (unsigned char)'�') *buf = 'Z';
-
-		buf++;
-	}
-	return b;
-}
-
-static char *ekg_change_encoding(char *b, int alloc_buf, const unsigned char *recode_table) {	/* sizeof(recode_table) = 0x80 ==> 0x80 items */
-	unsigned char *buf;
-	
-	if (alloc_buf)
-		b = xstrdup(b);
-	buf = (unsigned char *) b;
 
-	while (*buf) {
-		if (*buf >= 0x80)
-			*buf = recode_table[*buf - 0x80];
+static const char *ekg_recode_from_utf8_const(const unsigned short *table, const char *buf) {
+	if (!buf)
+		return NULL;
 
-		buf++;
-	}
-	return b;
+	/* XXX, gdy wszystkie znaczki w buf s� < 0x80 to mo�na zwr�ci� 'buf' bez zmian. */
+	return ekg_from_utf8(buf, table);
 }
 
-static struct ekg_recoder *ekg_recode_get(enum ekg_recode_name enc) {
-	if (enc == EKG_RECODE_CP) 
-		return &cp_recoder;
-	if (enc == EKG_RECODE_ISO2)
-		return &iso2_recoder;
-	if (enc == EKG_RECODE_UTF8)
-		return &utf8_recoder;
-	return &dummy_recoder;
-}
+static char *ekg_recode_from_utf8_dup(const unsigned short *table, const char *buf) {
+	if (!buf)
+		return NULL;
 
-static char *recode_ret(struct ekg_recoder *rec, int alloc_buf, char *buf) { 			/* locale => locale */
-	return (alloc_buf) ? xstrdup(buf) : buf;
+	return ekg_from_utf8(buf, table);
 }
 
-static char *recode_ansi_helper_from(struct ekg_recoder *rec, int alloc_buf, char *buf) {	/* locale => encoding */
-	return ekg_change_encoding(buf, alloc_buf, rec->conv_out);
-}
+static char *ekg_recode_to_utf8_dup(const unsigned short *table, const char *buf) {
+	if (!buf)
+		return NULL;
 
-static char *recode_ansi_helper_to(struct ekg_recoder *rec, int alloc_buf, char *buf) {		/* encoding => locale */
-	return ekg_change_encoding(buf, alloc_buf, rec->conv_in);
+	return ekg_to_utf8(buf, table);
 }
 
-static char *recode_utf8_helper_from(struct ekg_recoder *rec, int alloc_buf, char *buf) {	/* locale /utf-8/ => encoding */
-	return ekg_from_utf8(buf, rec->conv_out);
-}
+const char *ekg_utf8_to_iso2_const(const char *buf) { return ekg_recode_from_utf8_const(table_iso_8859_2, buf); }
 
-static char *recode_utf8_helper_to(struct ekg_recoder *rec, int alloc_buf, char *buf) {		/* encoding => locale /utf-8/ */
-	return ekg_to_utf8(buf, rec->conv_in);
+char *ekg_iso2_to_utf8(char *buf) {
+	char *ret = ekg_recode_to_utf8_dup(table_iso_8859_2, buf);
+	xfree(buf);
+	return ret;
 }
 
-#ifdef HAVE_ICONV
-static inline char *mutt_convert_string2(char *buf, size_t len, iconv_t cd, int is_utf) {
-	char *repls[] = { "\357\277\275", "?", 0 };
+const char *ekg_utf8_to_cp_const(const char *buf) { return ekg_recode_from_utf8_const(table_cp1250, buf); }
+char *ekg_utf8_to_cp_dup(const char *buf) { return ekg_recode_from_utf8_dup(table_cp1250, buf); }
 
-	char *ib;
-	char *res, *ob;
-	size_t ibl, obl;
-	char **inrepls = 0;
-	char *outrepl = 0;
-
-	if ( is_utf == 2 ) /* to utf */
-		outrepl = repls[0]; /* this would be more evil */
-	else if ( is_utf == 1 ) /* from utf */
-		inrepls = repls;
-	else
-		outrepl = "?";
-
-	ib = buf;
-	ibl = len + 1;
-	obl = 16 * ibl;
-	ob = res = xmalloc (obl + 1);
-
-	mutt_iconv (cd, &ib, &ibl, &ob, &obl, inrepls, outrepl);
-	return res;
+char *ekg_utf8_to_cp(char *buf) {
+	char *ret = ekg_recode_from_utf8_dup(table_cp1250, buf);
+	xfree(buf);
+	return ret;
 }
 
-static char *recode_iconv_helper_from(struct ekg_recoder *rec, int alloc_buf, char *buf) {	/* locale => iconv */
-	iconv(rec->conv_out, NULL, NULL, NULL, NULL);	/* reset iconv */
-	return mutt_convert_string2(buf, strlen(buf), rec->conv_out, (rec->is_utf == 2 ? 1 : (rec->is_utf == 1 ? 2 : 0)));
-}
+char *ekg_cp_to_utf8_dup(const char *buf) { return ekg_recode_to_utf8_dup(table_cp1250, buf); }
 
-static char *recode_iconv_helper_to(struct ekg_recoder *rec, int alloc_buf, char *buf) {	/* iconv => locale */
-	iconv(rec->conv_in, NULL, NULL, NULL, NULL);	/* reset iconv */
-	return mutt_convert_string2(buf, strlen(buf), rec->conv_in, rec->is_utf);
-}
-#endif
-
-static void ekg_recode_init_iconv(struct ekg_recoder *rec, const char *encoding) {
-#ifdef HAVE_ICONV
-	rec->conv_in	= iconv_open(config_console_charset, encoding);
-	rec->conv_out	= iconv_open(encoding, config_console_charset);
-
-	if (rec->conv_in != (iconv_t) -1)
-		rec->recode_to_locale = recode_iconv_helper_to;
-	if (rec->conv_out != (iconv_t) -1)
-		rec->recode_from_locale = recode_iconv_helper_from;
-
-	if (!xstrcasecmp(encoding, "UTF-8"))
-		rec->is_utf = 2;
-	else if (!xstrcasecmp(config_console_charset, "UTF-8"))
-		rec->is_utf = 1;
-#endif
+char *ekg_cp_to_utf8(char *buf) {
+	char *ret = ekg_recode_to_utf8_dup(table_cp1250, buf);
+	xfree(buf);
+	return ret;
 }
 
-static void ekg_recode_init(struct ekg_recoder *rec) {
-	if (!config_console_charset) {
-		/* init not possible. */
-
-	} else if (rec == &cp_recoder) {
-		if (!xstrcasecmp("ISO-8859-2", config_console_charset)) {
-			rec->recode_from_locale = recode_ansi_helper_from;
-			rec->recode_to_locale	= recode_ansi_helper_to;
-			rec->conv_in		= (void *) cp_to_iso_table;
-			rec->conv_out 		= (void *) iso_to_cp_table;
-		} else if (!xstrcasecmp("UTF-8", config_console_charset)) {
-			rec->recode_from_locale = recode_utf8_helper_from;
-			rec->recode_to_locale   = recode_utf8_helper_to;
-			rec->conv_in 		= (void *) table_cp1250;
-			rec->conv_out 		= (void *) table_cp1250;
-		} else {
-			ekg_recode_init_iconv(rec, "WINDOWS-1250");
-		}
-
-	} else if (rec == &iso2_recoder) {
-		if (!xstrcasecmp("ISO-8859-2", config_console_charset)) {
-			rec->recode_from_locale = rec->recode_to_locale = recode_ret;
-		} else if (!xstrcasecmp("US-ASCII", config_console_charset)) {
-			rec->recode_from_locale	= recode_ret;
-			rec->recode_to_locale	= iso_to_ascii;	/* XXX, recode_ansi_helper_to */
-		} else if (!xstrcasecmp("UTF-8", config_console_charset)) {
-			rec->recode_from_locale = recode_utf8_helper_from;
-			rec->recode_to_locale	= recode_utf8_helper_to;
-			rec->conv_in 		= (void *) table_iso_8859_2;
-			rec->conv_out 		= (void *) table_iso_8859_2;
-		} else {
-			ekg_recode_init_iconv(rec, "ISO-8859-2");
-		}
-	} else if (rec == &utf8_recoder) {
-		if (!xstrcasecmp("ISO-8859-2", config_console_charset)) {
-			/* note: reversed latin2 <==> utf8 */
-			rec->recode_from_locale = recode_utf8_helper_to;
-			rec->recode_to_locale	= recode_utf8_helper_from;
-			rec->conv_in 		= (void *) table_iso_8859_2;
-			rec->conv_out 		= (void *) table_iso_8859_2;
-		} else if (!xstrcasecmp("UTF-8", config_console_charset)) {
-			rec->recode_from_locale = rec->recode_to_locale = recode_ret;
-		} else {
-			ekg_recode_init_iconv(rec, "UTF-8");
-		}
-	}
-
-	/* if (!rec->recode_from_locale || !rec->recode_to_locale)
-	 * 	warn user
-	 */
-}
 
-static void ekg_recode_deinit(struct ekg_recoder *rec) {
-#ifdef HAVE_ICONV
-	if (rec->recode_to_locale == recode_iconv_helper_to)
-		iconv_close(rec->conv_in);
-
-	if (rec->recode_from_locale == recode_iconv_helper_from)
-		iconv_close(rec->conv_out);
-#endif
-	memset(rec, 0, sizeof(struct ekg_recoder));
-}
-
-void ekg_recode_inc_ref(enum ekg_recode_name enc) {
-	struct ekg_recoder *rec = ekg_recode_get(enc);
-
-	if (rec->count == 0)
-		ekg_recode_init(rec);
-	rec->count++;
-}
-
-void ekg_recode_dec_ref(enum ekg_recode_name enc) {
-	struct ekg_recoder *rec = ekg_recode_get(enc);
-
-	rec->count--;
-	if (rec->count == 0)
-		ekg_recode_deinit(rec);
-}
+/* ucs2be_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) */
+string_t ekg_utf8_to_ucs2_dup(const char *b) {
+	unsigned char *buf = (unsigned char *) b;
+	string_t str;
+	int len, i;
 
-char *ekg_recode_from_locale(enum ekg_recode_name enc, char *buf) {
-	struct ekg_recoder *rec;
-	
 	if (!buf)
 		return NULL;
 
-	rec = ekg_recode_get(enc);
-	if (rec->recode_from_locale) {
-		char *res = rec->recode_from_locale(rec, 0, buf);
-		if (res != buf)
-			xfree(buf);
-		return res;
-	}
-	// warn user.
-	return buf;
-}
-
-char *ekg_recode_to_locale(enum ekg_recode_name enc, char *buf) {
-	struct ekg_recoder *rec;
+	str = string_init(NULL);
 
-	if (!buf)
-		return NULL;
+	len = strlen(b);
 
-	rec = ekg_recode_get(enc);
-	if (rec->recode_to_locale) {
-		char *res = rec->recode_to_locale(rec, 0, buf);
-		if (res != buf)
-			xfree(buf);
-		return res;
-	}
-	// warn user.
-	return buf;
-}
+	for (i = 0; i < len;) {
+		unsigned short wc;
+		unsigned char r[2];
 
-char *ekg_recode_from_locale_dup(enum ekg_recode_name enc, const char *buf) {
-	struct ekg_recoder *rec;
-	
-	if (!buf)
-		return NULL;
+		i += ekg_utf8_helper(&buf[i], len - i, &wc);
 
-	rec = ekg_recode_get(enc);
-	if (rec->recode_from_locale)
-		return rec->recode_from_locale(rec, 1, (char *) buf);
-	// warn user.
-	return xstrdup(buf);
+		if (/* wc < 0x10000 && */ !(wc >= 0xd800 && wc < 0xe000)) 
+			wc = RECANT;
+		
+		r[0] = (unsigned char) (wc >> 8);
+		r[1] = (unsigned char) wc;
+		string_append_raw(str, (const char *) r, sizeof(r));
+	}
+	return str;
 }
 
-char *ekg_recode_to_locale_dup(enum ekg_recode_name enc, const char *buf) {
-	struct ekg_recoder *rec;
+/* static int ucs2be_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) */
+// XXX, size_t n
+char *ekg_ucs2_to_utf8(char *b, int n) {
+	unsigned char *buf = (unsigned char *) b;
+	char *newbuf;
+	int newlen = 0;
+	int i, j;
 
-	if (!buf)
-		return NULL;
+	for (i = 0; i < n; i += 2) {
+		unsigned short znak = (buf[i] >= 0xd8 && buf[i] < 0xe0) ? RECANT : (buf[i] << 8) + buf[i+1];
 
-	rec = ekg_recode_get(enc);
-	if (rec->recode_to_locale)
-		return rec->recode_to_locale(rec, 1, (char *) buf);
-	// warn user.
-	return xstrdup(buf);
-}
+		if (znak < 0x80)	newlen += 1;
+		else if (znak < 0x800)	newlen += 2;
+		else			newlen += 3;
+	}
+	if (n & 1)
+		newlen++;
 
-const char *ekg_recode_from_locale_use(enum ekg_recode_name enc, const char *buf) {
-	struct ekg_recoder *rec;
+	newbuf = xmalloc(newlen+1);
 
-	if (!buf)
-		return NULL;
+	for (i = 0, j = 0; i < n; i += 2) {
+		unsigned short znak = (buf[i] >= 0xd8 && buf[i] < 0xe0) ? RECANT : (buf[i] << 8) + buf[i+1];
+		int count;
 
-	rec = ekg_recode_get(enc);
-	if (rec->recode_from_locale == recode_ret)
-		return buf;
+		if (znak < 0x80)	count = 1;
+		else if (znak < 0x800)	count = 2;
+		else			count = 3;
 
-	/* almost like ekg_recode_from_locale_dup(), but don't strdup() @ error */
-	if (rec->recode_from_locale)
-		return rec->recode_from_locale(rec, 1, (char *) buf);
-	// warn user.
-	return buf;
+		switch (count) {
+			case 3: newbuf[j+2] = 0x80 | (znak & 0x3f); znak = znak >> 6; znak |= 0x800;
+			case 2: newbuf[j+1] = 0x80 | (znak & 0x3f); znak = znak >> 6; znak |= 0xc0;
+			case 1: newbuf[j] = znak;
+		}
+		j += count;
+	}
+	if (n & 1)
+		newbuf[j++] = '?'; // XXX RECANT.
+	newbuf[j] = '\0';
+	return newbuf;
 }
 
-const char *ekg_recode_to_locale_use(enum ekg_recode_name enc, const char *buf) {
-	struct ekg_recoder *rec;
-
-	if (!buf)
-		return NULL;
-
-	rec = ekg_recode_get(enc);
-	if (rec->recode_to_locale == recode_ret)
-		return buf;
-
-	/* almost like ekg_recode_to_locale_dup(), but don't strdup() @ error */
-	if (rec->recode_to_locale)
-		return rec->recode_to_locale(rec, 1, (char *) buf);
-	// warn user.
-	return buf;
-}
diff --git a/ekg/recode.h b/ekg/recode.h
index 4174434..2ff1d36 100644
--- a/ekg/recode.h
+++ b/ekg/recode.h
@@ -7,65 +7,39 @@
 extern "C" {
 #endif
 
-enum ekg_recode_name {
-	EKG_RECODE_CP = 0,	/* CP-1250 */
-	EKG_RECODE_ISO2,	/* ISO-8859-2 */
-	EKG_RECODE_UTF8		/* UTF-8 */
-};
-
 void *ekg_convert_string_init(const char *from, const char *to, void **rev);
 void ekg_convert_string_destroy(void *ptr);
 char *ekg_convert_string_p(const char *ps, void *ptr);
 char *ekg_convert_string(const char *ps, const char *from, const char *to);
 string_t ekg_convert_string_t_p(string_t s, void *ptr);
-string_t ekg_convert_string_t(string_t s, const char *from, const char *to);
 
-void changed_console_charset(const char *name);
 int ekg_converters_display(int quiet);
 
-void ekg_recode_inc_ref(enum ekg_recode_name enc);
-void ekg_recode_dec_ref(enum ekg_recode_name enc);
-
-char *ekg_recode_from_locale(enum ekg_recode_name enc, char *buf);
-char *ekg_recode_to_locale(enum ekg_recode_name enc, char *buf);
+#define recode_xfree(org, ret) do { if (org != ret) xfree((char *) ret); } while(0); 
 
-char *ekg_recode_from_locale_dup(enum ekg_recode_name enc, const char *buf);
-char *ekg_recode_to_locale_dup(enum ekg_recode_name enc, const char *buf);
+#define ekg_iso2_to_locale ekg_iso2_to_utf8
+#define ekg_locale_to_iso2_use ekg_utf8_to_iso2_const
+#define ekg_locale_to_cp_use ekg_utf8_to_cp_const
 
-const char *ekg_recode_from_locale_use(enum ekg_recode_name enc, const char *buf);
-const char *ekg_recode_to_locale_use(enum ekg_recode_name enc, const char *buf);
+#define ekg_cp_to_locale ekg_cp_to_utf8
+#define ekg_cp_to_locale_dup ekg_cp_to_utf8_dup
+#define ekg_locale_to_cp_dup ekg_utf8_to_cp_dup
+#define ekg_locale_to_cp ekg_utf8_to_cp
 
-#define recode_xfree(org, ret) do { if (org != ret) xfree((char *) ret); } while(0); 
+#define ekg_ucs2_to_locale ekg_ucs2_to_utf8
+#define ekg_locale_to_ucs2_dup ekg_utf8_to_ucs2_dup
 
-/* CP-1250 */
-#define ekg_recode_cp_inc()	ekg_recode_inc_ref(EKG_RECODE_CP)
-#define ekg_recode_cp_dec() 	ekg_recode_dec_ref(EKG_RECODE_CP)
-#define ekg_locale_to_cp(buf)	ekg_recode_from_locale(EKG_RECODE_CP, buf)
-#define ekg_cp_to_locale(buf)	ekg_recode_to_locale(EKG_RECODE_CP, buf)
-#define ekg_locale_to_cp_dup(buf) ekg_recode_from_locale_dup(EKG_RECODE_CP, buf)
-#define ekg_cp_to_locale_dup(buf) ekg_recode_to_locale_dup(EKG_RECODE_CP, buf)
-#define ekg_locale_to_cp_use(buf) ekg_recode_from_locale_use(EKG_RECODE_CP, buf)
-#define ekg_cp_to_locale_use(buf) ekg_recode_to_locale_use(EKG_RECODE_CP, buf)
+const char *ekg_utf8_to_iso2_const(const char *buf);
+char *ekg_iso2_to_utf8(char *buf);
 
-/* ISO-8859-2 */
-#define ekg_recode_iso2_inc()	ekg_recode_inc_ref(EKG_RECODE_ISO2)
-#define ekg_recode_iso2_dec()	ekg_recode_dec_ref(EKG_RECODE_ISO2)
-#define ekg_locale_to_iso2(buf)	ekg_recode_from_locale(EKG_RECODE_ISO2, buf)
-#define ekg_iso2_to_locale(buf)	ekg_recode_to_locale(EKG_RECODE_ISO2, buf)
-#define ekg_locale_to_iso2_dup(buf) ekg_recode_from_locale_dup(EKG_RECODE_ISO2, buf)
-#define ekg_iso2_to_locale_dup(buf) ekg_recode_to_locale_dup(EKG_RECODE_ISO2, buf)
-#define ekg_locale_to_iso2_use(buf) ekg_recode_from_locale_use(EKG_RECODE_ISO2, buf)
-#define ekg_iso2_to_locale_use(buf) ekg_recode_to_locale_use(EKG_RECODE_ISO2, buf)
+char *ekg_cp_to_utf8(char *buf);
+char *ekg_cp_to_utf8_dup(const char *buf);
+char *ekg_utf8_to_cp(char *buf);
+char *ekg_utf8_to_cp_dup(const char *buf);
+const char *ekg_utf8_to_cp_const(const char *buf);
 
-/* UTF-8 */
-#define ekg_recode_utf8_inc()	ekg_recode_inc_ref(EKG_RECODE_UTF8)
-#define ekg_recode_utf8_dec()	ekg_recode_dec_ref(EKG_RECODE_UTF8)
-#define ekg_locale_to_utf8(buf)	ekg_recode_from_locale(EKG_RECODE_UTF8, buf)
-#define ekg_utf8_to_locale(buf)	ekg_recode_to_locale(EKG_RECODE_UTF8, buf)
-#define ekg_locale_to_utf8_dup(buf) ekg_recode_from_locale_dup(EKG_RECODE_UTF8, buf)
-#define ekg_utf8_to_locale_dup(buf) ekg_recode_to_locale_dup(EKG_RECODE_UTF8, buf)
-#define ekg_locale_to_utf8_use(buf) ekg_recode_from_locale_use(EKG_RECODE_UTF8, buf)
-#define ekg_utf8_to_locale_use(buf) ekg_recode_to_locale_use(EKG_RECODE_UTF8, buf)
+string_t ekg_utf8_to_ucs2_dup(const char *b);
+char *ekg_ucs2_to_utf8(char *buf, int n);
 
 #ifdef __cplusplus
 }
diff --git a/ekg/recode_tables.h b/ekg/recode_tables.h
index 9e6845c..1eca775 100644
--- a/ekg/recode_tables.h
+++ b/ekg/recode_tables.h
@@ -1,8 +1,12 @@
+/* REPLACEMENT CHARACTER http://www.fileformat.info/info/unicode/char/fffd/index.htm */
+#define RECANT 0xfffd   /* "\357\277\275 */ 
+// #define RECANT '?'
+
 static const unsigned short table_cp1250[] = {
-	0x20ac, '?', 0x201a, '?', 0x201e, 0x2026, 0x2020, 0x2021, 		/* 0x80 -      */
-	'?', 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179,		/*      - 0x8F */
-	'?', 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,		/* 0x90 -      */ 
-	'?', 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a,		/*      - 0x9F */
+	0x20ac, RECANT, 0x201a, RECANT, 0x201e, 0x2026, 0x2020, 0x2021, 	/* 0x80 -      */
+	RECANT, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179,		/*      - 0x8F */
+	RECANT, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,		/* 0x90 -      */ 
+	RECANT, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a,		/*      - 0x9F */
 	0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7,		/* 0xA0 -      */
 	0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, 	/*      - 0xAF */
 	0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7,		/* 0xB0 -      */
@@ -18,10 +22,10 @@ static const unsigned short table_cp1250[] = {
 };
 
 static const unsigned short table_iso_8859_2[] = {
-	'?', '?', '?', '?', '?', '?', '?', '?',					/* 0x80 -      */
-	'?', '?', '?', '?', '?', '?', '?', '?',					/*      - 0x8F */
-	'?', '?', '?', '?', '?', '?', '?', '?',					/* 0x90 -      */
-	'?', '?', '?', '?', '?', '?', '?', '?',					/*      - 0x9F */
+	RECANT, RECANT, RECANT, RECANT, RECANT, RECANT, RECANT, RECANT,		/* 0x80 -      */
+	RECANT, RECANT, RECANT, RECANT, RECANT, RECANT, RECANT, RECANT,		/*      - 0x8F */
+	RECANT, RECANT, RECANT, RECANT, RECANT, RECANT, RECANT, RECANT,		/* 0x90 -      */
+	RECANT, RECANT, RECANT, RECANT, RECANT, RECANT, RECANT, RECANT,		/*      - 0x9F */
 	0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7,		/* 0xA0 -      */
 	0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b,		/*      - 0xAF */
 	0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7,		/* 0xB0 -      */
@@ -36,41 +40,3 @@ static const unsigned short table_iso_8859_2[] = {
 	0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9		/*      - 0xFF */
 };
 
-static const unsigned char iso_to_cp_table[] = {
-	'?', '?', '?', '?', '?', '?', '?', '?',					/* 0x80 -      */
-	'?', '?', '?', '?', '?', '?', '?', '?',					/*      - 0x8F */
-	'?', '?', '?', '?', '?', '?', '?', '?',					/* 0x90 -      */
-	'?', '?', '?', '?', '?', '?', '?', '?',					/*      - 0x9F */
-	0xa0, 0xa5, 0xa2, 0xa3, 0xa4, 0xbc, 0x8c, 0xa7,				/* 0xA0 -      */
-	0xa8, 0x8a, 0xaa, 0x8d, 0x8f, 0xad, 0x8e, 0xaf,				/*      - 0xAF */
-	0xb0, 0xb9, 0xb2, 0xb3, 0xb4, 0xbe, 0x9c, 0xa1,				/* 0xB0 -      */
-	0xb8, 0x9a, 0xba, 0x9d, 0x9f, 0xbd, 0x9e, 0xbf,				/*      - 0xBF */
-	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,				/* 0xC0 -      */
-	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,				/*      - 0xCF */
-	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,				/* 0xD0 -      */
-	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,				/*      - 0xDF */
-	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,				/* 0xE0 -      */
-	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,				/*      - 0xEF */
-	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,				/* 0xF0 -      */
-	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff				/*      - 0xFF */
-};
-
-static const unsigned char cp_to_iso_table[] = {
-	 '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',				/* 0x80 -      */
-	 '?',  '?', 0xa9,  '?', 0xa6, 0xab, 0xae, 0xac,				/*      - 0x8F */
-	 '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',				/* 0x90 -      */
-	 '?',  '?', 0xb9,  '?', 0xb6, 0xbb, 0xbe, 0xbc,				/*      - 0x9F */
-	0xa0, 0xb7, 0xa2, 0xa3, 0xa4, 0xa1,  '?', 0xa7,				/* 0xA0 -      */
-	0xa8,  '?', 0xaa,  '?',  '?', 0xad,  '?', 0xaf,				/*      - 0xAF */
-	0xb0,  '?', 0xb2, 0xb3, 0xb4,  '?',  '?',  '?',				/* 0xB0 -      */
-	0xb8, 0xb1, 0xba,  '?', 0xa5, 0xbd, 0xb5, 0xbf,				/*      - 0xBF */
-	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,				/* 0xC0 -      */
-	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,				/*      - 0xCF */
-	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,				/* 0xD0 -      */
-	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,				/*      - 0xDF */
-	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,				/* 0xE0 -      */
-	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,				/*      - 0xEF */
-	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,				/* 0xF0 -      */
-	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff				/*      - 0xFF */
-};
-
diff --git a/ekg/sessions.c b/ekg/sessions.c
index 90ec0c7..9e4d661 100644
--- a/ekg/sessions.c
+++ b/ekg/sessions.c
@@ -1613,7 +1613,7 @@ void session_help(session_t *s, const char *name)
 			break;
 		}
 
-		while ((line = read_file_utf(f, 0))) {
+		while ((line = read_file(f, 0))) {
 			if (!xstrcasecmp(line, name)) {
 				found = 1;
 				break;
@@ -1630,7 +1630,7 @@ void session_help(session_t *s, const char *name)
 			if (!(f = help_path("session", NULL)))
 				break;
 
-			while ((line = read_file_utf(f, 0))) {
+			while ((line = read_file(f, 0))) {
 				if (!xstrcasecmp(line, name)) {
 					found = 1;
 					break;
@@ -1650,14 +1650,14 @@ void session_help(session_t *s, const char *name)
 		return;
 	}
 
-	line = read_file_utf(f, 0);
+	line = read_file(f, 0);
 
 	if ((tmp = xstrstr(line, (": "))))
 		type = xstrdup(tmp + 2);
 	else
 		type = xstrdup(("?"));
 
-	line = read_file_utf(f, 0);
+	line = read_file(f, 0);
 	if ((tmp = xstrstr(line, (": "))))
 		def = xstrdup(tmp + 2);
 	else
@@ -1669,10 +1669,10 @@ void session_help(session_t *s, const char *name)
 	xfree(def);
 
 	if (tmp)		/* je�li nie jest to ukryta zmienna... */
-		read_file_utf(f, 0);	/* ... pomijamy lini� */
+		read_file(f, 0);	/* ... pomijamy lini� */
 
 	str = string_init(NULL);
-	while ((line = read_file_utf(f, 0))) {
+	while ((line = read_file(f, 0))) {
 		if (line[0] != '\t')
 			break;
 
diff --git a/ekg/stuff.c b/ekg/stuff.c
index 2242748..473fb0f 100644
--- a/ekg/stuff.c
+++ b/ekg/stuff.c
@@ -83,7 +83,6 @@
 #include "xmalloc.h"
 #include "plugins.h"
 #include "sessions.h"
-#include "recode.h"
 
 #include "dynstuff_inline.h"
 #include "queries.h"
@@ -1664,25 +1663,6 @@ char *read_file(FILE *f, int alloc) {
 	return (alloc) ? xstrdup(res) : res;
 }
 
-char *read_file_utf(FILE *f, int alloc) {
-	static char *tmp = NULL;
-	char *buf = read_file(f, 0);
-	char *res;
-
-	xfree(tmp);
-	tmp = NULL;
-	if (alloc == -1)
-		return NULL;
-
-	ekg_recode_utf8_inc();
-	res = ekg_utf8_to_locale_dup(buf);
-	if (!alloc)
-		tmp = res;
-
-	ekg_recode_utf8_dec();
-	return res;
-}
-
 /**
  * timestamp()
  *
diff --git a/ekg/stuff.h b/ekg/stuff.h
index d6f0b73..2290dd7 100644
--- a/ekg/stuff.h
+++ b/ekg/stuff.h
@@ -312,7 +312,6 @@ const char *prepare_path(const char *filename, int do_mkdir);
 const char *prepare_pathf(const char *filename, ...);
 const char *prepare_path_user(const char *path);
 char *read_file(FILE *f, int alloc);
-char *read_file_utf(FILE *f, int alloc);
 
 const char *timestamp(const char *format);
 const char *timestamp_time(const char *format, time_t t);
@@ -365,7 +364,6 @@ void ekg_convert_string_destroy(void *ptr);
 char *ekg_convert_string_p(const char *ps, void *ptr);
 char *ekg_convert_string(const char *ps, const char *from, const char *to);
 string_t ekg_convert_string_t_p(string_t s, void *ptr);
-string_t ekg_convert_string_t(string_t s, const char *from, const char *to);
 int ekg_converters_display(int quiet);
 
 char *password_input(const char *prompt, const char *rprompt, const bool norepeat);
diff --git a/ekg/themes.c b/ekg/themes.c
index 5e1c063..f1452e7 100644
--- a/ekg/themes.c
+++ b/ekg/themes.c
@@ -32,7 +32,6 @@
 
 #include "dynstuff.h"
 #include "stuff.h"
-#include "recode.h"
 #include "themes.h"
 #include "xmalloc.h"
 #include "windows.h"
diff --git a/ekg/vars.c b/ekg/vars.c
index 41a26fc..5321434 100644
--- a/ekg/vars.c
+++ b/ekg/vars.c
@@ -65,6 +65,11 @@ static int dd_sound(const char *name) { return (config_sound_app != NULL); }
 static int dd_color(const char *name) { return (config_display_color); }
 static int dd_beep(const char *name) { return (config_beep); }
 
+static void changed_console_charset(const char *name) {
+	if (!in_autoexec && xstrcasecmp(console_charset, config_console_charset)) 
+		print("console_charset_bad", console_charset, config_console_charset);
+}
+
 /*
  * variable_init()
  *
@@ -581,7 +586,7 @@ void variable_help(const char *name) {
 		seeking_name = name;
 	}
 
-	while ((line = read_file_utf(f, 0))) {
+	while ((line = read_file(f, 0))) {
 		if (!xstrcasecmp(line, seeking_name)) {
 			found = 1;
 			break;
@@ -594,14 +599,14 @@ void variable_help(const char *name) {
 		return;
 	}
 
-	line = read_file_utf(f, 0);
+	line = read_file(f, 0);
 	
 	if ((tmp = xstrstr(line, (": "))))
 		type = xstrdup(tmp + 2);
 	else
 		type = xstrdup(("?"));
 	
-	line = read_file_utf(f, 0);
+	line = read_file(f, 0);
 	if ((tmp = xstrstr(line, (": "))))
 		def = xstrdup(tmp + 2);
 	else
@@ -613,9 +618,9 @@ void variable_help(const char *name) {
 	xfree(def);
 
 	if (tmp)		/* je�li nie jest to ukryta zmienna... */
-		read_file_utf(f, 0);	/* ... pomijamy lini� */
+		read_file(f, 0);	/* ... pomijamy lini� */
 	s = string_init(NULL);
-	while ((line = read_file_utf(f, 0))) {
+	while ((line = read_file(f, 0))) {
 		if (line[0] != '\t')
 			break;
 
diff --git a/plugins/dbus/dbus_iface_im_ekg.c b/plugins/dbus/dbus_iface_im_ekg.c
index f601623..49e44d9 100644
--- a/plugins/dbus/dbus_iface_im_ekg.c
+++ b/plugins/dbus/dbus_iface_im_ekg.c
@@ -18,7 +18,7 @@ static EKG2_DBUS_IFACE_HANDLER(ekg2_dbus_iface_im_ekg2_getSessions)
 #define __FUNCTION__ "ekg2_dbus_iface_im_ekg2_getSessions"
 	EKG2_DBUS_CALL_HANDLER_VARIABLES;
 	session_t *sl;
-	char x[1] = "", *tmp_descr, *tmp;
+	char x[1] = "", *tmp;
 
 	EKG2_DBUS_INIT_REPLY;
 
@@ -37,9 +37,7 @@ static EKG2_DBUS_IFACE_HANDLER(ekg2_dbus_iface_im_ekg2_getSessions)
 		/* XXX convert to utf before sending, d-bus sux? XXX */
 		tmp = (char *)session_descr_get(s);
 		tmp = xstrdup(tmp?tmp:"");
-		tmp_descr = ekg_convert_string (tmp, NULL, "utf-8");
-		EKG2_DBUS_ADD_STRING(tmp_descr ? &tmp_descr : &tmp);
-		xfree(tmp_descr);
+		EKG2_DBUS_ADD_STRING(tmp);
 		xfree(tmp);
 	}
 	EKG2_DBUS_SEND_REPLY;
diff --git a/plugins/feed/rss.c b/plugins/feed/rss.c
index 95506ea..3393fa9 100644
--- a/plugins/feed/rss.c
+++ b/plugins/feed/rss.c
@@ -60,7 +60,7 @@
 #include "feed.h"
 
 #define rss_convert_string(text, encoding) \
-	ekg_convert_string(text, encoding ? encoding : "UTF-8", NULL)
+	(encoding ? ekg_convert_string(text, encoding, NULL) : NULL)
 
 typedef enum {
 	RSS_PROTO_UNKNOWN = 0,
diff --git a/plugins/gg/gg.c b/plugins/gg/gg.c
index faacaeb..00cc32e 100644
--- a/plugins/gg/gg.c
+++ b/plugins/gg/gg.c
@@ -1724,9 +1724,6 @@ int EXPORT gg_plugin_init(int prio) {
 
 	plugin_register(&gg_plugin, prio);
 
-	ekg_recode_utf8_inc();
-	ekg_recode_cp_inc();
-
 	gg_setvar_default(NULL, dummy);
 
 	query_connect_id(&gg_plugin, SET_VARS_DEFAULT, gg_setvar_default, NULL);
@@ -1800,9 +1797,6 @@ static int gg_plugin_destroy() {
 
 	image_flush_queue();
 
-	ekg_recode_utf8_dec();
-	ekg_recode_cp_dec();
-
 	plugin_unregister(&gg_plugin);
 
 	return 0;
diff --git a/plugins/gg/misc.c b/plugins/gg/misc.c
index d49b7ec..e3cfb75 100644
--- a/plugins/gg/misc.c
+++ b/plugins/gg/misc.c
@@ -258,30 +258,31 @@ int gg_userlist_send(struct gg_session *s, userlist_t *userlist) {
  *
  * starting from protocol version 0x2e, GG handles unicode
  *
+ * XXX fix, it depends on p.encoding not protocol version!!
  */
 char *gg_to_locale(session_t *s, char *txt) {
 	gg_private_t *g = session_private_get(s);
-	return (g->curr_prtcl_ver >= 0x2e) ? ekg_utf8_to_locale(txt) : ekg_cp_to_locale(txt);
+	return (g->curr_prtcl_ver >= 0x2e) ? txt : ekg_cp_to_locale(txt);
 }
 
 char *gg_to_locale_dup(session_t *s, const char *txt) {
 	gg_private_t *g = session_private_get(s);
-	return (g->curr_prtcl_ver >= 0x2e) ? ekg_utf8_to_locale_dup(txt) : ekg_cp_to_locale_dup(txt);
+	return (g->curr_prtcl_ver >= 0x2e) ? xstrdup(txt) : ekg_cp_to_locale_dup(txt);
 }
 
 char *locale_to_gg(session_t *s, char *txt) {
 	gg_private_t *g = session_private_get(s);
-	return (g->curr_prtcl_ver >= 0x2e) ? ekg_locale_to_utf8(txt) : ekg_locale_to_cp(txt);
+	return (g->curr_prtcl_ver >= 0x2e) ? txt : ekg_locale_to_cp(txt);
 }
 
 char *locale_to_gg_dup(session_t *s, const char *txt) {
 	gg_private_t *g = session_private_get(s);
-	return (g->curr_prtcl_ver >= 0x2e) ? ekg_locale_to_utf8_dup(txt) : ekg_locale_to_cp_dup(txt);
+	return (g->curr_prtcl_ver >= 0x2e) ? xstrdup(txt) : ekg_locale_to_cp_dup(txt);
 }
 
 const char *locale_to_gg_use(session_t *s, const char *txt) {
 	gg_private_t *g = session_private_get(s);
-	return (g->curr_prtcl_ver >= 0x2e) ? ekg_locale_to_utf8_use(txt) : ekg_locale_to_cp_use(txt);
+	return (g->curr_prtcl_ver >= 0x2e) ? txt : ekg_locale_to_cp_use(txt);
 }
 
 /*
diff --git a/plugins/gtk/main.c b/plugins/gtk/main.c
index 85e94ad..6e82f97 100644
--- a/plugins/gtk/main.c
+++ b/plugins/gtk/main.c
@@ -364,14 +364,6 @@ EXPORT int gtk_plugin_init(int prio) {
 	if (!(gtk_init_check(0, NULL)))
 		return -1;
 
-#ifdef USE_UNICODE
-	if (!config_use_unicode)
-#endif
-	{
-		int la = in_autoexec;
-		bind_textdomain_codeset("ekg2", "UTF-8");
-		in_autoexec = 0;	changed_theme(("theme"));	in_autoexec = la; /* gettext + themes... */
-	}
 
 		/* ... */
 
diff --git a/plugins/icq/icq.c b/plugins/icq/icq.c
index de1fb09..310b552 100644
--- a/plugins/icq/icq.c
+++ b/plugins/icq/icq.c
@@ -113,7 +113,7 @@ int icq_write_status_msg(session_t *s) {
 	if (j->aim == 0)
 		return -1;
 
-	msg = ekg_locale_to_utf8(xstrndup(s->descr, 0x1000));
+	msg = xstrndup(s->descr, 0x1000);
 
 	/* XXX, cookie */
 
@@ -1138,9 +1138,7 @@ static void icq_send_msg_ch2(session_t *session, const char *uid, const char *me
 	t2711 = string_init(NULL);
 {
 		icq_pack_append_rendezvous(t2711, ICQ_VERSION, cookie, MTYPE_PLAIN, 0, 1, prio);
-		char *recode = ekg_locale_to_utf8_dup(message);
-		icq_pack_append_nullterm_msg(t2711, recode);
-		xfree(recode);
+		icq_pack_append_nullterm_msg(t2711, message);
 		icq_pack_append(t2711, "II", 0, 0xffffffff);	// XXX text & background colors
 		icq_pack_append(t2711, "i", xstrlen(CAP_UTF8_str));
 		string_append(t2711, CAP_UTF8_str);
@@ -1771,9 +1769,6 @@ EXPORT int icq_plugin_init(int prio) {
 
 	PLUGIN_CHECK_VER("icq");
 
-	icq_convert_string_init();
-	ekg_recode_utf8_inc();
-
 	icq_plugin.params	= icq_plugin_vars;
 	icq_plugin.priv		= &icq_priv;
 
@@ -1829,8 +1824,6 @@ EXPORT int icq_plugin_init(int prio) {
 }
 
 static int icq_plugin_destroy() {
-	icq_convert_string_destroy();
 	plugin_unregister(&icq_plugin);
-	ekg_recode_utf8_dec();
 	return 0;
 }
diff --git a/plugins/icq/icq_snac_handlers_03buddy.c b/plugins/icq/icq_snac_handlers_03buddy.c
index 2408711..d2f9209 100644
--- a/plugins/icq/icq_snac_handlers_03buddy.c
+++ b/plugins/icq/icq_snac_handlers_03buddy.c
@@ -347,7 +347,7 @@ static void icq_get_user_info(session_t *s, userlist_t *u, struct icq_tlv_list *
 							char *tmp;
 							uint16_t enc;
 							icq_unpack_nc(t_data, item_len, "Uw", &tmp, &enc);
-							descr = !enc ? ekg_utf8_to_locale_dup(tmp) : xstrdup(tmp);
+							descr = xstrdup(tmp);
 						}
 						desc_chg = 1;
 					} else if ((item_type == 0x0e) && (item_len>7)) {
diff --git a/plugins/icq/icq_snac_handlers_04message.c b/plugins/icq/icq_snac_handlers_04message.c
index 0f697a3..7d73530 100644
--- a/plugins/icq/icq_snac_handlers_04message.c
+++ b/plugins/icq/icq_snac_handlers_04message.c
@@ -234,9 +234,7 @@ static void icq_send_status_descr(session_t *s, int msg_type, msg_params_t *msg_
 	desc = xstrdup(s->descr);
 	icq_pack_append_msg_header(pkt, msg_param);
 	icq_pack_append_rendezvous(pkt, msg_param->version, msg_param->cookie, msg_type, MFLAG_AUTO, 0, 0);
-	if (msg_param->version == 9) /* unicode */
-		desc = ekg_locale_to_utf8(desc);
-	else {
+	if (msg_param->version != 9) { /* not unicode */
 		/* XXX recode? */
 	}
 	icq_pack_append_nullterm_msg(pkt, desc);
@@ -329,11 +327,8 @@ static int icq_snac_message_recv_rtf2711(session_t *s, unsigned char *buf, int l
 					len -= msg.len;
 					if (msg.len > 0) {
 						time_t sent = time(NULL);
-						char *tmp = ekg_utf8_to_locale_dup(msg.str);
 
-						protocol_message_emit(s, msg_param->uid, NULL, tmp, NULL, sent, EKG_MSGCLASS_CHAT, NULL, EKG_TRY_BEEP, 0);
-
-						xfree(tmp);
+						protocol_message_emit(s, msg_param->uid, NULL, msg.str, NULL, sent, EKG_MSGCLASS_CHAT, NULL, EKG_TRY_BEEP, 0);
 					}
 					icq_send_adv_msg_ack(s, msg_param);
 					break;
@@ -541,8 +536,6 @@ SNAC_SUBHANDLER(icq_snac_message_server_ack) {
 }
 
 static void icq_snac_message_status_reply(msg_params_t *msg_param, char *msg) {
-	char *descr;
-
 	if (!msg_param->u) {
 		debug_warn("icq_snac_message_status_reply() Ignoring status description from unknown %s msg: %s\n", msg_param->uid, msg);
 		return;
@@ -550,15 +543,8 @@ static void icq_snac_message_status_reply(msg_params_t *msg_param, char *msg) {
 
 	debug_function("icq_snac_message_status_reply() status from %s msg: %s\n", msg_param->uid, msg);
 
-	if (msg_param->version == 9) /* utf-8 message */
-		descr = ekg_utf8_to_locale_dup(msg);
-	else
-		descr = xstrdup(msg);
-
 	/* We change only description, not status */
-	protocol_status_emit(msg_param->s, msg_param->uid, msg_param->u->status, descr, time(NULL));
-
-	xfree(descr);
+	protocol_status_emit(msg_param->s, msg_param->uid, msg_param->u->status, msg, time(NULL));
 }
 
 SNAC_SUBHANDLER(icq_snac_message_response) {
diff --git a/plugins/icq/icq_snac_handlers_13userlist.c b/plugins/icq/icq_snac_handlers_13userlist.c
index 347903c..5bb279d 100644
--- a/plugins/icq/icq_snac_handlers_13userlist.c
+++ b/plugins/icq/icq_snac_handlers_13userlist.c
@@ -89,7 +89,7 @@ static void set_userinfo_from_tlv(userlist_t *u, const char *var, icq_tlv_t *t)
 	if (!u)
 		return;
 
-	tmp = (t && t->len) ? ekg_utf8_to_locale(xstrndup((char *) t->buf, t->len)) : NULL;
+	tmp = (t && t->len) ? xstrndup((char *) t->buf, t->len) : NULL;
 
 	user_private_item_set(u, var, tmp);
 }
@@ -101,12 +101,11 @@ static int icq_userlist_parse_entry(session_t *s, struct icq_tlv_list *tlvs, con
 			icq_tlv_t *t_nick = icq_tlv_get(tlvs, 0x131);
 			icq_tlv_t *t_auth = icq_tlv_get(tlvs, 0x66);
 
-			char *nick, *tmp;
+			char *nick;
 			char *uid = icq_uid(name);
 			userlist_t *u;
 
-			tmp = (t_nick && t_nick->len) ? xstrndup((char *) t_nick->buf, t_nick->len) : xstrdup(uid);
-			nick = ekg_utf8_to_locale(tmp);
+			nick = (t_nick && t_nick->len) ? xstrndup((char *) t_nick->buf, t_nick->len) : xstrdup(uid);
 
 			if (!(u = userlist_find(s, uid)) && !(u = userlist_add(s, uid, nick)) ) {
 				debug_error("icq_userlist_parse_entry() userlist_add(%s, %s) failed!\n", uid, nick);
@@ -317,14 +316,13 @@ SNAC_SUBHANDLER(icq_snac_userlist_roster) {
 	buf = pkt.data;
 
 	for (i = 0; i < pkt.count; i++) {
-		char *orgname;
 		uint16_t item_id, item_type;
 		uint16_t group_id;
 		uint16_t tlv_len;
 		struct icq_tlv_list *tlvs;
 		char *name;
 
-		if (!ICQ_UNPACK(&buf, "UWWWW", &orgname, &group_id, &item_id, &item_type, &tlv_len))
+		if (!ICQ_UNPACK(&buf, "UWWWW", &name, &group_id, &item_id, &item_type, &tlv_len))
 			return -1;
 
 		if (len < tlv_len) {
@@ -332,15 +330,12 @@ SNAC_SUBHANDLER(icq_snac_userlist_roster) {
 			return -1;
 		}
 
-		name = ekg_utf8_to_locale_dup(orgname);
 		debug_white("%sName:'%s'\tgroup:%u item:%u type:0x%x tlvLEN:%u\n", item_type==1?"Group ":"", name, group_id, item_id, item_type, tlv_len);
 
 		tlvs = icq_unpack_tlvs_nc(buf, tlv_len, 0);
 		icq_userlist_parse_entry(s, tlvs, name, item_type, item_id, group_id);
 		icq_tlvs_destroy(&tlvs);
 
-		xfree(name);
-
 		buf += tlv_len; len -= tlv_len;
 
 	}
diff --git a/plugins/icq/misc.c b/plugins/icq/misc.c
index a8bbf5b..b2e3a42 100644
--- a/plugins/icq/misc.c
+++ b/plugins/icq/misc.c
@@ -22,25 +22,19 @@
 #include <stdarg.h>
 #include <string.h>
 #include <ctype.h>
-#ifdef HAVE_ICONV
-#	include <iconv.h>
-#endif
 
 #include <ekg/debug.h>
 #include <ekg/dynstuff.h>
 #include <ekg/dynstuff_inline.h>
 #include <ekg/stuff.h>
 #include <ekg/xmalloc.h>
-
+#include <ekg/recode.h>
 #include <ekg/userlist.h>
 
 #include "icq.h"
 #include "icq_snac_handlers.h"
 #include "misc.h"
 
-void *ucs2be_conv_in = (void*) -1;
-void *ucs2be_conv_out = (void*) -1;
-
 void icq_hexdump(int level, unsigned char *p, size_t len) {
 	#define MAX_BYTES_PER_LINE 16
 	unsigned char *payload = (unsigned char *) p;
@@ -623,59 +617,12 @@ void icq_pack_append_client_identification(string_t pkt) {
 	icq_pack_append(pkt, "T",  icq_pack_tlv_str(0x0e, CLIENT_COUNTRY));		// TLV(0x0E) - client country (2 symbols)
 }
 
-void icq_convert_string_init() {
-	ucs2be_conv_in = ekg_convert_string_init("UCS-2BE", NULL, &ucs2be_conv_out);
-}
-
-void icq_convert_string_destroy() {
-	if (ucs2be_conv_in != (void*) -1) {
-		ekg_convert_string_destroy(ucs2be_conv_in);
-		ekg_convert_string_destroy(ucs2be_conv_out);
-	}
-}
-
 char *icq_convert_from_ucs2be(char *buf, int len) {
-#ifdef HAVE_ICONV
-	char *ret, *ib, *ob;
-	size_t ibl, obl;
-	string_t text;
-
-	if (!buf || !len)
-		return NULL;
-
-	text = string_init(NULL);
-	string_append_raw(text, (char *) buf, len);
-
-	ib = text->str, ibl = len;
-	obl = 16 * ibl;
-	ob = ret = xmalloc(obl + 1);
-
-	iconv (ucs2be_conv_in, &ib, &ibl, &ob, &obl);
-
-	string_free(text, 1);
-
-	if (!ibl) {
-		*ob = '\0';
-		ret = (char*)xrealloc((void*)ret, xstrlen(ret)+1);
-		return ret;
-	}
-	xfree(ret);
-#endif
-	return NULL;
+	return ekg_ucs2_to_locale(buf, len);
 }
 
-string_t icq_convert_to_ucs2be(char *text) {
-	string_t ret, s;
-
-	if (!text || !*text)
-		return NULL;
-
-	s = string_init(text);
-	ret = ekg_convert_string_t_p(s, ucs2be_conv_out);
-	/* XXX, ret == NULL */
-	string_free(s, 1);
-
-	return ret;
+string_t icq_convert_to_ucs2be(char *text) { 
+	return ekg_locale_to_ucs2_dup(text);
 }
 
 void icq_send_snac(session_t *s, uint16_t family, uint16_t cmd, private_data_t *data, snac_subhandler_t subhandler, char *format, ...) {
diff --git a/plugins/icq/misc.h b/plugins/icq/misc.h
index fdada94..ba06ff3 100644
--- a/plugins/icq/misc.h
+++ b/plugins/icq/misc.h
@@ -68,9 +68,6 @@ const char *icq_lookuptable(struct fieldnames_t *table, int code);
 
 void icq_pack_append_client_identification(string_t pkt);
 
-void icq_convert_string_init();
-void icq_convert_string_destroy();
-
 char *icq_convert_from_ucs2be(char *buf, int len);
 string_t icq_convert_to_ucs2be(char *text);
 char *icq_convert_from_utf8(char *text);
diff --git a/plugins/irc/irc.c b/plugins/irc/irc.c
index 3e80d1f..ed937fe 100644
--- a/plugins/irc/irc.c
+++ b/plugins/irc/irc.c
@@ -188,8 +188,6 @@ static QUERY(irc_session_init) {
 
 	userlist_read(s);
 
-	ekg_recode_utf8_inc();
-
 	j = xmalloc(sizeof(irc_private_t));
 	j->nick_modes = j->nick_signs = NULL;
 	j->fd = -1;
diff --git a/plugins/irc/misc.c b/plugins/irc/misc.c
index 4cea125..e75aa9c 100644
--- a/plugins/irc/misc.c
+++ b/plugins/irc/misc.c
@@ -142,7 +142,7 @@ static char *irc_convert_in(irc_private_t *j, const char *line) {
 
 	/* convert from unicode */
 	if ( !recoded && is_utf8_string(line) ) /* XXX add variable here? */
-		recoded = ekg_utf8_to_locale_dup(line);
+		recoded = xstrdup(line);
 
 	return recoded;
 }
diff --git a/plugins/jabber/commands.c b/plugins/jabber/commands.c
index 968e64f..aa88d2c 100644
--- a/plugins/jabber/commands.c
+++ b/plugins/jabber/commands.c
@@ -274,8 +274,6 @@ static COMMAND(jabber_command_msg)
 
 	int secure		= 0;
 
-	const char *msg2;		/* used for transcoding */
-
 	if (!xstrcmp(target, "*")) {
 		if (msg_all(session, name, params[1]) == -1)
 			printq("list_empty");
@@ -320,9 +318,7 @@ static COMMAND(jabber_command_msg)
 		ismuc = 1;
 
 	if (!j->istlen) { /* Very, very simple XEP-0071 support + 'modified' jabber_encode() */
-		msg2 = ekg_locale_to_utf8_use(msg);
-
-		if ((htmlmsg = xstrchr(msg2, 18))) { /* ^R */
+		if ((htmlmsg = xstrchr(msg, 18))) { /* ^R */
 			int omitsyntaxcheck;
 
 			*(htmlmsg++) = 0;
@@ -355,8 +351,7 @@ static COMMAND(jabber_command_msg)
 					return -1;
 			}
 		}
-	} else
-		msg2 = msg;
+	}
 
 /* writing: */
 	if (j->send_watch) j->send_watch->transfer_limit = -1;
@@ -378,10 +373,10 @@ static COMMAND(jabber_command_msg)
 		xfree(thread);
 	}
 
-	if (!msg2) goto nomsg;
+	if (!msg) goto nomsg;
 
 	if (session_int_get(session, "__gpg_enabled") == 1) {
-		char *e_msg = xstrdup(msg2);
+		char *e_msg = xstrdup(msg);
 
 		if ((e_msg = jabber_openpgp(session, uid, JABBER_OPENGPG_ENCRYPT, e_msg, NULL, NULL))) {
 			watch_write(j->send_watch, 
@@ -392,13 +387,11 @@ static COMMAND(jabber_command_msg)
 		}
 	}
 	if (!secure /* || j->istlen */) {
-		char *tmp = (j->istlen ? tlen_encode(msg2) : xml_escape(msg2));
+		char *tmp = (j->istlen ? tlen_encode(msg) : xml_escape(msg));
 
 		watch_write(j->send_watch, "<body>%s</body>", tmp);
 		xfree(tmp);
 	}
-	if (!j->istlen)
-		recode_xfree(msg, msg2);			/* recoded string */
 
 	if (config_last & 4) 
 		last_add(1, uid, time(NULL), 0, params[1]);
diff --git a/plugins/jabber/digest.c b/plugins/jabber/digest.c
index aec124d..48f9bda 100644
--- a/plugins/jabber/digest.c
+++ b/plugins/jabber/digest.c
@@ -361,8 +361,6 @@ static void Final(unsigned char digest[20], EKG2_SHA1_CTX* context, int usesha)
 
 /* EKG2 STUFF */
 
-extern char *config_console_charset;							/* ekg/stuff.h */
-
 /**
  * base16_encode()
  *
@@ -398,19 +396,11 @@ char *jabber_challange_digest(const char *sid, const char *password, const char
 	EKG2_MD5_CTX ctx;
 	unsigned char digest[20];
 
-	const char *convnode, *convpasswd;	/* sid && password encoded in UTF-8 */
 	char *ha1, *ha2;
 	char *kd;
 
-/* ZERO STEP -> recode */
-	convnode = ekg_locale_to_utf8_use(sid);
-	convpasswd = ekg_locale_to_utf8_use(password);
-
 /* FIRST STEP */
-	kd = saprintf("%s:%s:%s", convnode, realm, convpasswd);
-
-	recode_xfree(sid, convnode);
-	recode_xfree(password, convpasswd);
+	kd = saprintf("%s:%s:%s", sid, realm, password);
 
 	MD5Init(&ctx);
 	MD5Update(&ctx, kd, xstrlen(kd));
@@ -508,11 +498,11 @@ char *jabber_digest(const char *sid, const char *password, int istlen) {
 
 	SHA1Init(&ctx);
 
-	tmp = (istlen) ? ekg_locale_to_iso2_use(sid) : ekg_locale_to_utf8_use(sid);
+	tmp = (istlen) ? ekg_locale_to_iso2_use(sid) : sid;
 	SHA1Update(&ctx, tmp, xstrlen(tmp));
 	recode_xfree(sid, tmp);
 
-	tmp = (istlen) ? ekg_locale_to_iso2_use(password) : ekg_locale_to_utf8_use(password);
+	tmp = (istlen) ? ekg_locale_to_iso2_use(password) : password;
 	SHA1Update(&ctx, tmp, xstrlen(tmp));
 	recode_xfree(password, tmp);
 
diff --git a/plugins/jabber/jabber.c b/plugins/jabber/jabber.c
index 1f18872..c264a03 100644
--- a/plugins/jabber/jabber.c
+++ b/plugins/jabber/jabber.c
@@ -115,11 +115,6 @@ static QUERY(jabber_session_init) {
 	j->fd = -1;
 	j->istlen = (tolower(s->uid[0]) == 't');	/* mark if this is tlen protocol */
 
-	if (!j->istlen)
-		ekg_recode_utf8_inc();
-	else
-		ekg_recode_iso2_inc();
-
 #ifdef JABBER_HAVE_GNUTLS
 	gnutls_certificate_allocate_credentials(&(j->xcred));
 	/* XXX - ~/.ekg/certs/server.pem */
@@ -159,11 +154,6 @@ static QUERY(jabber_session_deinit) {
 #ifdef JABBER_HAVE_GNUTLS
 	gnutls_certificate_free_credentials(j->xcred);
 #endif
-	if (!j->istlen)
-		ekg_recode_utf8_dec();
-	else
-		ekg_recode_iso2_dec();
-
 	xfree(j->server);
 	xfree(j->resource);
 	xfree(j->last_gmail_result_time);
diff --git a/plugins/jabber/misc.c b/plugins/jabber/misc.c
index 344263d..4bb1d05 100644
--- a/plugins/jabber/misc.c
+++ b/plugins/jabber/misc.c
@@ -204,17 +204,11 @@ char *jabber_attr(char **atts, const char *att)
  * @return Dynamic allocated string, which should be xfree()'d
  */
 
-char *jabber_escape(const char *text) {
-	const char *utftext;
-	char *res;
-
-	if (!text)
+char *jabber_escape(const char *utftext) {
+	if (!utftext)
 		return NULL;
 
-	utftext = ekg_locale_to_utf8_use(text);
-	res = xml_escape(utftext);
-	recode_xfree(text, utftext);
-	return res;
+	return xml_escape(utftext);
 }
 
 /**
@@ -232,10 +226,11 @@ char *jabber_escape(const char *text) {
  * @return Dynamic allocated string, which should be xfree()'d
  */
 
+/* XXX!!!!!!!! */
 char *jabber_unescape(const char *text) {
 	if (!text)
 		return NULL;
-	return ekg_utf8_to_locale_dup(text);
+	return xstrdup(text);
 }
 
 /**
diff --git a/plugins/jogger/drafts.c b/plugins/jogger/drafts.c
index daf150a..202a284 100644
--- a/plugins/jogger/drafts.c
+++ b/plugins/jogger/drafts.c
@@ -41,7 +41,7 @@
 #define JOGGER_VALUES_MAX 14
 
 	/* 10 char-long don't use ':', because they're already on limit (longer ones are discarded) */
-const char *utf_jogger_header_keys[JOGGER_KEYS_MAX] = {
+static const char *jogger_header_keys[JOGGER_KEYS_MAX] = {
 	"tytul:",	"temat:",	"subject:",	"tytuł:",		NULL,
 	"poziom:",	"level:",						NULL, /* 2 */
 	"tag:",									NULL, /* 3 */
@@ -53,7 +53,7 @@ const char *utf_jogger_header_keys[JOGGER_KEYS_MAX] = {
 	NULL
 };
 
-const char *utf_jogger_header_values[JOGGER_VALUES_MAX] = {
+static const char *jogger_header_values[JOGGER_VALUES_MAX] = {
 	"off",		"no",		"nie",		"wylacz",	"wyłącz",
 	"on",		"yes",		"tak",		"wlacz",	"włącz",	NULL,
 
@@ -61,35 +61,6 @@ const char *utf_jogger_header_values[JOGGER_VALUES_MAX] = {
 	NULL
 };
 
-char *jogger_header_keys[JOGGER_KEYS_MAX];
-char *jogger_header_values[JOGGER_VALUES_MAX];
-
-void jogger_free_headers(int real_free) {
-	int i;
-
-	for (i = 0; i < JOGGER_KEYS_MAX; i++) {
-		if (real_free)
-			xfree(jogger_header_keys[i]);
-		jogger_header_keys[i] = NULL;
-	}
-	for (i = 0; i < JOGGER_VALUES_MAX; i++) {
-		if (real_free)
-			xfree(jogger_header_values[i]);
-		jogger_header_values[i] = NULL;
-	}
-}
-
-void jogger_localize_headers() {
-	int i;
-
-	jogger_free_headers(1);
-	for (i = 0; i < JOGGER_KEYS_MAX; i++)
-		jogger_header_keys[i] = ekg_utf8_to_locale_dup(utf_jogger_header_keys[i]);
-
-	for (i = 0; i < JOGGER_VALUES_MAX; i++)
-		jogger_header_values[i] = ekg_utf8_to_locale_dup(utf_jogger_header_values[i]);
-}
-
 /**
  * jogger_checkoutfile()
  *
diff --git a/plugins/jogger/jogger.c b/plugins/jogger/jogger.c
index 7d80a69..e046691 100644
--- a/plugins/jogger/jogger.c
+++ b/plugins/jogger/jogger.c
@@ -35,15 +35,11 @@ int jogger_plugin_init(int prio);
 static int jogger_plugin_destroy(void);
 
 	/* messages.c */
-void jogger_localize_texts();
-void jogger_free_texts(int real_free);
 QUERY(jogger_msghandler);
 COMMAND(jogger_msg);
 COMMAND(jogger_subscribe);
 
 	/* drafts.c */
-void jogger_localize_headers();
-void jogger_free_headers(int real_free);
 COMMAND(jogger_prepare);
 COMMAND(jogger_publish);
 
@@ -197,12 +193,6 @@ static QUERY(jogger_newsession) {
 static QUERY(jogger_postconfig) {
 	session_t *js;
 
-	/* note: converters init only one-side converting (utf-8 ==> locale) recoders can't do it ;/ */
-	ekg_recode_utf8_inc();
-	jogger_localize_texts();
-	jogger_localize_headers();
-	ekg_recode_utf8_dec();
-
 	for (js = sessions; js; js = js->next) {
 		if ((js->plugin == &jogger_plugin) && !session_int_get(js, "userlist_keep"))
 			userlist_free(js);
@@ -299,8 +289,6 @@ int jogger_plugin_init(int prio) {
 #undef JOGGER_CMDFLAGS_TARGET
 #undef JOGGER_CMDFLAGS
 
-	jogger_free_texts(0); /* set NULLs */
-
 	plugin_register(&jogger_plugin, prio);
 
 	return 0;
@@ -309,8 +297,5 @@ int jogger_plugin_init(int prio) {
 static int jogger_plugin_destroy(void) {
 	plugin_unregister(&jogger_plugin);
 	
-	jogger_free_texts(1);
-	jogger_free_headers(1);
-
 	return 0;
 }
diff --git a/plugins/jogger/messages.c b/plugins/jogger/messages.c
index d3dfcff..17443cd 100644
--- a/plugins/jogger/messages.c
+++ b/plugins/jogger/messages.c
@@ -34,7 +34,7 @@
 	/* jogger.c */
 session_t *jogger_session_find_uid(session_t *s, const char *uid);
 
-const char *utf_jogger_text[JOGGER_TEXT_MAX] = {
+static const char *jogger_text[JOGGER_TEXT_MAX] = {
 	"Do Twojego joggera został dodany komentarz",		/* [0] url (#eid[ / Texti*])\n----------------\n */
 	"Pojawił się nowy komentarz do wpisu",			/* [1] as above */
 
@@ -55,26 +55,6 @@ const char *utf_jogger_text[JOGGER_TEXT_MAX] = {
 	"Brak uprawnień do komentowania tego wpisu!"		/* [13] */
 };
 
-char *jogger_text[JOGGER_TEXT_MAX];
-
-void jogger_free_texts(int real_free) {
-	int i;
-
-	for (i = 0; i < JOGGER_TEXT_MAX; i++) {
-		if (real_free)
-			xfree(jogger_text[i]);
-		jogger_text[i] = NULL;
-	}
-}
-
-void jogger_localize_texts() {
-	int i;
-
-	jogger_free_texts(1);
-	for (i = 0; i < JOGGER_TEXT_MAX; i++)
-		jogger_text[i] = ekg_utf8_to_locale_dup(utf_jogger_text[i]);
-}
-
 QUERY(jogger_msghandler) {
 	const char *suid	= *(va_arg(ap, const char **));
 	const char *uid		= *(va_arg(ap, char **));
diff --git a/plugins/ncurses/bindings.c b/plugins/ncurses/bindings.c
index 7132fa5..7d2ea2a 100644
--- a/plugins/ncurses/bindings.c
+++ b/plugins/ncurses/bindings.c
@@ -29,6 +29,10 @@
 #include <string.h>
 #include <unistd.h>
 
+#ifdef USE_UNICODE
+#  include <limits.h>
+#endif
+
 #include <ekg/bindings.h>
 #include <ekg/stuff.h>
 #include <ekg/metacontacts.h>
@@ -422,14 +426,14 @@ static BINDING_FUNCTION(binding_complete)
 
 			line_start_tmp = line_index_tmp = 0;
 			for (i = 0, j = 0; line[i] && i < LINE_MAXLEN; i++) {
-				char buf[MB_CUR_MAX+1];
+				char buf[MB_LEN_MAX+1];
 				int tmp;
 				int k;
 
 				tmp = wctomb(buf, line[i]);
 
-				if (tmp <= 0 || tmp >= MB_CUR_MAX) {
-					debug_error("binding_complete() wctomb() failed (%d)\n", tmp);
+				if (tmp <= 0 || tmp > MB_CUR_MAX) {
+					debug_error("binding_complete() wctomb() failed (%d) [%d]\n", tmp, MB_CUR_MAX);
 					return;
 				}
 
diff --git a/plugins/ncurses/old.c b/plugins/ncurses/old.c
index 4f5c2a1..14d5025 100644
--- a/plugins/ncurses/old.c
+++ b/plugins/ncurses/old.c
@@ -311,6 +311,72 @@ static int ncurses_backlog_add_real(window_t *w, fstring_t *str)
 	return ncurses_backlog_split(w, 0, removed);
 }
 
+#ifdef USE_UNICODE
+
+/* based on static int utf8_mbtowc(conv_t conv, ucs4_t *pwc, const unsigned char *s, int n); from libiconv-1.13.1/lib/utf8.h
+ * Copyright (C) 1999-2001, 2004 Free Software Foundation, Inc. under LGPL-2 */
+static int utf8_mbtowc(wchar_t *pwc, const char *_s, int n) {
+typedef unsigned int ucs4_t;
+
+	unsigned char *s = (unsigned char *) _s;
+	unsigned char c = s[0];
+
+	if (c < 0x80) {
+		*pwc = c;
+		return 1;
+	} 
+	
+	if (c < 0xc2)
+		return -1;
+	
+	if (c < 0xe0) {
+		if (n < 2)
+			return -1;
+		if (!((s[1] ^ 0x80) < 0x40))
+			return -1;
+		*pwc = (wchar_t) ((ucs4_t) (c & 0x1f) << 6) | (ucs4_t) (s[1] ^ 0x80);
+		return 2;
+	} 
+	
+	if (c < 0xf0) {
+		if (n < 3)
+			return -1;
+		if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (c >= 0xe1 || s[1] >= 0xa0)))
+			return -1;
+		*pwc = (wchar_t) ((ucs4_t) (c & 0x0f) << 12) | ((ucs4_t) (s[1] ^ 0x80) << 6) | (ucs4_t) (s[2] ^ 0x80);
+		return 3;
+	} 
+	
+	if (c < 0xf8 && sizeof(wchar_t) >= 4) {
+		if (n < 4)
+			return -1;
+		if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (s[3] ^ 0x80) < 0x40 && (c >= 0xf1 || s[1] >= 0x90)))
+			return -1;
+		*pwc = (wchar_t) ((ucs4_t) (c & 0x07) << 18) | ((ucs4_t) (s[1] ^ 0x80) << 12) | ((ucs4_t) (s[2] ^ 0x80) << 6) | (ucs4_t) (s[3] ^ 0x80);
+		return 4;
+	} 
+	
+	if (c < 0xfc && sizeof(wchar_t) >= 4) {
+		if (n < 5)
+			return -1;
+		if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 && (c >= 0xf9 || s[1] >= 0x88)))
+			return -1;
+		*pwc = (wchar_t) ((ucs4_t) (c & 0x03) << 24) | ((ucs4_t) (s[1] ^ 0x80) << 18) | ((ucs4_t) (s[2] ^ 0x80) << 12) | ((ucs4_t) (s[3] ^ 0x80) << 6) | (ucs4_t) (s[4] ^ 0x80);
+		return 5;
+	} 
+	
+	if (c < 0xfe && sizeof(wchar_t) >= 4) {
+		if (n < 6)
+			return -1;
+		if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 && (s[5] ^ 0x80) < 0x40 && (c >= 0xfd || s[1] >= 0x84)))
+			return -1;
+		*pwc = (wchar_t) ((ucs4_t) (c & 0x01) << 30) | ((ucs4_t) (s[1] ^ 0x80) << 24) | ((ucs4_t) (s[2] ^ 0x80) << 18) | ((ucs4_t) (s[3] ^ 0x80) << 12) | ((ucs4_t) (s[4] ^ 0x80) << 6) | (ucs4_t) (s[5] ^ 0x80);
+		return 6;
+	}
+	return -1;
+}
+#endif
+
 /*
  * ncurses_backlog_add()
  *
@@ -331,27 +397,19 @@ int ncurses_backlog_add(window_t *w, fstring_t *str) {
 		int cur = 0;
 		int i;
 
-		mbtowc(NULL, NULL, 0);	/* reset */
-
 		for (i = 0; cur < rlen; i++) {
 			wchar_t znak;
-			int len	= mbtowc(&znak, &(str->str.b[cur]), rlen-cur);
-
-			if (!len)	/* shouldn't happen -- cur < rlen */
-				break;
+			int len = utf8_mbtowc(&znak, &(str->str.b[cur]), rlen-cur);
 
 			if (len > 0) {
-				temp[i]		= znak;
-				str->attr[i]	= str->attr[cur]; 
+				temp[i]	= znak;
+				str->attr[i] = str->attr[cur]; 
 
 			} else {
-				/* here mbtowc() returns -1 */
-
-/*				debug("[%s:%d] mbtowc() failed ?! (%d, %s) (%d)\n", __FILE__, __LINE__, errno, strerror(errno), i); */
+				temp[i]	= '?';
+				str->attr[i] = str->attr[cur] | FSTR_REVERSE; 
 
-				len		= 1;		/* always move forward */
-				temp[i]		= '?';
-				str->attr[i]	= str->attr[cur] | FSTR_REVERSE; 
+				len	= 1;
 			}
 
 			if (cur == str->prompt_len)
diff --git a/plugins/polchat/polchat.c b/plugins/polchat/polchat.c
index 9a44b01..6205819 100644
--- a/plugins/polchat/polchat.c
+++ b/plugins/polchat/polchat.c
@@ -187,10 +187,8 @@ static watch_t *polchat_sendpkt(session_t *s, short headercode, ...)  {
 
 	va_start(ap, headercode);
 	while ((tmp = va_arg(ap, char *))) {
-		char *r = ekg_locale_to_utf8_dup(tmp);
-
-		array_add(&arr, r);
-		size += strlen(r) + 3;
+		array_add(&arr, tmp);
+		size += strlen(tmp) + 3;
 	}
 	va_end(ap);
 
@@ -702,7 +700,6 @@ EXPORT int polchat_plugin_init(int prio) {
 	polchat_plugin.params = polchat_plugin_vars;
 
 	plugin_register(&polchat_plugin, prio);
-	ekg_recode_utf8_inc();
 
 	query_connect_id(&polchat_plugin, PROTOCOL_VALIDATE_UID, polchat_validate_uid, NULL);
 	query_connect_id(&polchat_plugin, SESSION_ADDED, polchat_session_init, NULL);
@@ -748,7 +745,6 @@ EXPORT int polchat_plugin_init(int prio) {
 
 static int polchat_plugin_destroy() {
 	plugin_unregister(&polchat_plugin);
-	ekg_recode_utf8_dec();
 	return 0;
 }
 
diff --git a/plugins/polchat/polchat_handlers.inc b/plugins/polchat/polchat_handlers.inc
index 7e57988..99c342d 100644
--- a/plugins/polchat/polchat_handlers.inc
+++ b/plugins/polchat/polchat_handlers.inc
@@ -537,7 +537,7 @@ void polchat_processpkt(session_t *s, unsigned short nheaders, unsigned short ns
 
 		if (len < strlen+1) goto invalid_packet; len -= (strlen+1);
 
-		strings[i] = ekg_utf8_to_locale(xstrndup((char*) &data[2], strlen));
+		strings[i] = xstrndup((char*) &data[2], strlen);
 		data += (2 + strlen + 1);
 	}
 
diff --git a/plugins/rivchat/rivchat.c b/plugins/rivchat/rivchat.c
index 3c13334..f842f79 100644
--- a/plugins/rivchat/rivchat.c
+++ b/plugins/rivchat/rivchat.c
@@ -1489,7 +1489,6 @@ EXPORT int rivchat_plugin_init(int prio) {
 	rivchat_plugin.params = rivchat_plugin_vars;
 
 	plugin_register(&rivchat_plugin, prio);
-	ekg_recode_cp_inc();
 
 	query_connect_id(&rivchat_plugin, PROTOCOL_VALIDATE_UID, rivchat_validate_uid, NULL);
 	query_connect_id(&rivchat_plugin, SESSION_ADDED, rivchat_session_init, NULL);
@@ -1524,7 +1523,6 @@ EXPORT int rivchat_plugin_init(int prio) {
 
 static int rivchat_plugin_destroy() {
 	plugin_unregister(&rivchat_plugin);
-	ekg_recode_cp_dec();
 	return 0;
 }
 
diff --git a/plugins/sim/main.c b/plugins/sim/main.c
index 4b85c48..71bc3e4 100644
--- a/plugins/sim/main.c
+++ b/plugins/sim/main.c
@@ -353,7 +353,6 @@ EXPORT int sim_plugin_init(int prio)
 	PLUGIN_CHECK_VER("sim");
 
 	plugin_register(&sim_plugin, prio);
-	ekg_recode_cp_inc();
 
 	query_connect_id(&sim_plugin, MESSAGE_ENCRYPT, message_encrypt, NULL);
 	query_connect_id(&sim_plugin, MESSAGE_DECRYPT, message_decrypt, NULL);
@@ -376,7 +375,6 @@ EXPORT int sim_plugin_init(int prio)
 static int sim_plugin_destroy()
 {
 	plugin_unregister(&sim_plugin);
-	ekg_recode_cp_dec();
 
 	xfree(sim_key_path);
 
diff --git a/plugins/sniff/sniff.c b/plugins/sniff/sniff.c
index e662136..44b18e0 100644
--- a/plugins/sniff/sniff.c
+++ b/plugins/sniff/sniff.c
@@ -765,9 +765,6 @@ EXPORT int sniff_plugin_init(int prio) {
 	sniff_plugin.params = sniff_plugin_vars;
 	plugin_register(&sniff_plugin, prio);
 
-	ekg_recode_cp_inc();
-	ekg_recode_utf8_inc();
-
 	query_connect_id(&sniff_plugin, PROTOCOL_VALIDATE_UID,	sniff_validate_uid, NULL);
 	query_connect_id(&sniff_plugin, STATUS_SHOW,		sniff_status_show, NULL);
 	query_connect_id(&sniff_plugin, PLUGIN_PRINT_VERSION,	sniff_print_version, NULL);
@@ -782,9 +779,6 @@ EXPORT int sniff_plugin_init(int prio) {
 
 static int sniff_plugin_destroy() {
 	plugin_unregister(&sniff_plugin);
-
-	ekg_recode_cp_dec();
-	ekg_recode_utf8_dec();
 	return 0;
 }
 
diff --git a/plugins/sniff/sniff_gg.inc b/plugins/sniff/sniff_gg.inc
index 6a0b47b..3b35d59 100644
--- a/plugins/sniff/sniff_gg.inc
+++ b/plugins/sniff/sniff_gg.inc
@@ -1186,7 +1186,7 @@ SNIFF_HANDLER(sniff_gg_new_status80_real, gg_new_status80_real) {
 		tcp_print_payload((u_char *) pkt->data, len);
 	}
 
-	descr	= has_descr ? ekg_utf8_to_locale(xstrndup(pkt->data, len)) : NULL;
+	descr	= has_descr ? xstrndup(pkt->data, len) : NULL;
 	sniff_gg_print_new_status(s, hdr, 0, status, descr);
 	xfree(descr);
 	return 0;
@@ -1237,7 +1237,7 @@ SNIFF_HANDLER(sniff_gg_notify_reply80_real, gg_notify_reply80_real) {
 		next += pkt->descr_len;
 	}
 
-	descr = has_descr ? ekg_utf8_to_locale(xstrndup(pkt->next, pkt->descr_len)) : NULL;
+	descr = has_descr ? xstrndup(pkt->next, pkt->descr_len) : NULL;
 	sniff_gg_print_status(s, hdr, uin, status, descr);
 	xfree(descr);
 
@@ -1303,7 +1303,7 @@ SNIFF_HANDLER(sniff_gg_status80_real, gg_status80_real) {
 		tcp_print_payload((u_char *) pkt->descr, len);
 	}
 
-	descr 	= has_descr ? ekg_utf8_to_locale(xstrndup(pkt->descr, len)) : NULL;
+	descr 	= has_descr ? xstrndup(pkt->descr, len) : NULL;
 	sniff_gg_print_status(s, hdr, uin, status, descr);
 	xfree(descr);
 
