Index: calendar/libedata-cal/e-cal-backend.c
===================================================================
--- calendar/libedata-cal/e-cal-backend.c	(revision 10140)
+++ calendar/libedata-cal/e-cal-backend.c	(working copy)
@@ -27,6 +27,7 @@
 #include <libxml/xmlmemory.h>
 
 #include "e-cal-backend.h"
+#include "e-cal-backend-cache.h"
 
 
 
@@ -326,6 +327,32 @@ e_cal_backend_get_uri (ECalBackend *back
 }
 
 /**
+ * e_cal_backend_update_uri:
+ * @backend: An #ECalBackend object.
+ *
+ * Updates internal buffer with actual source's URI.
+ */
+void
+e_cal_backend_update_uri (ECalBackend *backend)
+{
+	ECalBackendPrivate *priv;
+	char *suri;
+
+	g_return_if_fail (backend != NULL);
+	g_return_if_fail (E_IS_CAL_BACKEND (backend));
+
+	priv = backend->priv;
+
+	suri = e_source_get_uri (priv->source);
+	if (!priv->uri || (suri && !g_str_equal (priv->uri, suri))) {
+		g_free (priv->uri);
+		priv->uri = suri;
+	} else {
+		g_free (suri);
+	}
+}
+
+/**
  * e_cal_backend_get_kind:
  * @backend: An #ECalBackend object.
  *
@@ -1456,3 +1483,49 @@ e_cal_backend_notify_error (ECalBackend 
 	for (l = priv->clients; l; l = l->next)
 		e_data_cal_notify_error (l->data, message);
 }
+
+/**
+ * e_cal_backend_empty_cache:
+ * @backend: A calendar backend.
+ * @cache: Backend's cache to empty.
+ *
+ * Empties backend's cache with all notifications nad so on, thus all listening
+ * will know there is nothing in this backend.
+ **/
+void
+e_cal_backend_empty_cache (ECalBackend *backend, ECalBackendCache *cache)
+{
+	GList *comps_in_cache;
+
+	g_return_if_fail (backend != NULL);
+	g_return_if_fail (E_IS_CAL_BACKEND (backend));
+
+	if (!cache)
+		return;
+
+	g_return_if_fail (E_IS_CAL_BACKEND_CACHE (cache));
+
+	e_file_cache_freeze_changes (E_FILE_CACHE (cache));
+
+	for (comps_in_cache = e_cal_backend_cache_get_components (cache);
+	     comps_in_cache;
+	     comps_in_cache = comps_in_cache->next) {
+		char *comp_str;
+		ECalComponentId *id;
+		ECalComponent *comp = comps_in_cache->data;
+
+		id = e_cal_component_get_id (comp);
+		comp_str = e_cal_component_get_as_string (comp);
+
+		e_cal_backend_cache_remove_component (cache, id->uid, id->rid);
+		e_cal_backend_notify_object_removed (backend, id, comp_str, NULL);
+
+		g_free (comp_str);
+		e_cal_component_free_id (id);
+		g_object_unref (comp);
+	}
+
+	g_list_free (comps_in_cache);
+
+	e_file_cache_thaw_changes (E_FILE_CACHE (cache));
+}
Index: calendar/libedata-cal/e-cal-backend.h
===================================================================
--- calendar/libedata-cal/e-cal-backend.h	(revision 10140)
+++ calendar/libedata-cal/e-cal-backend.h	(working copy)
@@ -44,8 +44,11 @@ G_BEGIN_DECLS
 #define E_IS_CAL_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_BACKEND))
 #define E_CAL_BACKEND_GET_CLASS(obj) (E_CAL_BACKEND_CLASS (G_OBJECT_GET_CLASS (obj)))
 
+struct _ECalBackendCache;
+
 typedef struct _ECalBackendPrivate ECalBackendPrivate;
 
+
 struct _ECalBackend {
 	GObject object;
 
@@ -116,6 +119,7 @@ GType e_cal_backend_get_type (void);
 
 ESource *e_cal_backend_get_source (ECalBackend *backend);
 const char *e_cal_backend_get_uri (ECalBackend *backend);
+void e_cal_backend_update_uri (ECalBackend *backend);
 icalcomponent_kind e_cal_backend_get_kind (ECalBackend *backend);
 
 void e_cal_backend_add_client (ECalBackend *backend, EDataCal *cal);
@@ -188,6 +192,8 @@ void e_cal_backend_notify_objects_added 
 void e_cal_backend_notify_objects_removed (ECalBackend *backend, EDataCalView *query, const GList *ids);
 void e_cal_backend_notify_objects_modified (ECalBackend *backend, EDataCalView *query, const GList *objects);
 
+void e_cal_backend_empty_cache (ECalBackend *backend, struct _ECalBackendCache *cache);
+
 G_END_DECLS
 
 #endif
Index: calendar/libedata-cal/e-cal-backend-cache.h
===================================================================
--- calendar/libedata-cal/e-cal-backend-cache.h	(revision 10140)
+++ calendar/libedata-cal/e-cal-backend-cache.h	(working copy)
@@ -35,11 +35,12 @@ G_BEGIN_DECLS
 #define E_IS_CAL_BACKEND_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_BACKEND_CACHE))
 
 typedef struct _ECalBackendCachePrivate ECalBackendCachePrivate;
+typedef struct _ECalBackendCache ECalBackendCache;
 
-typedef struct {
+struct _ECalBackendCache {
 	EFileCache parent;
 	ECalBackendCachePrivate *priv;
-} ECalBackendCache;
+};
 
 typedef struct {
 	EFileCacheClass parent_class;
Index: calendar/libedata-cal/e-data-cal-factory.c
===================================================================
--- calendar/libedata-cal/e-data-cal-factory.c	(revision 10140)
+++ calendar/libedata-cal/e-data-cal-factory.c	(working copy)
@@ -103,8 +103,8 @@ backend_last_client_gone_cb (ECalBackend
 	EDataCalFactory *factory;
 	EDataCalFactoryPrivate *priv;
 	ECalBackend *ret_backend;
-	const char *uristr;
-	char *uri;
+	ESource *source;
+	char *uid_type_string;
 	gboolean last_calendar;
 
 	fprintf (stderr, "backend_last_client_gone_cb() called!\n");
@@ -114,18 +114,18 @@ backend_last_client_gone_cb (ECalBackend
 
 	/* Remove the backend from the hash table */
 
-	uristr = e_cal_backend_get_uri (backend);
-	g_assert (uristr != NULL);
-	uri = g_strdup_printf("%s:%d", uristr, (int)e_cal_backend_get_kind(backend));
+	source = e_cal_backend_get_source (backend);
+	g_assert (source != NULL);
+	uid_type_string = g_strdup_printf ("%s:%d", e_source_peek_uid (source), (int)e_cal_backend_get_kind (backend));
 
 	g_mutex_lock (priv->backends_mutex);
 
-	ret_backend = g_hash_table_lookup (factory->priv->backends, uri);
+	ret_backend = g_hash_table_lookup (factory->priv->backends, uid_type_string);
 	g_assert (ret_backend != NULL);
 	g_assert (ret_backend == backend);
 
-	g_hash_table_remove (priv->backends, uri);
-	g_free(uri);
+	g_hash_table_remove (priv->backends, uid_type_string);
+	g_free (uid_type_string);
 
 	g_signal_handlers_disconnect_matched (backend, G_SIGNAL_MATCH_DATA,
 					      0, 0, NULL, NULL, data);
@@ -157,7 +157,7 @@ impl_CalFactory_getCal (PortableServer_S
 	ESource *source;
 	char *str_uri;
 	EUri *uri;
-	char *uri_type_string;
+	char *uid_type_string;
 
 	factory = E_DATA_CAL_FACTORY (bonobo_object_from_servant (servant));
 	priv = factory->priv;
@@ -186,8 +186,8 @@ impl_CalFactory_getCal (PortableServer_S
 		return CORBA_OBJECT_NIL;
 	}
 
-	uri_type_string = g_strdup_printf ("%s:%d", str_uri, (int)calobjtype_to_icalkind (type));
-	g_free(str_uri);
+	g_free (str_uri);
+	uid_type_string = g_strdup_printf ("%s:%d", e_source_peek_uid (source), (int)calobjtype_to_icalkind (type));
 
 	/* Find the associated backend factory (if any) */
 	backend_factory = get_backend_factory (priv->methods, uri->protocol, calobjtype_to_icalkind (type));
@@ -200,7 +200,7 @@ impl_CalFactory_getCal (PortableServer_S
 	g_mutex_lock (priv->backends_mutex);
 
 	/* Look for an existing backend */
-	backend = g_hash_table_lookup (factory->priv->backends, uri_type_string);
+	backend = g_hash_table_lookup (factory->priv->backends, uid_type_string);
 	if (!backend) {
 		/* There was no existing backend, create a new one */
 		if (E_IS_CAL_BACKEND_LOADER_FACTORY (backend_factory)) {
@@ -216,11 +216,22 @@ impl_CalFactory_getCal (PortableServer_S
 		}
 
 		/* Track the backend */
-		g_hash_table_insert (priv->backends, g_strdup (uri_type_string), backend);
+		g_hash_table_insert (priv->backends, g_strdup (uid_type_string), backend);
 
 		g_signal_connect (G_OBJECT (backend), "last_client_gone",
 				  G_CALLBACK (backend_last_client_gone_cb),
 				  factory);
+	} else if (!e_source_equal (source, e_cal_backend_get_source (backend))) {
+		xmlNodePtr xml;
+
+		/* source changed, update it in a backend */
+		xml = xmlNewNode (NULL, (const unsigned char *)"dummy");
+		e_source_dump_to_xml_node (source, xml);
+		e_source_update_from_xml_node (e_cal_backend_get_source (backend), xml->children, NULL);
+		xmlFreeNode (xml);
+
+		/* maybe URI changed too */
+		e_cal_backend_update_uri (backend);
 	}
 
 	/* Create the corba calendar */
@@ -242,7 +253,7 @@ impl_CalFactory_getCal (PortableServer_S
 	   backend_last_client_gone_cb(), for details see bug 506457. */
 	g_mutex_unlock (priv->backends_mutex);
 	e_uri_free (uri);
-	g_free (uri_type_string);
+	g_free (uid_type_string);
 	g_object_unref (source);
 
 	return ret_cal;
Index: calendar/ChangeLog
===================================================================
--- calendar/ChangeLog	(revision 10140)
+++ calendar/ChangeLog	(working copy)
@@ -1,3 +1,18 @@
+2009-03-06  Milan Crha  <mcrha@redhat.com>
+
+	** Part of fix for bug #494394
+
+	* libedata-cal/e-cal-backend-cache.h: (struct _ECalBackendCache):
+	* libedata-cal/e-cal-backend.h: (e_cal_backend_update_uri):
+	* libedata-cal/e-cal-backend.c: (e_cal_backend_empty_cache):
+	Two new API functions.
+	* libedata-cal/e-data-cal-factory.c: (backend_last_client_gone_cb),
+	(impl_CalFactory_getCal): Store list of backends with source's UID,
+	instead of source's URI. Also update source of the backend if changed.
+	* backends/http/e-cal-backend-http.c:(retrieval_done),
+	(begin_retrieval_cb), (e_cal_backend_http_open):
+	Update internal buffer of URI on open and empty cache on error.
+
 2009-03-05  Chenthill Palanisamy  <pchenthill@novell.com>
 
 	Fixes #479908
Index: calendar/backends/http/e-cal-backend-http.c
===================================================================
--- calendar/backends/http/e-cal-backend-http.c	(revision 10140)
+++ calendar/backends/http/e-cal-backend-http.c	(working copy)
@@ -250,6 +250,12 @@ retrieval_done (SoupSession *session, So
 	priv->is_loading = FALSE;
 	d(g_message ("Retrieval done.\n"));
 
+	if (!priv->uri) {
+		/* uri changed meanwhile, retrieve again */
+		begin_retrieval_cb (cbhttp);
+		return;
+	}
+
 	/* Handle redirection ourselves */
 	if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) {
 		newuri = soup_message_headers_get (msg->response_headers,
@@ -278,6 +284,7 @@ retrieval_done (SoupSession *session, So
 			e_cal_backend_notify_error (E_CAL_BACKEND (cbhttp),
 						    soup_status_get_phrase (msg->status_code));
 		}
+		e_cal_backend_empty_cache (E_CAL_BACKEND (cbhttp), priv->cache);
 		return;
 	}
 
@@ -287,6 +294,7 @@ retrieval_done (SoupSession *session, So
 	if (!icalcomp) {
 		if (!priv->opened)
 			e_cal_backend_notify_error (E_CAL_BACKEND (cbhttp), _("Bad file format."));
+		e_cal_backend_empty_cache (E_CAL_BACKEND (cbhttp), priv->cache);
 		return;
 	}
 
@@ -294,6 +302,7 @@ retrieval_done (SoupSession *session, So
 		if (!priv->opened)
 			e_cal_backend_notify_error (E_CAL_BACKEND (cbhttp), _("Not a calendar."));
 		icalcomponent_free (icalcomp);
+		e_cal_backend_empty_cache (E_CAL_BACKEND (cbhttp), priv->cache);
 		return;
 	}
 
@@ -414,7 +423,7 @@ begin_retrieval_cb (ECalBackendHttp *cbh
 	priv = cbhttp->priv;
 
 	if (priv->mode != CAL_MODE_REMOTE)
-		return TRUE;
+		return FALSE;
 
 	maybe_start_reload_timeout (cbhttp);
 
@@ -459,6 +468,7 @@ begin_retrieval_cb (ECalBackendHttp *cbh
 	soup_message = soup_message_new (SOUP_METHOD_GET, priv->uri);
 	if (soup_message == NULL) {
 		priv->is_loading = FALSE;
+		e_cal_backend_empty_cache (E_CAL_BACKEND (cbhttp), priv->cache);
 		return FALSE;
 	}
 
@@ -525,11 +535,17 @@ e_cal_backend_http_open (ECalBackendSync
 	ECalBackendHttp *cbhttp;
 	ECalBackendHttpPrivate *priv;
 	ESource *source;
+	char *tmp;
 
 	cbhttp = E_CAL_BACKEND_HTTP (backend);
 	priv = cbhttp->priv;
 	source = e_cal_backend_get_source (E_CAL_BACKEND (backend));
 
+	/* always read uri again */
+	tmp = priv->uri;
+	priv->uri = NULL;
+	g_free (tmp);
+
 	if (e_source_get_property (source, "auth") != NULL) {
 		if ((username == NULL || password == NULL)) {
 			return GNOME_Evolution_Calendar_AuthenticationRequired;
@@ -565,13 +581,12 @@ e_cal_backend_http_open (ECalBackendSync
 		if (priv->default_zone) {
 			e_cal_backend_cache_put_default_timezone (priv->cache, priv->default_zone);
 		}
+	}
 
-		if (priv->mode == CAL_MODE_LOCAL)
-			return GNOME_Evolution_Calendar_Success;
-
+	if (priv->mode == CAL_MODE_LOCAL)
+		return GNOME_Evolution_Calendar_Success;
 
-		g_idle_add ((GSourceFunc) begin_retrieval_cb, cbhttp);
-	}
+	g_idle_add ((GSourceFunc) begin_retrieval_cb, cbhttp);
 
 	return GNOME_Evolution_Calendar_Success;
 }
