Index: ChangeLog
===================================================================
--- ChangeLog	(revision 10220)
+++ ChangeLog	(working copy)
@@ -1,3 +1,11 @@
+2009-04-17  Milan Crha  <mcrha@redhat.com>
+
+	** Part of fix for bug #343505
+
+	* libedataserver/e-data-server-util.h: (e_util_utf8_remove_accents):
+	* libedataserver/e-data-server-util.c: (e_util_utf8_remove_accents):
+	Helper function to remove accents from a UTF-8 string.
+
 2009-04-12  Matthew Barnes  <mbarnes@redhat.com>
 
 	** Remove a bunch of juvenile comments.  Source code should
Index: libedataserver/e-data-server-util.c
===================================================================
--- libedataserver/e-data-server-util.c	(revision 10220)
+++ libedataserver/e-data-server-util.c	(working copy)
@@ -285,6 +285,38 @@ e_util_utf8_strcasecmp (const gchar *s1,
 }
 
 /**
+ * e_util_utf8_remove_accents:
+ *
+ * Returns newly allocates string, copy of 'str', without accents.
+ **/
+gchar *
+e_util_utf8_remove_accents (const char *str)
+{
+	char *res;
+	int i, j;
+
+	if (!str)
+		return NULL;
+
+	res = g_utf8_normalize (str, -1, G_NORMALIZE_NFD);
+	if (!res)
+		return g_strdup (str);
+
+	for (i = 0, j = 0; res [i]; i++) {
+		if ((unsigned char)res[i] != 0xCC || res [i + 1] == 0) {
+			res [j] = res [i];
+			j++;
+		} else {
+			i++;
+		}
+	}
+
+	res [j] = 0;
+
+	return res;
+}
+
+/**
  * e_strftime:
  * @s: The string array to store the result in.
  * @max: The size of array @s.
Index: libedataserver/e-data-server-util.h
===================================================================
--- libedataserver/e-data-server-util.h	(revision 10220)
+++ libedataserver/e-data-server-util.h	(working copy)
@@ -40,6 +40,7 @@ gchar       *e_util_unicode_get_utf8 (co
 const gchar *e_util_utf8_strstrcase (const gchar *haystack, const gchar *needle);
 const gchar *e_util_utf8_strstrcasedecomp (const gchar *haystack, const gchar *needle);
 int	     e_util_utf8_strcasecmp (const gchar *s1, const gchar *s2);
+gchar       *e_util_utf8_remove_accents (const char *str);
 guint64      e_util_pthread_id (pthread_t t);
 void         e_filename_make_safe (gchar *string);
 
Index: addressbook/ChangeLog
===================================================================
--- addressbook/ChangeLog	(revision 10220)
+++ addressbook/ChangeLog	(working copy)
@@ -1,3 +1,13 @@
+2009-04-17  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #343505
+
+	* libedata-book/e-book-backend-summary.c: (contains_helper),
+	(func_contains), (is_helper), (endswith_helper), (beginswith_helper):
+	* libedata-book/e-book-backend-sexp.c: (chars_to_unistring_lowercase),
+	(is_helper), (endswith_helper), (beginswith_helper), (exists_helper),
+	(func_exists): Compare texts without accents.
+
 2009-03-04  Jeff Cai <jeff.cai@sun.com>
 
 	* libebook/e-contact.c: (n_setter): 
Index: addressbook/libedata-book/e-book-backend-sexp.c
===================================================================
--- addressbook/libedata-book/e-book-backend-sexp.c	(revision 10220)
+++ addressbook/libedata-book/e-book-backend-sexp.c	(working copy)
@@ -445,13 +445,17 @@ try_contains_word (const gchar *s1, GSLi
    returns newly allocated GString
 */
 static GString *
-chars_to_unistring_lowercase (const char *str)
+chars_to_unistring_lowercase (const char *pstr)
 {
 	GString *res;
 	gunichar unich;
-	gchar *p;
+	gchar *p, *str;
 
-	if (str == NULL)
+	if (pstr == NULL)
+		return NULL;
+
+	str = e_util_utf8_remove_accents (pstr);
+	if (!str)
 		return NULL;
 
 	res = g_string_new ("");
@@ -460,6 +464,8 @@ chars_to_unistring_lowercase (const char
 		g_string_append_unichar (res, g_unichar_tolower (unich));
 	}
 
+	g_free (str);
+
 	/* it was invalid unichar string */
 	if (p == NULL) {
 		g_string_free (res, TRUE);
@@ -572,12 +578,22 @@ func_contains(struct _ESExp *f, int argc
 }
 
 static char *
-is_helper (const char *s1, const char *s2)
+is_helper (const char *ps1, const char *ps2)
 {
+	char *s1, *s2, *res;
+
+	s1 = e_util_utf8_remove_accents (ps1);
+	s2 = e_util_utf8_remove_accents (ps2);
+
 	if (!e_util_utf8_strcasecmp (s1, s2))
-		return (char*)s1;
+		res = (char*)ps1;
 	else
-		return NULL;
+		res = NULL;
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
 }
 
 static ESExpResult *
@@ -589,15 +605,23 @@ func_is(struct _ESExp *f, int argc, stru
 }
 
 static char *
-endswith_helper (const char *s1, const char *s2)
+endswith_helper (const char *ps1, const char *ps2)
 {
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+	char *res;
 	glong s1len = g_utf8_strlen (s1, -1);
 	glong s2len = g_utf8_strlen (s2, -1);
 
 	if (s1len < s2len)
-		return NULL;
+		res = NULL;
+	else
+		res = (char *)e_util_utf8_strstrcase (g_utf8_offset_to_pointer (s1, s1len - s2len), s2);
+
+	g_free (s1);
+	g_free (s2);
 
-	return (char *)e_util_utf8_strstrcase (g_utf8_offset_to_pointer (s1, s1len - s2len), s2);
+	return res;
 }
 
 static ESExpResult *
@@ -609,14 +633,22 @@ func_endswith(struct _ESExp *f, int argc
 }
 
 static char *
-beginswith_helper (const char *s1, const char *s2)
+beginswith_helper (const char *ps1, const char *ps2)
 {
-	char *p;
+	char *p, *res;
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+
 	if ((p = (char*) e_util_utf8_strstrcase(s1, s2))
 	    && (p == s1))
-		return p;
+		res = (char *)ps1;
 	else
-		return NULL;
+		res = NULL;
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
 }
 
 static ESExpResult *
@@ -627,6 +659,21 @@ func_beginswith(struct _ESExp *f, int ar
 	return entry_compare (ctx, f, argc, argv, beginswith_helper);
 }
 
+static char *
+exists_helper (const char *ps1, const char *ps2)
+{
+	char *res;
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+
+	res = (char *)e_util_utf8_strstrcase (s1, s2);
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
+}
+
 static ESExpResult *
 func_exists(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
 {
@@ -660,7 +707,7 @@ func_exists(struct _ESExp *f, int argc, 
 				}
 				else if (info->prop_type == PROP_TYPE_LIST) {
 				/* the special searches that match any of the list elements */
-					truth = info->list_compare (ctx->contact, "", (char *(*)(const char*, const char*)) e_util_utf8_strstrcase);
+					truth = info->list_compare (ctx->contact, "", exists_helper);
 				}
 
 				break;
Index: addressbook/libedata-book/e-book-backend-summary.c
===================================================================
--- addressbook/libedata-book/e-book-backend-summary.c	(revision 10220)
+++ addressbook/libedata-book/e-book-backend-summary.c	(working copy)
@@ -1076,21 +1076,45 @@ do_compare (EBookBackendSummary *summary
 	return r;
 }
 
+static char *
+contains_helper (const char *ps1, const char *ps2)
+{
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+	char *res;
+
+	res = (char *) e_util_utf8_strstrcase (s1, s2);
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
+}
+
 static ESExpResult *
 func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
 {
 	EBookBackendSummary *summary = data;
 
-	return do_compare (summary, f, argc, argv, (char *(*)(const char*, const char*)) e_util_utf8_strstrcase);
+	return do_compare (summary, f, argc, argv, contains_helper);
 }
 
 static char *
-is_helper (const char *s1, const char *s2)
+is_helper (const char *ps1, const char *ps2)
 {
-	if (!e_util_utf8_strcasecmp(s1, s2))
-		return (char*)s1;
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+	char *res;
+
+	if (!e_util_utf8_strcasecmp (s1, s2))
+		res = (char*)ps1;
 	else
-		return NULL;
+		res = NULL;
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
 }
 
 static ESExpResult *
@@ -1102,14 +1126,23 @@ func_is(struct _ESExp *f, int argc, stru
 }
 
 static char *
-endswith_helper (const char *s1, const char *s2)
+endswith_helper (const char *ps1, const char *ps2)
 {
-	char *p;
-	if ((p = (char*)e_util_utf8_strstrcase(s1, s2))
-	    && (strlen(p) == strlen(s2)))
-		return p;
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+	char *res;
+	glong s1len = g_utf8_strlen (s1, -1);
+	glong s2len = g_utf8_strlen (s2, -1);
+
+	if (s1len < s2len)
+		res = NULL;
 	else
-		return NULL;
+		res = (char *)e_util_utf8_strstrcase (g_utf8_offset_to_pointer (s1, s1len - s2len), s2);
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
 }
 
 static ESExpResult *
@@ -1121,14 +1154,22 @@ func_endswith(struct _ESExp *f, int argc
 }
 
 static char *
-beginswith_helper (const char *s1, const char *s2)
+beginswith_helper (const char *ps1, const char *ps2)
 {
-	char *p;
-	if ((p = (char*)e_util_utf8_strstrcase(s1, s2))
+	char *p, *res;
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+
+	if ((p = (char*) e_util_utf8_strstrcase(s1, s2))
 	    && (p == s1))
-		return p;
+		res = (char *)ps1;
 	else
-		return NULL;
+		res = NULL;
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
 }
 
 static ESExpResult *
