Index: ChangeLog
===================================================================
--- ChangeLog	(revision 10006)
+++ ChangeLog	(working copy)
@@ -1,3 +1,18 @@
+2009-02-02  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #569652
+
+	* libedataserver/e-source-list.h: (e_source_list_peek_group_by_name):
+	* libedataserver/e-source-list.c: (e_source_list_peek_group_by_name):
+	Deprecated since now, it's not safe for localized names.
+
+	* libedataserver/e-source-list.h: (e_source_list_ensure_group),
+	(e_source_list_peek_group_by_base_uri),
+	(e_source_list_peek_group_by_properties),
+	(e_source_list_remove_group_by_base_uri):
+	* libedataserver/e-source-list.c: (check_group_property):
+	New API functions.
+
 2009-01-28  Tor Lillqvist  <tml@novell.com>
 
 	* src/Makefile.am (evolution_data_server_LDFLAGS): Build as a
Index: servers/exchange/storage/exchange-esource.c
===================================================================
--- servers/exchange/storage/exchange-esource.c	(revision 10006)
+++ servers/exchange/storage/exchange-esource.c	(working copy)
@@ -32,6 +32,41 @@
 
 static gboolean is_offline (void);
 
+static ESourceGroup *
+find_account_group (ESourceList *source_list, ExchangeAccount *exa)
+{
+	ESourceGroup *group;
+	EAccount *account;
+
+	g_return_val_if_fail (exa != NULL, NULL);
+	g_return_val_if_fail (exa->account_name != NULL, NULL);
+	g_return_val_if_fail (source_list != NULL, NULL);
+
+	account = exchange_account_fetch (exa);
+	g_return_val_if_fail (account != NULL, NULL);
+	g_return_val_if_fail (account->uid != NULL, NULL);
+
+	group = e_source_list_peek_group_by_properties (source_list, "account-uid", account->uid, NULL);
+	if (!group) {
+		/* check whether is stored only with an account name - the old style */
+		GSList *g;
+
+		for (g = e_source_list_peek_groups (source_list); g != NULL; g = g->next) {
+			group = E_SOURCE_GROUP (g->data);
+
+			if (strcmp (e_source_group_peek_name (group), exa->account_name) == 0)
+				break;
+
+			group = NULL;
+		}
+
+		if (group)
+			e_source_group_set_property (group, "account-uid", account->uid);
+	}
+
+	return group;
+}
+
 void
 add_folder_esource (ExchangeAccount *account,
 	     	    FolderType folder_type,
@@ -91,8 +126,7 @@ add_folder_esource (ExchangeAccount *acc
 	useremail = exchange_account_get_email_id (account);
 	authtype = exchange_account_get_authtype (account);
 
-        if ((source_group = e_source_list_peek_group_by_name (source_list,
-					account->account_name)) == NULL) {
+        if ((source_group = find_account_group (source_list, account)) == NULL) {
 		source_group = e_source_group_new (account->account_name,
 						   EXCHANGE_URI_PREFIX);
 		if (!e_source_list_add_group (source_list, source_group, -1)) {
@@ -105,6 +139,8 @@ add_folder_esource (ExchangeAccount *acc
 				g_free (authtype);
 			return;
 		}
+		e_source_group_set_property (source_group, "account-uid", exchange_account_fetch (account)->uid);
+		
 		if (is_contacts_folder && g_str_has_prefix (physical_uri, "gal://")) {
 			char *browse = exchange_account_get_account_uri_param (account, "ad_browse");
 
Index: servers/exchange/ChangeLog
===================================================================
--- servers/exchange/ChangeLog	(revision 10006)
+++ servers/exchange/ChangeLog	(working copy)
@@ -1,3 +1,12 @@
+2009-02-02  Milan Crha  <mcrha@redhat.com>
+
+	** Part of fix for bug #569652
+
+	* storage/exchange-esource.c: (find_account_group),
+	(add_folder_esource): Do not use deprecated
+	e_source_list_peek_group_by_name and add
+	account's uid as a group property.
+
 2009-01-14  Matthew Barnes  <mbarnes@redhat.com>
 
 	** Fixes part of bug #564543
Index: libedataserver/e-source-list.c
===================================================================
--- libedataserver/e-source-list.c	(revision 10006)
+++ libedataserver/e-source-list.c	(working copy)
@@ -440,6 +440,11 @@ e_source_list_peek_group_by_uid (ESource
 	return NULL;
 }
 
+#ifndef EDS_DISABLE_DEPRECATED
+/**
+ * Note: This function isn't safe with respect of localized names,
+ * use e_source_list_peek_group_by_base_uri instead.
+ **/
 ESourceGroup *
 e_source_list_peek_group_by_name (ESourceList *list,
 				  const char *name)
@@ -458,6 +463,103 @@ e_source_list_peek_group_by_name (ESourc
 
 	return NULL;
 }
+#endif
+
+/**
+ * e_source_list_peek_group_by_base_uri:
+ * Returns the first group which base uri begins with a base_uri.
+ **/
+ESourceGroup *
+e_source_list_peek_group_by_base_uri (ESourceList *list, const char *base_uri)
+{
+	GSList *p;
+	int len;
+
+	g_return_val_if_fail (E_IS_SOURCE_LIST (list), NULL);
+	g_return_val_if_fail (base_uri != NULL, NULL);
+
+	len = strlen (base_uri);
+
+	for (p = list->priv->groups; p != NULL; p = p->next) {
+		ESourceGroup *group = E_SOURCE_GROUP (p->data);
+		const char *buri = e_source_group_peek_base_uri (group);
+
+		if (buri && g_ascii_strncasecmp (buri, base_uri, len) == 0)
+			return group;
+	}
+
+	return NULL;
+}
+
+struct property_check_struct {
+	ESourceGroup *group;
+	gboolean same;
+};
+
+static void
+check_group_property (const char *property_name, const char *property_value, struct property_check_struct *pcs)
+{
+	char *value;
+
+	g_return_if_fail (property_name != NULL);
+	g_return_if_fail (property_value != NULL);
+	g_return_if_fail (pcs != NULL);
+	g_return_if_fail (pcs->group != NULL);
+
+	value = e_source_group_get_property (pcs->group, property_name);
+	pcs->same = pcs->same && value && g_ascii_strcasecmp (property_value, value) == 0;
+	g_free (value);
+}
+
+/**
+ * e_source_list_peek_group_by_properties:
+ * Peeks group by its properties. Parameters are pairs of strings
+ * property_name, property_value, terminated by NULL! ESourceGroup
+ * is returned only if matches all the properties. Values are compared
+ * case insensitively.
+ **/
+ESourceGroup *
+e_source_list_peek_group_by_properties (ESourceList *list, const char *property_name, ...)
+{
+	GSList *p;
+	va_list ap;
+	GHashTable *props;
+
+	g_return_val_if_fail (E_IS_SOURCE_LIST (list), NULL);
+	g_return_val_if_fail (property_name != NULL, NULL);
+
+	props = g_hash_table_new (g_str_hash, g_str_equal);
+
+	va_start (ap, property_name);
+	while (property_name) {
+		const char *value = va_arg (ap, const char *);
+
+		if (!value)
+			break;
+
+		g_hash_table_insert (props, (gpointer)property_name, (gpointer)value);
+		property_name = va_arg (ap, const char *);
+	}
+	va_end (ap);
+
+	for (p = list->priv->groups; p != NULL; p = p->next) {
+		struct property_check_struct pcs;
+
+		pcs.group = E_SOURCE_GROUP (p->data);
+		pcs.same = TRUE;
+
+		g_hash_table_foreach (props, (GHFunc) check_group_property, &pcs);
+
+		if (pcs.same) {
+			g_hash_table_unref (props);
+			return pcs.group;
+		}
+	}
+
+	g_hash_table_unref (props);
+
+	return NULL;
+}
 
 ESource *
 e_source_list_peek_source_by_uid (ESourceList *list,
@@ -552,6 +654,70 @@ e_source_list_remove_group_by_uid (ESour
 	return TRUE;
 }
 
+/**
+ * e_source_list_ensure_group:
+ * Ensures group with the @base_uri will exists in the @list and its name will be @name.
+ * If ret_it will be TRUE the group will be also returned, in that case caller should
+ * g_object_unref the group. Otherwise it returns NULL.
+ **/
+ESourceGroup *
+e_source_list_ensure_group (ESourceList *list, const char *name, const char *base_uri, gboolean ret_it)
+{
+	ESourceGroup *group;
+
+	g_return_val_if_fail (E_IS_SOURCE_LIST (list), NULL);
+	g_return_val_if_fail (name != NULL, NULL);
+	g_return_val_if_fail (base_uri != NULL, NULL);
+
+	group = e_source_list_peek_group_by_base_uri (list, base_uri);
+	if (group) {
+		e_source_group_set_name (group, name);
+		if (ret_it)
+			g_object_ref (group);
+		else
+			group = NULL;
+	} else {
+		group = e_source_group_new (name, base_uri);
+
+		if (!e_source_list_add_group (list, group, -1)) {
+			g_warning ("Could not add source group %s with base uri %s to a source list", name, base_uri);
+			g_object_unref (group);
+			group = NULL;
+		} else {
+			/* save it now */
+			e_source_list_sync (list, NULL);
+
+			if (!ret_it) {
+				g_object_unref (group);
+				group = NULL;
+			}
+		}
+	}
+
+	return group;
+}
+
+/**
+ * e_source_list_remove_group_by_base_uri:
+ * Removes group with given base_uri.
+ * Returns TRUE if group was found.
+ **/
+gboolean
+e_source_list_remove_group_by_base_uri (ESourceList *list, const char *base_uri)
+{
+	ESourceGroup *group;
+
+	g_return_val_if_fail (E_IS_SOURCE_LIST (list), FALSE);
+	g_return_val_if_fail (base_uri != NULL, FALSE);
+
+	group = e_source_list_peek_group_by_base_uri (list, base_uri);
+	if (group == NULL)
+		return FALSE;
+
+	remove_group (list, group);
+	return TRUE;
+}
+
 gboolean
 e_source_list_remove_source_by_uid (ESourceList *list,
 				     const char *uid)
Index: libedataserver/e-source-list.h
===================================================================
--- libedataserver/e-source-list.h	(revision 10006)
+++ libedataserver/e-source-list.h	(working copy)
@@ -69,11 +69,17 @@ ESourceList *e_source_list_new_for_gconf
 GSList       *e_source_list_peek_groups         (ESourceList *list);
 ESourceGroup *e_source_list_peek_group_by_uid   (ESourceList *list,
 						 const char  *uid);
+#ifndef EDS_DISABLE_DEPRECATED
 ESourceGroup *e_source_list_peek_group_by_name  (ESourceList *list,
 						 const char *name);
+#endif
+ESourceGroup *e_source_list_peek_group_by_base_uri (ESourceList *list, const char *base_uri);
+ESourceGroup *e_source_list_peek_group_by_properties (ESourceList *list, const char *property_name, ...);
+
 ESource      *e_source_list_peek_source_by_uid  (ESourceList *list,
 						 const char  *uid);
 ESource      *e_source_list_peek_source_any     (ESourceList *list);
+
 gboolean  e_source_list_add_group             (ESourceList  *list,
 					       ESourceGroup *group,
 					       int           position);
@@ -81,6 +87,10 @@ gboolean  e_source_list_remove_group    
 					       ESourceGroup *group);
 gboolean  e_source_list_remove_group_by_uid   (ESourceList  *list,
 					       const char   *uid);
+
+ESourceGroup *e_source_list_ensure_group (ESourceList *list, const char *name, const char *base_uri, gboolean ret_it);
+gboolean e_source_list_remove_group_by_base_uri (ESourceList *list, const char *base_uri);
+
 gboolean  e_source_list_remove_source_by_uid  (ESourceList  *list,
 					       const char   *uidj);
 
Index: calendar/ChangeLog
===================================================================
--- calendar/ChangeLog	(revision 10006)
+++ calendar/ChangeLog	(working copy)
@@ -1,3 +1,10 @@
+2009-02-02  Milan Crha  <mcrha@redhat.com>
+
+	** Part of fix for bug #569652
+
+	* backends/caldav/create-account.c: (add_account):
+	Do not use deprecated e_source_list_peek_group_by_name.
+
 2009-01-30  Chenthill Palanisamy  <pchenthill@novell.com>
 
 	Fixes #347287
Index: calendar/backends/caldav/create-account.c
===================================================================
--- calendar/backends/caldav/create-account.c	(revision 10006)
+++ calendar/backends/caldav/create-account.c	(working copy)
@@ -19,7 +19,7 @@ add_account (const char *conf_key, const
 
 	source_list = e_source_list_new_for_gconf (conf_client, conf_key);
 
-	group = e_source_list_peek_group_by_name (source_list, "CalDAV");
+	group = e_source_list_peek_group_by_base_uri (source_list, "caldav://");
 
 	if (group == NULL) {
 		group = e_source_group_new ("CalDAV", "caldav://");
