Reimplement ECal using ECalClient.
authorMatthew Barnes <mbarnes@redhat.com>
Fri, 2 Nov 2012 13:12:38 +0000 (09:12 -0400)
committerMatthew Barnes <mbarnes@redhat.com>
Fri, 2 Nov 2012 16:28:55 +0000 (12:28 -0400)
This is primarily so I don't have to duplicate work while overhauling
the D-Bus API, but it's good to do anyway; it simplifies the deprecated
logic and helps ensure the two APIs behave consistently.

calendar/libecal/e-cal.c

index 025b371..bdb10db 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <libical/ical.h>
 
+#include "e-cal-client.h"
 #include "e-cal-check-timezones.h"
 #include "e-cal-marshal.h"
 #include "e-cal-time-util.h"
 #define CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS       "alarm-email-address"
 #define CAL_BACKEND_PROPERTY_DEFAULT_OBJECT            "default-object"
 
-static guint active_cals = 0, cal_connection_closed_id = 0;
-static EGdbusCalFactory *cal_factory = NULL;
-static GStaticRecMutex cal_factory_lock = G_STATIC_REC_MUTEX_INIT;
-#define LOCK_FACTORY()   g_static_rec_mutex_lock   (&cal_factory_lock)
-#define UNLOCK_FACTORY() g_static_rec_mutex_unlock (&cal_factory_lock)
-
-#define LOCK_CACHE()   g_static_rec_mutex_lock   (&priv->cache_lock)
-#define UNLOCK_CACHE() g_static_rec_mutex_unlock (&priv->cache_lock)
-
-G_DEFINE_TYPE (ECal, e_cal, G_TYPE_OBJECT)
-
 static gboolean open_calendar (ECal *ecal, gboolean only_if_exists, GError **error,
        ECalendarStatus *status,
        gboolean async);
-static void e_cal_dispose (GObject *object);
-static void e_cal_finalize (GObject *object);
 
-/* Private part of the ECal structure */
 struct _ECalPrivate {
-       GDBusProxy *dbus_proxy;
-       guint gone_signal_id;
+       ECalClient *client;
+       gulong backend_died_handler_id;
+       gulong notify_online_handler_id;
 
        /* Load state to avoid multiple loads */
        ECalLoadState load_state;
@@ -90,39 +78,16 @@ struct _ECalPrivate {
        ESource *source;
        ECalSourceType type;
 
-       /* Email address associated with this calendar, or NULL */
-       gchar *cal_address;
-       gchar *alarm_email_address;
-       gchar *ldap_attribute;
-
-       /* Scheduling info */
-       gchar *capabilities;
-
-       gint mode;
-
-       gboolean read_only;
-
-       /* A cache of timezones retrieved from the server, to avoid getting
-        * them repeatedly for each get_object () call. */
-       GHashTable *timezones;
-
-       /* The default timezone to use to resolve DATE and floating DATE-TIME
-        * values. */
-       icaltimezone *default_zone;
-
-       gchar *local_attachment_store;
-
-       /* For locking the operation while localling cache values like 
-        * static capabilities, cal address etc. */
-       GStaticRecMutex cache_lock;
-
        GList **free_busy_data;
        GMutex *free_busy_data_lock;
 };
 
-\f
+enum {
+       PROP_0,
+       PROP_SOURCE,
+       PROP_SOURCE_TYPE
+};
 
-/* Signal IDs */
 enum {
        CAL_OPENED,
        CAL_OPENED_EX,
@@ -132,61 +97,13 @@ enum {
        LAST_SIGNAL
 };
 
-static guint e_cal_signals[LAST_SIGNAL];
-
-#ifdef __PRETTY_FUNCTION__
-#define e_return_error_if_fail(expr,error_code)        G_STMT_START{           \
-     if G_LIKELY (expr) { } else                                               \
-       {                                                               \
-        g_log (G_LOG_DOMAIN,                                           \
-               G_LOG_LEVEL_CRITICAL,                                   \
-               "file %s: line %d (%s): assertion `%s' failed",         \
-               __FILE__,                                               \
-               __LINE__,                                               \
-               __PRETTY_FUNCTION__,                                    \
-               #expr);                                                 \
-        g_set_error (error, E_CALENDAR_ERROR, (error_code),                \
-               "file %s: line %d (%s): assertion `%s' failed",         \
-               __FILE__,                                               \
-               __LINE__,                                               \
-               __PRETTY_FUNCTION__,                                    \
-               #expr);                                                 \
-        return FALSE;                                                  \
-       };                              }G_STMT_END
-#else
-#define e_return_error_if_fail(expr,error_code)        G_STMT_START{           \
-     if G_LIKELY (expr) { } else                                               \
-       {                                                               \
-        g_log (G_LOG_DOMAIN,                                           \
-               G_LOG_LEVEL_CRITICAL,                                   \
-               "file %s: line %d: assertion `%s' failed",              \
-               __FILE__,                                               \
-               __LINE__,                                               \
-               #expr);                                                 \
-        g_set_error (error, E_CALENDAR_ERROR, (error_code),                \
-               "file %s: line %d: assertion `%s' failed",              \
-               __FILE__,                                               \
-               __LINE__,                                               \
-               #expr);                                                 \
-        return FALSE;                                                  \
-       };                              }G_STMT_END
-#endif
+static guint signals[LAST_SIGNAL];
+
+static void    e_cal_initable_init             (GInitableIface *interface);
 
-#define E_CALENDAR_CHECK_STATUS(status,error)                          \
-G_STMT_START{                                                          \
-       if ((status) == E_CALENDAR_STATUS_OK)                           \
-               return TRUE;                                            \
-       else {                                                          \
-               const gchar *msg;                                       \
-               if (error && *error)                                    \
-                       return unwrap_gerror (error);                   \
-               msg = e_cal_get_error_message ((status));               \
-               g_set_error ((error), E_CALENDAR_ERROR, (status), "%s", msg);   \
-               return FALSE;                                           \
-       }                                                               \
-} G_STMT_END
-
-\f
+G_DEFINE_TYPE_WITH_CODE (
+       ECal, e_cal, G_TYPE_OBJECT,
+       G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, e_cal_initable_init))
 
 /* Error quark */
 GQuark
@@ -268,33 +185,6 @@ get_status_from_error (const GError *error)
        }
 }
 
-/*
- * If the specified GError is a remote error, then create a new error
- * representing the remote error.  If the error is anything else, then leave it
- * alone.
- */
-static gboolean
-unwrap_gerror (GError **error)
-{
-       if (*error == NULL)
-               return TRUE;
-
-       if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR)) {
-               GError *new_error = NULL;
-               gint code;
-
-               code = get_status_from_error (*error);
-               g_dbus_error_strip_remote_error (*error);
-
-               new_error = g_error_new_literal (E_CALENDAR_ERROR, code, (*error)->message);
-
-               g_error_free (*error);
-               *error = new_error;
-       }
-
-       return FALSE;
-}
-
 /**
  * e_cal_source_type_enum_get_type:
  *
@@ -387,185 +277,125 @@ cal_mode_enum_get_type (void)
        return enum_type__volatile;
 }
 
-static EDataCalObjType
-convert_type (ECalSourceType type)
+static void
+cal_backend_died_cb (EClient *client,
+                     ECal *cal)
 {
-       switch (type) {
-       case E_CAL_SOURCE_TYPE_EVENT:
-               return Event;
-       case E_CAL_SOURCE_TYPE_TODO:
-               return Todo;
-       case E_CAL_SOURCE_TYPE_JOURNAL:
-               return Journal;
-       default:
-               return AnyType;
-       }
-
-       return AnyType;
+       /* Echo the signal emission from the ECalClient. */
+       g_signal_emit (cal, signals[BACKEND_DIED], 0);
 }
 
 static void
-e_cal_init (ECal *ecal)
+cal_notify_online_cb (EClient *client,
+                      GParamSpec *pspec,
+                      ECal *cal)
 {
-       LOCK_FACTORY ();
-       active_cals++;
-       UNLOCK_FACTORY ();
-
-       ecal->priv = E_CAL_GET_PRIVATE (ecal);
+       gboolean online = e_client_is_online (client);
 
-       ecal->priv->load_state = E_CAL_LOAD_NOT_LOADED;
-       ecal->priv->local_attachment_store = NULL;
-
-       ecal->priv->cal_address = NULL;
-       ecal->priv->alarm_email_address = NULL;
-       ecal->priv->ldap_attribute = NULL;
-       ecal->priv->capabilities = NULL;
-       ecal->priv->dbus_proxy = NULL;
-       ecal->priv->timezones = g_hash_table_new (g_str_hash, g_str_equal);
-       ecal->priv->default_zone = icaltimezone_get_utc_timezone ();
-       ecal->priv->free_busy_data_lock = g_mutex_new ();
-       g_static_rec_mutex_init (&ecal->priv->cache_lock);
+       g_signal_emit (
+               cal, signals[CAL_SET_MODE], 0,
+               E_CALENDAR_STATUS_OK, online ? Remote : Local);
 }
 
 static void
-gdbus_cal_disconnect (ECal *ecal);
-
-/*
- * Called when the calendar server dies.
- */
-static void
-gdbus_cal_closed_cb (GDBusConnection *connection,
-                     gboolean remote_peer_vanished,
-                     GError *error,
-                     ECal *ecal)
+cal_set_source (ECal *cal,
+                ESource *source)
 {
-       GError *err = NULL;
-
-       g_return_if_fail (E_IS_CAL (ecal));
-
-       if (error) {
-               err = g_error_copy (error);
-               unwrap_gerror (&err);
-       }
-
-       if (err) {
-               g_debug (G_STRLOC ": ECal GDBus connection is closed%s: %s", remote_peer_vanished ? ", remote peer vanished" : "", err->message);
-               g_error_free (err);
-       } else {
-               g_debug (G_STRLOC ": ECal GDBus connection is closed%s", remote_peer_vanished ? ", remote peer vanished" : "");
-       }
-
-       gdbus_cal_disconnect (ecal);
+       g_return_if_fail (E_IS_SOURCE (source));
+       g_return_if_fail (cal->priv->source == NULL);
 
-       g_signal_emit (G_OBJECT (ecal), e_cal_signals[BACKEND_DIED], 0);
+       cal->priv->source = g_object_ref (source);
 }
 
 static void
-gdbus_cal_connection_gone_cb (GDBusConnection *connection,
-                              const gchar *sender_name,
-                              const gchar *object_path,
-                              const gchar *interface_name,
-                              const gchar *signal_name,
-                              GVariant *parameters,
-                              gpointer user_data)
+cal_set_source_type (ECal *cal,
+                     ECalSourceType source_type)
 {
-       /* signal subscription takes care of correct parameters,
-        * thus just do what is to be done here */
-       gdbus_cal_closed_cb (connection, TRUE, NULL, user_data);
+       cal->priv->type = source_type;
 }
 
 static void
-gdbus_cal_disconnect (ECal *ecal)
-{
-       /* Ensure that everything relevant is NULL */
-       LOCK_FACTORY ();
-
-       if (ecal->priv->dbus_proxy != NULL) {
-               GDBusConnection *connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (ecal->priv->dbus_proxy));
-               GError *error = NULL;
+cal_set_property (GObject *object,
+                  guint property_id,
+                  const GValue *value,
+                  GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_SOURCE:
+                       cal_set_source (
+                               E_CAL (object),
+                               g_value_get_object (value));
+                       return;
 
-               g_signal_handlers_disconnect_by_func (connection, gdbus_cal_closed_cb, ecal);
-               g_dbus_connection_signal_unsubscribe (connection, ecal->priv->gone_signal_id);
-               ecal->priv->gone_signal_id = 0;
+               case PROP_SOURCE_TYPE:
+                       cal_set_source_type (
+                               E_CAL (object),
+                               g_value_get_enum (value));
+                       return;
+       }
 
-               e_gdbus_cal_call_close_sync (ecal->priv->dbus_proxy, NULL, &error);
-               g_object_unref (ecal->priv->dbus_proxy);
-               ecal->priv->dbus_proxy = NULL;
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
 
-               if (error) {
-                       unwrap_gerror (&error);
+static void
+cal_get_property (GObject *object,
+                  guint property_id,
+                  GValue *value,
+                  GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_SOURCE:
+                       g_value_set_object (
+                               value, e_cal_get_source (
+                               E_CAL (object)));
+                       return;
 
-                       g_warning ("%s: Failed to close calendar, %s\n", G_STRFUNC, error->message);
-                       g_error_free (error);
-               }
+               case PROP_SOURCE_TYPE:
+                       g_value_set_enum (
+                               value, e_cal_get_source_type (
+                               E_CAL (object)));
+                       return;
        }
-       UNLOCK_FACTORY ();
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 }
 
-/* Dispose handler for the calendar ecal */
 static void
-e_cal_dispose (GObject *object)
+cal_dispose (GObject *object)
 {
-       ECal *ecal = E_CAL (object);
+       ECalPrivate *priv;
+
+       priv = E_CAL_GET_PRIVATE (object);
+
+       if (priv->client != NULL) {
+               g_signal_handler_disconnect (
+                       priv->client,
+                       priv->backend_died_handler_id);
+               g_signal_handler_disconnect (
+                       priv->client,
+                       priv->notify_online_handler_id);
+               g_object_unref (priv->client);
+               priv->client = NULL;
+       }
 
-       gdbus_cal_disconnect (ecal);
+       if (priv->source != NULL) {
+               g_object_unref (priv->source);
+               priv->source = NULL;
+       }
 
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (e_cal_parent_class)->dispose (object);
 }
 
 static void
-free_timezone (gpointer key,
-               gpointer value,
-               gpointer data)
+cal_finalize (GObject *object)
 {
-       /* Note that the key comes from within the icaltimezone value, so we
-        * don't free that. */
-       icaltimezone_free (value, TRUE);
-}
-
-/* Finalize handler for the calendar ecal */
-static void
-e_cal_finalize (GObject *object)
-{
-       ECal *ecal;
        ECalPrivate *priv;
 
-       g_return_if_fail (object != NULL);
-       g_return_if_fail (E_IS_CAL (object));
-
-       ecal = E_CAL (object);
-       priv = ecal->priv;
+       priv = E_CAL_GET_PRIVATE (object);
 
        priv->load_state = E_CAL_LOAD_NOT_LOADED;
 
-       if (priv->source) {
-               g_object_unref (priv->source);
-               priv->source = NULL;
-       }
-
-       if (priv->local_attachment_store) {
-               g_free (priv->local_attachment_store);
-               priv->local_attachment_store = NULL;
-       }
-
-       if (priv->cal_address) {
-               g_free (priv->cal_address);
-               priv->cal_address = NULL;
-       }
-       if (priv->alarm_email_address) {
-               g_free (priv->alarm_email_address);
-               priv->alarm_email_address = NULL;
-       }
-       if (priv->ldap_attribute) {
-               g_free (priv->ldap_attribute);
-               priv->ldap_attribute = NULL;
-       }
-       if (priv->capabilities) {
-               g_free (priv->capabilities);
-               priv->capabilities = NULL;
-       }
-
        if (priv->free_busy_data) {
                g_mutex_lock (priv->free_busy_data_lock);
                g_list_foreach (*priv->free_busy_data, (GFunc) g_object_unref, NULL);
@@ -575,30 +405,93 @@ e_cal_finalize (GObject *object)
                g_mutex_unlock (priv->free_busy_data_lock);
        }
 
-       g_hash_table_foreach (priv->timezones, free_timezone, NULL);
-       g_hash_table_destroy (priv->timezones);
-       priv->timezones = NULL;
-       g_static_rec_mutex_free (&priv->cache_lock);
        g_mutex_free (priv->free_busy_data_lock);
 
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_cal_parent_class)->finalize (object);
+}
+
+static gboolean
+cal_initable_init (GInitable *initable,
+                   GCancellable *cancellable,
+                   GError **error)
+{
+       ECal *cal = E_CAL (initable);
+       ECalClientSourceType source_type;
+       ESource *source;
 
-       LOCK_FACTORY ();
-       active_cals--;
-       UNLOCK_FACTORY ();
+       source = e_cal_get_source (cal);
+
+       switch (e_cal_get_source_type (cal)) {
+               case E_CAL_SOURCE_TYPE_EVENT:
+                       source_type = E_CAL_CLIENT_SOURCE_TYPE_EVENTS;
+                       break;
+               case E_CAL_SOURCE_TYPE_TODO:
+                       source_type = E_CAL_CLIENT_SOURCE_TYPE_TASKS;
+                       break;
+               case E_CAL_SOURCE_TYPE_JOURNAL:
+                       source_type = E_CAL_CLIENT_SOURCE_TYPE_MEMOS;
+                       break;
+               default:
+                       g_return_val_if_reached (FALSE);
+       }
+
+       cal->priv->client = e_cal_client_new (source, source_type, error);
+
+       if (cal->priv->client == NULL)
+               return FALSE;
+
+       cal->priv->backend_died_handler_id = g_signal_connect (
+               cal->priv->client, "backend-died",
+               G_CALLBACK (cal_backend_died_cb), cal);
+
+       cal->priv->notify_online_handler_id = g_signal_connect (
+               cal->priv->client, "notify::online",
+               G_CALLBACK (cal_notify_online_cb), cal);
+
+       return TRUE;
 }
 
-/* Class initialization function for the calendar ecal */
 static void
 e_cal_class_init (ECalClass *class)
 {
        GObjectClass *object_class;
 
-       object_class = (GObjectClass *) class;
+       g_type_class_add_private (class, sizeof (ECalPrivate));
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = cal_set_property;
+       object_class->get_property = cal_get_property;
+       object_class->dispose = cal_dispose;
+       object_class->finalize = cal_finalize;
+
+       g_object_class_install_property (
+               object_class,
+               PROP_SOURCE,
+               g_param_spec_object (
+                       "source",
+                       "Source",
+                       "The data source for the ECal",
+                       E_TYPE_SOURCE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT_ONLY |
+                       G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (
+               object_class,
+               PROP_SOURCE_TYPE,
+               g_param_spec_enum (
+                       "source-type",
+                       "Source Type",
+                       "The iCalendar data type for the ECal",
+                       E_TYPE_CAL_SOURCE_TYPE,
+                       E_CAL_SOURCE_TYPE_EVENT,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT_ONLY |
+                       G_PARAM_STATIC_STRINGS));
 
        /* XXX The "cal-opened" signal is deprecated. */
-       e_cal_signals[CAL_OPENED] = g_signal_new (
+       signals[CAL_OPENED] = g_signal_new (
                "cal_opened",
                G_TYPE_FROM_CLASS (class),
                G_SIGNAL_RUN_FIRST,
@@ -612,7 +505,7 @@ e_cal_class_init (ECalClass *class)
         * @ecal:: self
         * @error: (type glong):
         */
-       e_cal_signals[CAL_OPENED_EX] = g_signal_new (
+       signals[CAL_OPENED_EX] = g_signal_new (
                "cal_opened_ex",
                G_TYPE_FROM_CLASS (class),
                G_SIGNAL_RUN_FIRST,
@@ -621,7 +514,7 @@ e_cal_class_init (ECalClass *class)
                g_cclosure_marshal_VOID__POINTER,
                G_TYPE_NONE, 1, G_TYPE_POINTER);
 
-       e_cal_signals[CAL_SET_MODE] = g_signal_new (
+       signals[CAL_SET_MODE] = g_signal_new (
                "cal_set_mode",
                G_TYPE_FROM_CLASS (class),
                G_SIGNAL_RUN_FIRST,
@@ -632,7 +525,7 @@ e_cal_class_init (ECalClass *class)
                E_CAL_SET_MODE_STATUS_ENUM_TYPE,
                CAL_MODE_ENUM_TYPE);
 
-       e_cal_signals[BACKEND_ERROR] = g_signal_new (
+       signals[BACKEND_ERROR] = g_signal_new (
                "backend_error",
                G_TYPE_FROM_CLASS (class),
                G_SIGNAL_RUN_FIRST,
@@ -642,7 +535,7 @@ e_cal_class_init (ECalClass *class)
                G_TYPE_NONE, 1,
                G_TYPE_STRING);
 
-       e_cal_signals[BACKEND_DIED] = g_signal_new (
+       signals[BACKEND_DIED] = g_signal_new (
                "backend_died",
                G_TYPE_FROM_CLASS (class),
                G_SIGNAL_RUN_FIRST,
@@ -650,257 +543,26 @@ e_cal_class_init (ECalClass *class)
                NULL, NULL,
                g_cclosure_marshal_VOID__VOID,
                G_TYPE_NONE, 0);
-
-       class->cal_opened = NULL;
-       class->cal_opened_ex = NULL;
-       class->backend_died = NULL;
-
-       object_class->dispose = e_cal_dispose;
-       object_class->finalize = e_cal_finalize;
-
-       g_type_class_add_private (class, sizeof (ECalPrivate));
 }
 
 static void
-cal_factory_closed_cb (GDBusConnection *connection,
-                       gboolean remote_peer_vanished,
-                       GError *error,
-                       gpointer user_data)
+e_cal_initable_init (GInitableIface *interface)
 {
-       GError *err = NULL;
-
-       LOCK_FACTORY ();
-
-       if (cal_connection_closed_id) {
-               g_dbus_connection_signal_unsubscribe (connection, cal_connection_closed_id);
-               cal_connection_closed_id = 0;
-               g_signal_handlers_disconnect_by_func (connection, cal_factory_closed_cb, NULL);
-       }
-
-       if (cal_factory != NULL) {
-               g_object_unref (cal_factory);
-               cal_factory = NULL;
-       }
-
-       if (error) {
-               err = g_error_copy (error);
-               unwrap_gerror (&err);
-       }
-
-       if (err) {
-               g_debug ("GDBus connection is closed%s: %s", remote_peer_vanished ? ", remote peer vanished" : "", err->message);
-               g_error_free (err);
-       } else if (active_cals) {
-               g_debug ("GDBus connection is closed%s", remote_peer_vanished ? ", remote peer vanished" : "");
-       }
-
-       UNLOCK_FACTORY ();
+       interface->init = cal_initable_init;
 }
 
 static void
-cal_factory_connection_gone_cb (GDBusConnection *connection,
-                                const gchar *sender_name,
-                                const gchar *object_path,
-                                const gchar *interface_name,
-                                const gchar *signal_name,
-                                GVariant *parameters,
-                                gpointer user_data)
-{
-       /* signal subscription takes care of correct parameters,
-        * thus just do what is to be done here */
-       cal_factory_closed_cb (connection, TRUE, NULL, user_data);
-}
-
-/* one-time start up for libecal */
-static gboolean
-e_cal_activate (GCancellable *cancellable,
-                GError **error)
+e_cal_init (ECal *ecal)
 {
-       GDBusConnection *connection;
-
-       LOCK_FACTORY ();
-       if (G_LIKELY (cal_factory != NULL)) {
-               UNLOCK_FACTORY ();
-               return TRUE;
-       }
-
-       cal_factory = e_gdbus_cal_factory_proxy_new_for_bus_sync (
-               G_BUS_TYPE_SESSION,
-               G_DBUS_PROXY_FLAGS_NONE,
-               CALENDAR_DBUS_SERVICE_NAME,
-               "/org/gnome/evolution/dataserver/CalendarFactory",
-               cancellable, error);
-
-       if (cal_factory == NULL) {
-               UNLOCK_FACTORY ();
-               return FALSE;
-       }
-
-       connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (cal_factory));
-       cal_connection_closed_id = g_dbus_connection_signal_subscribe (
-               connection,
-               NULL,                                   /* sender */
-               "org.freedesktop.DBus",                 /* interface */
-               "NameOwnerChanged",                     /* member */
-               "/org/freedesktop/DBus",                /* object_path */
-               CALENDAR_DBUS_SERVICE_NAME,             /* arg0 */
-               G_DBUS_SIGNAL_FLAGS_NONE,
-               cal_factory_connection_gone_cb, NULL, NULL);
-
-       g_signal_connect (
-               connection, "closed",
-               G_CALLBACK (cal_factory_closed_cb), NULL);
+       ecal->priv = E_CAL_GET_PRIVATE (ecal);
 
-       UNLOCK_FACTORY ();
+       ecal->priv->load_state = E_CAL_LOAD_NOT_LOADED;
 
-       return TRUE;
+       ecal->priv->free_busy_data_lock = g_mutex_new ();
 }
 
 static void async_open_report_result (ECal *ecal, const GError *error);
 
-static void
-free_busy_data_cb (EGdbusCal *gdbus_cal,
-                   const gchar * const *free_busy_strv,
-                   ECal *cal)
-{
-       ECalPrivate *priv;
-
-       g_return_if_fail (E_IS_CAL (cal));
-
-       priv = cal->priv;
-
-       g_mutex_lock (priv->free_busy_data_lock);
-
-       if (priv->free_busy_data) {
-               gint ii;
-               GList *list = *priv->free_busy_data;
-
-               for (ii = 0; free_busy_strv[ii]; ii++) {
-                       ECalComponent *comp;
-                       icalcomponent *icalcomp;
-                       icalcomponent_kind kind;
-
-                       icalcomp = icalcomponent_new_from_string (free_busy_strv[ii]);
-                       if (!icalcomp)
-                               continue;
-
-                       kind = icalcomponent_isa (icalcomp);
-                       if (kind == ICAL_VFREEBUSY_COMPONENT) {
-                               comp = e_cal_component_new ();
-                               if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
-                                       icalcomponent_free (icalcomp);
-                                       g_object_unref (G_OBJECT (comp));
-                                       continue;
-                               }
-
-                               list = g_list_append (list, comp);
-                       } else {
-                               icalcomponent_free (icalcomp);
-                       }
-               }
-
-               *priv->free_busy_data = list;
-       }
-
-       g_mutex_unlock (priv->free_busy_data_lock);
-}
-
-typedef struct
-{
-       ECal *ecal;
-       gchar *message;
-}  ECalErrorData;
-
-static gboolean
-backend_error_idle_cb (gpointer data)
-{
-       ECalErrorData *error_data = data;
-
-       g_signal_emit (G_OBJECT (error_data->ecal), e_cal_signals[BACKEND_ERROR], 0, error_data->message);
-
-       g_object_unref (error_data->ecal);
-       g_free (error_data->message);
-       g_free (error_data);
-
-       return FALSE;
-}
-
-/* Handle the error_occurred signal from the listener */
-static void
-backend_error_cb (EGdbusCal *gdbus_cal,
-                  const gchar *message,
-                  ECal *ecal)
-{
-       ECalErrorData *error_data;
-
-       g_return_if_fail (E_IS_CAL (ecal));
-
-       error_data = g_new0 (ECalErrorData, 1);
-
-       error_data->ecal = g_object_ref (ecal);
-       error_data->message = g_strdup (message);
-
-       g_idle_add (backend_error_idle_cb, error_data);
-}
-
-static void
-readonly_cb (EGdbusCal *gdbus_cal,
-             gboolean read_only,
-             ECal *cal)
-{
-       ECalPrivate *priv;
-
-       g_return_if_fail (cal && E_IS_CAL (cal));
-
-       priv = cal->priv;
-       priv->read_only = read_only;
-}
-
-static void
-online_cb (EGdbusCal *gdbus_cal,
-           gboolean is_online,
-           ECal *cal)
-{
-       g_return_if_fail (E_IS_CAL (cal));
-
-       g_signal_emit (
-               G_OBJECT (cal), e_cal_signals[CAL_SET_MODE],
-               0, E_CALENDAR_STATUS_OK, is_online ? Remote : Local);
-}
-
-/*
-static void
-backend_died_cb (EComponentListener *cl,
- *               gpointer user_data)
-{
-       ECalPrivate *priv;
-       ECal *ecal = (ECal *) user_data;
- *
-       priv = ecal->priv;
-       priv->load_state = E_CAL_LOAD_NOT_LOADED;
-       g_signal_emit (G_OBJECT (ecal), e_cal_signals[BACKEND_DIED], 0);
-}*/
-
-static void
-set_local_attachment_store (ECal *ecal)
-{
-       gchar *cache_dir = NULL;
-       GError *error = NULL;
-
-       e_gdbus_cal_call_get_backend_property_sync (
-               ecal->priv->dbus_proxy,
-               CLIENT_BACKEND_PROPERTY_CACHE_DIR,
-               &cache_dir, NULL, &error);
-
-       if (error == NULL)
-               ecal->priv->local_attachment_store = cache_dir;
-       else {
-               unwrap_gerror (&error);
-               g_warning ("%s", error->message);
-               g_error_free (error);
-       }
-}
-
 /**
  * e_cal_new:
  * @source: An #ESource to be used for the client.
@@ -918,111 +580,12 @@ ECal *
 e_cal_new (ESource *source,
            ECalSourceType type)
 {
-       ECal *ecal;
-       ECalPrivate *priv;
-       gchar **strv;
-       const gchar *uid;
-       gchar *object_path;
-       GError *error = NULL;
-       GDBusConnection *connection;
-
-       g_return_val_if_fail (source && E_IS_SOURCE (source), NULL);
+       g_return_val_if_fail (E_IS_SOURCE (source), NULL);
        g_return_val_if_fail (type < E_CAL_SOURCE_TYPE_LAST, NULL);
 
-       /* XXX Oops, e_cal_new() forgot to take a GCancellable. */
-       if (!e_cal_activate (NULL, &error)) {
-               unwrap_gerror (&error);
-               g_warning ("Cannot activate ECal: %s\n", error ? error->message : "Unknown error");
-               if (error)
-                       g_error_free (error);
-               return NULL;
-       }
-
-       ecal = g_object_new (E_TYPE_CAL, NULL);
-       priv = ecal->priv;
-
-       priv->source = g_object_ref (source);
-       priv->type = type;
-
-       uid = e_source_get_uid (source);
-       strv = e_gdbus_cal_factory_encode_get_cal (uid, convert_type (priv->type));
-
-       e_gdbus_cal_factory_call_get_cal_sync (
-               G_DBUS_PROXY (cal_factory),
-               (const gchar * const *) strv, &object_path, NULL, &error);
-
-       /* Sanity check. */
-       g_return_val_if_fail (
-               ((object_path != NULL) && (error == NULL)) ||
-               ((object_path == NULL) && (error != NULL)), NULL);
-
-       g_strfreev (strv);
-
-       if (error != NULL) {
-               unwrap_gerror (&error);
-               g_error_free (error);
-               g_object_unref (ecal);
-               return NULL;
-       }
-
-       connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (cal_factory));
-
-       priv->dbus_proxy = G_DBUS_PROXY (e_gdbus_cal_proxy_new_sync (
-               connection,
-               G_DBUS_PROXY_FLAGS_NONE,
-               CALENDAR_DBUS_SERVICE_NAME,
-               object_path,
-               NULL, &error));
-
-       g_free (object_path);
-
-       /* Sanity check. */
-       g_return_val_if_fail (
-               ((priv->dbus_proxy != NULL) && (error == NULL)) ||
-               ((priv->dbus_proxy == NULL) && (error != NULL)), NULL);
-
-       if (error != NULL) {
-               unwrap_gerror (&error);
-               if (error)
-                       g_error_free (error);
-               g_object_unref (ecal);
-               return NULL;
-       }
-
-       priv->gone_signal_id = g_dbus_connection_signal_subscribe (
-               connection,
-               "org.freedesktop.DBus",                 /* sender */
-               "org.freedesktop.DBus",                 /* interface */
-               "NameOwnerChanged",                     /* member */
-               "/org/freedesktop/DBus",                /* object_path */
-               CALENDAR_DBUS_SERVICE_NAME,             /* arg0 */
-               G_DBUS_SIGNAL_FLAGS_NONE,
-               gdbus_cal_connection_gone_cb, ecal, NULL);
-
-       g_signal_connect (
-               connection, "closed",
-               G_CALLBACK (gdbus_cal_closed_cb), ecal);
-
-       g_signal_connect (
-               priv->dbus_proxy, "backend-error",
-               G_CALLBACK (backend_error_cb), ecal);
-
-       g_signal_connect (
-               priv->dbus_proxy, "readonly",
-               G_CALLBACK (readonly_cb), ecal);
-
-       g_signal_connect (
-               priv->dbus_proxy, "online",
-               G_CALLBACK (online_cb), ecal);
-
-       g_signal_connect (
-               priv->dbus_proxy, "free-busy-data",
-               G_CALLBACK (free_busy_data_cb), ecal);
-
-       /* Set the local attachment store path for the calendar */
-       set_local_attachment_store (ecal);
-
-       return ecal;
+       return g_initable_new (
+               E_TYPE_CAL, NULL, NULL,
+               "source", source, "source-type", type, NULL);
 }
 
 static void
@@ -1031,7 +594,7 @@ async_open_report_result (ECal *ecal,
 {
        ECalendarStatus status;
 
-       g_return_if_fail (ecal && E_IS_CAL (ecal));
+       g_return_if_fail (E_IS_CAL (ecal));
 
        if (!error)
                ecal->priv->load_state = E_CAL_LOAD_LOADED;
@@ -1042,27 +605,26 @@ async_open_report_result (ECal *ecal,
                status = E_CALENDAR_STATUS_OK;
        }
 
-       g_signal_emit (G_OBJECT (ecal), e_cal_signals[CAL_OPENED], 0, status);
-       g_signal_emit (G_OBJECT (ecal), e_cal_signals[CAL_OPENED_EX], 0, error);
+       g_signal_emit (G_OBJECT (ecal), signals[CAL_OPENED], 0, status);
+       g_signal_emit (G_OBJECT (ecal), signals[CAL_OPENED_EX], 0, error);
 }
 
 static void
-async_open_ready_cb (GDBusProxy *gdbus_cal,
-                     GAsyncResult *res,
-                     ECal *ecal)
+async_open_ready_cb (GObject *source_object,
+                     GAsyncResult *result,
+                     gpointer user_data)
 {
+       ECal *cal = E_CAL (user_data);
        GError *error = NULL;
 
-       g_return_if_fail (ecal && E_IS_CAL (ecal));
-
-       e_gdbus_cal_call_open_finish (gdbus_cal, res, &error);
+       e_client_open_finish (E_CLIENT (source_object), result, &error);
 
-       unwrap_gerror (&error);
+       async_open_report_result (cal, error);
 
-       async_open_report_result (ecal, error);
-
-       if (error)
+       if (error != NULL)
                g_error_free (error);
+
+       g_object_unref (cal);
 }
 
 static gboolean
@@ -1072,37 +634,34 @@ open_calendar (ECal *ecal,
                ECalendarStatus *status,
                gboolean async)
 {
-       ECalPrivate *priv;
-
-       g_return_val_if_fail (error != NULL, FALSE);
-
-       e_return_error_if_fail (ecal != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
+       gboolean success = TRUE;
 
-       if (priv->load_state == E_CAL_LOAD_LOADED)
+       if (ecal->priv->load_state == E_CAL_LOAD_LOADED)
                return TRUE;
 
-       priv->load_state = E_CAL_LOAD_LOADING;
+       ecal->priv->load_state = E_CAL_LOAD_LOADING;
 
        *status = E_CALENDAR_STATUS_OK;
        if (!async) {
-               if (!e_gdbus_cal_call_open_sync (priv->dbus_proxy, only_if_exists, NULL, error)) {
+               success = e_client_open_sync (
+                       E_CLIENT (ecal->priv->client),
+                       only_if_exists, NULL, error);
+               if (success) {
+                       *status = E_CALENDAR_STATUS_OK;
+                       ecal->priv->load_state = E_CAL_LOAD_LOADED;
+               } else {
                        *status = E_CALENDAR_STATUS_DBUS_EXCEPTION;
+                       ecal->priv->load_state = E_CAL_LOAD_NOT_LOADED;
                }
-               if (!*error)
-                       priv->load_state = E_CAL_LOAD_LOADED;
        } else {
-               e_gdbus_cal_call_open (priv->dbus_proxy, only_if_exists, NULL, (GAsyncReadyCallback) async_open_ready_cb, ecal);
-       }
-
-       if (*error) {
-               unwrap_gerror (error);
-               priv->load_state = E_CAL_LOAD_NOT_LOADED;
+               e_client_open (
+                       E_CLIENT (ecal->priv->client),
+                       only_if_exists, NULL,
+                       async_open_ready_cb,
+                       g_object_ref (ecal));
        }
 
-       return *error == NULL;
+       return success;
 }
 
 /**
@@ -1134,8 +693,8 @@ e_cal_open (ECal *ecal,
        gboolean result;
 
        result = open_calendar (ecal, only_if_exists, &err, &status, FALSE);
-       g_signal_emit (G_OBJECT (ecal), e_cal_signals[CAL_OPENED], 0, status);
-       g_signal_emit (G_OBJECT (ecal), e_cal_signals[CAL_OPENED_EX], 0, err);
+       g_signal_emit (G_OBJECT (ecal), signals[CAL_OPENED], 0, status);
+       g_signal_emit (G_OBJECT (ecal), signals[CAL_OPENED_EX], 0, err);
 
        if (err)
                g_propagate_error (error, err);
@@ -1207,7 +766,6 @@ e_cal_open_async (ECal *ecal,
        GError *error = NULL;
        ECalendarStatus status;
 
-       g_return_if_fail (ecal != NULL);
        g_return_if_fail (E_IS_CAL (ecal));
 
        priv = ecal->priv;
@@ -1247,17 +805,10 @@ gboolean
 e_cal_refresh (ECal *ecal,
                GError **error)
 {
-       ECalPrivate *priv;
-
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-
-       if (!e_gdbus_cal_call_refresh_sync (priv->dbus_proxy, NULL, error)) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
 
-       return TRUE;
+       return e_client_refresh_sync (
+               E_CLIENT (ecal->priv->client), NULL, error);
 }
 
 /**
@@ -1314,42 +865,6 @@ GList *
 e_cal_uri_list (ECal *ecal,
                 CalMode mode)
 {
-#if 0
-       ECalPrivate *priv;
-       GNOME_Evolution_Calendar_StringSeq *uri_seq;
-       GList *uris = NULL;
-       CORBA_Environment ev;
-       GList *f;
-
-       g_return_val_if_fail (ecal != NULL, NULL);
-       g_return_val_if_fail (E_IS_CAL (ecal), NULL);
-
-       priv = ecal->priv;
-
-       for (f = priv->factories; f; f = f->next) {
-               CORBA_exception_init (&ev);
-               uri_seq = GNOME_Evolution_Calendar_CalFactory_uriList (f->data, mode, &ev);
-
-               if (BONOBO_EX (&ev)) {
-                       g_message ("e_cal_uri_list(): request failed");
-
-                       /* free memory and return */
-                       g_list_foreach (uris, (GFunc) g_free, NULL);
-                       g_list_free (uris);
-                       uris = NULL;
-                       break;
-               }
-               else {
-                       uris = g_list_concat (uris, build_uri_list (uri_seq));
-                       CORBA_free (uri_seq);
-               }
-
-               CORBA_exception_free (&ev);
-       }
-
-       return uris;
-#endif
-
        return NULL;
 }
 
@@ -1369,7 +884,6 @@ e_cal_get_source_type (ECal *ecal)
 {
        ECalPrivate *priv;
 
-       g_return_val_if_fail (ecal != NULL, E_CAL_SOURCE_TYPE_LAST);
        g_return_val_if_fail (E_IS_CAL (ecal), E_CAL_SOURCE_TYPE_LAST);
 
        priv = ecal->priv;
@@ -1392,13 +906,9 @@ e_cal_get_source_type (ECal *ecal)
 ECalLoadState
 e_cal_get_load_state (ECal *ecal)
 {
-       ECalPrivate *priv;
-
-       g_return_val_if_fail (ecal != NULL, E_CAL_LOAD_NOT_LOADED);
        g_return_val_if_fail (E_IS_CAL (ecal), E_CAL_LOAD_NOT_LOADED);
 
-       priv = ecal->priv;
-       return priv->load_state;
+       return ecal->priv->load_state;
 }
 
 /**
@@ -1417,7 +927,6 @@ e_cal_get_source (ECal *ecal)
 {
        ECalPrivate *priv;
 
-       g_return_val_if_fail (ecal != NULL, NULL);
        g_return_val_if_fail (E_IS_CAL (ecal), NULL);
 
        priv = ecal->priv;
@@ -1442,13 +951,9 @@ e_cal_get_source (ECal *ecal)
 const gchar *
 e_cal_get_local_attachment_store (ECal *ecal)
 {
-       ECalPrivate *priv;
-
-       g_return_val_if_fail (ecal != NULL, NULL);
        g_return_val_if_fail (E_IS_CAL (ecal), NULL);
 
-       priv = ecal->priv;
-       return (const gchar *) priv->local_attachment_store;
+       return e_cal_client_get_local_attachment_store (ecal->priv->client);
 }
 
 /**
@@ -1470,13 +975,10 @@ e_cal_is_read_only (ECal *ecal,
                     gboolean *read_only,
                     GError **error)
 {
-       ECalPrivate *priv;
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (read_only != NULL, FALSE);
 
-       if (!(ecal && E_IS_CAL (ecal)))
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_INVALID_ARG, error);
-
-       priv = ecal->priv;
-       *read_only = priv->read_only;
+       *read_only = e_client_is_readonly (E_CLIENT (ecal->priv->client));
 
        return TRUE;
 }
@@ -1500,32 +1002,13 @@ e_cal_get_cal_address (ECal *ecal,
                        gchar **cal_address,
                        GError **error)
 {
-       ECalPrivate *priv;
-
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (cal_address != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-       *cal_address = NULL;
-
-       LOCK_CACHE ();
-       if (priv->cal_address == NULL) {
-               e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-               if (priv->load_state != E_CAL_LOAD_LOADED) {
-                       UNLOCK_CACHE ();
-                       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-               }
-
-               if (!e_gdbus_cal_call_get_backend_property_sync (priv->dbus_proxy, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS, &priv->cal_address, NULL, error)) {
-                       UNLOCK_CACHE ();
-                       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-               }
-       }
-
-       *cal_address = g_strdup (priv->cal_address);
-       UNLOCK_CACHE ();
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (cal_address != NULL, FALSE);
 
-       return TRUE;
+       return e_client_get_backend_property_sync (
+               E_CLIENT (ecal->priv->client),
+               CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS,
+               cal_address, NULL, error);
 }
 
 /**
@@ -1547,23 +1030,13 @@ e_cal_get_alarm_email_address (ECal *ecal,
                                gchar **alarm_address,
                                GError **error)
 {
-       ECalPrivate *priv;
-
-       e_return_error_if_fail (alarm_address != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-       *alarm_address = NULL;
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       if (!e_gdbus_cal_call_get_backend_property_sync (priv->dbus_proxy, CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS, alarm_address, NULL, error)) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (alarm_address != NULL, FALSE);
 
-       return TRUE;
+       return e_client_get_backend_property_sync (
+               E_CLIENT (ecal->priv->client),
+               CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS,
+               alarm_address, NULL, error);
 }
 
 /**
@@ -1584,59 +1057,15 @@ e_cal_get_ldap_attribute (ECal *ecal,
                           gchar **ldap_attribute,
                           GError **error)
 {
-       ECalPrivate *priv;
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (ldap_attribute != NULL, FALSE);
 
-       e_return_error_if_fail (ldap_attribute != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
        *ldap_attribute = NULL;
 
-       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_NOT_SUPPORTED, error);
-}
-
-static gboolean
-load_capabilities (ECal *ecal,
-                   GError **error)
-{
-       ECalPrivate *priv;
-
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       LOCK_CACHE ();
-
-       if (priv->capabilities) {
-               UNLOCK_CACHE ();
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
-       }
-
-       if (!e_gdbus_cal_call_get_backend_property_sync (priv->dbus_proxy, CLIENT_BACKEND_PROPERTY_CAPABILITIES, &priv->capabilities, NULL, error)) {
-               UNLOCK_CACHE ();
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
-
-       UNLOCK_CACHE ();
-
-       return TRUE;
-}
-
-static gboolean
-check_capability (ECal *ecal,
-                  const gchar *cap)
-{
-       ECalPrivate *priv;
-
-       priv = ecal->priv;
-
-       /* FIXME Check result */
-       load_capabilities (ecal, NULL);
-       if (priv->capabilities && strstr (priv->capabilities, cap))
-               return TRUE;
+       g_set_error (
+               error, E_CALENDAR_ERROR,
+               E_CALENDAR_STATUS_NOT_SUPPORTED,
+               _("Not supported"));
 
        return FALSE;
 }
@@ -1654,10 +1083,11 @@ check_capability (ECal *ecal,
 gboolean
 e_cal_get_one_alarm_only (ECal *ecal)
 {
-       g_return_val_if_fail (ecal != NULL, FALSE);
-       g_return_val_if_fail (ecal && E_IS_CAL (ecal), FALSE);
+       const gchar *cap = CAL_STATIC_CAPABILITY_ONE_ALARM_ONLY;
 
-       return check_capability (ecal, CAL_STATIC_CAPABILITY_ONE_ALARM_ONLY);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+
+       return e_cal_get_static_capability (ecal, cap);
 }
 
 /**
@@ -1674,10 +1104,11 @@ e_cal_get_one_alarm_only (ECal *ecal)
 gboolean
 e_cal_get_organizer_must_attend (ECal *ecal)
 {
-       g_return_val_if_fail (ecal != NULL, FALSE);
+       const gchar *cap = CAL_STATIC_CAPABILITY_ORGANIZER_MUST_ATTEND;
+
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
 
-       return check_capability (ecal, CAL_STATIC_CAPABILITY_ORGANIZER_MUST_ATTEND);
+       return e_cal_get_static_capability (ecal, cap);
 }
 
 /**
@@ -1694,10 +1125,11 @@ e_cal_get_organizer_must_attend (ECal *ecal)
 gboolean
 e_cal_get_recurrences_no_master (ECal *ecal)
 {
-       g_return_val_if_fail (ecal != NULL, FALSE);
+       const gchar *cap = CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER;
+
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
 
-       return check_capability (ecal, CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER);
+       return e_cal_get_static_capability (ecal, cap);
 }
 
 /**
@@ -1715,10 +1147,10 @@ gboolean
 e_cal_get_static_capability (ECal *ecal,
                              const gchar *cap)
 {
-       g_return_val_if_fail (ecal != NULL, FALSE);
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (cap != NULL, FALSE);
 
-       return check_capability (ecal, cap);
+       return e_client_check_capability (E_CLIENT (ecal->priv->client), cap);
 }
 
 /**
@@ -1734,10 +1166,11 @@ e_cal_get_static_capability (ECal *ecal,
 gboolean
 e_cal_get_save_schedules (ECal *ecal)
 {
-       g_return_val_if_fail (ecal != NULL, FALSE);
+       const gchar *cap = CAL_STATIC_CAPABILITY_SAVE_SCHEDULES;
+
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
 
-       return check_capability (ecal, CAL_STATIC_CAPABILITY_SAVE_SCHEDULES);
+       return e_cal_get_static_capability (ecal, cap);
 }
 
 /**
@@ -1755,10 +1188,11 @@ e_cal_get_save_schedules (ECal *ecal)
 gboolean
 e_cal_get_organizer_must_accept (ECal *ecal)
 {
-       g_return_val_if_fail (ecal != NULL, FALSE);
+       const gchar *cap = CAL_STATIC_CAPABILITY_ORGANIZER_MUST_ACCEPT;
+
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
 
-       return check_capability (ecal, CAL_STATIC_CAPABILITY_ORGANIZER_MUST_ACCEPT);
+       return e_cal_get_static_capability (ecal, cap);
 }
 
 /**
@@ -1776,10 +1210,11 @@ e_cal_get_organizer_must_accept (ECal *ecal)
 gboolean
 e_cal_get_refresh_supported (ECal *ecal)
 {
-       g_return_val_if_fail (ecal != NULL, FALSE);
+       const gchar *cap = CAL_STATIC_CAPABILITY_REFRESH_SUPPORTED;
+
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
 
-       return check_capability (ecal, CAL_STATIC_CAPABILITY_REFRESH_SUPPORTED);
+       return e_cal_get_static_capability (ecal, cap);
 }
 
 /**
@@ -1797,32 +1232,14 @@ gboolean
 e_cal_set_mode (ECal *ecal,
                 CalMode mode)
 {
-       ECalPrivate *priv;
-
-       g_return_val_if_fail (ecal != NULL, FALSE);
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
        g_return_val_if_fail (mode & CAL_MODE_ANY, FALSE);
 
-       priv = ecal->priv;
-       g_return_val_if_fail (priv->dbus_proxy, FALSE);
-       g_return_val_if_fail (priv->load_state == E_CAL_LOAD_LOADED, FALSE);
-
-       g_debug ("%s: This function is not supported since 3.2", G_STRFUNC);
+       g_warning ("%s: This function is not supported since 3.2", G_STRFUNC);
 
        return FALSE;
 }
 
-/* This is used in the callback which fetches all the timezones needed for an
- * object. */
-typedef struct _ECalGetTimezonesData ECalGetTimezonesData;
-struct _ECalGetTimezonesData {
-       ECal *ecal;
-
-       /* This starts out at E_CALENDAR_STATUS_OK. If an error occurs this
-        * contains the last error. */
-       ECalendarStatus status;
-};
-
 /**
  * e_cal_get_default_object: (skip)
  * @ecal: A calendar client.
@@ -1841,38 +1258,11 @@ e_cal_get_default_object (ECal *ecal,
                           icalcomponent **icalcomp,
                           GError **error)
 {
-       ECalPrivate *priv;
-       ECalendarStatus status;
-       gchar *object = NULL;
-
-       e_return_error_if_fail (icalcomp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-       *icalcomp = NULL;
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       if (!e_gdbus_cal_call_get_backend_property_sync (priv->dbus_proxy, CAL_BACKEND_PROPERTY_DEFAULT_OBJECT, &object, NULL, error)) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
-
-       if (object) {
-               *icalcomp = icalparser_parse_string (object);
-               g_free (object);
-
-               if (!(*icalcomp))
-                       status = E_CALENDAR_STATUS_INVALID_OBJECT;
-               else
-                       status = E_CALENDAR_STATUS_OK;
-
-               E_CALENDAR_CHECK_STATUS (status, error);
-       } else
-               status = E_CALENDAR_STATUS_OTHER_ERROR;
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (icalcomp != NULL, FALSE);
 
-       E_CALENDAR_CHECK_STATUS (status, error);
+       return e_cal_client_get_default_object_sync (
+               ecal->priv->client, icalcomp, NULL, error);
 }
 
 /**
@@ -1897,42 +1287,12 @@ e_cal_get_attachments_for_comp (ECal *ecal,
                                 GSList **list,
                                 GError **error)
 {
-       ECalPrivate *priv;
-       ECalendarStatus status;
-       gchar **list_array;
-       gchar **strv;
-
-       e_return_error_if_fail (uid != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (list != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-       *list = NULL;
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       strv = e_gdbus_cal_encode_get_attachment_uris (uid, rid);
-       if (!e_gdbus_cal_call_get_attachment_uris_sync (priv->dbus_proxy, (const gchar * const *) strv, &list_array, NULL, error)) {
-               g_strfreev (strv);
-
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
-
-       g_strfreev (strv);
-
-       if (list_array) {
-               gchar **string;
-               for (string = list_array; *string; string++) {
-                       *list = g_slist_append (*list, g_strdup (*string));
-               }
-               g_strfreev (list_array);
-               status = E_CALENDAR_STATUS_OK;
-       } else
-               status = E_CALENDAR_STATUS_OTHER_ERROR;
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (uid != NULL, FALSE);
+       g_return_val_if_fail (list != NULL, FALSE);
 
-       E_CALENDAR_CHECK_STATUS (status, error);
+       return e_cal_client_get_attachment_uris_sync (
+               ecal->priv->client, uid, rid, list, NULL, error);
 }
 
 /**
@@ -1957,72 +1317,12 @@ e_cal_get_object (ECal *ecal,
                   icalcomponent **icalcomp,
                   GError **error)
 {
-       ECalPrivate *priv;
-       ECalendarStatus status;
-       gchar *object = NULL, **strv;
-       icalcomponent *tmp_icalcomp;
-       icalcomponent_kind kind;
-
-       e_return_error_if_fail (uid != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (icalcomp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-       *icalcomp = NULL;
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       strv = e_gdbus_cal_encode_get_object (uid, rid);
-       if (!e_gdbus_cal_call_get_object_sync (priv->dbus_proxy, (const gchar * const *) strv, &object, NULL, error)) {
-               g_strfreev (strv);
-
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
-
-       g_strfreev (strv);
-
-       status = E_CALENDAR_STATUS_OK;
-       tmp_icalcomp = icalparser_parse_string (object);
-       if (!tmp_icalcomp) {
-               status = E_CALENDAR_STATUS_INVALID_OBJECT;
-               *icalcomp = NULL;
-       } else {
-               kind = icalcomponent_isa (tmp_icalcomp);
-               if ((kind == ICAL_VEVENT_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_EVENT) ||
-                   (kind == ICAL_VTODO_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_TODO) ||
-                   (kind == ICAL_VJOURNAL_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_JOURNAL)) {
-                       *icalcomp = icalcomponent_new_clone (tmp_icalcomp);
-               } else if (kind == ICAL_VCALENDAR_COMPONENT) {
-                       icalcomponent *subcomp = NULL;
-
-                       switch (priv->type) {
-                       case E_CAL_SOURCE_TYPE_EVENT :
-                               subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VEVENT_COMPONENT);
-                               break;
-                       case E_CAL_SOURCE_TYPE_TODO :
-                               subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VTODO_COMPONENT);
-                               break;
-                       case E_CAL_SOURCE_TYPE_JOURNAL :
-                               subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VJOURNAL_COMPONENT);
-                               break;
-                       default:
-                               /* ignore everything else */
-                               break;
-                       }
-
-                       /* we are only interested in the first component */
-                       if (subcomp)
-                               *icalcomp = icalcomponent_new_clone (subcomp);
-               }
-
-               icalcomponent_free (tmp_icalcomp);
-       }
-
-       g_free (object);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (uid != NULL, FALSE);
+       g_return_val_if_fail (icalcomp != NULL, FALSE);
 
-       E_CALENDAR_CHECK_STATUS (status, error);
+       return e_cal_client_get_object_sync (
+               ecal->priv->client, uid, rid, icalcomp, NULL, error);
 }
 
 /**
@@ -2046,82 +1346,30 @@ e_cal_get_objects_for_uid (ECal *ecal,
                            GList **objects,
                            GError **error)
 {
-       ECalPrivate *priv;
-       ECalendarStatus status;
-       gchar *object = NULL, **strv;
-
-       e_return_error_if_fail (uid != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (objects != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-       *objects = NULL;
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
+       GSList *slist = NULL;
+       gboolean success;
 
-       strv = e_gdbus_cal_encode_get_object (uid, "");
-       if (!e_gdbus_cal_call_get_object_sync (priv->dbus_proxy, (const gchar * const *) strv, &object, NULL, error)) {
-               g_strfreev (strv);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (uid != NULL, FALSE);
+       g_return_val_if_fail (objects != NULL, FALSE);
 
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
+       *objects = NULL;
 
-       g_strfreev (strv);
+       success = e_cal_client_get_objects_for_uid_sync (
+               ecal->priv->client, uid, &slist, NULL, error);
 
-       status = E_CALENDAR_STATUS_OK;
-       {
-               icalcomponent *icalcomp;
-               icalcomponent_kind kind;
+       if (slist != NULL) {
+               GSList *link;
 
-               icalcomp = icalparser_parse_string (object);
-               if (!icalcomp) {
-                       status = E_CALENDAR_STATUS_INVALID_OBJECT;
-                       *objects = NULL;
-               } else {
-                       ECalComponent *comp;
-
-                       kind = icalcomponent_isa (icalcomp);
-                       if ((kind == ICAL_VEVENT_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_EVENT) ||
-                           (kind == ICAL_VTODO_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_TODO) ||
-                           (kind == ICAL_VJOURNAL_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_JOURNAL)) {
-                               comp = e_cal_component_new ();
-                               e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
-                               *objects = g_list_append (NULL, comp);
-                       } else if (kind == ICAL_VCALENDAR_COMPONENT) {
-                               icalcomponent *subcomp;
-                               icalcomponent_kind kind_to_find;
-
-                               switch (priv->type) {
-                               case E_CAL_SOURCE_TYPE_TODO :
-                                       kind_to_find = ICAL_VTODO_COMPONENT;
-                                       break;
-                               case E_CAL_SOURCE_TYPE_JOURNAL :
-                                       kind_to_find = ICAL_VJOURNAL_COMPONENT;
-                                       break;
-                               case E_CAL_SOURCE_TYPE_EVENT :
-                               default:
-                                       kind_to_find = ICAL_VEVENT_COMPONENT;
-                                       break;
-                               }
-
-                               *objects = NULL;
-                               subcomp = icalcomponent_get_first_component (icalcomp, kind_to_find);
-                               while (subcomp) {
-                                       comp = e_cal_component_new ();
-                                       e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (subcomp));
-                                       *objects = g_list_append (*objects, comp);
-                                       subcomp = icalcomponent_get_next_component (icalcomp, kind_to_find);
-                               }
-                       }
+               /* XXX Never use GSList in a public API. */
+               for (link = slist; link != NULL; link = g_slist_next (link))
+                       *objects = g_list_prepend (*objects, link->data);
+               *objects = g_list_reverse (*objects);
 
-                       icalcomponent_free (icalcomp);
-               }
+               g_slist_free (slist);
        }
-       g_free (object);
 
-       E_CALENDAR_CHECK_STATUS (status, error);
+       return success;
 }
 
 /**
@@ -2175,16 +1423,19 @@ e_cal_get_changes (ECal *ecal,
                    GList **changes,
                    GError **error)
 {
-       ECalPrivate *priv;
 
-       e_return_error_if_fail (changes != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (change_id != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (change_id != NULL, FALSE);
+       g_return_val_if_fail (changes != NULL, FALSE);
+
        *changes = NULL;
 
-       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_NOT_SUPPORTED, error);
+       g_set_error (
+               error, E_CALENDAR_ERROR,
+               E_CALENDAR_STATUS_NOT_SUPPORTED,
+               _("Not supported"));
+
+       return FALSE;
 }
 
 /**
@@ -2236,43 +1487,30 @@ e_cal_get_object_list (ECal *ecal,
                        GList **objects,
                        GError **error)
 {
-       ECalPrivate *priv;
-       gchar **object_array = NULL, *gdbus_query = NULL;
-
-       e_return_error_if_fail (objects != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (query, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-       *objects = NULL;
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
+       GSList *slist = NULL;
+       gboolean success;
 
-       if (!e_gdbus_cal_call_get_object_list_sync (priv->dbus_proxy, e_util_ensure_gdbus_string (query, &gdbus_query), &object_array, NULL, error)) {
-               g_free (gdbus_query);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (query != NULL, FALSE);
+       g_return_val_if_fail (objects != NULL, FALSE);
 
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
+       *objects = NULL;
 
-       g_free (gdbus_query);
+       success = e_cal_client_get_object_list_sync (
+               ecal->priv->client, query, &slist, NULL, error);
 
-       if (object_array) {
-               icalcomponent *comp;
-               gchar **object;
-               for (object = object_array; *object; object++) {
-                       comp = icalcomponent_new_from_string (*object);
-                       if (!comp) continue;
-                       *objects = g_list_prepend (*objects, comp);
-               }
+       if (slist != NULL) {
+               GSList *link;
 
-               g_strfreev (object_array);
+               /* XXX Never use GSList in a public API. */
+               for (link = slist; link != NULL; link = g_slist_next (link))
+                       *objects = g_list_prepend (*objects, link->data);
+               *objects = g_list_reverse (*objects);
 
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+               g_slist_free (slist);
        }
-       else
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OTHER_ERROR, error);
+
+       return success;
 }
 
 /**
@@ -2293,517 +1531,97 @@ e_cal_get_object_list (ECal *ecal,
 gboolean
 e_cal_get_object_list_as_comp (ECal *ecal,
                                const gchar *query,
-                               GList **objects,
-                               GError **error)
-{
-       GList *ical_objects = NULL;
-       GList *l;
-
-       e_return_error_if_fail (objects != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       *objects = NULL;
-
-       e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (query, E_CALENDAR_STATUS_INVALID_ARG);
-
-       if (!e_cal_get_object_list (ecal, query, &ical_objects, error))
-               return FALSE;
-
-       for (l = ical_objects; l; l = l->next) {
-               ECalComponent *comp;
-
-               comp = e_cal_component_new ();
-               e_cal_component_set_icalcomponent (comp, l->data);
-               *objects = g_list_prepend (*objects, comp);
-       }
-
-       g_list_free (ical_objects);
-
-       return TRUE;
-}
-
-/**
- * e_cal_free_object_list: (skip)
- * @objects: List of objects to be freed.
- *
- * Frees a list of objects as returned by #e_cal_get_object_list.
- *
- * Deprecated: 3.2: Use e_cal_client_free_icalcomp_slist() instead.
- */
-void
-e_cal_free_object_list (GList *objects)
-{
-       GList *l;
-
-       for (l = objects; l; l = l->next)
-               icalcomponent_free (l->data);
-
-       g_list_free (objects);
-}
-
-/**
- * e_cal_get_free_busy: (skip)
- * @ecal: A calendar client.
- * @users: List of users to retrieve free/busy information for.
- * @start: Start time for query.
- * @end: End time for query.
- * @freebusy: Return value for VFREEBUSY objects.
- * @error: Placeholder for error information.
- *
- * Gets free/busy information from the calendar server.
- *
- * Returns: TRUE if the operation was successful, FALSE otherwise.
- *
- * Deprecated: 3.2: Use e_cal_client_get_free_busy_sync() instead.
- */
-gboolean
-e_cal_get_free_busy (ECal *ecal,
-                     GList *users,
-                     time_t start,
-                     time_t end,
-                     GList **freebusy,
-                     GError **error)
-{
-       ECalPrivate *priv;
-       gchar **strv;
-       GSList *susers;
-       GList *l;
-
-       e_return_error_if_fail (users != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (freebusy != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-       *freebusy = NULL;
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       susers = NULL;
-       for (l = users; l; l = l->next) {
-               susers = g_slist_prepend (susers, l->data);
-       }
-       susers = g_slist_reverse (susers);
-       strv = e_gdbus_cal_encode_get_free_busy (start, end, susers);
-       g_slist_free (susers);
-
-       g_mutex_lock (priv->free_busy_data_lock);
-       priv->free_busy_data = freebusy;
-       g_mutex_unlock (priv->free_busy_data_lock);
-
-       if (!e_gdbus_cal_call_get_free_busy_sync (priv->dbus_proxy, (const gchar * const *) strv, NULL, error)) {
-               g_strfreev (strv);
-               g_mutex_lock (priv->free_busy_data_lock);
-               priv->free_busy_data = NULL;
-               g_mutex_unlock (priv->free_busy_data_lock);
-
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
-       g_strfreev (strv);
-
-       g_mutex_lock (priv->free_busy_data_lock);
-       priv->free_busy_data = NULL;
-       g_mutex_unlock (priv->free_busy_data_lock);
-
-       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
-}
-
-struct comp_instance {
-       ECalComponent *comp;
-       time_t start;
-       time_t end;
-};
-
-struct instances_info {
-       GList **instances;
-       icaltimezone *start_zone;
-};
-
-/* Called from cal_recur_generate_instances(); adds an instance to the list */
-static gboolean
-add_instance (ECalComponent *comp,
-              time_t start,
-              time_t end,
-              gpointer data)
-{
-       GList **list;
-       struct comp_instance *ci;
-       struct icaltimetype itt;
-       icalcomponent *icalcomp;
-       struct instances_info *instances_hold;
-
-       instances_hold = data;
-       list = instances_hold->instances;
-
-       ci = g_new (struct comp_instance, 1);
-
-       icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp));
-
-       /* add the instance to the list */
-       ci->comp = e_cal_component_new ();
-       e_cal_component_set_icalcomponent (ci->comp, icalcomp);
-
-       /* set the RECUR-ID for the instance */
-       if (e_cal_util_component_has_recurrences (icalcomp)) {
-               if (!(icalcomponent_get_first_property (icalcomp, ICAL_RECURRENCEID_PROPERTY))) {
-                       ECalComponentRange *range;
-                       ECalComponentDateTime datetime;
-
-                       datetime.value = NULL;
-                       datetime.tzid = NULL;
-
-                       e_cal_component_get_dtstart (comp, &datetime);
-
-                       if (instances_hold->start_zone)
-                               itt = icaltime_from_timet_with_zone (start, datetime.value && datetime.value->is_date, instances_hold->start_zone);
-                       else {
-                               itt = icaltime_from_timet (start, datetime.value && datetime.value->is_date);
-
-                               if (datetime.tzid) {
-                                       g_free ((gchar *) datetime.tzid);
-                                       datetime.tzid = NULL;
-                               }
-                       }
-
-                       g_free (datetime.value);
-                       datetime.value = &itt;
-
-                       range = g_new0 (ECalComponentRange, 1);
-                       range->type = E_CAL_COMPONENT_RANGE_SINGLE;
-                       range->datetime = datetime;
-
-                       e_cal_component_set_recurid (ci->comp, range);
-
-                       if (datetime.tzid)
-                               g_free ((gchar *) datetime.tzid);
-                       g_free (range);
-               }
-       }
-
-       ci->start = start;
-       ci->end = end;
-
-       *list = g_list_prepend (*list, ci);
-
-       return TRUE;
-}
-
-/* Used from g_list_sort(); compares two struct comp_instance structures */
-static gint
-compare_comp_instance (gconstpointer a,
-                       gconstpointer b)
-{
-       const struct comp_instance *cia, *cib;
-       time_t diff;
-
-       cia = a;
-       cib = b;
-
-       diff = cia->start - cib->start;
-       return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
-}
-
-static GList *
-process_detached_instances (GList *instances,
-                            GList *detached_instances)
-{
-       struct comp_instance *ci, *cid;
-       GList *dl, *unprocessed_instances = NULL;
-
-       for (dl = detached_instances; dl != NULL; dl = dl->next) {
-               GList *il;
-               const gchar *uid;
-               gboolean processed;
-               ECalComponentRange recur_id, instance_recur_id;
-
-               processed = FALSE;
-               recur_id.type = E_CAL_COMPONENT_RANGE_SINGLE;
-               instance_recur_id.type = E_CAL_COMPONENT_RANGE_SINGLE;
-
-               cid = dl->data;
-               e_cal_component_get_uid (cid->comp, &uid);
-               e_cal_component_get_recurid (cid->comp, &recur_id);
-
-               /* search for coincident instances already expanded */
-               for (il = instances; il != NULL; il = il->next) {
-                       const gchar *instance_uid;
-                       gint cmp;
-
-                       ci = il->data;
-                       e_cal_component_get_uid (ci->comp, &instance_uid);
-                       e_cal_component_get_recurid (ci->comp, &instance_recur_id);
-                       if (strcmp (uid, instance_uid) == 0) {
-                               gchar *i_rid = NULL, *d_rid = NULL;
-
-                               i_rid = e_cal_component_get_recurid_as_string (ci->comp);
-                               d_rid = e_cal_component_get_recurid_as_string (cid->comp);
-
-                               if (i_rid && d_rid && strcmp (i_rid, d_rid) == 0) {
-                                       g_object_unref (ci->comp);
-                                       ci->comp = g_object_ref (cid->comp);
-                                       ci->start = cid->start;
-                                       ci->end = cid->end;
-
-                                       processed = TRUE;
-                               } else {
-                                       if (!instance_recur_id.datetime.value ||
-                                           !recur_id.datetime.value) {
-                                               /*
-                                                * Prevent obvious segfault by ignoring missing
-                                                * recurrency ids. Real problem might be elsewhere,
-                                                * but anything is better than crashing...
-                                                */
-                                               g_log (
-                                                       G_LOG_DOMAIN,
-                                                       G_LOG_LEVEL_CRITICAL,
-                                                       "UID %s: instance RECURRENCE-ID %s + detached instance RECURRENCE-ID %s: cannot compare",
-                                                       uid,
-                                                       i_rid,
-                                                       d_rid);
-
-                                               e_cal_component_free_datetime (&instance_recur_id.datetime);
-                                               g_free (i_rid);
-                                               g_free (d_rid);
-                                               continue;
-                                       }
-                                       cmp = icaltime_compare (
-                                               *instance_recur_id.datetime.value,
-                                               *recur_id.datetime.value);
-                                       if ((recur_id.type == E_CAL_COMPONENT_RANGE_THISPRIOR && cmp <= 0) ||
-                                               (recur_id.type == E_CAL_COMPONENT_RANGE_THISFUTURE && cmp >= 0)) {
-                                               ECalComponent *comp;
-
-                                               comp = e_cal_component_new ();
-                                               e_cal_component_set_icalcomponent (
-                                                       comp,
-                                                       icalcomponent_new_clone (e_cal_component_get_icalcomponent (cid->comp)));
-                                               e_cal_component_set_recurid (comp, &instance_recur_id);
-
-                                               /* replace the generated instances */
-                                               g_object_unref (ci->comp);
-                                               ci->comp = comp;
-                                       }
-                               }
-                               g_free (i_rid);
-                               g_free (d_rid);
-                       }
-                       e_cal_component_free_datetime (&instance_recur_id.datetime);
-               }
-
-               e_cal_component_free_datetime (&recur_id.datetime);
-
-               if (!processed)
-                       unprocessed_instances = g_list_prepend (unprocessed_instances, cid);
-       }
-
-       /* add the unprocessed instances (ie, detached instances with no master object */
-       while (unprocessed_instances != NULL) {
-               cid = unprocessed_instances->data;
-               ci = g_new0 (struct comp_instance, 1);
-               ci->comp = g_object_ref (cid->comp);
-               ci->start = cid->start;
-               ci->end = cid->end;
-               instances = g_list_append (instances, ci);
-
-               unprocessed_instances = g_list_remove (unprocessed_instances, cid);
-       }
-
-       return instances;
-}
-
-static void
-generate_instances (ECal *ecal,
-                    time_t start,
-                    time_t end,
-                    const gchar *uid,
-                    ECalRecurInstanceFn cb,
-                    gpointer cb_data)
-{
-       GList *objects = NULL;
-       GList *instances, *detached_instances = NULL;
-       GList *l;
-       gchar *query;
-       gchar *iso_start, *iso_end;
-       ECalPrivate *priv;
-
-       priv = ecal->priv;
-
-       /* Generate objects */
-       if (uid && *uid) {
-               GError *error = NULL;
-               gint tries = 0;
-
-try_again:
-               if (!e_cal_get_objects_for_uid (ecal, uid, &objects, &error)) {
-                       if (error->code == E_CALENDAR_STATUS_BUSY && tries >= 10) {
-                               tries++;
-                               g_usleep (500);
-                               g_clear_error (&error);
-
-                               goto try_again;
-                       }
-
-                       unwrap_gerror (&error);
-                       g_message ("Failed to get recurrence objects for uid %s \n", error ? error->message : "Unknown error");
-                       g_clear_error (&error);
-                       return;
-               }
-       }
-       else {
-               iso_start = isodate_from_time_t (start);
-               if (!iso_start)
-                       return;
-
-               iso_end = isodate_from_time_t (end);
-               if (!iso_end) {
-                       g_free (iso_start);
-                       return;
-               }
-
-               query = g_strdup_printf (
-                       "(occur-in-time-range? (make-time \"%s\") (make-time \"%s\"))",
-                       iso_start, iso_end);
-               g_free (iso_start);
-               g_free (iso_end);
-               if (!e_cal_get_object_list_as_comp (ecal, query, &objects, NULL)) {
-                       g_free (query);
-                       return;
-               }
-               g_free (query);
-       }
-
-       instances = NULL;
-
-       for (l = objects; l; l = l->next) {
-               ECalComponent *comp;
-               icaltimezone *default_zone;
-
-               if (priv->default_zone)
-                       default_zone = priv->default_zone;
-               else
-                       default_zone = icaltimezone_get_utc_timezone ();
-
-               comp = l->data;
-               if (e_cal_component_is_instance (comp)) {
-                       struct comp_instance *ci;
-                       ECalComponentDateTime dtstart, dtend;
-                       icaltimezone *start_zone = NULL, *end_zone = NULL;
-
-                       /* keep the detached instances apart */
-                       ci = g_new0 (struct comp_instance, 1);
-                       ci->comp = comp;
-
-                       e_cal_component_get_dtstart (comp, &dtstart);
-                       e_cal_component_get_dtend (comp, &dtend);
-
-                       /* For DATE-TIME values with a TZID, we use
-                        * e_cal_resolve_tzid_cb to resolve the TZID.
-                        * For DATE values and DATE-TIME values without a
-                        * TZID (i.e. floating times) we use the default
-                        * timezone. */
-                       if (dtstart.tzid && dtstart.value && !dtstart.value->is_date) {
-                               start_zone = e_cal_resolve_tzid_cb (dtstart.tzid, ecal);
-                               if (!start_zone)
-                                       start_zone = default_zone;
-                       } else {
-                               start_zone = default_zone;
-                       }
-
-                       if (dtend.tzid && dtend.value && !dtend.value->is_date) {
-                               end_zone = e_cal_resolve_tzid_cb (dtend.tzid, ecal);
-                               if (!end_zone)
-                                       end_zone = default_zone;
-                       } else {
-                               end_zone = default_zone;
-                       }
-
-                       ci->start = icaltime_as_timet_with_zone (*dtstart.value, start_zone);
-
-                       if (dtend.value)
-                               ci->end = icaltime_as_timet_with_zone (*dtend.value, end_zone);
-                       else if (icaltime_is_date (*dtstart.value))
-                               ci->end = time_day_end (ci->start);
-                       else
-                               ci->end = ci->start;
-
-                       e_cal_component_free_datetime (&dtstart);
-                       e_cal_component_free_datetime (&dtend);
-
-                       if (ci->start <= end && ci->end >= start) {
-                               detached_instances = g_list_prepend (detached_instances, ci);
-                       } else {
-                               /* it doesn't fit to our time range, thus skip it */
-                               g_object_unref (G_OBJECT (ci->comp));
-                               g_free (ci);
-                       }
-               } else {
-                       ECalComponentDateTime datetime;
-                       icaltimezone *start_zone = NULL;
-                       struct instances_info *instances_hold;
-
-                       /* Get the start timezone */
-                       e_cal_component_get_dtstart (comp, &datetime);
-                       if (datetime.tzid)
-                               e_cal_get_timezone (ecal, datetime.tzid, &start_zone, NULL);
-                       else
-                               start_zone = NULL;
-                       e_cal_component_free_datetime (&datetime);
-
-                       instances_hold = g_new0 (struct instances_info, 1);
-                       instances_hold->instances = &instances;
-                       instances_hold->start_zone = start_zone;
-
-                       e_cal_recur_generate_instances (
-                               comp, start, end, add_instance, instances_hold,
-                               e_cal_resolve_tzid_cb, ecal,
-                               default_zone);
-
-                       g_free (instances_hold);
-                       g_object_unref (comp);
-               }
-       }
-
-       g_list_free (objects);
+                               GList **objects,
+                               GError **error)
+{
+       GSList *slist = NULL;
+       gboolean success;
 
-       /* Generate instances and spew them out */
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (query != NULL, FALSE);
+       g_return_val_if_fail (objects != NULL, FALSE);
 
-       instances = g_list_sort (instances, compare_comp_instance);
-       instances = process_detached_instances (instances, detached_instances);
+       *objects = NULL;
 
-       for (l = instances; l; l = l->next) {
-               struct comp_instance *ci;
-               gboolean result;
+       success = e_cal_client_get_object_list_as_comps_sync (
+               ecal->priv->client, query, &slist, NULL, error);
 
-               ci = l->data;
+       if (slist != NULL) {
+               GSList *link;
 
-               result = (* cb) (ci->comp, ci->start, ci->end, cb_data);
+               /* XXX Never use GSList in a public API. */
+               for (link = slist; link != NULL; link = g_slist_next (link))
+                       *objects = g_list_prepend (*objects, link->data);
+               *objects = g_list_reverse (*objects);
 
-               if (!result)
-                       break;
+               g_slist_free (slist);
        }
 
-       /* Clean up */
+       return success;
+}
 
-       for (l = instances; l; l = l->next) {
-               struct comp_instance *ci;
+/**
+ * e_cal_free_object_list: (skip)
+ * @objects: List of objects to be freed.
+ *
+ * Frees a list of objects as returned by #e_cal_get_object_list.
+ *
+ * Deprecated: 3.2: Use e_cal_client_free_icalcomp_slist() instead.
+ */
+void
+e_cal_free_object_list (GList *objects)
+{
+       g_list_free_full (objects, (GDestroyNotify) icalcomponent_free);
+}
 
-               ci = l->data;
-               g_object_unref (G_OBJECT (ci->comp));
-               g_free (ci);
-       }
+/**
+ * e_cal_get_free_busy: (skip)
+ * @ecal: A calendar client.
+ * @users: List of users to retrieve free/busy information for.
+ * @start: Start time for query.
+ * @end: End time for query.
+ * @freebusy: Return value for VFREEBUSY objects.
+ * @error: Placeholder for error information.
+ *
+ * Gets free/busy information from the calendar server.
+ *
+ * Returns: TRUE if the operation was successful, FALSE otherwise.
+ *
+ * Deprecated: 3.2: Use e_cal_client_get_free_busy_sync() instead.
+ */
+gboolean
+e_cal_get_free_busy (ECal *ecal,
+                     GList *users,
+                     time_t start,
+                     time_t end,
+                     GList **freebusy,
+                     GError **error)
+{
+       GSList *slist = NULL;
+       gboolean success;
 
-       g_list_free (instances);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (users != NULL, FALSE);
+       g_return_val_if_fail (freebusy != NULL, FALSE);
 
-       for (l = detached_instances; l; l = l->next) {
-               struct comp_instance *ci;
+       *freebusy = NULL;
 
-               ci = l->data;
-               g_object_unref (G_OBJECT (ci->comp));
-               g_free (ci);
-       }
+       /* XXX Never use GSList in a public API. */
+       for (; users != NULL; users = g_list_next (users))
+               slist = g_slist_prepend (slist, users->data);
 
-       g_list_free (detached_instances);
+       /* FIXME ECalClient's API for this is a giant W.T.F.
+        *       There's no way to populate the freebusy list
+        *       in a way that will avoid deadlocking for all
+        *       cases.  I guess leave the list empty and hope
+        *       no one notices until ECalClient grows a saner
+        *       free/busy API. */
+       success = e_cal_client_get_free_busy_sync (
+               ecal->priv->client, start, end, slist, NULL, error);
 
+       g_slist_free (slist);
+
+       return success;
 }
 
 /**
@@ -2830,19 +1648,10 @@ e_cal_generate_instances (ECal *ecal,
                           ECalRecurInstanceFn cb,
                           gpointer cb_data)
 {
-       ECalPrivate *priv;
-
-       g_return_if_fail (ecal != NULL);
        g_return_if_fail (E_IS_CAL (ecal));
 
-       priv = ecal->priv;
-       g_return_if_fail (priv->load_state == E_CAL_LOAD_LOADED);
-
-       g_return_if_fail (start >= 0);
-       g_return_if_fail (end >= 0);
-       g_return_if_fail (cb != NULL);
-
-       generate_instances (ecal, start, end, NULL, cb, cb_data);
+       e_cal_client_generate_instances_sync (
+               ecal->priv->client, start, end, cb, cb_data);
 }
 
 /**
@@ -2872,86 +1681,11 @@ e_cal_generate_instances_for_object (ECal *ecal,
                                      ECalRecurInstanceFn cb,
                                      gpointer cb_data)
 {
-       ECalComponent *comp;
-       const gchar *uid;
-       gchar *rid;
-       gboolean result;
-       GList *instances = NULL;
-       ECalComponentDateTime datetime;
-       icaltimezone *start_zone = NULL;
-       struct instances_info *instances_hold;
-       gboolean is_single_instance = FALSE;
-
        g_return_if_fail (E_IS_CAL (ecal));
-       g_return_if_fail (start >= 0);
-       g_return_if_fail (end >= 0);
-       g_return_if_fail (cb != NULL);
-
-       comp = e_cal_component_new ();
-       e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
-
-       if (!e_cal_component_has_recurrences (comp))
-               is_single_instance = TRUE;
-
-       /*If the backend stores it as individual instances and does not
-        * have a master object - do not expand*/
-       if (is_single_instance || e_cal_get_static_capability (ecal, CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER)) {
-
-               /*return the same instance */
-               result = (* cb)  (comp, icaltime_as_timet_with_zone (icalcomponent_get_dtstart (icalcomp), ecal->priv->default_zone),
-                               icaltime_as_timet_with_zone (icalcomponent_get_dtend (icalcomp), ecal->priv->default_zone), cb_data);
-               g_object_unref (comp);
-               return;
-       }
-
-       e_cal_component_get_uid (comp, &uid);
-       rid = e_cal_component_get_recurid_as_string (comp);
-
-       /* Get the start timezone */
-       e_cal_component_get_dtstart (comp, &datetime);
-       if (datetime.tzid)
-               e_cal_get_timezone (ecal, datetime.tzid, &start_zone, NULL);
-       else
-               start_zone = NULL;
-       e_cal_component_free_datetime (&datetime);
-
-       instances_hold = g_new0 (struct instances_info, 1);
-       instances_hold->instances = &instances;
-       instances_hold->start_zone = start_zone;
-
-       /* generate all instances in the given time range */
-       generate_instances (ecal, start, end, uid, add_instance, instances_hold);
-
-       instances = *(instances_hold->instances);
-       /* now only return back the instances for the given object */
-       result = TRUE;
-       while (instances != NULL) {
-               struct comp_instance *ci;
-               gchar *instance_rid = NULL;
-
-               ci = instances->data;
-
-               if (result) {
-                       instance_rid = e_cal_component_get_recurid_as_string (ci->comp);
-
-                       if (rid && *rid) {
-                               if (instance_rid && *instance_rid && strcmp (rid, instance_rid) == 0)
-                                       result = (* cb) (ci->comp, ci->start, ci->end, cb_data);
-                       } else
-                               result = (* cb)  (ci->comp, ci->start, ci->end, cb_data);
-               }
-
-               /* remove instance from list */
-               instances = g_list_remove (instances, ci);
-               g_object_unref (ci->comp);
-               g_free (ci);
-               g_free (instance_rid);
-       }
 
-       /* clean up */
-       g_object_unref (comp);
-       g_free (instances_hold);
-       g_free (rid);
+       e_cal_client_generate_instances_for_object (
+               ecal->priv->client, icalcomp,
+               start, end, NULL, cb, cb_data, NULL);
 }
 
 /* Builds a list of ECalComponentAlarms structures */
@@ -2961,11 +1695,14 @@ build_component_alarms_list (ECal *ecal,
                              time_t start,
                              time_t end)
 {
+       icaltimezone *default_zone;
        GSList *comp_alarms;
        GList *l;
 
        comp_alarms = NULL;
 
+       default_zone = e_cal_client_get_default_timezone (ecal->priv->client);
+
        for (l = object_list; l != NULL; l = l->next) {
                ECalComponent *comp;
                ECalComponentAlarms *alarms;
@@ -2979,7 +1716,7 @@ build_component_alarms_list (ECal *ecal,
 
                alarms = e_cal_util_generate_alarms_for_comp (
                        comp, start, end, omit, e_cal_resolve_tzid_cb,
-                       ecal, ecal->priv->default_zone);
+                       ecal, default_zone);
                if (alarms)
                        comp_alarms = g_slist_prepend (comp_alarms, alarms);
        }
@@ -3013,7 +1750,6 @@ e_cal_get_alarms_in_range (ECal *ecal,
        gchar *sexp, *iso_start, *iso_end;
        GList *object_list = NULL;
 
-       g_return_val_if_fail (ecal != NULL, NULL);
        g_return_val_if_fail (E_IS_CAL (ecal), NULL);
 
        priv = ecal->priv;
@@ -3109,13 +1845,13 @@ e_cal_get_alarms_for_object (ECal *ecal,
 {
        ECalPrivate *priv;
        icalcomponent *icalcomp;
+       icaltimezone *default_zone;
        ECalComponent *comp;
        ECalComponentAlarmAction omit[] = {-1};
 
        g_return_val_if_fail (alarms != NULL, FALSE);
        *alarms = NULL;
 
-       g_return_val_if_fail (ecal != NULL, FALSE);
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
 
        priv = ecal->priv;
@@ -3137,8 +1873,11 @@ e_cal_get_alarms_for_object (ECal *ecal,
                return FALSE;
        }
 
-       *alarms = e_cal_util_generate_alarms_for_comp (comp, start, end, omit, e_cal_resolve_tzid_cb,
-                                                      ecal, priv->default_zone);
+       default_zone = e_cal_client_get_default_timezone (ecal->priv->client);
+
+       *alarms = e_cal_util_generate_alarms_for_comp (
+               comp, start, end, omit, e_cal_resolve_tzid_cb,
+               ecal, default_zone);
 
        return TRUE;
 }
@@ -3167,177 +1906,16 @@ e_cal_discard_alarm (ECal *ecal,
                      const gchar *auid,
                      GError **error)
 {
-       ECalPrivate *priv;
-
-       e_return_error_if_fail (ecal != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (comp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL_COMPONENT (comp), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (auid != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_NOT_SUPPORTED, error);
-}
-
-typedef struct _ForeachTZIDCallbackData ForeachTZIDCallbackData;
-struct _ForeachTZIDCallbackData {
-       ECal *ecal;
-       GHashTable *timezone_hash;
-       gboolean include_all_timezones;
-       gboolean success;
-};
-
-/* This adds the VTIMEZONE given by the TZID parameter to the GHashTable in
- * data. */
-static void
-foreach_tzid_callback (icalparameter *param,
-                       gpointer cbdata)
-{
-       ForeachTZIDCallbackData *data = cbdata;
-       ECalPrivate *priv;
-       const gchar *tzid;
-       icaltimezone *zone = NULL;
-       icalcomponent *vtimezone_comp;
-       gchar *vtimezone_as_string;
-
-       priv = data->ecal->priv;
-
-       /* Get the TZID string from the parameter. */
-       tzid = icalparameter_get_tzid (param);
-       if (!tzid)
-               return;
-
-       /* Check if we've already added it to the GHashTable. */
-       if (g_hash_table_lookup (data->timezone_hash, tzid))
-               return;
-
-       if (data->include_all_timezones) {
-               if (!e_cal_get_timezone (data->ecal, tzid, &zone, NULL)) {
-                       data->success = FALSE;
-                       return;
-               }
-       } else {
-               /* Check if it is in our cache. If it is, it must already be
-                * on the server so return. */
-               if (g_hash_table_lookup (priv->timezones, tzid))
-                       return;
-
-               /* Check if it is a builtin timezone. If it isn't, return. */
-               zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
-               if (!zone)
-                       return;
-       }
-
-       /* Convert it to a string and add it to the hash. */
-       vtimezone_comp = icaltimezone_get_component (zone);
-       if (!vtimezone_comp)
-               return;
-
-       vtimezone_as_string = icalcomponent_as_ical_string_r (vtimezone_comp);
-
-       g_hash_table_insert (
-               data->timezone_hash, (gchar *) tzid,
-               vtimezone_as_string);
-}
-
-/* This appends the value string to the GString given in data. */
-static void
-append_timezone_string (gpointer key,
-                        gpointer value,
-                        gpointer data)
-{
-       GString *vcal_string = data;
-
-       g_string_append (vcal_string, value);
-       g_free (value);
-}
-
-/* This simply frees the hash values. */
-static void
-free_timezone_string (gpointer key,
-                      gpointer value,
-                      gpointer data)
-{
-       g_free (value);
-}
-
-/* This converts the VEVENT/VTODO to a string. If include_all_timezones is
- * TRUE, it includes all the VTIMEZONE components needed for the VEVENT/VTODO.
- * If not, it only includes builtin timezones that may not be on the server.
- *
- * To do that we check every TZID in the component to see if it is a builtin
- * timezone. If it is, we see if it it in our cache. If it is in our cache,
- * then we know the server already has it and we don't need to send it.
- * If it isn't in our cache, then we need to send it to the server.
- * If we need to send any timezones to the server, then we have to create a
- * complete VCALENDAR object, otherwise we can just send a single VEVENT/VTODO
- * as before. */
-static gchar *
-e_cal_get_component_as_string_internal (ECal *ecal,
-                                        icalcomponent *icalcomp,
-                                        gboolean include_all_timezones)
-{
-       GHashTable *timezone_hash;
-       GString *vcal_string;
-       gint initial_vcal_string_len;
-       ForeachTZIDCallbackData cbdata;
-       gchar *obj_string;
-
-       timezone_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
-       /* Add any timezones needed to the hash. We use a hash since we only
-        * want to add each timezone once at most. */
-       cbdata.ecal = ecal;
-       cbdata.timezone_hash = timezone_hash;
-       cbdata.include_all_timezones = include_all_timezones;
-       cbdata.success = TRUE;
-       icalcomponent_foreach_tzid (icalcomp, foreach_tzid_callback, &cbdata);
-       if (!cbdata.success) {
-               g_hash_table_foreach (timezone_hash, free_timezone_string,
-                                     NULL);
-               return NULL;
-       }
-
-       /* Create the start of a VCALENDAR, to add the VTIMEZONES to,
-        * and remember its length so we know if any VTIMEZONEs get added. */
-       vcal_string = g_string_new (NULL);
-       g_string_append (
-               vcal_string,
-               "BEGIN:VCALENDAR\n"
-               "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
-               "VERSION:2.0\n"
-               "METHOD:PUBLISH\n");
-       initial_vcal_string_len = vcal_string->len;
-
-       /* Now concatenate all the timezone strings. This also frees the
-        * timezone strings as it goes. */
-       g_hash_table_foreach (timezone_hash, append_timezone_string,
-                             vcal_string);
-
-       /* Get the string for the VEVENT/VTODO. */
-       obj_string = icalcomponent_as_ical_string_r (icalcomp);
-
-       /* If there were any timezones to send, create a complete VCALENDAR,
-        * else just send the VEVENT / VTODO string. */
-       if (!include_all_timezones
-           && vcal_string->len == initial_vcal_string_len) {
-               g_string_free (vcal_string, TRUE);
-       } else {
-               g_string_append (vcal_string, obj_string);
-               g_string_append (vcal_string, "END:VCALENDAR\n");
-               g_free (obj_string);
-               obj_string = vcal_string->str;
-               g_string_free (vcal_string, FALSE);
-       }
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
+       g_return_val_if_fail (auid != NULL, FALSE);
 
-       g_hash_table_destroy (timezone_hash);
+       g_set_error (
+               error, E_CALENDAR_ERROR,
+               E_CALENDAR_STATUS_NOT_SUPPORTED,
+               _("Not supported"));
 
-       return obj_string;
+       return FALSE;
 }
 
 /**
@@ -3357,7 +1935,11 @@ gchar *
 e_cal_get_component_as_string (ECal *ecal,
                                icalcomponent *icalcomp)
 {
-       return e_cal_get_component_as_string_internal (ecal, icalcomp, TRUE);
+       g_return_val_if_fail (E_IS_CAL (ecal), NULL);
+       g_return_val_if_fail (icalcomp != NULL, NULL);
+
+       return e_cal_client_get_component_as_string (
+               ecal->priv->client, icalcomp);
 }
 
 /**
@@ -3381,48 +1963,12 @@ e_cal_create_object (ECal *ecal,
                      gchar **uid,
                      GError **error)
 {
-       ECalPrivate *priv;
-       gchar *obj, *gdbus_obj = NULL;
-       const gchar *strv[2];
-       gchar **muids = NULL;
-
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (icalcomp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (icalcomponent_is_valid (icalcomp), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       obj = icalcomponent_as_ical_string_r (icalcomp);
-       strv[0] = e_util_ensure_gdbus_string (obj, &gdbus_obj);
-       strv[1] = NULL;
-
-       if (!e_gdbus_cal_call_create_objects_sync (priv->dbus_proxy, strv, &muids, NULL, error)) {
-               g_free (obj);
-               g_free (gdbus_obj);
-               g_strfreev (muids);
-
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
-
-       g_free (obj);
-       g_free (gdbus_obj);
-
-       if (!muids) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OTHER_ERROR, error);
-       } else {
-               icalcomponent_set_uid (icalcomp, muids[0]);
-
-               if (uid)
-                       *uid = g_strdup (muids[0]);
-
-               g_strfreev (muids);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (icalcomp != NULL, FALSE);
+       g_return_val_if_fail (uid != NULL, FALSE);
 
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
-       }
+       return e_cal_client_create_object_sync (
+               ecal->priv->client, icalcomp, uid, NULL, error);
 }
 
 /**
@@ -3450,43 +1996,11 @@ e_cal_modify_object (ECal *ecal,
                      CalObjModType mod,
                      GError **error)
 {
-       ECalPrivate *priv;
-       gchar *obj, **strv;
-       GSList objs = {0,};
-
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (icalcomp, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (icalcomponent_is_valid (icalcomp), E_CALENDAR_STATUS_INVALID_ARG);
-       switch (mod) {
-       case CALOBJ_MOD_THIS:
-       case CALOBJ_MOD_THISANDPRIOR:
-       case CALOBJ_MOD_THISANDFUTURE:
-       case CALOBJ_MOD_ALL:
-               break;
-       default:
-               e_return_error_if_fail ("valid CalObjModType" && FALSE, E_CALENDAR_STATUS_INVALID_ARG);
-       }
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       obj = icalcomponent_as_ical_string_r (icalcomp);
-       objs.data = obj;
-       strv = e_gdbus_cal_encode_modify_objects (&objs, mod);
-       if (!e_gdbus_cal_call_modify_objects_sync (priv->dbus_proxy, (const gchar * const *) strv, NULL, error)) {
-               g_free (obj);
-               g_strfreev (strv);
-
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
-
-       g_free (obj);
-       g_strfreev (strv);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (icalcomp != NULL, FALSE);
 
-       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+       return e_cal_client_modify_object_sync (
+               ecal->priv->client, icalcomp, mod, NULL, error);
 }
 
 /**
@@ -3543,43 +2057,11 @@ e_cal_remove_object_with_mod (ECal *ecal,
                               CalObjModType mod,
                               GError **error)
 {
-       ECalPrivate *priv;
-       gchar **strv;
-       GSList ids = {0,};
-       ECalComponentId id;
-
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (uid, E_CALENDAR_STATUS_INVALID_ARG);
-       switch (mod) {
-       case CALOBJ_MOD_THIS:
-       case CALOBJ_MOD_THISANDPRIOR:
-       case CALOBJ_MOD_THISANDFUTURE:
-       case CALOBJ_MOD_ONLY_THIS:
-       case CALOBJ_MOD_ALL:
-               break;
-       default:
-               e_return_error_if_fail ("valid CalObjModType" && FALSE, E_CALENDAR_STATUS_INVALID_ARG);
-       }
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       id.uid = (gchar *) uid;
-       id.rid = (gchar *) rid;
-       ids.data = &id;
-       strv = e_gdbus_cal_encode_remove_objects (&ids, mod);
-       if (!e_gdbus_cal_call_remove_objects_sync (priv->dbus_proxy, (const gchar * const *) strv, NULL, error)) {
-               g_strfreev (strv);
-
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
-
-       g_strfreev (strv);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (uid != NULL, FALSE);
 
-       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+       return e_cal_client_remove_object_sync (
+               ecal->priv->client, uid, rid, mod, NULL, error);
 }
 
 /**
@@ -3602,10 +2084,11 @@ e_cal_remove_object (ECal *ecal,
                      const gchar *uid,
                      GError **error)
 {
-       e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (uid, E_CALENDAR_STATUS_INVALID_ARG);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (uid != NULL, FALSE);
 
-       return e_cal_remove_object_with_mod (ecal, uid, NULL, CALOBJ_MOD_ALL, error);
+       return e_cal_remove_object_with_mod (
+               ecal, uid, NULL, CALOBJ_MOD_ALL, error);
 }
 
 /**
@@ -3627,31 +2110,11 @@ e_cal_receive_objects (ECal *ecal,
                        icalcomponent *icalcomp,
                        GError **error)
 {
-       ECalPrivate *priv;
-       gchar *obj, *gdbus_obj = NULL;
-
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (icalcomp, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (icalcomponent_is_valid (icalcomp), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       obj = icalcomponent_as_ical_string_r (icalcomp);
-       if (!e_gdbus_cal_call_receive_objects_sync (priv->dbus_proxy, e_util_ensure_gdbus_string (obj, &gdbus_obj), NULL, error)) {
-               g_free (obj);
-               g_free (gdbus_obj);
-
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
-
-       g_free (obj);
-       g_free (gdbus_obj);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (icalcomp != NULL, FALSE);
 
-       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+       return e_cal_client_receive_objects_sync (
+               ecal->priv->client, icalcomp, NULL, error);
 }
 
 /**
@@ -3677,59 +2140,30 @@ e_cal_send_objects (ECal *ecal,
                     icalcomponent **modified_icalcomp,
                     GError **error)
 {
-       ECalPrivate *priv;
-       ECalendarStatus status;
-       gchar **out_array = NULL;
-       gchar *obj, *gdbus_obj = NULL;
-
-       e_return_error_if_fail (users != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (modified_icalcomp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (icalcomp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (icalcomponent_is_valid (icalcomp), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-       *users = NULL;
-       *modified_icalcomp = NULL;
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       obj = icalcomponent_as_ical_string_r (icalcomp);
-       if (!e_gdbus_cal_call_send_objects_sync (priv->dbus_proxy, e_util_ensure_gdbus_string (obj, &gdbus_obj), &out_array, NULL, error)) {
-               g_free (obj);
-               g_free (gdbus_obj);
-
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
+       GSList *slist = NULL;
+       gboolean success;
 
-       g_free (obj);
-       g_free (gdbus_obj);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (icalcomp != NULL, FALSE);
+       g_return_val_if_fail (users != NULL, FALSE);
+       g_return_val_if_fail (modified_icalcomp != NULL, FALSE);
 
-       status = E_CALENDAR_STATUS_OK;
-       if (out_array) {
-               GSList *susers = NULL, *iter;
-               gchar *object = NULL;
+       success = e_cal_client_send_objects_sync (
+               ecal->priv->client, icalcomp, &slist,
+               modified_icalcomp, NULL, error);
 
-               e_return_error_if_fail (e_gdbus_cal_decode_send_objects ((const gchar * const *) out_array, &object, &susers), E_CALENDAR_STATUS_OTHER_ERROR);
+       if (slist != NULL) {
+               GSList *link;
 
-               *modified_icalcomp = icalparser_parse_string (object);
-               if (!(*modified_icalcomp))
-                       status = E_CALENDAR_STATUS_INVALID_OBJECT;
+               /* XXX Never use GSList in a public API. */
+               for (link = slist; link != NULL; link = g_slist_next (link))
+                       *users = g_list_prepend (*users, link->data);
+               *users = g_list_reverse (*users);
 
-               *users = NULL;
-               for (iter = susers; iter; iter = iter->next) {
-                       *users = g_list_append (*users, iter->data);
-               }
-               /* do not call g_free() on item's data of susers, it's moved to *users */
-               g_slist_free (susers);
-               g_strfreev (out_array);
-               g_free (object);
-       } else
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OTHER_ERROR, error);
+               g_slist_free (slist);
+       }
 
-       E_CALENDAR_CHECK_STATUS (status, error);
+       return success;
 }
 
 /**
@@ -3751,112 +2185,12 @@ e_cal_get_timezone (ECal *ecal,
                     icaltimezone **zone,
                     GError **error)
 {
-       ECalPrivate *priv;
-       ECalendarStatus status = E_CALENDAR_STATUS_OK;
-       icalcomponent *icalcomp = NULL;
-       gchar *object = NULL, *gdbus_tzid = NULL;
-       const gchar *systzid = NULL;
-
-       e_return_error_if_fail (zone, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-       *zone = NULL;
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       /* Check for well known zones and in the cache */
-       /* If tzid is NULL or "" we return NULL, since it is a 'local time'. */
-       if (!tzid || !tzid[0]) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
-       }
-
-       LOCK_CACHE ();
-       /* If it is UTC, we return the special UTC timezone. */
-       if (!strcmp (tzid, "UTC")) {
-               *zone = icaltimezone_get_utc_timezone ();
-       } else {
-               /* See if we already have it in the cache. */
-               *zone = g_hash_table_lookup (priv->timezones, tzid);
-       }
-
-       if (*zone) {
-               UNLOCK_CACHE ();
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
-       }
-
-       /*
-        * Try to replace the original time zone with a more complete
-        * and/or potentially updated system time zone. Note that this
-        * also applies to TZIDs which match system time zones exactly:
-        * they are extracted via icaltimezone_get_builtin_timezone_from_tzid()
-        * below without a roundtrip to the backend.
-        */
-       systzid = e_cal_match_tzid (tzid);
-       if (!systzid) {
-               /* call the backend */
-               if (!e_gdbus_cal_call_get_timezone_sync (priv->dbus_proxy, e_util_ensure_gdbus_string (tzid, &gdbus_tzid), &object, NULL, error)) {
-                       g_free (gdbus_tzid);
-
-                       UNLOCK_CACHE ();
-                       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-               }
-
-               g_free (gdbus_tzid);
-
-               icalcomp = icalparser_parse_string (object);
-               if (!icalcomp)
-                       status = E_CALENDAR_STATUS_INVALID_OBJECT;
-               g_free (object);
-       } else {
-               /*
-                * Use built-in time zone *and* rename it:
-                * if the caller is asking for a TZID=FOO,
-                * then likely because it has an event with
-                * such a TZID. Returning a different TZID
-                * would lead to broken VCALENDARs in the
-                * caller.
-                */
-               icaltimezone *syszone = icaltimezone_get_builtin_timezone_from_tzid (systzid);
-               if (syszone) {
-                       gboolean found = FALSE;
-                       icalproperty *prop;
-
-                       icalcomp = icalcomponent_new_clone (icaltimezone_get_component (syszone));
-                       prop = icalcomponent_get_first_property (
-                               icalcomp, ICAL_ANY_PROPERTY);
-                       while (!found && prop) {
-                               if (icalproperty_isa (prop) == ICAL_TZID_PROPERTY) {
-                                       icalproperty_set_value_from_string (prop, tzid, "NO");
-                                       found = TRUE;
-                               }
-                               prop = icalcomponent_get_next_property (
-                                       icalcomp, ICAL_ANY_PROPERTY);
-                       }
-               } else {
-                       status = E_CALENDAR_STATUS_INVALID_OBJECT;
-               }
-       }
-
-       if (!icalcomp) {
-               UNLOCK_CACHE ();
-               E_CALENDAR_CHECK_STATUS (status, error);
-       }
-
-       *zone = icaltimezone_new ();
-       if (!icaltimezone_set_component (*zone, icalcomp)) {
-               icaltimezone_free (*zone, 1);
-               UNLOCK_CACHE ();
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OBJECT_NOT_FOUND, error);
-       }
-
-       /* Now add it to the cache, to avoid the server call in future. */
-       g_hash_table_insert (priv->timezones, (gpointer) icaltimezone_get_tzid (*zone), *zone);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (tzid != NULL, FALSE);
+       g_return_val_if_fail (zone != NULL, FALSE);
 
-       UNLOCK_CACHE ();
-       return TRUE;
+       return e_cal_client_get_timezone_sync (
+               ecal->priv->client, tzid, zone, NULL, error);
 }
 
 /**
@@ -3876,45 +2210,11 @@ e_cal_add_timezone (ECal *ecal,
                     icaltimezone *izone,
                     GError **error)
 {
-       ECalPrivate *priv;
-       gchar *tzobj, *gdbus_tzobj = NULL;
-       icalcomponent *icalcomp;
-
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (izone, E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       /* Make sure we have a valid component - UTC doesn't, nor do
-        * we really have to add it */
-       if (izone == icaltimezone_get_utc_timezone ()) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
-       }
-
-       icalcomp = icaltimezone_get_component (izone);
-       if (!icalcomp) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_INVALID_ARG, error);
-       }
-
-       /* convert icaltimezone into a string */
-       tzobj = icalcomponent_as_ical_string_r (icalcomp);
-
-       /* call the backend */
-       if (!e_gdbus_cal_call_add_timezone_sync (priv->dbus_proxy, e_util_ensure_gdbus_string (tzobj, &gdbus_tzobj), NULL, error)) {
-               g_free (tzobj);
-               g_free (gdbus_tzobj);
-
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
-
-       g_free (tzobj);
-       g_free (gdbus_tzobj);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (izone != NULL, FALSE);
 
-       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+       return e_cal_client_add_timezone_sync (
+               ecal->priv->client, izone, NULL, error);
 }
 
 /**
@@ -3937,51 +2237,29 @@ e_cal_get_query (ECal *ecal,
                  ECalView **query,
                  GError **error)
 {
-       ECalPrivate *priv;
-       ECalendarStatus status;
-       gchar *query_path = NULL, *gdbus_sexp = NULL;
-       EGdbusCalView *gdbus_calview;
-
-       e_return_error_if_fail (sexp, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (query, E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-       *query = NULL;
-
-       if (priv->load_state != E_CAL_LOAD_LOADED) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
-       }
-
-       if (!e_gdbus_cal_call_get_view_sync (priv->dbus_proxy, e_util_ensure_gdbus_string (sexp, &gdbus_sexp), &query_path, NULL, error)) {
-               g_free (gdbus_sexp);
-
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
-       }
+       ECalClientView *client_view = NULL;
+       gboolean success;
 
-       g_free (gdbus_sexp);
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (sexp != NULL, FALSE);
+       g_return_val_if_fail (query != NULL, FALSE);
 
-       status = E_CALENDAR_STATUS_OK;
+       *query = NULL;
 
-       gdbus_calview = e_gdbus_cal_view_proxy_new_sync (
-               g_dbus_proxy_get_connection (G_DBUS_PROXY (cal_factory)),
-               G_DBUS_PROXY_FLAGS_NONE,
-               CALENDAR_DBUS_SERVICE_NAME,
-               query_path,
-               NULL,
-               error);
+       success = e_cal_client_get_view_sync (
+               ecal->priv->client, sexp, &client_view, NULL, error);
 
-       g_free (query_path);
+       /* Sanity check. */
+       g_return_val_if_fail (
+               (success && (client_view != NULL)) ||
+               (!success && (client_view == NULL)), FALSE);
 
-       if (!gdbus_calview) {
-               *query = NULL;
-               status = E_CALENDAR_STATUS_OTHER_ERROR;
-       } else {
-               *query = _e_cal_view_new (ecal, gdbus_calview);
-               g_object_unref (gdbus_calview);
+       if (client_view != NULL) {
+               *query = _e_cal_view_new (ecal, client_view);
+               g_object_unref (client_view);
        }
 
-       E_CALENDAR_CHECK_STATUS (status, error);
+       return success;
 }
 
 /**
@@ -4002,25 +2280,12 @@ e_cal_set_default_timezone (ECal *ecal,
                             icaltimezone *zone,
                             GError **error)
 {
-       ECalPrivate *priv;
-
-       e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
-       e_return_error_if_fail (zone, E_CALENDAR_STATUS_INVALID_ARG);
-       priv = ecal->priv;
-       e_return_error_if_fail (priv->dbus_proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
-
-       /* If the same timezone is already set, we don't have to do anything. */
-       if (priv->default_zone == zone)
-               return TRUE;
-
-       /* FIXME Adding it to the server to change the tzid */
-       if (!icaltimezone_get_component (zone)) {
-               E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_INVALID_ARG, error);
-       }
+       g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+       g_return_val_if_fail (zone != NULL, FALSE);
 
-       priv->default_zone = zone;
+       e_cal_client_set_default_timezone (ecal->priv->client, zone);
 
-       E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+       return TRUE;
 }
 
 /**