commit 5a399e1fb1ee2ed788b015c6504ba471e785b407
Author: Matthew Barnes <mbarnes@redhat.com>
Date:   Thu Apr 26 00:23:35 2012 -0400

    Adapt to Evolution-Data-Server API changes.

diff --git a/applets/clock/calendar-client.c b/applets/clock/calendar-client.c
index bbdb473..4065f5a 100644
--- a/applets/clock/calendar-client.c
+++ b/applets/clock/calendar-client.c
@@ -30,18 +30,13 @@
 #include <libintl.h>
 #include <string.h>
 #define HANDLE_LIBICAL_MEMORY
-#include <libecal/e-cal.h>
-#include <libecal/e-cal-time-util.h>
-#include <libecal/e-cal-recur.h>
+#include <libecal/libecal.h>
 
 #include "calendar-sources.h"
 
 #undef CALENDAR_ENABLE_DEBUG
 #include "calendar-debug.h"
 
-#define CALENDAR_CONFIG_PREFIX   "/apps/evolution/calendar"
-#define CALENDAR_CONFIG_TIMEZONE CALENDAR_CONFIG_PREFIX "/display/timezone"
-
 #ifndef _
 #define _(x) gettext(x)
 #endif
@@ -85,7 +80,7 @@ struct _CalendarClientPrivate
   icaltimezone        *zone;
 
   guint                zone_listener;
-  GConfClient         *gconf_client;
+  GSettings           *calendar_settings;
 
   guint                day;
   guint                month;
@@ -106,7 +101,7 @@ static void calendar_client_get_property (GObject             *object,
 
 static GSList *calendar_client_update_sources_list         (CalendarClient       *client,
 							    GSList               *sources,
-							    GSList               *esources,
+							    GList                *esources,
 							    guint                 changed_signal_id);
 static void    calendar_client_appointment_sources_changed (CalendarClient       *client);
 static void    calendar_client_task_sources_changed        (CalendarClient       *client);
@@ -236,24 +231,18 @@ calendar_client_class_init (CalendarClientClass *klass)
 /* The current timezone, e.g. "Europe/London". It may be NULL, in which case
    you should assume UTC. */
 static gchar *
-calendar_client_config_get_timezone (GConfClient *gconf_client)
+calendar_client_config_get_timezone (GSettings *calendar_settings)
 {
-  char *location;
-
-  location = gconf_client_get_string (gconf_client,
-                                      CALENDAR_CONFIG_TIMEZONE,
-                                      NULL);
-
-  return location;
+  return g_settings_get_string (calendar_settings, "timezone");
 }
 
 static icaltimezone *
-calendar_client_config_get_icaltimezone (GConfClient *gconf_client)
+calendar_client_config_get_icaltimezone (GSettings *calendar_settings)
 {
   char         *location;
   icaltimezone *zone = NULL;
 	
-  location = calendar_client_config_get_timezone (gconf_client);
+  location = calendar_client_config_get_timezone (calendar_settings);
   if (!location)
     return icaltimezone_get_utc_timezone ();
 
@@ -266,23 +255,23 @@ calendar_client_config_get_icaltimezone (GConfClient *gconf_client)
 static void
 calendar_client_set_timezone (CalendarClient *client) 
 {
-  GSList *l;
-  GSList *esources;
+  GList *list, *link;
 
-  client->priv->zone = calendar_client_config_get_icaltimezone (client->priv->gconf_client);
+  client->priv->zone = calendar_client_config_get_icaltimezone (client->priv->calendar_settings);
 
-  esources = calendar_sources_get_appointment_sources (client->priv->calendar_sources);
-  for (l = esources; l; l = l->next) {
-    ECal *source = l->data;
-			
-    e_cal_set_default_timezone (source, client->priv->zone, NULL);
-  }
+  list = calendar_sources_get_appointment_clients (client->priv->calendar_sources);
+  for (link = list; link != NULL; link = g_list_next (link))
+    {
+      ECal *cal = E_CAL (link->data);
+
+      e_cal_set_default_timezone (cal, client->priv->zone, NULL);
+    }
+  g_list_free (list);
 }
 
 static void
-calendar_client_timezone_changed_cb (GConfClient    *gconf_client,
-                                     guint           id,
-                                     GConfEntry     *entry,
+calendar_client_timezone_changed_cb (GSettings      *calendar_settings,
+                                     const gchar    *key,
                                      CalendarClient *client)
 {
   calendar_client_set_timezone (client);
@@ -365,20 +354,22 @@ load_calendars (CalendarClient    *client,
 static void
 calendar_client_init (CalendarClient *client)
 {
-  GSList *esources;
+  GList *list;
 
   client->priv = CALENDAR_CLIENT_GET_PRIVATE (client);
 
   client->priv->calendar_sources = calendar_sources_get ();
-  client->priv->gconf_client = gconf_client_get_default ();
+  client->priv->calendar_settings = g_settings_new ("org.gnome.evolution.calendar");
 
-  esources = calendar_sources_get_appointment_sources (client->priv->calendar_sources);
+  list = calendar_sources_get_appointment_clients (client->priv->calendar_sources);
   client->priv->appointment_sources =
-    calendar_client_update_sources_list (client, NULL, esources, signals [APPOINTMENTS_CHANGED]);
+    calendar_client_update_sources_list (client, NULL, list, signals [APPOINTMENTS_CHANGED]);
+  g_list_free (list);
 
-  esources = calendar_sources_get_task_sources (client->priv->calendar_sources);
+  list = calendar_sources_get_task_clients (client->priv->calendar_sources);
   client->priv->task_sources =
-    calendar_client_update_sources_list (client, NULL, esources, signals [TASKS_CHANGED]);
+    calendar_client_update_sources_list (client, NULL, list, signals [TASKS_CHANGED]);
+  g_list_free (list);
  
   /* set the timezone before loading the clients */ 
   calendar_client_set_timezone (client);
@@ -394,15 +385,10 @@ calendar_client_init (CalendarClient *client)
 			    G_CALLBACK (calendar_client_task_sources_changed),
 			    client);
 
-  gconf_client_add_dir (client->priv->gconf_client,
-			CALENDAR_CONFIG_PREFIX,
-			GCONF_CLIENT_PRELOAD_NONE,
-			NULL);
-
-  client->priv->zone_listener = gconf_client_notify_add (client->priv->gconf_client,
-                                                         CALENDAR_CONFIG_TIMEZONE,
-                                                         (GConfClientNotifyFunc) calendar_client_timezone_changed_cb,
-                                                         client, NULL, NULL);
+  client->priv->zone_listener = g_signal_connect (client->priv->calendar_settings,
+                                                  "changed::timezone",
+                                                  G_CALLBACK (calendar_client_timezone_changed_cb),
+                                                  client);
 
   client->priv->day   = -1;
   client->priv->month = -1;
@@ -417,18 +403,14 @@ calendar_client_finalize (GObject *object)
 
   if (client->priv->zone_listener)
     {
-      gconf_client_notify_remove (client->priv->gconf_client,
-                                  client->priv->zone_listener);
+      g_signal_handler_disconnect (client->priv->calendar_settings,
+                                   client->priv->zone_listener);
       client->priv->zone_listener = 0;
     }
 
-  gconf_client_remove_dir (client->priv->gconf_client,
-                           CALENDAR_CONFIG_PREFIX,
-                           NULL);
-
-  if (client->priv->gconf_client)
-    g_object_unref (client->priv->gconf_client);
-  client->priv->gconf_client = NULL;
+  if (client->priv->calendar_settings)
+    g_object_unref (client->priv->calendar_settings);
+  client->priv->calendar_settings = NULL;
 
   for (l = client->priv->appointment_sources; l; l = l->next)
     {
@@ -737,37 +719,60 @@ static char *
 get_source_color (ECal *esource)
 {
   ESource *source;
+  ECalSourceType source_type;
+  ESourceSelectable *extension;
+  const gchar *extension_name;
 
   g_return_val_if_fail (E_IS_CAL (esource), NULL);
 
   source = e_cal_get_source (esource);
+  source_type = e_cal_get_source_type (esource);
+
+  switch (source_type)
+    {
+      case E_CAL_SOURCE_TYPE_EVENT:
+        extension_name = E_SOURCE_EXTENSION_CALENDAR;
+        break;
+      case E_CAL_SOURCE_TYPE_TODO:
+        extension_name = E_SOURCE_EXTENSION_TASK_LIST;
+        break;
+      default:
+        g_return_val_if_reached (NULL);
+    }
+
+  extension = e_source_get_extension (source, extension_name);
 
-  return g_strdup (e_source_peek_color_spec (source));
+  return e_source_selectable_dup_color (extension);
 }
 
 static gchar *
-get_source_uri (ECal *esource)
+get_source_backend_name (ECal *esource)
 {
-    ESource *source;
-    gchar   *string;
-    gchar  **list;
+  ESource *source;
+  ECalSourceType source_type;
+  ESourceBackend *extension;
+  const gchar *extension_name;
 
-    g_return_val_if_fail (E_IS_CAL (esource), NULL);
+  g_return_val_if_fail (E_IS_CAL (esource), NULL);
 
-    source = e_cal_get_source (esource);
-    string = g_strdup (e_source_get_uri (source));
-    if (string) {
-        list = g_strsplit (string, ":", 2);
-        g_free (string);
+  source = e_cal_get_source (esource);
+  source_type = e_cal_get_source_type (esource);
 
-        if (list[0]) {
-            string = g_strdup (list[0]);
-            g_strfreev (list);
-            return string;
-        }
-	g_strfreev (list);
+  switch (source_type)
+    {
+      case E_CAL_SOURCE_TYPE_EVENT:
+        extension_name = E_SOURCE_EXTENSION_CALENDAR;
+        break;
+      case E_CAL_SOURCE_TYPE_TODO:
+        extension_name = E_SOURCE_EXTENSION_TASK_LIST;
+        break;
+      default:
+        g_return_val_if_reached (NULL);
     }
-    return NULL;
+
+  extension = e_source_get_extension (source, extension_name);
+
+  return e_source_backend_dup_backend_name (extension);
 }
 
 static inline int
@@ -798,7 +803,7 @@ calendar_appointment_equal (CalendarAppointment *a,
 
   return
     null_safe_strcmp (a->uid,          b->uid)          == 0 &&
-    null_safe_strcmp (a->uri,          b->uri)          == 0 &&
+    null_safe_strcmp (a->backend_name, b->backend_name) == 0 &&
     null_safe_strcmp (a->summary,      b->summary)      == 0 &&
     null_safe_strcmp (a->description,  b->description)  == 0 &&
     null_safe_strcmp (a->color_string, b->color_string) == 0 &&
@@ -830,7 +835,7 @@ calendar_appointment_copy (CalendarAppointment *appointment,
     }
 
   appointment_copy->uid          = g_strdup (appointment->uid);
-  appointment_copy->uri          = g_strdup (appointment->uri);
+  appointment_copy->backend_name = g_strdup (appointment->backend_name);
   appointment_copy->summary      = g_strdup (appointment->summary);
   appointment_copy->description  = g_strdup (appointment->description);
   appointment_copy->color_string = g_strdup (appointment->color_string);
@@ -855,8 +860,8 @@ calendar_appointment_finalize (CalendarAppointment *appointment)
   g_free (appointment->rid);
   appointment->rid = NULL;
 
-  g_free (appointment->uri);
-  appointment->uri = NULL;
+  g_free (appointment->backend_name);
+  appointment->backend_name = NULL;
 
   g_free (appointment->summary);
   appointment->summary = NULL;
@@ -879,7 +884,7 @@ calendar_appointment_init (CalendarAppointment  *appointment,
 {
   appointment->uid          = get_ical_uid (ical);
   appointment->rid          = get_ical_rid (ical);
-  appointment->uri          = get_source_uri (source->source);
+  appointment->backend_name = get_source_backend_name (source->source);
   appointment->summary      = get_ical_summary (ical);
   appointment->description  = get_ical_description (ical);
   appointment->color_string = get_source_color (source->source);
@@ -1686,19 +1691,20 @@ compare_calendar_sources (CalendarClientSource *s1,
 static GSList *
 calendar_client_update_sources_list (CalendarClient *client,
 				     GSList         *sources,
-				     GSList         *esources,
+				     GList          *esources,
 				     guint           changed_signal_id)
 {
+  GList *link;
   GSList *retval, *l;
 
   retval = NULL;
 
-  for (l = esources; l; l = l->next)
+  for (link = esources; link != NULL; link = g_list_next (link->next))
     {
       CalendarClientSource  dummy_source;
       CalendarClientSource *new_source;
       GSList               *s;
-      ECal                 *esource = l->data;
+      ECal                 *esource = link->data;
 
       dummy_source.source = esource;
 
@@ -1743,39 +1749,43 @@ calendar_client_update_sources_list (CalendarClient *client,
 static void
 calendar_client_appointment_sources_changed (CalendarClient  *client)
 {
-  GSList *esources;
+  GList *list;
 
   dprintf ("appointment_sources_changed: updating ...\n");
 
-  esources = calendar_sources_get_appointment_sources (client->priv->calendar_sources);
+  list = calendar_sources_get_appointment_clients (client->priv->calendar_sources);
 
   client->priv->appointment_sources = 
     calendar_client_update_sources_list (client,
 					 client->priv->appointment_sources,
-					 esources,
+					 list,
 					 signals [APPOINTMENTS_CHANGED]);
 
   load_calendars (client, CALENDAR_EVENT_APPOINTMENT);
   calendar_client_update_appointments (client);
+
+  g_list_free (list);
 }
 
 static void
 calendar_client_task_sources_changed (CalendarClient  *client)
 {
-  GSList *esources;
+  GList *list;
 
   dprintf ("task_sources_changed: updating ...\n");
 
-  esources = calendar_sources_get_task_sources (client->priv->calendar_sources);
+  list = calendar_sources_get_task_clients (client->priv->calendar_sources);
 
   client->priv->task_sources = 
     calendar_client_update_sources_list (client,
 					 client->priv->task_sources,
-					 esources,
+					 list,
 					 signals [TASKS_CHANGED]);
 
   load_calendars (client, CALENDAR_EVENT_TASK);
   calendar_client_update_tasks (client);
+
+  g_list_free (list);
 }
 
 void
diff --git a/applets/clock/calendar-client.h b/applets/clock/calendar-client.h
index 3ae3b2f..f45e712 100644
--- a/applets/clock/calendar-client.h
+++ b/applets/clock/calendar-client.h
@@ -73,7 +73,7 @@ typedef struct
 {
   char   *uid;
   char   *rid;
-  char   *uri;
+  char   *backend_name;
   char   *summary;
   char   *description;
   char   *color_string;
diff --git a/applets/clock/calendar-sources.c b/applets/clock/calendar-sources.c
index fa1fcac..718d1dc 100644
--- a/applets/clock/calendar-sources.c
+++ b/applets/clock/calendar-sources.c
@@ -29,11 +29,8 @@
 
 #include <libintl.h>
 #include <string.h>
-#include <gconf/gconf-client.h>
 #define HANDLE_LIBICAL_MEMORY
-#include <libecal/e-cal.h>
-#include <libedataserver/e-source-list.h>
-#include <libedataserverui/e-passwords.h>
+#include <libecal/libecal.h>
 
 #undef CALENDAR_ENABLE_DEBUG
 #include "calendar-debug.h"
@@ -48,28 +45,23 @@
 
 #define CALENDAR_SOURCES_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CALENDAR_TYPE_SOURCES, CalendarSourcesPrivate))
 
-#define CALENDAR_SOURCES_EVO_DIR                          "/apps/evolution"
-#define CALENDAR_SOURCES_APPOINTMENT_SOURCES_KEY          CALENDAR_SOURCES_EVO_DIR "/calendar/sources"
-#define CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR CALENDAR_SOURCES_EVO_DIR "/calendar/display"
-#define CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_KEY CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR "/selected_calendars"
-#define CALENDAR_SOURCES_TASK_SOURCES_KEY                 CALENDAR_SOURCES_EVO_DIR "/tasks/sources"
-#define CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR        CALENDAR_SOURCES_EVO_DIR "/calendar/tasks"
-#define CALENDAR_SOURCES_SELECTED_TASK_SOURCES_KEY        CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR "/selected_tasks"
-
+typedef struct _ClientData ClientData;
 typedef struct _CalendarSourceData CalendarSourceData;
 
+struct _ClientData
+{
+  ECal *client;
+  gulong backend_died_id;
+};
+
 struct _CalendarSourceData
 {
   ECalSourceType   source_type;
   CalendarSources *sources;
   guint            changed_signal;
 
-  GSList          *clients;
-  GSList          *selected_sources;
-  ESourceList     *esource_list;
-
-  guint            selected_sources_listener;
-  char            *selected_sources_dir;
+  /* ESource -> EClient */
+  GHashTable      *clients;
 
   guint            timeout_id;
 
@@ -78,10 +70,13 @@ struct _CalendarSourceData
 
 struct _CalendarSourcesPrivate
 {
+  ESourceRegistry    *registry;
+  gulong              source_added_id;
+  gulong              source_changed_id;
+  gulong              source_removed_id;
+
   CalendarSourceData  appointment_sources;
   CalendarSourceData  task_sources;
-
-  GConfClient        *gconf_client;
 };
 
 static void calendar_sources_class_init (CalendarSourcesClass *klass);
@@ -89,8 +84,12 @@ static void calendar_sources_init       (CalendarSources      *sources);
 static void calendar_sources_finalize   (GObject             *object);
 
 static void backend_died_cb (ECal *client, CalendarSourceData *source_data);
-static void calendar_sources_esource_list_changed (ESourceList        *source_list,
-                                                   CalendarSourceData *source_data);
+static void calendar_sources_registry_source_changed_cb (ESourceRegistry *registry,
+                                                         ESource         *source,
+                                                         CalendarSources *sources);
+static void calendar_sources_registry_source_removed_cb (ESourceRegistry *registry,
+                                                         ESource         *source,
+                                                         CalendarSources *sources);
 
 enum
 {
@@ -103,6 +102,14 @@ static guint signals [LAST_SIGNAL] = { 0, };
 static GObjectClass    *parent_class = NULL;
 static CalendarSources *calendar_sources_singleton = NULL;
 
+static void
+client_data_free (ClientData *data)
+{
+  g_signal_handler_disconnect (data->client, data->backend_died_id);
+  g_object_unref (data->client);
+  g_slice_free (ClientData, data);
+}
+
 GType
 calendar_sources_get_type (void)
 {
@@ -170,19 +177,49 @@ calendar_sources_class_init (CalendarSourcesClass *klass)
 static void
 calendar_sources_init (CalendarSources *sources)
 {
+  GError *error = NULL;
+
   sources->priv = CALENDAR_SOURCES_GET_PRIVATE (sources);
 
+  /* XXX Not sure what to do if this fails.
+   *     Should this class implement GInitable or pass the
+   *     registry in as a G_PARAM_CONSTRUCT_ONLY property? */
+  sources->priv->registry = e_source_registry_new_sync (NULL, &error);
+  if (error != NULL) {
+    g_critical ("%s: %s", G_STRFUNC, error->message);
+    g_error_free (error);
+  }
+
+  sources->priv->source_added_id   = g_signal_connect (sources->priv->registry,
+                                                       "source-added",
+                                                       G_CALLBACK (calendar_sources_registry_source_changed_cb),
+                                                       sources);
+  sources->priv->source_changed_id = g_signal_connect (sources->priv->registry,
+                                                       "source-changed",
+                                                       G_CALLBACK (calendar_sources_registry_source_changed_cb),
+                                                       sources);
+  sources->priv->source_removed_id = g_signal_connect (sources->priv->registry,
+                                                       "source-removed",
+                                                       G_CALLBACK (calendar_sources_registry_source_removed_cb),
+                                                       sources);
+
   sources->priv->appointment_sources.source_type    = E_CAL_SOURCE_TYPE_EVENT;
   sources->priv->appointment_sources.sources        = sources;
   sources->priv->appointment_sources.changed_signal = signals [APPOINTMENT_SOURCES_CHANGED];
+  sources->priv->appointment_sources.clients        = g_hash_table_new_full ((GHashFunc) e_source_hash,
+                                                                             (GEqualFunc) e_source_equal,
+                                                                             (GDestroyNotify) g_object_unref,
+                                                                             (GDestroyNotify) client_data_free);
   sources->priv->appointment_sources.timeout_id     = 0;
 
   sources->priv->task_sources.source_type    = E_CAL_SOURCE_TYPE_TODO;
   sources->priv->task_sources.sources        = sources;
   sources->priv->task_sources.changed_signal = signals [TASK_SOURCES_CHANGED];
+  sources->priv->task_sources.clients        = g_hash_table_new_full ((GHashFunc) e_source_hash,
+                                                                      (GEqualFunc) e_source_equal,
+                                                                      (GDestroyNotify) g_object_unref,
+                                                                      (GDestroyNotify) client_data_free);
   sources->priv->task_sources.timeout_id     = 0;
-
-  sources->priv->gconf_client = gconf_client_get_default ();
 }
 
 static void
@@ -191,49 +228,9 @@ calendar_sources_finalize_source_data (CalendarSources    *sources,
 {
   if (source_data->loaded)
     {
-      GSList *l;
-
-      if (source_data->selected_sources_dir)
-	{
-	  gconf_client_remove_dir (sources->priv->gconf_client,
-				   source_data->selected_sources_dir,
-				   NULL);
-
-	  g_free (source_data->selected_sources_dir);
-	  source_data->selected_sources_dir = NULL;
-	}
-
-      if (source_data->selected_sources_listener)
-	{
-	  gconf_client_notify_remove (sources->priv->gconf_client,
-				      source_data->selected_sources_listener);
-	  source_data->selected_sources_listener = 0;
-	}
-
-      for (l = source_data->clients; l; l = l->next)
-        {
-          g_signal_handlers_disconnect_by_func (G_OBJECT (l->data),
-                                                G_CALLBACK (backend_died_cb),
-                                                source_data);
-          g_object_unref (l->data);
-        }
-      g_slist_free (source_data->clients);
+      g_hash_table_destroy (source_data->clients);
       source_data->clients = NULL;
 
-      if (source_data->esource_list)
-        {
-          g_signal_handlers_disconnect_by_func (source_data->esource_list,
-                                                G_CALLBACK (calendar_sources_esource_list_changed),
-                                                source_data);
-          g_object_unref (source_data->esource_list);
-	}
-      source_data->esource_list = NULL;
-
-      for (l = source_data->selected_sources; l; l = l->next)
-	g_free (l->data);
-      g_slist_free (source_data->selected_sources);
-      source_data->selected_sources = NULL;
-
       if (source_data->timeout_id != 0)
         {
           g_source_remove (source_data->timeout_id);
@@ -249,13 +246,21 @@ calendar_sources_finalize (GObject *object)
 {
   CalendarSources *sources = CALENDAR_SOURCES (object);
 
+  if (sources->priv->registry)
+    {
+      g_signal_handler_disconnect (sources->priv->registry,
+                                   sources->priv->source_added_id);
+      g_signal_handler_disconnect (sources->priv->registry,
+                                   sources->priv->source_changed_id);
+      g_signal_handler_disconnect (sources->priv->registry,
+                                   sources->priv->source_removed_id);
+      g_object_unref (sources->priv->registry);
+    }
+  sources->priv->registry = NULL;
+
   calendar_sources_finalize_source_data (sources, &sources->priv->appointment_sources);
   calendar_sources_finalize_source_data (sources, &sources->priv->task_sources);
 
-  if (sources->priv->gconf_client)
-    g_object_unref (sources->priv->gconf_client);
-  sources->priv->gconf_client = NULL;
-
   if (G_OBJECT_CLASS (parent_class)->finalize)
     G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -275,150 +280,68 @@ calendar_sources_get (void)
   return calendar_sources_singleton;
 }
 
-static gboolean
-is_source_selected (ESource *esource,
-		    GSList  *selected_sources)
-{
-  const char *uid;
-  GSList     *l;
-
-  uid = e_source_peek_uid (esource);
-
-  for (l = selected_sources; l; l = l->next)
-    {
-      const char *source = l->data;
-
-      if (!strcmp (source, uid))
-	return TRUE;
-    }
-
-  return FALSE;
-}
-
-static char *
-auth_func_cb (ECal       *ecal,
-	      const char *prompt,
-	      const char *key,
-	      gpointer    user_data)
-{
-	ESource *source;
-	const gchar *auth_domain;
-	const gchar *component_name;
-
-	source = e_cal_get_source (ecal);
-	auth_domain = e_source_get_property (source, "auth-domain");
-	component_name = auth_domain ? auth_domain : "Calendar";
-
-	return e_passwords_get_password (component_name, key);
-}
-
 /* The clients are just created here but not loaded */
-static ECal *
-get_ecal_from_source (ESource        *esource,
-		      ECalSourceType  source_type,
-		      GSList         *existing_clients)
-{
-  ECal *retval;
-
-  if (existing_clients)
-    {
-      GSList *l;
-
-      for (l = existing_clients; l; l = l->next)
-	{
-	  ECal *client = E_CAL (l->data);
-
-	  if (e_source_equal (esource, e_cal_get_source (client)))
-	    {
-	      dprintf ("        load_esource: found existing source ... returning that\n");
-
-	      return g_object_ref (client);
-	    }
-	}
-    }
-
-  retval = e_cal_new (esource, source_type);
-  if (!retval)
-    {
-      g_warning ("Could not load source '%s' from '%s'\n",
-		 e_source_peek_name (esource),
-		 e_source_peek_relative_uri (esource));
-      return NULL;
-    }
-
-  e_cal_set_auth_func (retval, auth_func_cb, NULL);
-
-  return retval;
-}
-
-/* - Order doesn't matter
- * - Can just compare object pointers since we
- *   re-use client connections
- */
-static gboolean
-compare_ecal_lists (GSList *a,
-		    GSList *b)
+static void
+create_client_for_source (ESource            *source,
+		          ECalSourceType      source_type,
+		          CalendarSourceData *source_data)
 {
-  GSList *l;
+  ClientData *data;
+  ECal *client;
 
-  if (g_slist_length (a) != g_slist_length (b))
-    return FALSE;
+  client = g_hash_table_lookup (source_data->clients, source);
+  g_return_if_fail (client == NULL);
 
-  for (l = a; l; l = l->next)
+  client = e_cal_new (source, source_type);
+  if (!client)
     {
-      if (!g_slist_find (b, l->data))
-	return FALSE;
+      g_warning ("Could not load source '%s'\n",
+		 e_source_get_uid (source));
+      return;
     }
 
-  return TRUE;
-}
-
-static inline void
-debug_dump_selected_sources (GSList *selected_sources)
-{
-#ifdef CALENDAR_ENABLE_DEBUG
-  GSList *l;
-
-  dprintf ("Selected sources:\n");
-  for (l = selected_sources; l; l = l->next)
-    {
-      char *source = l->data;
+  data = g_slice_new0 (ClientData);
+  data->client = client;  /* takes ownership */
+  data->backend_died_id = g_signal_connect (client,
+                                            "backend-died",
+                                            G_CALLBACK (backend_died_cb),
+                                            source_data);
 
-      dprintf ("  %s\n", source);
-    }
-  dprintf ("\n");
-#endif
+  g_hash_table_insert (source_data->clients, g_object_ref (source), data);
 }
 
 static inline void
-debug_dump_ecal_list (GSList *ecal_list)
+debug_dump_ecal_list (GHashTable *clients)
 {
 #ifdef CALENDAR_ENABLE_DEBUG
-  GSList *l;
+  GList *list, *link;
 
   dprintf ("Loaded clients:\n");
-  for (l = ecal_list; l; l = l->next)
+  list = g_hash_table_get_keys (clients);
+  for (link = list; link != NULL; link = g_list_next (link))
     {
-      ECal    *client = l->data;
-      ESource *source = e_cal_get_source (client);
+      ESource *source = E_SOURCE (link->data);
 
-      dprintf ("  %s %s %s\n",
-	       e_source_peek_uid (source),
-	       e_source_peek_name (source),
-	       e_cal_get_uri (client));
+      dprintf ("  %s %s\n",
+	       e_source_get_uid (source),
+	       e_source_get_display_name (source));
     }
 #endif
 }
 
 static void
-calendar_sources_load_esource_list (CalendarSourceData *source_data);
+calendar_sources_load_esource_list (ESourceRegistry *registry,
+                                    CalendarSourceData *source_data);
 
 static gboolean
 backend_restart (gpointer data)
 {
   CalendarSourceData *source_data = data;
+  ESourceRegistry *registry;
 
-  calendar_sources_load_esource_list (source_data);
+  registry = source_data->sources->priv->registry;
+  calendar_sources_load_esource_list (registry, source_data);
+  g_signal_emit (source_data->sources, source_data->changed_signal, 0);
 
   source_data->timeout_id = 0;
     
@@ -428,16 +351,13 @@ backend_restart (gpointer data)
 static void
 backend_died_cb (ECal *client, CalendarSourceData *source_data)
 {
-  const char *uristr;
+  ESource *source;
+  const char *display_name;
 
-  source_data->clients = g_slist_remove (source_data->clients, client);
-  if (g_slist_length (source_data->clients) < 1) 
-    {
-      g_slist_free (source_data->clients);
-      source_data->clients = NULL;
-    }
-  uristr = e_cal_get_uri (client);
-  g_warning ("The calendar backend for %s has crashed.", uristr);
+  source = e_cal_get_source (client);
+  display_name = e_source_get_display_name (source);
+  g_warning ("The calendar backend for '%s' has crashed.", display_name);
+  g_hash_table_remove (source_data->clients, source);
 
   if (source_data->timeout_id != 0)
     {
@@ -450,209 +370,162 @@ backend_died_cb (ECal *client, CalendarSourceData *source_data)
 }
 
 static void
-calendar_sources_load_esource_list (CalendarSourceData *source_data)
+calendar_sources_load_esource_list (ESourceRegistry *registry,
+                                    CalendarSourceData *source_data)
 {
-  GSList  *clients = NULL;
-  GSList  *groups, *l;
-  gboolean emit_signal = FALSE;
-
-  g_return_if_fail (source_data->esource_list != NULL);
+  GList *list, *link;
+  const gchar *extension_name;
 
-  debug_dump_selected_sources (source_data->selected_sources);
-
-  dprintf ("Source groups:\n");
-  groups = e_source_list_peek_groups (source_data->esource_list);
-  for (l = groups; l; l = l->next)
+  switch (source_data->source_type)
     {
-      GSList *esources, *s;
-
-      dprintf ("  %s\n", e_source_group_peek_uid (l->data));
-      dprintf ("    sources:\n");
-
-      esources = e_source_group_peek_sources (l->data);
-      for (s = esources; s; s = s->next)
-	{
-	  ESource *esource = E_SOURCE (s->data);
-	  ECal    *client;
-
-	  dprintf ("      type = '%s' uid = '%s', name = '%s', relative uri = '%s': \n",
-                   source_data->source_type == E_CAL_SOURCE_TYPE_EVENT ? "appointment" : "task",
-		   e_source_peek_uid (esource),
-		   e_source_peek_name (esource),
-		   e_source_peek_relative_uri (esource));
-
-	  if (is_source_selected (esource, source_data->selected_sources) &&
-	      (client = get_ecal_from_source (esource, source_data->source_type, source_data->clients)))
-	    {
-	      clients = g_slist_prepend (clients, client);
-	    }
-	}
+      case E_CAL_SOURCE_TYPE_EVENT:
+        extension_name = E_SOURCE_EXTENSION_CALENDAR;
+        break;
+      case E_CAL_SOURCE_TYPE_TODO:
+        extension_name = E_SOURCE_EXTENSION_TASK_LIST;
+        break;
+      default:
+        g_return_if_reached ();
     }
-  dprintf ("\n");
 
-  if (source_data->loaded && 
-      !compare_ecal_lists (source_data->clients, clients))
-    emit_signal = TRUE;
+  list = e_source_registry_list_sources (registry, extension_name);
 
-  for (l = source_data->clients; l; l = l->next)
+  for (link = list; link != NULL; link = g_list_next (link))
     {
-      g_signal_handlers_disconnect_by_func (G_OBJECT (l->data),
-                                            G_CALLBACK (backend_died_cb),
-                                            source_data);
+      ESource *source = E_SOURCE (link->data);
+      ESourceSelectable *extension;
+      gboolean show_source;
 
-      g_object_unref (l->data);
-    }
-  g_slist_free (source_data->clients);
-  source_data->clients = g_slist_reverse (clients);
-
-  /* connect to backend_died after we disconnected the previous signal
-   * handlers. If we do it before, we'll lose some handlers (for clients that
-   * were already there before) */
-  for (l = source_data->clients; l; l = l->next)
-    {
-      g_signal_connect (G_OBJECT (l->data), "backend_died",
-                        G_CALLBACK (backend_died_cb), source_data);
-    }
+      extension = e_source_get_extension (source, extension_name);
+      show_source = e_source_get_enabled (source) && e_source_selectable_get_selected (extension);
 
-  if (emit_signal) 
-    {
-      dprintf ("Emitting %s-sources-changed signal\n",
-	       source_data->source_type == E_CAL_SOURCE_TYPE_EVENT ? "appointment" : "task");
-      g_signal_emit (source_data->sources, source_data->changed_signal, 0);
+      if (show_source)
+        create_client_for_source (source, source_data->source_type, source_data);
     }
 
   debug_dump_ecal_list (source_data->clients);
-}
 
-static void
-calendar_sources_esource_list_changed (ESourceList        *source_list,
-				       CalendarSourceData *source_data)
-				       
-{
-  dprintf ("ESourceList changed, reloading\n");
-
-  calendar_sources_load_esource_list (source_data);
+  g_list_free_full (list, g_object_unref);
 }
 
 static void
-calendar_sources_selected_sources_notify (GConfClient        *client,
-					  guint               cnx_id,
-					  GConfEntry         *entry,
-					  CalendarSourceData *source_data)
+calendar_sources_registry_source_changed_cb (ESourceRegistry *registry,
+                                             ESource         *source,
+                                             CalendarSources *sources)
 {
-  GSList *l;
-
-  if (!entry->value ||
-      entry->value->type != GCONF_VALUE_LIST ||
-      gconf_value_get_list_type (entry->value) != GCONF_VALUE_STRING)
-    return;
+  if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR))
+    {
+      CalendarSourceData *source_data;
+      ESourceSelectable *extension;
+      gboolean have_client;
+      gboolean show_source;
 
-  dprintf ("Selected sources key (%s) changed, reloading\n", entry->key);
+      source_data = &sources->priv->appointment_sources;
+      extension = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
+      have_client = (g_hash_table_lookup (source_data->clients, source) != NULL);
+      show_source = e_source_get_enabled (source) && e_source_selectable_get_selected (extension);
 
-  for (l = source_data->selected_sources; l; l = l->next)
-    g_free (l->data);
-  source_data->selected_sources = NULL;
+      if (!show_source && have_client)
+        {
+          g_hash_table_remove (source_data->clients, source);
+          g_signal_emit (sources, source_data->changed_signal, 0);
+        }
+      if (show_source && !have_client)
+        {
+          create_client_for_source (source, source_data->source_type, source_data);
+          g_signal_emit (sources, source_data->changed_signal, 0);
+        }
+    }
 
-  for (l = gconf_value_get_list (entry->value); l; l = l->next)
+  if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
     {
-      const char *source = gconf_value_get_string (l->data);
+      CalendarSourceData *source_data;
+      ESourceSelectable *extension;
+      gboolean have_client;
+      gboolean show_source;
 
-      source_data->selected_sources = 
-	g_slist_prepend (source_data->selected_sources,
-			 g_strdup (source));
-    }
-  source_data->selected_sources =
-    g_slist_reverse (source_data->selected_sources);
+      source_data = &sources->priv->task_sources;
+      extension = e_source_get_extension (source, E_SOURCE_EXTENSION_TASK_LIST);
+      have_client = (g_hash_table_lookup (source_data->clients, source) != NULL);
+      show_source = e_source_get_enabled (source) && e_source_selectable_get_selected (extension);
 
-  calendar_sources_load_esource_list (source_data);
+      if (!show_source && have_client)
+        {
+          g_hash_table_remove (source_data->clients, source);
+          g_signal_emit (sources, source_data->changed_signal, 0);
+        }
+      if (show_source && !have_client)
+        {
+          create_client_for_source (source, source_data->source_type, source_data);
+          g_signal_emit (sources, source_data->changed_signal, 0);
+        }
+    }
 }
 
 static void
-calendar_sources_load_sources (CalendarSources    *sources,
-			       CalendarSourceData *source_data,
-			       const char         *sources_key,
-			       const char         *selected_sources_key,
-			       const char         *selected_sources_dir)
+calendar_sources_registry_source_removed_cb (ESourceRegistry *registry,
+                                             ESource         *source,
+                                             CalendarSources *sources)
 {
-  GConfClient *gconf_client;
-  GError      *error;
-
-  dprintf ("---------------------------\n");
-  dprintf ("Loading sources:\n");
-  dprintf ("  sources_key: %s\n", sources_key);
-  dprintf ("  selected_sources_key: %s\n", selected_sources_key);
-  dprintf ("  selected_sources_dir: %s\n", selected_sources_dir);
-
-  gconf_client = sources->priv->gconf_client;
-
-  error = NULL;
-  source_data->selected_sources = gconf_client_get_list (gconf_client,
-							 selected_sources_key,
-							 GCONF_VALUE_STRING,
-							 &error);
-  if (error)
+  if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR))
     {
-      g_warning ("Failed to get selected sources from '%s': %s\n",
-		 selected_sources_key,
-		 error->message);
-      g_error_free (error);
-      return;
-    }
+      CalendarSourceData *source_data;
 
-  gconf_client_add_dir (gconf_client,
-			selected_sources_dir,
-			GCONF_CLIENT_PRELOAD_NONE,
-			NULL);
-  source_data->selected_sources_dir = g_strdup (selected_sources_dir);
-
-  source_data->selected_sources_listener =
-    gconf_client_notify_add (gconf_client,
-			     selected_sources_dir,
-			     (GConfClientNotifyFunc) calendar_sources_selected_sources_notify,
-			     source_data, NULL, NULL);
-
-  source_data->esource_list = e_source_list_new_for_gconf (gconf_client, sources_key);
-  g_signal_connect (source_data->esource_list, "changed",
-		    G_CALLBACK (calendar_sources_esource_list_changed),
-		    source_data);
-
-  calendar_sources_load_esource_list (source_data);
+      source_data = &sources->priv->appointment_sources;
+      g_hash_table_remove (source_data->clients, source);
+      g_signal_emit (sources, source_data->changed_signal, 0);
+    }
 
-  source_data->loaded = TRUE;
+  if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
+    {
+      CalendarSourceData *source_data;
 
-  dprintf ("---------------------------\n");
+      source_data = &sources->priv->task_sources;
+      g_hash_table_remove (source_data->clients, source);
+      g_signal_emit (sources, source_data->changed_signal, 0);
+    }
 }
 
-GSList *
-calendar_sources_get_appointment_sources (CalendarSources *sources)
+GList *
+calendar_sources_get_appointment_clients (CalendarSources *sources)
 {
+  GList *list, *link;
+
   g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
 
   if (!sources->priv->appointment_sources.loaded)
     {
-      calendar_sources_load_sources (sources,
-				     &sources->priv->appointment_sources,
-				     CALENDAR_SOURCES_APPOINTMENT_SOURCES_KEY,
-				     CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_KEY,
-				     CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR);
+      calendar_sources_load_esource_list (sources->priv->registry,
+                                          &sources->priv->appointment_sources);
+      sources->priv->appointment_sources.loaded = TRUE;
     }
-  
-  return sources->priv->appointment_sources.clients;
+
+  list = g_hash_table_get_values (sources->priv->appointment_sources.clients);
+
+  for (link = list; link != NULL; link = g_list_next (link))
+    link->data = ((ClientData *) link->data)->client;
+
+  return list;
 }
 
-GSList *
-calendar_sources_get_task_sources (CalendarSources *sources)
+GList *
+calendar_sources_get_task_clients (CalendarSources *sources)
 {
+  GList *list, *link;
+
   g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
 
   if (!sources->priv->task_sources.loaded)
     {
-      calendar_sources_load_sources (sources,
-				     &sources->priv->task_sources,
-				     CALENDAR_SOURCES_TASK_SOURCES_KEY,
-				     CALENDAR_SOURCES_SELECTED_TASK_SOURCES_KEY,
-				     CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR);
+      calendar_sources_load_esource_list (sources->priv->registry,
+                                          &sources->priv->task_sources);
+      sources->priv->task_sources.loaded = TRUE;
     }
 
-  return sources->priv->task_sources.clients;
+  list = g_hash_table_get_values (sources->priv->task_sources.clients);
+
+  for (link = list; link != NULL; link = g_list_next (link))
+    link->data = ((ClientData *) link->data)->client;
+
+  return list;
 }
diff --git a/applets/clock/calendar-sources.h b/applets/clock/calendar-sources.h
index 52741ab..eed0270 100644
--- a/applets/clock/calendar-sources.h
+++ b/applets/clock/calendar-sources.h
@@ -58,8 +58,8 @@ struct _CalendarSourcesClass
 
 GType            calendar_sources_get_type                (void) G_GNUC_CONST;
 CalendarSources *calendar_sources_get                     (void);
-GSList          *calendar_sources_get_appointment_sources (CalendarSources *sources);
-GSList          *calendar_sources_get_task_sources        (CalendarSources *sources);
+GList           *calendar_sources_get_appointment_clients (CalendarSources *sources);
+GList           *calendar_sources_get_task_clients        (CalendarSources *sources);
 
 G_END_DECLS
 
diff --git a/applets/clock/calendar-window.c b/applets/clock/calendar-window.c
index 89938e4..9fd5c0e 100644
--- a/applets/clock/calendar-window.c
+++ b/applets/clock/calendar-window.c
@@ -961,9 +961,9 @@ handle_appointments_changed (CalendarWindow *calwin)
                                                   appointment->start_time,
                                                   year, month, day);
 
-                if (g_ascii_strcasecmp (appointment->uri, "weather") == 0)
+                if (g_ascii_strcasecmp (appointment->backend_name, "weather") == 0)
                         type = APPOINTMENT_TYPE_WEATHER;
-                else if (g_ascii_strcasecmp (appointment->uri, "contacts") == 0)
+                else if (g_ascii_strcasecmp (appointment->backend_name, "contacts") == 0)
                         type = APPOINTMENT_TYPE_BIRTHDAY;
                 else
                         type = APPOINTMENT_TYPE_APPOINTMENT;
diff --git a/applets/clock/clock.c b/applets/clock/clock.c
index 5496cab..2b02eb6 100644
--- a/applets/clock/clock.c
+++ b/applets/clock/clock.c
@@ -57,10 +57,6 @@
 #include <libgweather/location-entry.h>
 #include <libgweather/timezone-menu.h>
 
-#ifdef HAVE_LIBECAL
-#include <libedataserverui/e-passwords.h>
-#endif
-
 #include "clock.h"
 
 #include "calendar-window.h"
@@ -189,10 +185,6 @@ struct _ClockData {
 	guint listeners [N_GCONF_PREFS];
 };
 
-/* Used to count the number of clock instances. It's there to know when we
- * should free resources that are shared. */
-static int clock_numbers = 0;
-
 static void  update_clock (ClockData * cd);
 static void  update_tooltip (ClockData * cd);
 static void  update_panel_weather (ClockData *cd);
@@ -790,13 +782,6 @@ destroy_clock (GtkWidget * widget, ClockData *cd)
 	}
 
 	g_free (cd);
-
-#ifdef HAVE_LIBECAL
-	if (clock_numbers > 0) {
-		e_passwords_shutdown ();
-		clock_numbers--;
-	}
-#endif
 }
 
 static gboolean
@@ -1383,11 +1368,6 @@ weather_tooltip (GtkWidget   *widget,
 static void
 create_clock_widget (ClockData *cd)
 {
-#ifdef HAVE_LIBECAL
-	clock_numbers++;
-	e_passwords_init ();
-#endif
-
         /* Main toggle button */
         cd->panel_button = create_main_clock_button ();
 	g_signal_connect (cd->panel_button, "button_press_event",
diff --git a/configure.ac b/configure.ac
index 2a01523..2d32951 100644
--- a/configure.ac
+++ b/configure.ac
@@ -72,9 +72,8 @@ LIBWNCK_REQUIRED=2.91.0
 GCONF_REQUIRED=2.6.1
 LIBGNOME_MENU_REQUIRED=3.1.4
 TELEPATHY_GLIB_REQUIRED=0.14.0
-LIBECAL_REQUIRED=2.91.2
-LIBEDATASERVER_REQUIRED=2.91.2
-LIBEDATASERVERUI_REQUIRED=2.91.2
+LIBECAL_REQUIRED=3.5.3
+LIBEDATASERVER_REQUIRED=3.5.3
 CAIRO_REQUIRED=1.0.0
 GWEATHER_REQUIRED=2.91.0
 DBUS_GLIB_REQUIRED=0.80
@@ -123,14 +122,14 @@ AC_ARG_ENABLE(eds,
 LIBECAL_REQUIREMENT=
 HAVE_EDS=no
 if test "x$enable_eds" = "xyes"; then
-  LIBECAL_REQUIREMENT="libecal-1.2 >= $LIBECAL_REQUIRED libedataserver-1.2 >= $LIBEDATASERVER_REQUIRED libedataserverui-3.0 >= $LIBEDATASERVERUI_REQUIRED gnome-desktop-3.0 >= $LIBGNOME_DESKTOP_REQUIRED"
+  LIBECAL_REQUIREMENT="libecal-1.2 >= $LIBECAL_REQUIRED libedataserver-1.2 >= $LIBEDATASERVER_REQUIRED gnome-desktop-3.0 >= $LIBGNOME_DESKTOP_REQUIRED"
   CLOCK_EDS_ICONDIR=`$PKG_CONFIG --variable=datadir evolution-data-server-1.2`/pixmaps/evolution-data-server
 else
   if test "x$enable_eds" != "xno"; then
     AC_MSG_CHECKING(for evolution-data-server)
-    if $PKG_CONFIG --exists libecal-1.2 libedataserverui-3.0 evolution-data-server-1.2; then
+    if $PKG_CONFIG --exists libecal-1.2 evolution-data-server-1.2; then
        AC_MSG_RESULT(yes)
-       LIBECAL_REQUIREMENT="libecal-1.2 >= $LIBECAL_REQUIRED libedataserver-1.2 >= $LIBEDATASERVER_REQUIRED libedataserverui-3.0 >= $LIBEDATASERVERUI_REQUIRED gnome-desktop-3.0 >= $LIBGNOME_DESKTOP_REQUIRED"
+       LIBECAL_REQUIREMENT="libecal-1.2 >= $LIBECAL_REQUIRED libedataserver-1.2 >= $LIBEDATASERVER_REQUIRED gnome-desktop-3.0 >= $LIBGNOME_DESKTOP_REQUIRED"
        CLOCK_EDS_ICONDIR=`$PKG_CONFIG --variable=datadir evolution-data-server-1.2`/pixmaps/evolution-data-server
        HAVE_EDS=yes
     else
@@ -140,7 +139,7 @@ else
 fi
 if test -n "$LIBECAL_REQUIREMENT"; then
   AC_DEFINE([HAVE_LIBECAL], 1,
-            [Defined when evolution-data-server libecal-1.2 and libedataserverui-3.0 are detected])
+            [Defined when evolution-data-server and libecal-1.2 are detected])
 fi
 AM_CONDITIONAL(HAVE_LIBECAL, test -n "$LIBECAL_REQUIREMENT")
 AC_SUBST(CLOCK_EDS_ICONDIR)
