diff -Naur evolution-2.0.4.orig/camel/camel-charset-map.c evolution-2.0.4/camel/camel-charset-map.c
--- evolution-2.0.4.orig/camel/camel-charset-map.c	2004-12-06 08:46:50.000000000 +0100
+++ evolution-2.0.4/camel/camel-charset-map.c	2005-04-22 14:38:28.000000000 +0200
@@ -200,19 +200,18 @@
 
 #else
 
-#include "camel-charset-map.h"
-#include "camel-charset-map-private.h"
-
-#include <gal/util/e-iconv.h>
-
 #include <glib.h>
 #include <locale.h>
-#include <ctype.h>
-#include <pthread.h>
 #ifdef HAVE_CODESET
 #include <langinfo.h>
 #endif
 
+#include "camel-charset-map.h"
+#include "camel-charset-map-private.h"
+#include "camel-utf8.h"
+
+#include <gal/util/e-iconv.h>
+
 void
 camel_charset_init (CamelCharset *c)
 {
@@ -221,42 +220,34 @@
 }
 
 void
-camel_charset_step (CamelCharset *c, const char *in, int len)
+camel_charset_step (CamelCharset *cc, const char *in, int len)
 {
 	register unsigned int mask;
 	register int level;
-	const char *inptr = in, *inend = in+len;
+	const unsigned char *inptr = in, *inend = in+len;
+	register guint32 c;
 
-	mask = c->mask;
-	level = c->level;
+	mask = cc->mask;
+	level = cc->level;
 
 	/* check what charset a given string will fit in */
-	while (inptr < inend) {
-		gunichar c;
-		const char *newinptr;
-		newinptr = g_utf8_next_char(inptr);
-		c = g_utf8_get_char(inptr);
-		if (newinptr == NULL || !g_unichar_validate (c)) {
-			inptr++;
-			continue;
-		}
-
-		inptr = newinptr;
-		if (c<=0xffff) {
+	while ( (c = camel_utf8_getc_limit(&inptr, inend)) != 0xffff) {
+		if (c < 0xffff) {
 			mask &= charset_mask(c);
 		
 			if (c>=128 && c<256)
 				level = MAX(level, 1);
 			else if (c>=256)
-				level = MAX(level, 2);
+				level = 2;
 		} else {
 			mask = 0;
-			level = MAX(level, 2);
+			level = 2;
+			break;
 		}
 	}
 
-	c->mask = mask;
-	c->level = level;
+	cc->mask = mask;
+	cc->level = level;
 }
 
 /* gets the best charset from the mask of chars in it */
diff -Naur evolution-2.0.4.orig/camel/camel-mime-utils.c evolution-2.0.4/camel/camel-mime-utils.c
--- evolution-2.0.4.orig/camel/camel-mime-utils.c	2005-02-14 17:09:04.000000000 +0100
+++ evolution-2.0.4/camel/camel-mime-utils.c	2005-04-22 13:40:59.000000000 +0200
@@ -2998,44 +2998,24 @@
 	const unsigned char *inptr = in;
 	unsigned char *outbuf = NULL;
 	const char *charset;
-	int encoding;
 	GString *out;
 	guint32 c;
 
 	*encoded = FALSE;
 	
 	g_return_val_if_fail (in != NULL, NULL);
-	
-	/* do a quick us-ascii check (the common case?) */
-	while (*inptr) {
-		if (*inptr > 127)
-			break;
-		inptr++;
-	}
-	
-	if (*inptr == '\0')
-		return g_strdup (in);
-	
-	inptr = in;
-	encoding = 0;
-	while ( encoding !=2 && (c = camel_utf8_getc(&inptr)) ) {
-		if (c > 127 && c < 256)
-			encoding = MAX (encoding, 1);
-		else if (c >= 256)
-			encoding = MAX (encoding, 2);
-	}
 
-	if (encoding == 2)
-		charset = camel_charset_best(in, strlen(in));
-	else
-		charset = "iso-8859-1";
+	/* if we have really broken utf8 passed in, we just treat it as binary data */
+
+	charset = camel_charset_best(in, strlen(in));
+	if (charset == NULL)
+		return g_strdup(in);
 	
-	if (strcasecmp(charset, "UTF-8") != 0
-	    && (outbuf = header_convert(charset, "UTF-8", in, strlen(in)))) {
-		inptr = outbuf;
-	} else {
-		charset = "UTF-8";
-		inptr = in;
+	if (g_ascii_strcasecmp(charset, "UTF-8") != 0) {
+		if ((outbuf = header_convert(charset, "UTF-8", in, strlen(in))))
+			inptr = outbuf;
+		else
+			return g_strdup(in);
 	}
 	
 	/* FIXME: set the 'language' as well, assuming we can get that info...? */
diff -Naur evolution-2.0.4.orig/camel/tests/misc/test2.c evolution-2.0.4/camel/tests/misc/test2.c
--- evolution-2.0.4.orig/camel/tests/misc/test2.c	2004-06-01 12:07:13.000000000 +0200
+++ evolution-2.0.4/camel/tests/misc/test2.c	2005-04-22 13:50:58.000000000 +0200
@@ -53,7 +53,7 @@
 	{ 1,
 	  { "name", "Doul\xC3\xADk01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123457890123456789123456789" },
 	  ";\n"
-	  "\tname*0*=iso-8859-1''Doul%EDk012345678901234567890123456789012345678901234;\n"
+	  "\tname*0*=ISO-8859-1''Doul%EDk012345678901234567890123456789012345678901234;\n"
 	  "\tname*1*=56789012345678901234567890123456789012345678901234567890123457890;\n"
 	  "\tname*2*=123456789123456789" },
 	{ 1,
@@ -61,7 +61,7 @@
 	  "; name=\"\\\"%$#@ special chars?;; !\"" },
 	{ 1,
 	  { "name", "\"%$#@ special chars?;; !\xC3\xAD" },
-	  "; name*=iso-8859-1''%22%25$#%40%20special%20chars%3F%3B%3B%20!%ED" },
+	  "; name*=ISO-8859-1''%22%25$#%40%20special%20chars%3F%3B%3B%20!%ED" },
 };
 
 int
diff -Naur evolution-2.0.4.orig/mail/em-inline-filter.c evolution-2.0.4/mail/em-inline-filter.c
--- evolution-2.0.4.orig/mail/em-inline-filter.c	2004-05-19 09:02:12.000000000 +0200
+++ evolution-2.0.4/mail/em-inline-filter.c	2005-04-22 13:50:36.000000000 +0200
@@ -196,6 +196,7 @@
 			if (strncmp(start, "begin ", 6) == 0
 			    && start[6] >= '0' && start[6] <= '7') {
 				int i = 7;
+				char *name;
 
 				while (start[i] >='0' && start[i] <='7')
 					i++;
@@ -206,7 +207,10 @@
 					break;
 
 				emif_add_part(emif, data_start, start-data_start);
-				emif->filename = g_strndup(start+i, inptr-start-i-1);
+
+				name = g_strndup(start+i, inptr-start-i-1);
+				emif->filename = camel_header_decode_string(name, emif->base_type?camel_content_type_param(emif->base_type, "charset"):NULL);
+				g_free(name);
 				data_start = start;
 				emif->state = EMIF_UUENC;
 			} else if (strncmp(start, "(This file must be converted with BinHex 4.0)", 45) == 0) {
