[evolution-exchange] Adapt to EClient changes in eds master



commit aab33b4d38b8774fa1a0a16a762c93b6db294715
Author: Milan Crha <mcrha redhat com>
Date:   Tue May 24 11:53:11 2011 +0200

    Adapt to EClient changes in eds master

 addressbook/e-book-backend-exchange.c      |  527 +++++++---------------------
 addressbook/e-book-backend-gal.c           |  407 ++++++++++------------
 calendar/e-cal-backend-exchange-calendar.c |  101 +++---
 calendar/e-cal-backend-exchange-tasks.c    |   52 ++--
 calendar/e-cal-backend-exchange.c          |  526 +++++++---------------------
 calendar/e-cal-backend-exchange.h          |    3 -
 configure.ac                               |    6 +-
 7 files changed, 506 insertions(+), 1116 deletions(-)
---
diff --git a/addressbook/e-book-backend-exchange.c b/addressbook/e-book-backend-exchange.c
index 0ea4078..402ee63 100644
--- a/addressbook/e-book-backend-exchange.c
+++ b/addressbook/e-book-backend-exchange.c
@@ -76,9 +76,6 @@ struct EBookBackendExchangePrivate {
 	ExchangeAccount *account;
 	E2kContext *ctx;
 	gboolean connected;
-	GHashTable *ops;
-	gint mode;
-	gboolean is_writable;
 	gboolean is_cache_ready;
 	gboolean marked_for_offline;
 
@@ -758,11 +755,7 @@ e_book_backend_exchange_connect (EBookBackendExchange *be, GError **perror)
 		return FALSE;
 	}
 
-	bepriv->is_writable = ((access & MAPI_ACCESS_CREATE_CONTENTS) != 0);
-	e_book_backend_set_is_writable (E_BOOK_BACKEND (be),
-					bepriv->is_writable);
-	e_book_backend_notify_writable (E_BOOK_BACKEND (be),
-					bepriv->is_writable);
+	e_book_backend_notify_readonly (E_BOOK_BACKEND (be), ((access & MAPI_ACCESS_CREATE_CONTENTS) == 0));
 
 	bepriv->base_rn = e2k_restriction_orv (
 		e2k_restriction_prop_string (E2K_PR_DAV_CONTENT_CLASS,
@@ -823,7 +816,6 @@ e_book_backend_exchange_connect (EBookBackendExchange *be, GError **perror)
 				     subscription_notify, be);
 
 	bepriv->connected = TRUE;
-	e_book_backend_set_is_loaded (E_BOOK_BACKEND (be), TRUE);
 	if (nresults)
 		e2k_results_free (results, nresults);
 
@@ -1667,10 +1659,10 @@ merge_contact_lists (EBookBackendExchange *be, const gchar *location, EContact *
 static void
 e_book_backend_exchange_create_contact (EBookBackendSync  *backend,
 					EDataBook         *book,
-					guint32            opid,
-					const gchar        *vcard,
+					GCancellable	  *cancellable,
+					const gchar       *vcard,
 					EContact         **contact,
-					GError **perror)
+					GError		 **perror)
 {
 	EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
 	EBookBackendExchangePrivate *bepriv = be->priv;
@@ -1683,15 +1675,11 @@ e_book_backend_exchange_create_contact (EBookBackendSync  *backend,
 
 	LOCK (bepriv);
 
-	switch (bepriv->mode) {
-
-	case E_DATA_BOOK_MODE_LOCAL:
+	if (!e_book_backend_is_online (E_BOOK_BACKEND (backend))) {
 		*contact = NULL;
 		UNLOCK (bepriv);
 		g_propagate_error (perror, EDB_ERROR (REPOSITORY_OFFLINE));
-		return;
-
-	case E_DATA_BOOK_MODE_REMOTE:
+	} else {
 		*contact = e_contact_new_from_vcard (vcard);
 
 		/* figure out the right uri to be using */
@@ -1755,8 +1743,6 @@ e_book_backend_exchange_create_contact (EBookBackendSync  *backend,
 			http_status_to_error (status, perror);
 			return;
 		}
-	default:
-		break;
 	}
 	UNLOCK (bepriv);
 }
@@ -1764,8 +1750,8 @@ e_book_backend_exchange_create_contact (EBookBackendSync  *backend,
 static void
 e_book_backend_exchange_modify_contact (EBookBackendSync  *backend,
 					EDataBook         *book,
-					guint32	  opid,
-					const gchar        *vcard,
+					GCancellable	  *cancellable,
+					const gchar       *vcard,
 					EContact         **contact,
 					GError **perror)
 {
@@ -1780,15 +1766,10 @@ e_book_backend_exchange_modify_contact (EBookBackendSync  *backend,
 
 	d(printf("ebbe_modify_contact(%p, %p, %s)\n", backend, book, vcard));
 
-	switch (bepriv->mode) {
-
-	case E_DATA_BOOK_MODE_LOCAL:
+	if (!e_book_backend_is_online (E_BOOK_BACKEND (backend))) {
 		*contact = NULL;
 		g_propagate_error (perror, EDB_ERROR (REPOSITORY_OFFLINE));
-		return;
-
-	case E_DATA_BOOK_MODE_REMOTE:
-
+	} else {
 		*contact = e_contact_new_from_vcard (vcard);
 		uri = e_contact_get_const (*contact, E_CONTACT_UID);
 
@@ -1891,38 +1872,30 @@ e_book_backend_exchange_modify_contact (EBookBackendSync  *backend,
 			http_status_to_error (status, perror);
 			return;
 		}
-
-	default:
-		break;
 	}
 }
 
 static void
 e_book_backend_exchange_remove_contacts (EBookBackendSync  *backend,
 					 EDataBook         *book,
-					 guint32	   opid,
-					 GList             *id_list,
-					 GList            **removed_ids,
+					 GCancellable	   *cancellable,
+					 const GSList      *id_list,
+					 GSList           **removed_ids,
 					 GError           **perror)
 {
 	EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
 	EBookBackendExchangePrivate *bepriv = be->priv;
 	const gchar *uri;
 	E2kHTTPStatus status;
-	GList *l;
+	const GSList *l;
 
 	 /* Remove one or more contacts */
 	d(printf("ebbe_remove_contact(%p, %p, %s)\n", backend, book, (gchar *)id_list->data));
 
-	switch (bepriv->mode) {
-
-	case E_DATA_BOOK_MODE_LOCAL:
+	if (!e_book_backend_is_online (E_BOOK_BACKEND (backend))) {
 		*removed_ids = NULL;
 		g_propagate_error (perror, EDB_ERROR (REPOSITORY_OFFLINE));
-		return;
-
-	case E_DATA_BOOK_MODE_REMOTE:
-
+	} else {
 		for (l = id_list; l; l = l->next) {
 			uri = l->data;
 			status = e2k_context_delete (bepriv->ctx, NULL, uri);
@@ -1931,16 +1904,12 @@ e_book_backend_exchange_remove_contacts (EBookBackendSync  *backend,
 				e_book_backend_summary_remove_contact (
 							bepriv->summary, uri);
 				e_book_backend_cache_remove_contact (bepriv->cache, uri);
-				*removed_ids = g_list_append (
+				*removed_ids = g_slist_append (
 						*removed_ids, g_strdup (uri));
 				UNLOCK (bepriv);
 			} else
 				http_status_to_error (status, perror);
 		}
-		return;
-
-	default:
-		break;
 	}
 }
 
@@ -2214,9 +2183,9 @@ subscription_notify (E2kContext *ctx, const gchar *uri,
 static void
 e_book_backend_exchange_get_contact_list (EBookBackendSync  *backend,
 					  EDataBook         *book,
-					  guint32	     opid,
+					  GCancellable	    *cancellable,
 					  const gchar       *query,
-					  GList            **contacts,
+					  GSList           **contacts,
 					  GError           **perror)
 {
 	EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
@@ -2226,21 +2195,20 @@ e_book_backend_exchange_get_contact_list (EBookBackendSync  *backend,
 	E2kResult *result;
 	E2kHTTPStatus status;
 	gchar *vcard;
-	GList *vcard_list = NULL, *temp, *offline_contacts;
+	GList *temp, *offline_contacts;
+	GSList *vcard_list = NULL;
 	EBookBackendSExp *sexp = NULL;
 
 	d(printf("ebbe_get_contact_list(%p, %p, %s)\n", backend, book, query));
 
-	switch (bepriv->mode) {
-
-	case E_DATA_BOOK_MODE_LOCAL:
+	if (!e_book_backend_is_online (E_BOOK_BACKEND (backend))) {
 		/* FIXME */
 		offline_contacts = e_book_backend_cache_get_contacts (bepriv->cache,
 							      query);
 		temp = offline_contacts;
 		for (; offline_contacts != NULL;
 		       offline_contacts = g_list_next (offline_contacts)) {
-			vcard_list = g_list_append (
+			vcard_list = g_slist_append (
 					vcard_list,
 					e_vcard_to_string (
 						E_VCARD (offline_contacts->data),
@@ -2251,10 +2219,7 @@ e_book_backend_exchange_get_contact_list (EBookBackendSync  *backend,
 		*contacts = vcard_list;
 		if (temp)
 			g_list_free (temp);
-		return;
-
-	case E_DATA_BOOK_MODE_REMOTE:
-
+	} else {
 		rn = e_book_backend_exchange_build_restriction (query,
 								bepriv->base_rn);
 
@@ -2294,7 +2259,7 @@ e_book_backend_exchange_get_contact_list (EBookBackendSync  *backend,
 			if (!vcard)
 				continue;
 
-			*contacts = g_list_prepend (*contacts, vcard);
+			*contacts = g_slist_prepend (*contacts, vcard);
 		}
 		status = e2k_result_iter_free (iter);
 
@@ -2302,10 +2267,6 @@ e_book_backend_exchange_get_contact_list (EBookBackendSync  *backend,
 			g_object_unref (sexp);
 
 		http_status_to_error (status, perror);
-		return;
-
-	default:
-		break;
 	}
 }
 
@@ -2327,11 +2288,9 @@ e_book_backend_exchange_start_book_view (EBookBackend  *backend,
 	d(printf("ebbe_start_book_view(%p, %p)\n", backend, book_view));
 
 	e_data_book_view_ref (book_view);
-	e_data_book_view_notify_status_message (book_view, _("Searching..."));
+	e_data_book_view_notify_progress (book_view, -1, _("Searching..."));
 
-	switch (bepriv->mode) {
-
-	case E_DATA_BOOK_MODE_LOCAL:
+	if (!e_book_backend_is_online (E_BOOK_BACKEND (backend))) {
 		if (!bepriv->marked_for_offline) {
 			err = EDB_ERROR (OFFLINE_UNAVAILABLE);
 			e_data_book_view_notify_complete (book_view, err);
@@ -2367,13 +2326,10 @@ e_book_backend_exchange_start_book_view (EBookBackend  *backend,
 		if (temp_list)
 			 g_list_free (temp_list);
 		e_data_book_view_unref (book_view);
-		return;
-
-	case E_DATA_BOOK_MODE_REMOTE:
-
+	} else {
 		if (!be->priv->ctx) {
 			err = EDB_ERROR (AUTHENTICATION_REQUIRED);
-			e_book_backend_notify_auth_required (backend);
+			e_book_backend_notify_auth_required (backend, TRUE, NULL);
 			e_data_book_view_notify_complete (book_view, err);
 			e_data_book_view_unref (book_view);
 			g_error_free (err);
@@ -2412,9 +2368,6 @@ e_book_backend_exchange_start_book_view (EBookBackend  *backend,
 
 		/* also update the folder list */
 		exchange_account_rescan_tree (bepriv->account);
-
-	default:
-		break;
 	}
 }
 
@@ -2422,168 +2375,14 @@ static void
 e_book_backend_exchange_stop_book_view (EBookBackend  *backend,
 				     EDataBookView *book_view)
 {
-	EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
-	EBookBackendExchangePrivate *bepriv = be->priv;
-	E2kOperation *op;
-
 	d(printf("ebbe_stop_book_view(%p, %p)\n", backend, book_view));
-
-	op = g_hash_table_lookup (bepriv->ops, book_view);
-	if (op) {
-		g_hash_table_remove (bepriv->ops, book_view);
-		e2k_operation_cancel (op);
-	}
-}
-
-typedef struct {
-	EXmlHash *ehash;
-	GHashTable *seen_ids;
-	GList *changes;
-} EBookBackendExchangeChangeContext;
-
-static void
-free_change (gpointer data, gpointer user_data)
-{
-	EDataBookChange *change = data;
-
-	if (change) {
-		g_free (change->vcard);
-		g_free (change);
-	}
-}
-
-static gboolean
-find_deleted_ids (const gchar *id, const gchar *vcard, gpointer user_data)
-{
-	EBookBackendExchangeChangeContext *ctx = user_data;
-	gboolean remove = FALSE;
-
-	if (!g_hash_table_lookup (ctx->seen_ids, id)) {
-		gchar *vcard = NULL;
-		EContact *contact = e_contact_new ();
-		if (contact) {
-			e_contact_set (contact, E_CONTACT_UID, (gpointer) id);
-			vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
-			if (vcard) {
-				ctx->changes = g_list_prepend (
-							       ctx->changes,
-							       e_book_backend_change_delete_new (vcard));
-				g_free (vcard);
-			}
-			g_object_unref (contact);
-		}
-		remove = TRUE;
-	}
-	return remove;
-}
-
-static void
-e_book_backend_exchange_get_changes (EBookBackendSync  *backend,
-				     EDataBook         *book,
-				     guint32		opid,
-				     const gchar        *change_id,
-				     GList            **changes,
-				     GError           **perror)
-{
-	EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
-	EBookBackendExchangePrivate *bepriv = be->priv;
-	EBookBackendExchangeChangeContext *ctx;
-	gchar *filename, *path, *vcard;
-	E2kResultIter *iter;
-	E2kResult *result;
-	E2kHTTPStatus status;
-
-	d(printf("ebbe_get_changes(%p, %p, %s)\n", backend, book, change_id));
-
-	switch (bepriv->mode) {
-
-	case E_DATA_BOOK_MODE_LOCAL:
-		*changes = NULL;
-		g_propagate_error (perror, EDB_ERROR (REPOSITORY_OFFLINE));
-		return;
-
-	case E_DATA_BOOK_MODE_REMOTE:
-
-		ctx = g_new0 (EBookBackendExchangeChangeContext, 1);
-		ctx->seen_ids = g_hash_table_new_full (g_str_hash, g_str_equal,
-					       g_free, NULL);
-
-		/* open the changes file */
-		filename = g_strdup_printf ("%s.changes", change_id);
-		path = e_folder_exchange_get_storage_file (bepriv->folder,
-							   filename);
-		ctx->ehash = e_xmlhash_new (path);
-		g_free (path);
-		g_free (filename);
-
-		iter = e_folder_exchange_search_start (bepriv->folder, NULL,
-					       field_names, n_field_names,
-					       bepriv->base_rn, NULL, TRUE);
-
-		while ((result = e2k_result_iter_next (iter))) {
-			vcard = vcard_from_props (be, result);
-			if (!vcard)
-				continue;
-
-			g_hash_table_insert (ctx->seen_ids,
-					     g_strdup (result->href),
-					     GINT_TO_POINTER (1));
-
-			/* Check what type of change has occurred, if any. */
-			switch (e_xmlhash_compare (ctx->ehash, result->href,
-						   vcard)) {
-			case E_XMLHASH_STATUS_SAME:
-				break;
-
-			case E_XMLHASH_STATUS_NOT_FOUND:
-				e_xmlhash_add (ctx->ehash, result->href, vcard);
-				ctx->changes = g_list_prepend (
-					ctx->changes,
-					e_book_backend_change_add_new (vcard));
-				break;
-
-			case E_XMLHASH_STATUS_DIFFERENT:
-				e_xmlhash_add (ctx->ehash, result->href, vcard);
-				ctx->changes = g_list_prepend (
-					ctx->changes,
-					e_book_backend_change_modify_new (vcard));
-				break;
-			}
-
-			g_free (vcard);
-		}
-		status = e2k_result_iter_free (iter);
-
-		if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
-			g_warning ("e_book_backend_exchange_changes: error building list (err = %d)\n", status);
-			g_list_foreach (ctx->changes, free_change, NULL);
-			ctx->changes = NULL;
-		} else {
-			e_xmlhash_foreach_key_remove (ctx->ehash, find_deleted_ids, ctx);
-			e_xmlhash_write (ctx->ehash);
-		}
-
-		/* transfer ownership of result to caller before cleaning up */
-		*changes = ctx->changes;
-		ctx->changes = NULL;
-
-		e_xmlhash_destroy (ctx->ehash);
-		g_hash_table_destroy (ctx->seen_ids);
-		g_free (ctx);
-
-		http_status_to_error (status, perror);
-		return;
-
-	default:
-		break;
-	}
 }
 
 static void
 e_book_backend_exchange_get_contact (EBookBackendSync  *backend,
 				     EDataBook         *book,
-				     guint32            opid,
-				     const gchar        *id,
+				     GCancellable      *cancellable,
+				     const gchar       *id,
 				     gchar             **vcard,
 				     GError            **perror)
 {
@@ -2598,25 +2397,18 @@ e_book_backend_exchange_get_contact (EBookBackendSync  *backend,
 
 	be = E_BOOK_BACKEND_EXCHANGE (e_data_book_get_backend (book));
 
-	switch (bepriv->mode) {
-
-	case E_DATA_BOOK_MODE_LOCAL:
+	if (!e_book_backend_is_online (E_BOOK_BACKEND (backend))) {
 		contact = e_book_backend_cache_get_contact (bepriv->cache,
 							    id);
 		if (contact) {
 			*vcard =  e_vcard_to_string (E_VCARD (contact),
 						     EVC_FORMAT_VCARD_30);
 			g_object_unref (contact);
-			return;
-		}
-		else {
+		} else {
 			*vcard = g_strdup ("");
 			g_propagate_error (perror, EDB_ERROR (CONTACT_NOT_FOUND));
-			return;
 		}
-
-	case E_DATA_BOOK_MODE_REMOTE:
-
+	} else {
 		if (bepriv->marked_for_offline && e_book_backend_cache_is_populated (bepriv->cache)) {
 			contact = e_book_backend_cache_get_contact (bepriv->cache,
 								    id);
@@ -2670,21 +2462,11 @@ e_book_backend_exchange_get_contact (EBookBackendSync  *backend,
 				return;
 			}
 		}
-
-	default:
-		break;
 	}
-
-	g_propagate_error (perror, EDB_ERROR (OTHER_ERROR));
 }
 
 static void
-e_book_backend_exchange_authenticate_user (EBookBackend *backend,
-					   EDataBook        *book,
-					   guint32	     opid,
-					   const gchar       *user,
-					   const gchar       *password,
-					   const gchar       *auth_method)
+e_book_backend_exchange_authenticate_user (EBookBackend *backend, GCancellable *cancellable, ECredentials *credentials)
 {
 	EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
 	EBookBackendExchangePrivate *bepriv = be->priv;
@@ -2693,129 +2475,50 @@ e_book_backend_exchange_authenticate_user (EBookBackend *backend,
 
 	d(printf("ebbe_authenticate_user(%p, %p, %s, %s, %s)\n", backend, book, user, password, auth_method));
 
-	switch (bepriv->mode) {
-
-	case E_DATA_BOOK_MODE_LOCAL:
-		e_book_backend_notify_writable (E_BOOK_BACKEND (backend), FALSE);
-		e_book_backend_notify_connection_status (E_BOOK_BACKEND (backend), FALSE);
-		e_data_book_respond_authenticate_user (book, opid, NULL);
-		return;
-
-	case E_DATA_BOOK_MODE_REMOTE:
+	if (!e_book_backend_is_online (backend)) {
+		e_book_backend_notify_readonly (backend, TRUE);
+		e_book_backend_notify_opened (backend, NULL);
+	} else {
+		GError *error = NULL;
 
 		bepriv->account = account = exchange_share_config_listener_get_account_for_uri (NULL, bepriv->exchange_uri);
 		/* FIXME : Check for failures */
 		if (!(bepriv->ctx = exchange_account_get_context (account))) {
 			exchange_account_set_online (account);
-			if (!exchange_account_connect (account, password, &result)) {
-				e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (AUTHENTICATION_FAILED));
+			if (!exchange_account_connect (account, e_credentials_peek (credentials, E_CREDENTIALS_KEY_PASSWORD), &result)) {
+				e_book_backend_notify_opened (backend, EDB_ERROR (AUTHENTICATION_FAILED));
 				return;
 			}
 		}
 		if (!bepriv->connected)
-			e_book_backend_exchange_connect (be, NULL);
+			e_book_backend_exchange_connect (be, &error);
 		if (e_book_backend_cache_is_populated (bepriv->cache)) {
-			if (bepriv->is_writable)
+			if (!e_book_backend_is_readonly (backend))
 				g_thread_create ((GThreadFunc) update_cache,
 						  be, FALSE, NULL);
 		}
-		else if (bepriv->is_writable || bepriv->marked_for_offline) {
+		else if (!e_book_backend_is_readonly (backend) || bepriv->marked_for_offline) {
 			/* for personal books we always cache*/
 			g_thread_create ((GThreadFunc) build_cache, be, FALSE, NULL);
 		}
-		e_data_book_respond_authenticate_user (book, opid, NULL);
-		return;
-
-	default:
-		break;
-	}
-	e_data_book_respond_authenticate_user (book, opid, NULL);
-}
-
-static void
-e_book_backend_exchange_get_supported_auth_methods (EBookBackend *backend,
-						    EDataBook *book,
-						    guint32 opid)
-{
-	GList *auth_methods = NULL;
-	gchar *auth_method;
-
-	d(printf ("ebbe_get_supported_auth_methods (%p, %p)\n", backend, book));
-
-	auth_method = g_strdup_printf ("plain/password");
-	auth_methods = g_list_append (auth_methods, auth_method);
-	e_data_book_respond_get_supported_auth_methods (book, opid,
-				NULL,
-				auth_methods);
-
-	g_free (auth_method);
-	g_list_free (auth_methods);
-}
-
-static void
-e_book_backend_exchange_get_supported_fields (EBookBackendSync  *backend,
-					      EDataBook         *book,
-					      guint32		 opid,
-					      GList            **methods,
-					      GError           **perror)
-{
-	gint i;
-
-	d(printf("ebbe_get_supported_fields(%p, %p)\n", backend, book));
-
-	*methods = NULL;
-	for (i = 0; i < G_N_ELEMENTS (prop_mappings); i++) {
-		if (prop_mappings[i].e_book_field) {
-			*methods = g_list_prepend (*methods,
-					g_strdup (e_contact_field_name (prop_mappings[i].field)));
-		}
+		e_book_backend_notify_opened (backend, error);
 	}
 }
 
 static void
-e_book_backend_exchange_get_required_fields (EBookBackendSync *backend,
-					  EDataBook *book,
-					  guint32 opid,
-					  GList **fields_out,
-					  GError **perror)
-{
-	GList *fields = NULL;
-
-	fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_FILE_AS)));
-	*fields_out = fields;
-
-}
-
-static void
-e_book_backend_exchange_cancel_operation (EBookBackend *backend, EDataBook *book, GError **perror)
-{
-	EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
-	EBookBackendExchangePrivate *bepriv = be->priv;
-	E2kOperation *op;
-
-	d(printf("ebbe_cancel_operation(%p, %p)\n", backend, book));
-
-	op = g_hash_table_lookup (bepriv->ops, book);
-	if (op) {
-		e2k_operation_cancel (op);
-	} else {
-		g_propagate_error (perror, EDB_ERROR (COULD_NOT_CANCEL));
-	}
-}
-
-static void
-e_book_backend_exchange_load_source (EBookBackend *backend,
-				     ESource      *source,
-				     gboolean      only_if_exists,
-				     GError      **error)
+e_book_backend_exchange_open (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, gboolean only_if_exists)
 {
 	EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
 	EBookBackendExchangePrivate *bepriv = be->priv;
+	ESource *source = e_book_backend_get_source (backend);
 	const gchar *cache_dir;
 	const gchar *offline;
 	gchar *filename;
 
-	e_return_data_book_error_if_fail (bepriv->connected == FALSE, E_DATA_BOOK_STATUS_OTHER_ERROR);
+	if (bepriv->connected) {
+		e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OTHER_ERROR));
+		return;
+	}
 
 	d(printf("ebbe_load_source(%p, %p[%s])\n", backend, source, e_source_peek_name (source)));
 
@@ -2825,27 +2528,25 @@ e_book_backend_exchange_load_source (EBookBackend *backend,
 	if (offline  && g_str_equal (offline, "1"))
 		bepriv->marked_for_offline = TRUE;
 
-	if (bepriv->mode ==  E_DATA_BOOK_MODE_LOCAL &&
+	if (!e_book_backend_is_online (E_BOOK_BACKEND (backend)) &&
 	    !bepriv->marked_for_offline ) {
-		g_propagate_error (error, EDB_ERROR (OFFLINE_UNAVAILABLE));
+		e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE));
 		return;
 	}
 
 	bepriv->exchange_uri = e_source_get_uri (source);
 	if (bepriv->exchange_uri == NULL) {
-		g_propagate_error (error, EDB_ERROR_EX (OTHER_ERROR, "Cannot get source's URI"));
+		e_book_backend_respond_opened (backend, book, opid, EDB_ERROR_EX (OTHER_ERROR, "Cannot get source's URI"));
 		return;
 	}
 	bepriv->original_uri = g_strdup (bepriv->exchange_uri);
 
 	filename = g_build_filename (cache_dir, "cache.xml", NULL);
 
-	if (bepriv->mode == E_DATA_BOOK_MODE_LOCAL) {
-		e_book_backend_set_is_writable (backend, FALSE);
-		e_book_backend_notify_writable (backend, FALSE);
-		e_book_backend_notify_connection_status (backend, FALSE);
+	if (!e_book_backend_is_online (E_BOOK_BACKEND (backend))) {
+		e_book_backend_notify_readonly (backend, TRUE);
 		if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
-			g_propagate_error (error, EDB_ERROR (OFFLINE_UNAVAILABLE));
+			e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE));
 			g_free (filename);
 			return;
 		}
@@ -2856,18 +2557,19 @@ e_book_backend_exchange_load_source (EBookBackend *backend,
 	g_free (filename);
 
 	/* Once aunthentication in address book works this can be removed */
-	if (bepriv->mode == E_DATA_BOOK_MODE_LOCAL) {
+	if (!e_book_backend_is_online (backend)) {
+		e_book_backend_respond_opened (backend, book, opid, NULL);
 		return;
 	}
 
-	// writable property will be set in authenticate_user callback
-	e_book_backend_set_is_writable (E_BOOK_BACKEND (backend), FALSE);
-	e_book_backend_set_is_loaded (E_BOOK_BACKEND (be), TRUE);
-	e_book_backend_notify_connection_status (E_BOOK_BACKEND (be), TRUE);
+	/* writable property will be set in authenticate_user callback */
+	e_book_backend_notify_readonly (backend, TRUE);
+	e_book_backend_notify_auth_required (backend, TRUE, NULL);
+	e_data_book_respond_open (book, opid, NULL);
 }
 
 static void
-e_book_backend_exchange_remove (EBookBackendSync *backend, EDataBook *book, guint32 opid, GError **perror)
+e_book_backend_exchange_remove (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, GError **perror)
 {
 	EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
 	EBookBackendExchangePrivate *bepriv = be->priv;
@@ -2904,36 +2606,58 @@ e_book_backend_exchange_remove (EBookBackendSync *backend, EDataBook *book, guin
 		g_propagate_error (perror, e_data_book_create_error_fmt (E_DATA_BOOK_STATUS_OTHER_ERROR, "Failed with result code %d", result));
 }
 
-static gchar *
-e_book_backend_exchange_get_static_capabilites (EBookBackend *backend)
+static gboolean
+e_book_backend_exchange_get_backend_property (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *prop_name, gchar **prop_value, GError **error)
 {
-	return g_strdup ("net,bulk-removes,do-initial-query,cache-completions,contact-lists");
+	gboolean processed = TRUE;
+
+	g_return_val_if_fail (prop_name != NULL, FALSE);
+	g_return_val_if_fail (prop_value != NULL, FALSE);
+
+	if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
+		*prop_value = g_strdup ("net,bulk-removes,do-initial-query,cache-completions,contact-lists");
+	} else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS)) {
+		*prop_value = g_strdup (e_contact_field_name (E_CONTACT_FILE_AS));
+	} else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS)) {
+		GSList *fields = NULL;
+		gint i;
+
+		for (i = 0; i < G_N_ELEMENTS (prop_mappings); i++) {
+			if (prop_mappings[i].e_book_field)
+				fields = g_slist_append (fields, (gpointer) e_contact_field_name (prop_mappings[i].field));
+		}
+
+		*prop_value = e_data_book_string_slist_to_comma_string (fields);
+
+		g_slist_free (fields);
+	} else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_SUPPORTED_AUTH_METHODS)) {
+		*prop_value = g_strdup ("plain/password");
+	} else {
+		processed = FALSE;
+	}
+
+	return processed;
 }
 
 static void
-e_book_backend_exchange_set_mode (EBookBackend *backend,
-                                  EDataBookMode mode)
+e_book_backend_exchange_set_online (EBookBackend *backend, gboolean is_online)
 {
 	EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
 	EBookBackendExchangePrivate *bepriv = be->priv;
 	ExchangeAccount *account = NULL;
 
-	bepriv->mode = mode;
-	/* if (e_book_backend_is_loaded (backend)) { */
-	if (mode == E_DATA_BOOK_MODE_LOCAL) {
-		e_book_backend_set_is_writable (backend, FALSE);
-		e_book_backend_notify_writable (backend, FALSE);
-		e_book_backend_notify_connection_status (backend, FALSE);
-		/* FIXME : free context ? */
-	} else if (mode == E_DATA_BOOK_MODE_REMOTE) {
-		e_book_backend_set_is_writable (backend, bepriv->is_writable);
-		e_book_backend_notify_writable (backend, bepriv->is_writable);
-		e_book_backend_notify_connection_status (backend, TRUE);
-		account = exchange_share_config_listener_get_account_for_uri (NULL, bepriv->exchange_uri);
-		if (!exchange_account_get_context (account))
-			e_book_backend_notify_auth_required (backend);
+	e_book_backend_notify_online (E_BOOK_BACKEND (backend), is_online);
+
+	if (e_book_backend_is_opened (backend)) {
+		if (!is_online) {
+			e_book_backend_notify_readonly (backend, TRUE);
+			/* FIXME : free context ? */
+		} else {
+			account = exchange_share_config_listener_get_account_for_uri (NULL, bepriv->exchange_uri);
+			if (!exchange_account_get_context (account))
+				e_book_backend_notify_auth_required (backend, TRUE, NULL);
+		}
 	}
-	/*}*/
 }
 
 /**
@@ -2973,9 +2697,6 @@ e_book_backend_exchange_dispose (GObject *object)
 		if (be->priv->account)
 			be->priv->account = NULL;
 
-		if (be->priv->ops)
-			g_hash_table_destroy (be->priv->ops);
-
 		if (be->priv->cache)
 			g_object_unref (be->priv->cache);
 
@@ -3015,24 +2736,19 @@ e_book_backend_exchange_class_init (EBookBackendExchangeClass *klass)
 	n_field_names = field_names_array->len;
 
 	/* Set the virtual methods. */
-	backend_class->load_source             = e_book_backend_exchange_load_source;
-	backend_class->get_static_capabilities = e_book_backend_exchange_get_static_capabilites;
-	backend_class->start_book_view         = e_book_backend_exchange_start_book_view;
-	backend_class->stop_book_view          = e_book_backend_exchange_stop_book_view;
-	backend_class->cancel_operation        = e_book_backend_exchange_cancel_operation;
-	backend_class->set_mode			= e_book_backend_exchange_set_mode;
-	backend_class->get_supported_auth_methods = e_book_backend_exchange_get_supported_auth_methods;
-	backend_class->authenticate_user     = e_book_backend_exchange_authenticate_user;
-
-	sync_class->remove_sync                = e_book_backend_exchange_remove;
-	sync_class->create_contact_sync        = e_book_backend_exchange_create_contact;
-	sync_class->remove_contacts_sync       = e_book_backend_exchange_remove_contacts;
-	sync_class->modify_contact_sync        = e_book_backend_exchange_modify_contact;
-	sync_class->get_contact_sync           = e_book_backend_exchange_get_contact;
-	sync_class->get_contact_list_sync      = e_book_backend_exchange_get_contact_list;
-	sync_class->get_changes_sync           = e_book_backend_exchange_get_changes;
-	sync_class->get_supported_fields_sync  = e_book_backend_exchange_get_supported_fields;
-	sync_class->get_required_fields_sync   = e_book_backend_exchange_get_required_fields;
+	backend_class->open			= e_book_backend_exchange_open;
+	backend_class->start_book_view		= e_book_backend_exchange_start_book_view;
+	backend_class->stop_book_view		= e_book_backend_exchange_stop_book_view;
+	backend_class->set_online		= e_book_backend_exchange_set_online;
+	backend_class->authenticate_user	= e_book_backend_exchange_authenticate_user;
+
+	sync_class->remove_sync			= e_book_backend_exchange_remove;
+	sync_class->create_contact_sync		= e_book_backend_exchange_create_contact;
+	sync_class->remove_contacts_sync	= e_book_backend_exchange_remove_contacts;
+	sync_class->modify_contact_sync		= e_book_backend_exchange_modify_contact;
+	sync_class->get_contact_sync		= e_book_backend_exchange_get_contact;
+	sync_class->get_contact_list_sync	= e_book_backend_exchange_get_contact_list;
+	sync_class->get_backend_property_sync	= e_book_backend_exchange_get_backend_property;
 
 	object_class->dispose = e_book_backend_exchange_dispose;
 }
@@ -3043,12 +2759,10 @@ e_book_backend_exchange_init (EBookBackendExchange *backend)
 	EBookBackendExchangePrivate *priv;
 
 	priv		= g_new0 (EBookBackendExchangePrivate, 1);
-	priv->ops	= g_hash_table_new (NULL, NULL);
 	priv->is_cache_ready	= FALSE;
 	priv->marked_for_offline= FALSE;
 	priv->cache		= NULL;
 	priv->original_uri	= NULL;
-	priv->is_writable	= TRUE;
 
 	priv->cache_lock      = g_mutex_new ();
 
@@ -3056,4 +2770,3 @@ e_book_backend_exchange_init (EBookBackendExchange *backend)
 }
 
 E2K_MAKE_TYPE (e_book_backend_exchange, EBookBackendExchange, e_book_backend_exchange_class_init, e_book_backend_exchange_init, PARENT_TYPE)
-
diff --git a/addressbook/e-book-backend-gal.c b/addressbook/e-book-backend-gal.c
index 03c7c42..c18a376 100644
--- a/addressbook/e-book-backend-gal.c
+++ b/addressbook/e-book-backend-gal.c
@@ -89,7 +89,6 @@ static EBookBackendClass *parent_class;
 
 typedef struct LDAPOp LDAPOp;
 
-static GList *supported_fields;
 static const gchar **search_attrs;
 
 struct _EBookBackendGALPrivate {
@@ -107,7 +106,6 @@ struct _EBookBackendGALPrivate {
 	GStaticRecMutex op_hash_mutex;
 	GHashTable *id_to_op;
 	gint active_ops;
-	gint mode;
 	gint poll_timeout;
 #if defined(ENABLE_CACHE) && ENABLE_CACHE
 	DB *file_db;
@@ -138,12 +136,13 @@ struct LDAPOp {
 	LDAPOpDtor     dtor;
 	EBookBackend  *backend;
 	EDataBook     *book;
+	GCancellable  *cancellable; /* cancellable of the operation */
 	EDataBookView *view;
 	guint32        opid; /* the libebook operation id */
 	gint            id;   /* the ldap msg id */
 };
 
-static void     ldap_op_add (LDAPOp *op, EBookBackend *backend, EDataBook *book,
+static void     ldap_op_add (LDAPOp *op, EBookBackend *backend, EDataBook *book, GCancellable *cancellable,
 			     EDataBookView *view, gint opid, gint msgid, LDAPOpHandler handler, LDAPOpDtor dtor);
 static void     ldap_op_finished (LDAPOp *op);
 
@@ -247,27 +246,30 @@ book_view_notify_status (EDataBookView *view, const gchar *status)
 {
 	if (!view)
 		return;
-	e_data_book_view_notify_status_message (view, status);
+	e_data_book_view_notify_progress (view, -1, status);
+}
+
+static gboolean
+pick_view_cb (EDataBookView *view, gpointer user_data)
+{
+	EDataBookView **pick = user_data;
+
+	g_return_val_if_fail (user_data != NULL, FALSE);
+
+	/* just always use the first book view */
+	*pick = view;
+
+	return view == NULL;
 }
 
 static EDataBookView*
 find_book_view (EBookBackendGAL *bl)
 {
-	EList *views = e_book_backend_get_book_views (E_BOOK_BACKEND (bl));
-	EIterator *iter = e_list_get_iterator (views);
-	EDataBookView *rv = NULL;
-
-	if (e_iterator_is_valid (iter)) {
-		/* just always use the first book view */
-		EDataBookView *v = (EDataBookView*) e_iterator_get (iter);
-		if (v)
-			rv = v;
-	}
+	EDataBookView *pick = NULL;
 
-	g_object_unref (iter);
-	g_object_unref (views);
+	e_book_backend_foreach_view (E_BOOK_BACKEND (bl), pick_view_cb, &pick);
 
-	return rv;
+	return pick;
 }
 
 static gboolean
@@ -314,7 +316,7 @@ gal_connect (EBookBackendGAL *bl, GError **perror)
 	g_mutex_unlock (blpriv->ldap_lock);
 
 	blpriv->connected = TRUE;
-	e_book_backend_set_is_loaded (E_BOOK_BACKEND (bl), TRUE);
+
 	return TRUE;
 }
 
@@ -371,9 +373,38 @@ gal_reconnect (EBookBackendGAL *bl, EDataBookView *book_view, gint ldap_status)
 	}
 }
 
+static gboolean
+find_by_cancellable_cb (gpointer key, gpointer ptrop, gpointer ptrcancellable)
+{
+	LDAPOp *op = ptrop;
+	GCancellable *cancellable = ptrcancellable;
+
+	return op && op->cancellable == cancellable;
+}
+
+static void
+cancelled_cb (GCancellable *cancellable, EBookBackendGAL *bl)
+{
+	LDAPOp *op;
+
+	g_static_rec_mutex_lock (&bl->priv->op_hash_mutex);
+
+	op = g_hash_table_find (bl->priv->id_to_op, find_by_cancellable_cb, cancellable);
+	if (op) {
+		g_mutex_lock (bl->priv->ldap_lock);
+		if (bl->priv->ldap)
+			ldap_abandon (bl->priv->ldap, op->id);
+		g_mutex_unlock (bl->priv->ldap_lock);
+	} else {
+		g_debug ("%s: Cannot find GAL op for cancellable %p", G_STRFUNC, cancellable);
+	}
+
+	g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex);
+}
+
 static void
 ldap_op_add (LDAPOp *op, EBookBackend *backend,
-	     EDataBook *book, EDataBookView *view,
+	     EDataBook *book, GCancellable *cancellable, EDataBookView *view,
 	     gint opid,
 	     gint msgid,
 	     LDAPOpHandler handler, LDAPOpDtor dtor)
@@ -382,6 +413,7 @@ ldap_op_add (LDAPOp *op, EBookBackend *backend,
 
 	op->backend = backend;
 	op->book = book;
+	op->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
 	op->view = view;
 	op->opid = opid;
 	op->id = msgid;
@@ -389,6 +421,10 @@ ldap_op_add (LDAPOp *op, EBookBackend *backend,
 	op->dtor = dtor;
 
 	g_static_rec_mutex_lock (&bl->priv->op_hash_mutex);
+
+	if (op->cancellable)
+		g_signal_connect (op->cancellable, "cancelled", G_CALLBACK (cancelled_cb), g_object_ref (backend));
+
 	if (g_hash_table_lookup (bl->priv->id_to_op, &op->id)) {
 		g_warning ("conflicting ldap msgid's");
 	}
@@ -414,6 +450,12 @@ ldap_op_finished (LDAPOp *op)
 
 	g_static_rec_mutex_lock (&bl->priv->op_hash_mutex);
 	g_hash_table_remove (bl->priv->id_to_op, &op->id);
+	if (op->cancellable) {
+		g_signal_handlers_disconnect_by_func (op->cancellable, cancelled_cb, backend);
+		g_object_unref (op->cancellable);
+		op->cancellable = NULL;
+		g_object_unref (backend);
+	}
 
 	/* should handle errors here */
 	g_mutex_lock (bl->priv->ldap_lock);
@@ -456,6 +498,7 @@ static void
 create_contact (EBookBackend *backend,
 		EDataBook    *book,
 		guint32       opid,
+		GCancellable *cancellable,
 		const gchar   *vcard)
 {
 	e_data_book_respond_create (book, opid,
@@ -467,7 +510,8 @@ static void
 remove_contacts (EBookBackend *backend,
 		 EDataBook    *book,
 		 guint32       opid,
-		 GList        *ids)
+		 GCancellable *cancellable,
+		 const GSList *ids)
 {
 	e_data_book_respond_remove_contacts (book, opid,
 					     EDB_ERROR (PERMISSION_DENIED),
@@ -478,6 +522,7 @@ static void
 modify_contact (EBookBackend *backend,
 		EDataBook    *book,
 		guint32       opid,
+		GCancellable *cancellable,
 		const gchar   *vcard)
 {
 	e_data_book_respond_modify (book, opid,
@@ -583,6 +628,7 @@ static void
 get_contact (EBookBackend *backend,
 	     EDataBook    *book,
 	     guint32       opid,
+	     GCancellable *cancellable,
 	     const gchar   *id)
 {
 	LDAPGetContactOp *get_contact_op;
@@ -592,8 +638,7 @@ get_contact (EBookBackend *backend,
 	gint ldap_error;
 
 	d(printf("get contact\n"));
-	switch (bl->priv->mode) {
-	case E_DATA_BOOK_MODE_LOCAL:
+	if (!e_book_backend_is_online (backend)) {
 #if defined(ENABLE_CACHE) && ENABLE_CACHE
 		if (bl->priv->marked_for_offline && bl->priv->file_db) {
 			EContact *contact = e_book_backend_db_cache_get_contact (bl->priv->file_db, id);
@@ -616,9 +661,7 @@ get_contact (EBookBackend *backend,
 		}
 #endif
 		e_data_book_respond_get_contact(book, opid, EDB_ERROR (REPOSITORY_OFFLINE), "");
-		return;
-
-	case E_DATA_BOOK_MODE_REMOTE :
+	} else {
 #if defined(ENABLE_CACHE) && ENABLE_CACHE
 		d(printf("Mode:Remote\n"));
 		if (bl->priv->marked_for_offline && bl->priv->file_db) {
@@ -665,7 +708,7 @@ get_contact (EBookBackend *backend,
 			} while (gal_reconnect (bl, book_view, ldap_error));
 
 			if (ldap_error == LDAP_SUCCESS) {
-				ldap_op_add ((LDAPOp*) get_contact_op, backend, book,
+				ldap_op_add ((LDAPOp*) get_contact_op, backend, book, cancellable,
 					     book_view, opid, get_contact_msgid,
 					     get_contact_handler, get_contact_dtor);
 			}
@@ -684,7 +727,7 @@ get_contact (EBookBackend *backend,
 
 typedef struct {
 	LDAPOp op;
-	GList *contacts;
+	GSList *contacts;
 } LDAPGetContactListOp;
 
 static void
@@ -716,7 +759,7 @@ contact_list_handler (LDAPOp *op, LDAPMessage *res)
 
 			d(printf ("vcard = %s\n", vcard));
 
-			contact_list_op->contacts = g_list_append (contact_list_op->contacts,
+			contact_list_op->contacts = g_slist_append (contact_list_op->contacts,
 								   vcard);
 
 			g_object_unref (contact);
@@ -788,6 +831,7 @@ static void
 get_contact_list (EBookBackend *backend,
 		  EDataBook    *book,
 		  guint32       opid,
+		  GCancellable *cancellable,
 		  const gchar   *query)
 {
 	LDAPGetContactListOp *contact_list_op;
@@ -799,50 +843,51 @@ get_contact_list (EBookBackend *backend,
 	GError *error = NULL;
 
 	d(printf("get contact list\n"));
-	switch (bl->priv->mode) {
-	case E_DATA_BOOK_MODE_LOCAL:
+	if (!e_book_backend_is_online (backend)) {
 #if defined(ENABLE_CACHE) && ENABLE_CACHE
 		if (bl->priv->marked_for_offline && bl->priv->file_db) {
 			GList *contacts;
-			GList *vcard_strings = NULL;
+			GSList *vcard_strings = NULL;
 			GList *l;
 
 			contacts = e_book_backend_db_cache_get_contacts (bl->priv->file_db, query);
 
 			for (l = contacts; l; l = g_list_next (l)) {
 				EContact *contact = l->data;
-				vcard_strings = g_list_prepend (vcard_strings, e_vcard_to_string (E_VCARD (contact),
+				vcard_strings = g_slist_prepend (vcard_strings, e_vcard_to_string (E_VCARD (contact),
 								EVC_FORMAT_VCARD_30));
 				g_object_unref (contact);
 			}
 
 			g_list_free (contacts);
 			e_data_book_respond_get_contact_list (book, opid, NULL /* Success */, vcard_strings);
+			g_slist_foreach (vcard_strings, (GFunc) g_free, NULL);
+			g_slist_free (vcard_strings);
 			return;
 		}
 #endif
 		e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (REPOSITORY_OFFLINE), NULL);
-		return;
-
-	case E_DATA_BOOK_MODE_REMOTE:
+	} else {
 #if defined(ENABLE_CACHE) && ENABLE_CACHE
 		d(printf("Mode : Remote\n"));
 		if (bl->priv->marked_for_offline && bl->priv->file_db) {
 			GList *contacts;
-			GList *vcard_strings = NULL;
+			GSList *vcard_strings = NULL;
 			GList *l;
 
 			contacts = e_book_backend_db_cache_get_contacts (bl->priv->file_db, query);
 
 			for (l = contacts; l;l = g_list_next (l)) {
 				EContact *contact = l->data;
-				vcard_strings = g_list_prepend (vcard_strings, e_vcard_to_string (E_VCARD (contact),
+				vcard_strings = g_slist_prepend (vcard_strings, e_vcard_to_string (E_VCARD (contact),
 								EVC_FORMAT_VCARD_30));
 				g_object_unref (contact);
 			}
 
 			g_list_free (contacts);
 			e_data_book_respond_get_contact_list (book, opid, NULL /* Success */, vcard_strings);
+			g_slist_foreach (vcard_strings, (GFunc) g_free, NULL);
+			g_slist_free (vcard_strings);
 			return;
 		}
 		else {
@@ -880,7 +925,7 @@ get_contact_list (EBookBackend *backend,
 			g_free (ldap_query);
 
 			if (ldap_error == LDAP_SUCCESS) {
-				ldap_op_add ((LDAPOp*) contact_list_op, backend, book,
+				ldap_op_add ((LDAPOp*) contact_list_op, backend, book, cancellable,
 					     book_view, opid, contact_list_msgid,
 					     contact_list_handler, contact_list_dtor);
 			}
@@ -1500,7 +1545,7 @@ build_contact_from_entry (EBookBackendGAL *bl, LDAPMessage *e, GList **existing_
 
 							book_view = find_book_view (bl);
 							if (book_view)
-								view_limit = e_data_book_view_get_max_results (book_view);
+								view_limit = -1;
 							if (view_limit == -1 || view_limit > bl->priv->gc->response_limit)
 								view_limit = bl->priv->gc->response_limit;
 
@@ -1787,8 +1832,7 @@ start_book_view (EBookBackend  *backend,
 	GError *err = NULL;
 
 	d(printf("start book view\n"));
-	switch (bl->priv->mode) {
-	case E_DATA_BOOK_MODE_LOCAL:
+	if (!e_book_backend_is_online (backend)) {
 #if defined(ENABLE_CACHE) && ENABLE_CACHE
 		if (!(bl->priv->marked_for_offline && bl->priv->file_db)) {
 			err = EDB_ERROR (REPOSITORY_OFFLINE);
@@ -1816,7 +1860,7 @@ start_book_view (EBookBackend  *backend,
 		g_error_free (err);
 		return;
 #endif
-	case E_DATA_BOOK_MODE_REMOTE:
+	} else {
 #if defined(ENABLE_CACHE) && ENABLE_CACHE
 		d(printf("Mode:Remote\n"));
 		if (bl->priv->marked_for_offline && bl->priv->file_db) {
@@ -1892,12 +1936,7 @@ start_book_view (EBookBackend  *backend,
 			}
 			g_mutex_unlock (bl->priv->ldap_lock);
 
-			/* we start at 1 so the user sees stuff as it appears and we
-			   aren't left waiting for more cards to show up, if the
-			   connection is slow. */
-			e_data_book_view_set_thresholds (view, 1, 3000);
-
-			view_limit = e_data_book_view_get_max_results (view);
+			view_limit = -1;
 			if (view_limit == -1 || view_limit > bl->priv->gc->response_limit)
 				view_limit = bl->priv->gc->response_limit;
 
@@ -1971,7 +2010,7 @@ start_book_view (EBookBackend  *backend,
 
 				e_data_book_view_ref (view);
 
-				ldap_op_add ((LDAPOp*) op, E_BOOK_BACKEND (bl), NULL, view,
+				ldap_op_add ((LDAPOp*) op, E_BOOK_BACKEND (bl), NULL, NULL, view,
 					     0, search_msgid,
 					     ldap_search_handler, ldap_search_dtor);
 				d(printf("start_book_view: Setting op %p in book %p\n", op, view));
@@ -2000,15 +2039,6 @@ stop_book_view (EBookBackend  *backend,
 	}
 }
 
-static void
-get_changes (EBookBackend *backend,
-	     EDataBook    *book,
-	     guint32	   opid,
-	     const gchar   *change_id)
-{
-	/* FIXME: implement */
-}
-
 #if defined(ENABLE_CACHE) && ENABLE_CACHE
 static gint pagedResults = 1;
 static ber_int_t pageSize = 1000;
@@ -2377,11 +2407,8 @@ update_cache (EBookBackendGAL *gal)
 
 static void
 authenticate_user (EBookBackend *backend,
-		   EDataBook    *book,
-		   guint32       opid,
-		   const gchar   *user,
-		   const gchar   *password,
-		   const gchar   *auth_method)
+		   GCancellable *cancellable,
+		   ECredentials *credentials)
 {
 	EBookBackendGAL *be = E_BOOK_BACKEND_GAL (backend);
 	EBookBackendGALPrivate *bepriv = be->priv;
@@ -2403,29 +2430,23 @@ authenticate_user (EBookBackend *backend,
 
 	d(printf("authenticate_user(%p, %p, %s, %s, %s)\n", backend, book, user, password, auth_method));
 
-	switch (bepriv->mode) {
-
-	case E_DATA_BOOK_MODE_LOCAL:
-		e_book_backend_notify_writable (E_BOOK_BACKEND (backend), FALSE);
-		e_book_backend_notify_connection_status (E_BOOK_BACKEND (backend), FALSE);
-		e_data_book_respond_authenticate_user (book, opid, NULL /* Success */);
-		return;
-
-	case E_DATA_BOOK_MODE_REMOTE:
-
+	if (!e_book_backend_is_online (backend)) {
+		e_book_backend_notify_readonly (backend, TRUE);
+		e_book_backend_notify_opened (backend, NULL /* Success */);
+	} else {
 		account = exchange_share_config_listener_get_account_for_uri (NULL, bepriv->gal_uri);
 		/* FIXME : Check for failures */
 		if (!exchange_account_get_context (account)) {
 			exchange_account_set_online (account);
-			if (!exchange_account_connect (account, password, &result)) {
+			if (!exchange_account_connect (account, e_credentials_peek (credentials, E_CREDENTIALS_KEY_PASSWORD), &result)) {
 				d(printf("%s:%s: failed\n", G_STRLOC, G_STRFUNC));
-				e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (AUTHENTICATION_FAILED));
+				e_book_backend_notify_opened (backend, EDB_ERROR (AUTHENTICATION_FAILED));
 				return;
 			}
 		}
 
 		if (!gal_connect (be, &err)) {
-			e_data_book_respond_authenticate_user (book, opid, err);
+			e_book_backend_notify_opened (backend, err);
 			return;
 		}
 #if defined(ENABLE_CACHE) && ENABLE_CACHE
@@ -2456,18 +2477,8 @@ authenticate_user (EBookBackend *backend,
 			}
 		}
 #endif
-		e_data_book_respond_authenticate_user (book, opid, NULL /* Success*/ );
-		return;
-
-	default:
-		break;
+		e_book_backend_notify_opened (backend, NULL /* Success*/ );
 	}
-
-	/* We should not be here */
-	e_data_book_respond_authenticate_user (book,
-					       opid,
-					       EDB_ERROR (UNSUPPORTED_AUTHENTICATION_METHOD));
-	return;
 }
 
 #ifdef SUNLDAP
@@ -2503,7 +2514,7 @@ ldap_cancel_op (gpointer key, gpointer value, gpointer data)
 }
 
 static void
-cancel_operation (EBookBackend *backend, EDataBook *book, GError **perror)
+cancel_operations (EBookBackend *backend)
 {
 	EBookBackendGAL *bl = E_BOOK_BACKEND_GAL (backend);
 
@@ -2513,95 +2524,40 @@ cancel_operation (EBookBackend *backend, EDataBook *book, GError **perror)
 }
 
 static void
-set_mode (EBookBackend *backend, EDataBookMode mode)
+set_online (EBookBackend *backend, gboolean is_online)
 {
 	EBookBackendGAL *be = E_BOOK_BACKEND_GAL (backend);
 	EBookBackendGALPrivate *bepriv;
 
 	bepriv = be->priv;
 
-	if (bepriv->mode == mode)
-		return;
+	/* Cancel all running operations */
+	cancel_operations (backend);
 
-	bepriv->mode = mode;
+	e_book_backend_notify_online (backend, is_online);
 
-	/* Cancel all running operations */
-	cancel_operation (backend, NULL, NULL);
-
-	if (e_book_backend_is_loaded (backend)) {
-		if (mode == E_DATA_BOOK_MODE_LOCAL) {
-			e_book_backend_set_is_writable (backend, FALSE);
-			e_book_backend_notify_writable (backend, FALSE);
-			e_book_backend_notify_connection_status (backend, FALSE);
-		} else if (mode == E_DATA_BOOK_MODE_REMOTE) {
-			e_book_backend_set_is_writable (backend, FALSE);
-			e_book_backend_notify_writable (backend, FALSE);
-			e_book_backend_notify_connection_status (backend, TRUE);
-
-			if (e_book_backend_is_loaded (backend)) {
-				gal_connect (be, NULL);
-				e_book_backend_notify_auth_required (backend);
+	if (e_book_backend_is_opened (backend)) {
+		e_book_backend_notify_readonly (backend, TRUE);
+		if (is_online) {
+			gal_connect (be, NULL);
+			e_book_backend_notify_auth_required (backend, TRUE, NULL);
 #if defined(ENABLE_CACHE) && ENABLE_CACHE
-				if (bepriv->marked_for_offline && bepriv->file_db) {
-					if (e_book_backend_db_cache_is_populated (be->priv->file_db))
-						update_cache (be);
-					else
-						generate_cache (be, NULL);
-				}
-#endif
+			if (bepriv->marked_for_offline && bepriv->file_db) {
+				if (e_book_backend_db_cache_is_populated (be->priv->file_db))
+					update_cache (be);
+				else
+					generate_cache (be, NULL);
 			}
+#endif
 		}
 	}
 }
 
 static void
-get_supported_fields (EBookBackend *backend,
-		      EDataBook    *book,
-		      guint32	    opid)
-
-{
-	e_data_book_respond_get_supported_fields (book,
-						  opid,
-						  NULL /* Success */,
-						  supported_fields);
-}
-
-static void
-get_required_fields (EBookBackend *backend,
-		     EDataBook *book,
-		     guint32 opid)
-{
-	GList *fields = NULL;
-
-	fields = g_list_append (fields, (gchar *) e_contact_field_name (E_CONTACT_FILE_AS));
-	e_data_book_respond_get_required_fields (book,
-						  opid,
-						  NULL /* Success */,
-						  fields);
-	g_list_free (fields);
-
-}
-
-static void
-get_supported_auth_methods (EBookBackend *backend,
-			    EDataBook    *book,
-			    guint32       opid)
-
-{
-	d(printf("%s:%s: NONE\n", G_STRLOC, G_STRFUNC));
-	e_data_book_respond_get_supported_auth_methods (book,
-							opid,
-							NULL /* Success */,
-							NULL);
-}
-
-static void
-load_source (EBookBackend *backend,
-	     ESource      *source,
-	     gboolean      only_if_exists,
-	     GError      **error)
+gal_open (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, gboolean only_if_exists)
 {
 	EBookBackendGAL *bl = E_BOOK_BACKEND_GAL (backend);
+	ESource *source = e_book_backend_get_source (backend);
 	const gchar *host;
 	gchar **tokens;
 	const gchar *offline;
@@ -2615,22 +2571,25 @@ load_source (EBookBackend *backend,
 	DB *db;
 	DB_ENV *env;
 #endif
-	e_return_data_book_error_if_fail (bl->priv->connected == FALSE, E_DATA_BOOK_STATUS_OTHER_ERROR);
+	if (bl->priv->connected) {
+		e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OTHER_ERROR));
+		return;
+	}
 
 	offline = e_source_get_property (source, "offline_sync");
 	if (offline && g_str_equal (offline, "1"))
 		bl->priv->marked_for_offline = TRUE;
 
-	if (bl->priv->mode ==  E_DATA_BOOK_MODE_LOCAL &&
+	if (!e_book_backend_is_online (backend) &&
 	    !bl->priv->marked_for_offline) {
-		g_propagate_error (error, EDB_ERROR (OFFLINE_UNAVAILABLE));
+		e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE));
 		return;
 	}
 
 	uri = e_source_get_uri (source);
 	host = uri + sizeof ("gal://") - 1;
 	if (strncmp (uri, "gal://", host - uri)) {
-		g_propagate_error (error, EDB_ERROR_EX (OTHER_ERROR, "Not a gal:// URI"));
+		e_book_backend_respond_opened (backend, book, opid, EDB_ERROR_EX (OTHER_ERROR, "Not a gal:// URI"));
 		return;
 	}
 
@@ -2653,18 +2612,14 @@ load_source (EBookBackend *backend,
 #if defined(ENABLE_CACHE) && ENABLE_CACHE
 	bl->priv->file_db = NULL;
 #endif
-	if (bl->priv->mode == E_DATA_BOOK_MODE_LOCAL && !bl->priv->marked_for_offline) {
+	if (!e_book_backend_is_online (backend) && !bl->priv->marked_for_offline) {
 		/* Offline */
-
-		e_book_backend_set_is_loaded (backend, FALSE);
-		e_book_backend_set_is_writable (backend, FALSE);
-		e_book_backend_notify_writable (backend, FALSE);
-		e_book_backend_notify_connection_status (backend, FALSE);
+		e_book_backend_notify_readonly (backend, TRUE);
 
 		g_free (book_name);
 		g_free (uri);
 
-		g_propagate_error (error, EDB_ERROR (REPOSITORY_OFFLINE));
+		e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (REPOSITORY_OFFLINE));
 		return;
 	}
 		d(printf("offlin==============\n"));
@@ -2689,7 +2644,7 @@ load_source (EBookBackend *backend,
 			g_warning ("db recovery failed with %d", db_error);
 			g_free (dirname);
 			g_free (filename);
-			g_propagate_error (error, EDB_ERROR (OTHER_ERROR));
+			e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OTHER_ERROR));
 			return;
 		}
 
@@ -2705,7 +2660,7 @@ load_source (EBookBackend *backend,
 				g_static_mutex_unlock (&global_env_lock);
 				g_free (dirname);
 				g_free (filename);
-				g_propagate_error (error, EDB_ERROR (OTHER_ERROR));
+				e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OTHER_ERROR));
 				return;
 			}
 
@@ -2716,7 +2671,7 @@ load_source (EBookBackend *backend,
 				g_static_mutex_unlock (&global_env_lock);
 				g_free (dirname);
 				g_free (filename);
-				g_propagate_error (error, EDB_ERROR (OTHER_ERROR));
+				e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OTHER_ERROR));
 				return;
 			}
 
@@ -2732,7 +2687,7 @@ load_source (EBookBackend *backend,
 			g_warning ("db_create failed with %d", db_error);
 			g_free (dirname);
 			g_free (filename);
-			g_propagate_error (error, EDB_ERROR (OTHER_ERROR));
+			e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OTHER_ERROR));
 			return;
 		}
 
@@ -2745,7 +2700,7 @@ load_source (EBookBackend *backend,
 				g_warning ("db format upgrade failed with %d", db_error);
 				g_free (filename);
 				g_free (dirname);
-				g_propagate_error (error, EDB_ERROR (OTHER_ERROR));
+				e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OTHER_ERROR));
 				return;
 			}
 
@@ -2763,10 +2718,10 @@ load_source (EBookBackend *backend,
 				g_free (dirname);
 				g_free (filename);
 				if (errno == EACCES || errno == EPERM) {
-					g_propagate_error (error, EDB_ERROR (PERMISSION_DENIED));
+					e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (PERMISSION_DENIED));
 					return;
 				} else {
-					g_propagate_error (error, EDB_ERROR (OTHER_ERROR));
+					e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OTHER_ERROR));
 					return;
 				}
 			}
@@ -2783,7 +2738,7 @@ load_source (EBookBackend *backend,
 
 			g_free (filename);
 			g_free (dirname);
-			g_propagate_error (error, EDB_ERROR (OTHER_ERROR));
+			e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OTHER_ERROR));
 			return;
 		}
 
@@ -2796,29 +2751,57 @@ load_source (EBookBackend *backend,
 	}
 #endif
 	/* Online */
-	e_book_backend_set_is_writable (E_BOOK_BACKEND (backend), FALSE);
-	e_book_backend_set_is_loaded (E_BOOK_BACKEND (backend), TRUE);
-	e_book_backend_notify_writable (backend, FALSE);
+	e_book_backend_notify_readonly (backend, TRUE);
 
-	if (bl->priv->mode == E_DATA_BOOK_MODE_LOCAL)
-		e_book_backend_notify_connection_status (E_BOOK_BACKEND (backend), FALSE);
-	else
-		e_book_backend_notify_connection_status (E_BOOK_BACKEND (backend), TRUE);
+	if (!e_book_backend_is_online (backend)) {
+		e_book_backend_respond_opened (backend, book, opid, NULL);
+	} else {
+		e_book_backend_notify_auth_required (E_BOOK_BACKEND (backend), TRUE, NULL);
+		e_data_book_respond_open (book, opid, NULL);
+	}
 }
 
 static void
-remove_gal (EBookBackend *backend, EDataBook *book, guint32 opid)
+gal_remove (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable)
 {
 	e_data_book_respond_remove (book, opid, EDB_ERROR (PERMISSION_DENIED));
 }
 
-static gchar *
-get_static_capabilities (EBookBackend *backend)
+static void
+gal_get_backend_property (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *prop_name)
 {
-	if (can_browse (backend))
-		return g_strdup ("net,do-initial-query");
-	else
-		return g_strdup ("net");
+	g_return_if_fail (backend != NULL);
+	g_return_if_fail (prop_name != NULL);
+
+	if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
+		if (can_browse (backend))
+			e_data_book_respond_get_backend_property (book, opid, NULL, "net,do-initial-query");
+		else
+			e_data_book_respond_get_backend_property (book, opid, NULL, "net");
+	} else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS)) {
+		e_data_book_respond_get_backend_property (book, opid, NULL, e_contact_field_name (E_CONTACT_FILE_AS));
+	} else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS)) {
+		GSList *supported_fields;
+		gchar *value;
+		gint ii;
+
+		supported_fields = NULL;
+		for (ii = 0; ii < G_N_ELEMENTS (prop_info); ii++) {
+			supported_fields = g_slist_append (supported_fields,
+							  (gchar *) e_contact_field_name (prop_info[ii].field_id));
+		}
+		supported_fields = g_slist_append (supported_fields, (gpointer) "file_as");
+		value = e_data_book_string_slist_to_comma_string (supported_fields);
+
+		e_data_book_respond_get_backend_property (book, opid, NULL, value);
+
+		g_free (value);
+		g_slist_free (supported_fields);
+	} else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_SUPPORTED_AUTH_METHODS)) {
+		e_data_book_respond_get_backend_property (book, opid, NULL, NULL);
+	} else {
+		(* E_BOOK_BACKEND_CLASS (parent_class)->get_backend_property) (backend, book, opid, cancellable, prop_name);
+	}
 }
 
 /**
@@ -2916,35 +2899,23 @@ class_init (EBookBackendGALClass *klass)
 	parent_class = g_type_class_peek_parent (klass);
 
 	/* Set the virtual methods. */
-	backend_class->load_source                = load_source;
-	backend_class->remove                     = remove_gal;
-	backend_class->get_static_capabilities    = get_static_capabilities;
-
-	backend_class->create_contact             = create_contact;
-	backend_class->remove_contacts            = remove_contacts;
-	backend_class->modify_contact             = modify_contact;
-	backend_class->get_contact                = get_contact;
-	backend_class->get_contact_list           = get_contact_list;
-	backend_class->start_book_view            = start_book_view;
-	backend_class->stop_book_view             = stop_book_view;
-	backend_class->get_changes                = get_changes;
-	backend_class->authenticate_user          = authenticate_user;
-	backend_class->get_supported_fields       = get_supported_fields;
-	backend_class->set_mode                   = set_mode;
-	backend_class->get_required_fields        = get_required_fields;
-	backend_class->get_supported_auth_methods = get_supported_auth_methods;
-	backend_class->cancel_operation           = cancel_operation;
+	backend_class->open			= gal_open;
+	backend_class->remove			= gal_remove;
+	backend_class->get_backend_property	= gal_get_backend_property;
+
+	backend_class->create_contact		= create_contact;
+	backend_class->remove_contacts		= remove_contacts;
+	backend_class->modify_contact		= modify_contact;
+	backend_class->get_contact		= get_contact;
+	backend_class->get_contact_list		= get_contact_list;
+	backend_class->start_book_view		= start_book_view;
+	backend_class->stop_book_view		= stop_book_view;
+	backend_class->authenticate_user	= authenticate_user;
+	backend_class->set_online		= set_online;
 
 	object_class->dispose = dispose;
 
 	/* Set up static data */
-	supported_fields = NULL;
-	for (i = 0; i < G_N_ELEMENTS (prop_info); i++) {
-		supported_fields = g_list_append (supported_fields,
-						  (gchar *) e_contact_field_name (prop_info[i].field_id));
-	}
-	supported_fields = g_list_append (supported_fields, (gpointer) "file_as");
-
 	search_attrs = g_new (const gchar *, G_N_ELEMENTS (prop_info) + 1);
 	for (i = 0; i < G_N_ELEMENTS (prop_info); i++)
 		search_attrs[i] = prop_info[i].ldap_attr;
diff --git a/calendar/e-cal-backend-exchange-calendar.c b/calendar/e-cal-backend-exchange-calendar.c
index 5da490a..4be6879 100644
--- a/calendar/e-cal-backend-exchange-calendar.c
+++ b/calendar/e-cal-backend-exchange-calendar.c
@@ -57,7 +57,7 @@ static ECalBackendExchange *parent_class = NULL;
 
 #define d(x)
 
-static gboolean modify_object_with_href (ECalBackendSync *backend, EDataCal *cal, const gchar *calobj, CalObjModType mod, gchar **old_object, gchar **new_object, const gchar *href, const gchar *rid_to_remove, GError **error);
+static gboolean modify_object_with_href (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, CalObjModType mod, gchar **old_object, gchar **new_object, const gchar *href, const gchar *rid_to_remove, GError **error);
 
 static icalproperty *find_attendee_prop (icalcomponent *ical_comp, const gchar *address);
 static gboolean check_owner_partstatus_for_declined (ECalBackendSync *backend,
@@ -569,23 +569,20 @@ notify_changes (E2kContext *ctx, const gchar *uri,
 }
 
 static void
-open_calendar (ECalBackendSync *backend, EDataCal *cal,
-	       gboolean only_if_exists,
-	       const gchar *username, const gchar *password, GError **perror)
+authenticate_user (ECalBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **perror)
 {
 	GThread *thread = NULL;
 	GError *error = NULL;
 	ECalBackendExchangeCalendar *cbexc = E_CAL_BACKEND_EXCHANGE_CALENDAR (backend);
 
 	/* Do the generic part */
-	E_CAL_BACKEND_SYNC_CLASS (parent_class)->open_sync (
-		backend, cal, only_if_exists, username, password, &error);
+	E_CAL_BACKEND_SYNC_CLASS (parent_class)->authenticate_user_sync (backend, cancellable, credentials, &error);
 	if (error) {
 		g_propagate_error (perror, error);
 		return;
 	}
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		return; /* Success */
 	}
 
@@ -612,7 +609,7 @@ open_calendar (ECalBackendSync *backend, EDataCal *cal,
 }
 
 static void
-refresh_calendar (ECalBackendSync *backend, EDataCal *cal, GError **perror)
+refresh_calendar (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, GError **perror)
 {
 	g_return_if_fail (E_IS_CAL_BACKEND_EXCHANGE (backend));
 
@@ -740,8 +737,8 @@ check_owner_partstatus_for_declined (ECalBackendSync *backend,
 }
 
 static void
-create_object (ECalBackendSync *backend, EDataCal *cal,
-	       gchar **calobj, gchar **uid, GError **error)
+create_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
+	       const gchar *calobj, gchar **uid, gchar **new_object, GError **error)
 {
 	/* FIXME : Return some value in uid */
 	ECalBackendExchangeCalendar *cbexc;
@@ -775,7 +772,7 @@ create_object (ECalBackendSync *backend, EDataCal *cal,
 	e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_EXCHANGE_CALENDAR (cbexc), InvalidArg);
 	e_return_data_cal_error_if_fail (calobj != NULL, InvalidArg);
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		g_propagate_error (error, EDC_ERROR (RepositoryOffline));
 		return;
 	}
@@ -784,7 +781,7 @@ create_object (ECalBackendSync *backend, EDataCal *cal,
 	   ....
 	 */
 
-	icalcomp = icalparser_parse_string (*calobj);
+	icalcomp = icalparser_parse_string (calobj);
 	if (!icalcomp) {
 		g_propagate_error (error, EDC_ERROR (InvalidObject));
 		return;
@@ -882,15 +879,15 @@ create_object (ECalBackendSync *backend, EDataCal *cal,
 	/* add the timezones information and the component itself
 	   to the VCALENDAR object */
 	e_cal_component_commit_sequence (comp);
-	*calobj = e_cal_component_get_as_string (comp);
-	if (!*calobj) {
+	*new_object = e_cal_component_get_as_string (comp);
+	if (!*new_object) {
 		g_object_unref (comp);
 		icalcomponent_free (cbdata->vcal_comp);
 		g_free (cbdata);
 		g_propagate_error (error, EDC_ERROR_EX (OtherError, "Cannot get comp as string"));
 		return;
 	}
-	real_icalcomp = icalparser_parse_string (*calobj);
+	real_icalcomp = icalparser_parse_string (*new_object);
 
 	icalcomponent_foreach_tzid (real_icalcomp, add_timezone_cb, cbdata);
 	icalcomponent_add_component (cbdata->vcal_comp, real_icalcomp);
@@ -1091,13 +1088,13 @@ update_x_properties (ECalBackendExchange *cbex, ECalComponent *comp)
 }
 
 static void
-modify_object (ECalBackendSync *backend, EDataCal *cal,
+modify_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
 	       const gchar *calobj, CalObjModType mod,
 	       gchar **old_object, gchar **new_object, GError **perror)
 {
 	d(printf ("ecbexc_modify_object(%p, %p, %d, %s)", backend, cal, mod, *old_object ? *old_object : NULL));
 
-	modify_object_with_href (backend, cal, calobj, mod, old_object, new_object, NULL, NULL, perror);
+	modify_object_with_href (backend, cal, cancellable, calobj, mod, old_object, new_object, NULL, NULL, perror);
 }
 
 #define e_return_data_cal_error_and_val_if_fail(expr, _code, _val)		\
@@ -1116,7 +1113,7 @@ modify_object (ECalBackendSync *backend, EDataCal *cal,
 	} G_STMT_END
 
 static gboolean
-modify_object_with_href (ECalBackendSync *backend, EDataCal *cal,
+modify_object_with_href (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
 	       const gchar *calobj, CalObjModType mod,
 	       gchar **old_object, gchar **new_object, const gchar *href, const gchar *rid_to_remove, GError **error)
 {
@@ -1153,7 +1150,7 @@ modify_object_with_href (ECalBackendSync *backend, EDataCal *cal,
 	e_return_data_cal_error_and_val_if_fail (E_IS_CAL_BACKEND_EXCHANGE_CALENDAR (cbexc), InvalidArg, FALSE);
 	e_return_data_cal_error_and_val_if_fail (calobj != NULL, InvalidArg, FALSE);
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		g_propagate_error (error, EDC_ERROR (RepositoryOffline));
 		return FALSE;
 	}
@@ -1298,9 +1295,7 @@ modify_object_with_href (ECalBackendSync *backend, EDataCal *cal,
 	if (dt.value->is_date) {
 		icaltimezone *zone;
 
-		zone = e_cal_backend_exchange_get_default_time_zone (backend);
-		if (!zone)
-			zone = icaltimezone_get_utc_timezone ();
+		zone = icaltimezone_get_utc_timezone ();
 
 		dt.value->is_date = FALSE;
 		dt.value->is_utc = FALSE;
@@ -1533,7 +1528,7 @@ modify_object_with_href (ECalBackendSync *backend, EDataCal *cal,
 }
 
 static void
-remove_object (ECalBackendSync *backend, EDataCal *cal,
+remove_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
 	       const gchar *uid, const gchar *rid, CalObjModType mod,
 	       gchar **old_object, gchar **object, GError **error)
 {
@@ -1555,7 +1550,7 @@ remove_object (ECalBackendSync *backend, EDataCal *cal,
 
 	e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_EXCHANGE_CALENDAR (cbexc), InvalidArg);
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		g_propagate_error (error, EDC_ERROR (RepositoryOffline));
 		return;
 	}
@@ -1587,7 +1582,7 @@ remove_object (ECalBackendSync *backend, EDataCal *cal,
 		calobj  = (gchar *) icalcomponent_as_ical_string_r (ecomp->icomp);
 
 		e_cal_backend_exchange_cache_unlock (cbex);
-		res = modify_object_with_href (backend, cal, calobj, mod, &obj, &new_object, NULL, rid, error);
+		res = modify_object_with_href (backend, cal, cancellable, calobj, mod, &obj, &new_object, NULL, rid, error);
 		g_object_unref (comp);
 		g_free (calobj);
 		if (!res)
@@ -1622,7 +1617,7 @@ remove_object (ECalBackendSync *backend, EDataCal *cal,
 }
 
 static void
-receive_objects (ECalBackendSync *backend, EDataCal *cal,
+receive_objects (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
 		 const gchar *calobj, GError **error)
 {
 	ECalBackendExchangeCalendar *cbexc;
@@ -1642,7 +1637,7 @@ receive_objects (ECalBackendSync *backend, EDataCal *cal,
 	e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_EXCHANGE_CALENDAR (cbexc), InvalidArg);
 	e_return_data_cal_error_if_fail (calobj != NULL, InvalidArg);
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		g_propagate_error (error, EDC_ERROR (RepositoryOffline));
 		return;
 	}
@@ -1700,7 +1695,7 @@ receive_objects (ECalBackendSync *backend, EDataCal *cal,
 				e_cal_backend_exchange_cache_unlock (cbex);
 				if (check_owner_partstatus_for_declined (backend, subcomp)) {
 					ECalComponentId *id = NULL;
-					remove_object (backend, cal, uid, NULL,
+					remove_object (backend, cal, cancellable, uid, NULL,
 								CALOBJ_MOD_ALL, &old_object,
 								NULL, &err);
 					if (err) {
@@ -1728,7 +1723,7 @@ receive_objects (ECalBackendSync *backend, EDataCal *cal,
 						mod = CALOBJ_MOD_THIS;
 
 					icalobj = e_cal_component_get_as_string (comp);
-					if (!modify_object_with_href (backend, cal, icalobj,
+					if (!modify_object_with_href (backend, cal, cancellable, icalobj,
 									  mod,
 									  &old_object, &new_object, NULL, NULL, error)) {
 						g_free (rid);
@@ -1758,14 +1753,14 @@ receive_objects (ECalBackendSync *backend, EDataCal *cal,
 				d(printf ("Create a new object : %s\n", icalobj));
 
 				e_cal_backend_exchange_cache_unlock (cbex);
-				create_object (backend, cal, &icalobj, &returned_uid, &err);
+				create_object (backend, cal, cancellable, icalobj, &returned_uid, &object, &err);
+				g_free (icalobj);
 				if (err) {
 					g_propagate_error (error, err);
 					g_free (rid);
 					goto error;
 				}
 
-				object = icalobj;
 				e_cal_backend_notify_object_created (E_CAL_BACKEND (backend), icalobj);
 				d(printf ("Notify that the new object is created : %s\n", icalobj));
 				g_free (object);
@@ -1781,9 +1776,9 @@ receive_objects (ECalBackendSync *backend, EDataCal *cal,
 		case ICAL_METHOD_CANCEL:
 			icalobj = (gchar *) icalcomponent_as_ical_string_r (subcomp);
 			if (rid)
-				remove_object (backend, cal, uid, rid, CALOBJ_MOD_THIS, &icalobj, &object, &err);
+				remove_object (backend, cal, cancellable, uid, rid, CALOBJ_MOD_THIS, &icalobj, &object, &err);
 			else
-				remove_object (backend, cal, uid, NULL, CALOBJ_MOD_ALL, &icalobj, &object, &err);
+				remove_object (backend, cal, cancellable, uid, NULL, CALOBJ_MOD_ALL, &icalobj, &object, &err);
 			if (!err) {
 				ECalComponentId *id = e_cal_component_get_id (comp);
 				e_cal_backend_notify_object_removed (E_CAL_BACKEND (backend), id, icalobj, NULL);
@@ -2031,16 +2026,16 @@ book_resource (ECalBackendExchange *cbex,
 	icalparameter_set_partstat (part_param, ICAL_PARTSTAT_ACCEPTED);
 
 	e_cal_component_commit_sequence (comp);
-	calobj = (gchar *) e_cal_component_get_as_string (comp);
+	calobj = e_cal_component_get_as_string (comp);
 
 	/* status = e_cal_component_update (comp, method, FALSE  ); */
 	if (ecomp) {
 		gboolean modify_ok = FALSE;
 		/* Use the PUT method to create the meeting item in the resource's calendar. */
-		if (modify_object_with_href (E_CAL_BACKEND_SYNC (cbex), cal, calobj, book_all ? CALOBJ_MOD_ALL : CALOBJ_MOD_THIS, &old_object, &new_object, href, NULL, NULL)) {
+		if (modify_object_with_href (E_CAL_BACKEND_SYNC (cbex), cal, NULL, calobj, book_all ? CALOBJ_MOD_ALL : CALOBJ_MOD_THIS, &old_object, &new_object, href, NULL, NULL)) {
 			/* Need this to update the participation status of the resource
 			   in the organizer's calendar. */
-			modify_ok = modify_object_with_href (E_CAL_BACKEND_SYNC (cbex), cal, calobj, book_all ? CALOBJ_MOD_ALL : CALOBJ_MOD_THIS, &old_object, &new_object, NULL, NULL, NULL);
+			modify_ok = modify_object_with_href (E_CAL_BACKEND_SYNC (cbex), cal, NULL, calobj, book_all ? CALOBJ_MOD_ALL : CALOBJ_MOD_THIS, &old_object, &new_object, NULL, NULL, NULL);
 		} else {
 			retval = E_CAL_BACKEND_EXCHANGE_BOOKING_ERROR;
 			goto cleanup;
@@ -2054,13 +2049,15 @@ book_resource (ECalBackendExchange *cbex,
 	} else {
 		GError *err = NULL;
 
-		create_object (E_CAL_BACKEND_SYNC (cbex), cal, &calobj, &returned_uid, &err);
+		create_object (E_CAL_BACKEND_SYNC (cbex), cal, NULL, calobj, &returned_uid, &new_object, &err);
 		if (!err) {
 			e_cal_backend_notify_object_created (E_CAL_BACKEND (cbex), calobj);
 			retval = E_CAL_BACKEND_EXCHANGE_BOOKING_OK;
 		} else {
 			g_error_free (err);
 		}
+
+		g_free (new_object);
 	}
 
  cleanup:
@@ -2077,9 +2074,9 @@ book_resource (ECalBackendExchange *cbex,
 }
 
 static void
-send_objects (ECalBackendSync *backend, EDataCal *cal,
+send_objects (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
 	      const gchar *calobj,
-	      GList **users, gchar **modified_calobj, GError **error)
+	      GSList **users, gchar **modified_calobj, GError **error)
 {
 	ECalBackendExchange *cbex = (ECalBackendExchange *) backend;
 	ECalBackendExchangeBookingResult result;
@@ -2091,7 +2088,7 @@ send_objects (ECalBackendSync *backend, EDataCal *cal,
 
 	e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_EXCHANGE (cbex), InvalidArg);
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (cbex))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (cbex))) {
 		g_propagate_error (error, EDC_ERROR (RepositoryOffline));
 		return;
 	}
@@ -2157,7 +2154,7 @@ send_objects (ECalBackendSync *backend, EDataCal *cal,
 		result = book_resource (cbex, cal, attendee + 7, comp, method, param, icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY) || icalcomponent_get_first_property (icalcomp, ICAL_RDATE_PROPERTY));
 		switch (result) {
 		case E_CAL_BACKEND_EXCHANGE_BOOKING_OK:
-			*users = g_list_append (*users, g_strdup (attendee));
+			*users = g_slist_append (*users, g_strdup (attendee));
 			break;
 
 		case E_CAL_BACKEND_EXCHANGE_BOOKING_BUSY:
@@ -2252,8 +2249,8 @@ set_freebusy_info (icalcomponent *vfb, const gchar *data, time_t start)
 }
 
 static void
-discard_alarm (ECalBackendSync *backend, EDataCal *cal,
-		const gchar *uid, const gchar *auid, GError **error)
+discard_alarm (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
+		const gchar *uid, const gchar *rid, const gchar *auid, GError **error)
 {
 	ECalBackendExchange *cbex = NULL;
 	ECalBackendExchangeComponent *ecbexcomp;
@@ -2268,7 +2265,7 @@ discard_alarm (ECalBackendSync *backend, EDataCal *cal,
 
 	d(printf("ecbe_discard_alarm(%p, %p, uid=%s, auid=%s)\n", backend, cal, uid, auid));
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		g_propagate_error (error, EDC_ERROR (RepositoryOffline));
 		return;
 	}
@@ -2303,13 +2300,13 @@ discard_alarm (ECalBackendSync *backend, EDataCal *cal,
 }
 
 static void
-get_free_busy (ECalBackendSync *backend, EDataCal *cal,
-	       GList *users, time_t start, time_t end,
-	       GList **freebusy, GError **perror)
+get_free_busy (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
+	       const GSList *users, time_t start, time_t end,
+	       GSList **freebusy, GError **perror)
 {
 	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
 	gchar *start_str, *end_str;
-	GList *l;
+	const GSList *l;
 	GString *uri;
 	SoupBuffer *response;
 	E2kHTTPStatus http_status;
@@ -2317,7 +2314,7 @@ get_free_busy (ECalBackendSync *backend, EDataCal *cal,
 	xmlNode *recipients, *item;
 	xmlDoc *doc;
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		g_propagate_error (perror, EDC_ERROR (RepositoryOffline));
 		return;
 	}
@@ -2406,7 +2403,7 @@ get_free_busy (ECalBackendSync *backend, EDataCal *cal,
 		set_freebusy_info (vfb, content, start);
 
 		calobj = icalcomponent_as_ical_string_r (vfb);
-		*freebusy = g_list_prepend (*freebusy, calobj);
+		*freebusy = g_slist_prepend (*freebusy, calobj);
 		icalcomponent_free (vfb);
 	}
 	xmlFreeDoc (doc);
@@ -2450,14 +2447,14 @@ class_init (ECalBackendExchangeCalendarClass *klass)
 
 	parent_class = g_type_class_peek_parent (klass);
 
-	sync_class->open_sync = open_calendar;
+	sync_class->authenticate_user_sync = authenticate_user;
 	sync_class->refresh_sync = refresh_calendar;
 	sync_class->create_object_sync = create_object;
 	sync_class->modify_object_sync = modify_object;
 	sync_class->remove_object_sync = remove_object;
 	sync_class->receive_objects_sync = receive_objects;
 	sync_class->send_objects_sync = send_objects;
-	sync_class->get_freebusy_sync = get_free_busy;
+	sync_class->get_free_busy_sync = get_free_busy;
 	sync_class->discard_alarm_sync = discard_alarm;
 
 	object_class->dispose = dispose;
diff --git a/calendar/e-cal-backend-exchange-tasks.c b/calendar/e-cal-backend-exchange-tasks.c
index 571b361..ecac68a 100644
--- a/calendar/e-cal-backend-exchange-tasks.c
+++ b/calendar/e-cal-backend-exchange-tasks.c
@@ -986,22 +986,19 @@ notify_changes (E2kContext *ctx, const gchar *uri,
 }
 
 static void
-open_task (ECalBackendSync *backend, EDataCal *cal,
-	   gboolean only_if_exits,
-	   const gchar *username, const gchar *password, GError **perror)
+authenticate_user_task (ECalBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **perror)
 {
 	GThread *thread = NULL;
 	GError *error = NULL;
 	ECalBackendExchangeTasks *cbext = E_CAL_BACKEND_EXCHANGE_TASKS (backend);
 
-	E_CAL_BACKEND_SYNC_CLASS (parent_class)->open_sync (backend,
-				     cal, only_if_exits, username, password, &error);
+	E_CAL_BACKEND_SYNC_CLASS (parent_class)->authenticate_user_sync (backend, cancellable, credentials, &error);
 	if (error) {
 		g_propagate_error (perror, error);
 		return;
 	}
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		d(printf ("ECBEC : calendar is offline\n"));
 		return;
 	}
@@ -1028,7 +1025,7 @@ open_task (ECalBackendSync *backend, EDataCal *cal,
 }
 
 static void
-refresh_task (ECalBackendSync *backend, EDataCal *cal, GError **perror)
+refresh_task (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, GError **perror)
 {
 	g_return_if_fail (E_IS_CAL_BACKEND_EXCHANGE (backend));
 
@@ -1042,8 +1039,8 @@ struct _cb_data {
 };
 
 static void
-create_task_object (ECalBackendSync *backend, EDataCal *cal,
-		    gchar **calobj, gchar **return_uid, GError **error)
+create_task_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, 
+		    const gchar *calobj, gchar **return_uid, gchar **new_object, GError **error)
 {
 	ECalBackendExchange *ecalbex;
 	E2kProperties *props;
@@ -1067,14 +1064,14 @@ create_task_object (ECalBackendSync *backend, EDataCal *cal,
 
 	e_return_data_cal_error_if_fail (calobj != NULL, InvalidArg);
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		d(printf ("tasks are offline\n"));
 		g_propagate_error (error, EDC_ERROR (RepositoryOffline));
 		return;
 	}
 
 	/* Parse the icalendar text */
-	icalcomp = icalparser_parse_string (*calobj);
+	icalcomp = icalparser_parse_string (calobj);
 	if (!icalcomp) {
 		g_propagate_error (error, EDC_ERROR (InvalidObject));
 		return;
@@ -1172,8 +1169,8 @@ create_task_object (ECalBackendSync *backend, EDataCal *cal,
 
 	update_props (comp, &props);
 	e_cal_component_commit_sequence (comp);
-	*calobj = e_cal_component_get_as_string (comp);
-	if (!*calobj) {
+	*new_object = e_cal_component_get_as_string (comp);
+	if (!*new_object) {
 		g_object_unref (comp);
 		g_free (from_name);
 		g_free (from_addr);
@@ -1181,7 +1178,7 @@ create_task_object (ECalBackendSync *backend, EDataCal *cal,
 		return;
 	}
 
-	real_icalcomp = icalparser_parse_string (*calobj);
+	real_icalcomp = icalparser_parse_string (*new_object);
 
 	e2kctx = exchange_account_get_context (ecalbex->account);
 	status = e_folder_exchange_proppatch_new (ecalbex->folder, NULL,
@@ -1211,7 +1208,7 @@ create_task_object (ECalBackendSync *backend, EDataCal *cal,
 }
 
 static void
-modify_task_object (ECalBackendSync *backend, EDataCal *cal,
+modify_task_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
 	       const gchar *calobj, CalObjModType mod,
 	       gchar **old_object, gchar **new_object, GError **error)
 {
@@ -1237,7 +1234,7 @@ modify_task_object (ECalBackendSync *backend, EDataCal *cal,
 	e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_EXCHANGE_TASKS (ecalbextask), InvalidArg);
 	e_return_data_cal_error_if_fail (calobj != NULL, InvalidArg);
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		d(printf ("tasks are offline\n"));
 		g_propagate_error (error, EDC_ERROR (RepositoryOffline));
 		return;
@@ -1339,7 +1336,7 @@ modify_task_object (ECalBackendSync *backend, EDataCal *cal,
 }
 
 static void
-receive_task_objects (ECalBackendSync *backend, EDataCal *cal,
+receive_task_objects (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
                  const gchar *calobj, GError **error)
 {
 	ECalBackendExchangeTasks *ecalbextask;
@@ -1357,7 +1354,7 @@ receive_task_objects (ECalBackendSync *backend, EDataCal *cal,
 	e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_EXCHANGE_TASKS (ecalbextask), InvalidArg);
 	e_return_data_cal_error_if_fail (calobj != NULL, InvalidArg);
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		d(printf ("tasks are offline\n"));
 		g_propagate_error (error, EDC_ERROR (RepositoryOffline));
 		return;
@@ -1391,7 +1388,7 @@ receive_task_objects (ECalBackendSync *backend, EDataCal *cal,
 			gchar *old_object;
 
 			e_cal_backend_exchange_cache_unlock (cbex);
-			modify_task_object (backend, cal, calobj, CALOBJ_MOD_THIS, &old_object, NULL, &err);
+			modify_task_object (backend, cal, cancellable, calobj, CALOBJ_MOD_THIS, &old_object, NULL, &err);
 			if (err) {
 				g_free (rid);
 				g_propagate_error (error, err);
@@ -1401,20 +1398,21 @@ receive_task_objects (ECalBackendSync *backend, EDataCal *cal,
 			e_cal_backend_notify_object_modified (E_CAL_BACKEND (backend), old_object, calobj);
 			g_free (old_object);
 		} else {
-			gchar *returned_uid;
+			gchar *returned_uid, *new_object = NULL;
 
 			e_cal_backend_exchange_cache_unlock (cbex);
 			calobj = (gchar *) icalcomponent_as_ical_string_r (subcomp);
-			create_task_object (backend, cal, &calobj, &returned_uid, &err);
+			create_task_object (backend, cal, cancellable, calobj, &returned_uid, &new_object, &err);
+			g_free (calobj);
 			if (err) {
-				g_free (calobj);
+				g_free (new_object);
 				g_free (rid);
 				g_propagate_error (error, err);
 				return;
 			}
 
-			e_cal_backend_notify_object_created (E_CAL_BACKEND (backend), calobj);
-			g_free (calobj);
+			e_cal_backend_notify_object_created (E_CAL_BACKEND (backend), new_object);
+			g_free (new_object);
 		}
 		g_free (rid);
 	}
@@ -1423,7 +1421,7 @@ receive_task_objects (ECalBackendSync *backend, EDataCal *cal,
 }
 
 static void
-remove_task_object (ECalBackendSync *backend, EDataCal *cal,
+remove_task_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
 	       const gchar *uid, const gchar *rid, CalObjModType mod,
 	       gchar **old_object, gchar **object, GError **error)
 {
@@ -1435,7 +1433,7 @@ remove_task_object (ECalBackendSync *backend, EDataCal *cal,
 
 	e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_EXCHANGE (ecalbex), InvalidArg);
 
-	if (!e_cal_backend_exchange_is_online (E_CAL_BACKEND_EXCHANGE (backend))) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (backend))) {
 		d(printf ("tasks are offline\n"));
 		g_propagate_error (error, EDC_ERROR (RepositoryOffline));
 		return;
@@ -1507,7 +1505,7 @@ class_init (ECalBackendExchangeTasksClass *klass)
 
 	parent_class = g_type_class_peek_parent (klass);
 
-	sync_class->open_sync = open_task;
+	sync_class->authenticate_user_sync = authenticate_user_task;
 	sync_class->refresh_sync = refresh_task;
 	sync_class->create_object_sync = create_task_object;
 	sync_class->modify_object_sync = modify_task_object;
diff --git a/calendar/e-cal-backend-exchange.c b/calendar/e-cal-backend-exchange.c
index 34e035e..4a9dbe0 100644
--- a/calendar/e-cal-backend-exchange.c
+++ b/calendar/e-cal-backend-exchange.c
@@ -59,6 +59,7 @@
 
 struct ECalBackendExchangePrivate {
 	gboolean read_only;
+	gboolean is_loaded;
 
 	/* Objects */
 	GHashTable *objects, *cache_unseen;
@@ -72,9 +73,6 @@ struct ECalBackendExchangePrivate {
 
 	/* Timezones */
 	GHashTable *timezones;
-	icaltimezone *default_timezone;
-	gboolean is_loaded;
-	CalMode mode;
 };
 
 #define PARENT_TYPE E_TYPE_CAL_BACKEND_SYNC
@@ -85,25 +83,57 @@ static GObjectClass *parent_class = NULL;
 static icaltimezone *
 internal_get_timezone (ECalBackend *backend, const gchar *tzid);
 
-static void
-is_read_only (ECalBackendSync *backend, EDataCal *cal, gboolean *read_only, GError **perror)
-{
-	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
+static gboolean
+get_backend_property (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *prop_name, gchar **prop_value, GError **error)
+{
+	gboolean processed = TRUE;
+
+	g_return_val_if_fail (backend != NULL, FALSE);
+	g_return_val_if_fail (prop_name != NULL, FALSE);
+	g_return_val_if_fail (prop_value != NULL, FALSE);
+
+	if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
+		d(printf("ecbe_get_static_capabilities(%p, %p)\n", backend, cal));
+
+		*prop_value = g_strdup (
+			CAL_STATIC_CAPABILITY_NO_EMAIL_ALARMS ","
+			CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT ","
+			CAL_STATIC_CAPABILITY_NO_THISANDFUTURE ","
+			CAL_STATIC_CAPABILITY_NO_THISANDPRIOR ","
+			CAL_STATIC_CAPABILITY_REMOVE_ALARMS ","
+			CAL_STATIC_CAPABILITY_REFRESH_SUPPORTED);
+	} else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS)) {
+		ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
+		ExchangeHierarchy *hier;
+
+		hier = e_folder_exchange_get_hierarchy (cbex->folder);
+		d(printf("ecbe_get_cal_address(%p, %p) -> %s\n", backend, cal, hier->owner_email));
+		*prop_value = g_strdup (hier->owner_email);
+	} else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS)) {
+		d(printf("ecbe_get_alarm_email_address(%p, %p)\n", backend, cal));
+
+		/* We don't support email alarms.
+		 * This should not have been called.
+		 */
+		*prop_value = NULL;
 
-	d(printf("ecbe_is_read_only(%p, %p) -> %d\n", backend, cal, cbex->priv->read_only));
+		g_propagate_error (error, EDC_ERROR (NotSupported));
+	} else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_DEFAULT_OBJECT)) {
+		icalcomponent *comp;
+		gchar *ical_obj;
 
-	*read_only = cbex->priv->read_only;
-}
+		d(printf("ecbe_get_default_object(%p, %p)\n", backend, cal));
 
-static void
-get_cal_address (ECalBackendSync *backend, EDataCal *cal, gchar **address, GError **perror)
-{
-	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
-	ExchangeHierarchy *hier;
+		comp = e_cal_util_new_component (e_cal_backend_get_kind (E_CAL_BACKEND (backend)));
+		ical_obj = icalcomponent_as_ical_string_r (comp);
+		*prop_value = ical_obj;
 
-	hier = e_folder_exchange_get_hierarchy (cbex->folder);
-	d(printf("ecbe_get_cal_address(%p, %p) -> %s\n", backend, cal, hier->owner_email));
-	*address = g_strdup (hier->owner_email);
+		icalcomponent_free (comp);
+	} else {
+		processed = FALSE;
+	}
+
+	return processed;
 }
 
 static void
@@ -118,47 +148,6 @@ get_cal_owner (ECalBackendSync *backend, gchar **name)
 	*name = g_strdup (hier->owner_name);
 }
 
-static void
-get_alarm_email_address (ECalBackendSync *backend, EDataCal *cal, gchar **address, GError **perror)
-{
-	d(printf("ecbe_get_alarm_email_address(%p, %p)\n", backend, cal));
-
-	/* We don't support email alarms.
-	 * This should not have been called.
-	 */
-	*address = NULL;
-
-	g_propagate_error (perror, EDC_ERROR (NotSupported));
-}
-
-static void
-get_ldap_attribute (ECalBackendSync *backend, EDataCal *cal, gchar **attribute, GError **perror)
-{
-	d(printf("ecbe_get_ldap_attribute(%p, %p)\n", backend, cal));
-
-	if (!attribute) {
-		g_propagate_error (perror, EDC_ERROR (InvalidObject));
-		return;
-	}
-
-	/* This is just a hack for SunONE */
-	*attribute = NULL;
-}
-
-static void
-get_static_capabilities (ECalBackendSync *backend, EDataCal *cal, gchar **capabilities, GError **perror)
-{
-	d(printf("ecbe_get_static_capabilities(%p, %p)\n", backend, cal));
-
-	*capabilities = g_strdup (
-		CAL_STATIC_CAPABILITY_NO_EMAIL_ALARMS ","
-		CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT ","
-		CAL_STATIC_CAPABILITY_NO_THISANDFUTURE ","
-		CAL_STATIC_CAPABILITY_NO_THISANDPRIOR ","
-		CAL_STATIC_CAPABILITY_REMOVE_ALARMS ","
-		CAL_STATIC_CAPABILITY_REFRESH_SUPPORTED);
-}
-
 static gboolean
 load_cache (ECalBackendExchange *cbex, E2kUri *e2kuri, GError **perror)
 {
@@ -365,20 +354,13 @@ save_cache (ECalBackendExchange *cbex)
 }
 
 static void
-open_calendar (ECalBackendSync *backend, EDataCal *cal, gboolean only_if_exists,
-	       const gchar *username, const gchar *password, GError **perror)
+open_calendar (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, gboolean only_if_exists, GError **perror)
 {
 	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
 	const gchar *uristr;
-	ExchangeHierarchy *hier;
 	ExchangeAccountResult acresult;
-	const gchar *prop = PR_ACCESS;
-	E2kHTTPStatus status;
 	gboolean load_result;
-	E2kResult *results;
 	E2kUri *euri = NULL;
-	gint nresults = 0;
-	guint access = 0;
 
 	d(printf("ecbe_open_calendar(%p, %p, %sonly if exists, user=%s, pass=%s)\n", backend, cal, only_if_exists?"":"not ", username?username:"(null)", password?password:"(null)"));
 
@@ -386,7 +368,7 @@ open_calendar (ECalBackendSync *backend, EDataCal *cal, gboolean only_if_exists,
 
 	g_mutex_lock (cbex->priv->open_lock);
 
-	if (cbex->priv->mode == CAL_MODE_LOCAL) {
+	if (!e_cal_backend_is_online (E_CAL_BACKEND (cbex))) {
 		ESource *source;
 		const gchar *display_contents = NULL;
 
@@ -399,6 +381,7 @@ open_calendar (ECalBackendSync *backend, EDataCal *cal, gboolean only_if_exists,
 		if (!display_contents || !g_str_equal (display_contents, "1")) {
 			g_mutex_unlock (cbex->priv->open_lock);
 			g_propagate_error (perror, EDC_ERROR (RepositoryOffline));
+			e_cal_backend_notify_opened (E_CAL_BACKEND (backend), EDC_ERROR (RepositoryOffline));
 			return;
 		}
 
@@ -413,6 +396,7 @@ open_calendar (ECalBackendSync *backend, EDataCal *cal, gboolean only_if_exists,
 
 		if (cbex->priv->is_loaded) {
 			g_mutex_unlock (cbex->priv->open_lock);
+			e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
 			return;
 		}
 
@@ -423,12 +407,14 @@ open_calendar (ECalBackendSync *backend, EDataCal *cal, gboolean only_if_exists,
 		if (load_result)
 			cbex->priv->is_loaded = TRUE;
 		g_mutex_unlock (cbex->priv->open_lock);
+		e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
 		return;
 	}
 
 	/* What else to check */
 	if (cbex->priv->is_loaded && cbex->account && exchange_account_get_context (cbex->account)) {
 		g_mutex_unlock (cbex->priv->open_lock);
+		e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
 		return;
 	}
 
@@ -441,12 +427,31 @@ open_calendar (ECalBackendSync *backend, EDataCal *cal, gboolean only_if_exists,
 	if (!cbex->account) {
 		g_mutex_unlock (cbex->priv->open_lock);
 		g_propagate_error (perror, EDC_ERROR (NoSuchCal));
+		e_cal_backend_notify_opened (E_CAL_BACKEND (backend), EDC_ERROR (NoSuchCal));
 		return;
 	}
 
 	exchange_account_set_online (cbex->account);
+	e_cal_backend_notify_auth_required (E_CAL_BACKEND (backend), TRUE, NULL);
+}
+
+static void
+authenticate_user (ECalBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **perror)
+{
+	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
+	const gchar *uristr;
+	ExchangeHierarchy *hier;
+	ExchangeAccountResult acresult;
+	const gchar *prop = PR_ACCESS;
+	E2kHTTPStatus status;
+	E2kResult *results;
+	E2kUri *euri = NULL;
+	gint nresults = 0;
+	guint access = 0;
+
+	uristr = e_cal_backend_get_uri (E_CAL_BACKEND (backend));
 
-	exchange_account_connect (cbex->account, password, &acresult);
+	exchange_account_connect (cbex->account, e_credentials_peek (credentials, E_CREDENTIALS_KEY_PASSWORD), &acresult);
 	if (acresult != EXCHANGE_ACCOUNT_CONNECT_SUCCESS) {
 		g_mutex_unlock (cbex->priv->open_lock);
 		g_propagate_error (perror, EDC_ERROR (AuthenticationFailed));
@@ -548,7 +553,7 @@ open_calendar (ECalBackendSync *backend, EDataCal *cal, gboolean only_if_exists,
 }
 
 static void
-remove_calendar (ECalBackendSync *backend, EDataCal *cal, GError **perror)
+remove_calendar (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, GError **perror)
 {
 	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
 	ExchangeAccountFolderResult result;
@@ -647,7 +652,7 @@ e_cal_backend_exchange_ensure_utc_zone (ECalBackend *cb, struct icaltimetype *it
 	/* RFC 2445 - CREATED/DTSTAMP/LAST-MODIFIED always in UTC */
 	if (!icaltime_is_null_time (*itt) && !icaltime_is_utc (*itt)) {
 		if (!itt->zone)
-			icaltime_set_timezone (itt, e_cal_backend_internal_get_default_timezone (cb));
+			icaltime_set_timezone (itt, icaltimezone_get_utc_timezone ());
 
 		icaltimezone_convert_time (itt, (icaltimezone*) icaltime_get_timezone (*itt), icaltimezone_get_utc_timezone ());
 		icaltime_set_timezone (itt, icaltimezone_get_utc_timezone ());
@@ -907,8 +912,8 @@ e_cal_backend_exchange_remove_object (ECalBackendExchange *cbex, const gchar *ui
 }
 
 static void
-discard_alarm (ECalBackendSync *backend, EDataCal *cal,
-	       const gchar *uid, const gchar *auid, GError **perror)
+discard_alarm (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
+	       const gchar *uid, const gchar *rid, const gchar *auid, GError **perror)
 {
 	/* To be called from the Calendar derived class */
 	g_propagate_error (perror, EDC_ERROR (NotSupported));
@@ -916,15 +921,15 @@ discard_alarm (ECalBackendSync *backend, EDataCal *cal,
 
 /*To be overriden by Calendar and Task classes*/
 static void
-create_object (ECalBackendSync *backend, EDataCal *cal,
-	       gchar **calobj, gchar **uid, GError **perror)
+create_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
+	       const gchar *calobj, gchar **uid, gchar **new_object, GError **perror)
 {
 	g_propagate_error (perror, EDC_ERROR (NotSupported));
 }
 
 /*To be overriden by Calendar and Task classes*/
 static void
-modify_object (ECalBackendSync *backend, EDataCal *cal,
+modify_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
 			const gchar * calobj, CalObjModType mod, gchar **old_object, gchar **new_object, GError **perror)
 {
 	g_propagate_error (perror, EDC_ERROR (NotSupported));
@@ -970,7 +975,7 @@ add_instances_to_vcal (gpointer value, gpointer user_data)
 }
 
 static void
-get_object (ECalBackendSync *backend, EDataCal *cal,
+get_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
 	    const gchar *uid, const gchar *rid, gchar **object, GError **error)
 {
 	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
@@ -1128,38 +1133,23 @@ e_cal_backend_exchange_extract_components (const gchar *calobj,
 }
 
 static void
-send_objects (ECalBackendSync *backend, EDataCal *cal,
+send_objects (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
 	      const gchar *calobj,
-	      GList **users, gchar **modified_calobj, GError **perror)
+	      GSList **users, gchar **modified_calobj, GError **perror)
 {
 	d(printf("ecbe_send_objects(%p, %p, %s)\n", backend, cal, calobj));
 
 	g_propagate_error (perror, EDC_ERROR (NotSupported));
 }
 
-static void
-get_default_object (ECalBackendSync *backend, EDataCal *cal, gchar **object, GError **perror)
-{
-	icalcomponent *comp;
-	gchar *ical_obj;
-
-	d(printf("ecbe_get_default_object(%p, %p)\n", backend, cal));
-
-	comp = e_cal_util_new_component (e_cal_backend_get_kind (E_CAL_BACKEND (backend)));
-	ical_obj = icalcomponent_as_ical_string_r (comp);
-	*object = ical_obj;
-
-	icalcomponent_free (comp);
-}
-
 typedef struct {
-	GList *obj_list;
+	GSList *obj_list;
 	gboolean search_needed;
 	const gchar *query;
 	ECalBackendSExp *obj_sexp;
 	ECalBackend *backend;
-	icaltimezone *default_zone;
 } MatchObjectData;
+
 static void
 match_recurrence_sexp (gpointer data, gpointer user_data)
 {
@@ -1179,7 +1169,7 @@ match_recurrence_sexp (gpointer data, gpointer user_data)
 	if ((!match_data->search_needed) ||
 	    (e_cal_backend_sexp_match_comp (match_data->obj_sexp, comp, match_data->backend))) {
 		comp_as_string = e_cal_component_get_as_string (comp);
-		match_data->obj_list = g_list_append (match_data->obj_list, comp_as_string);
+		match_data->obj_list = g_slist_append (match_data->obj_list, comp_as_string);
 		d(printf ("ecbe_match_recurrence_sexp: match found, adding \n%s\n", comp_as_string));
 	}
 	g_object_unref (comp);
@@ -1206,7 +1196,7 @@ match_object_sexp (gpointer key, gpointer value, gpointer data)
 
 		if ((!match_data->search_needed) ||
 		    (e_cal_backend_sexp_match_comp (match_data->obj_sexp, comp, match_data->backend))) {
-			match_data->obj_list = g_list_append (match_data->obj_list,
+			match_data->obj_list = g_slist_append (match_data->obj_list,
 						      e_cal_component_get_as_string (comp));
 		}
 		g_object_unref (comp);
@@ -1219,8 +1209,8 @@ match_object_sexp (gpointer key, gpointer value, gpointer data)
 }
 
 static void
-get_object_list (ECalBackendSync *backend, EDataCal *cal,
-		 const gchar *sexp, GList **objects, GError **perror)
+get_object_list (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
+		 const gchar *sexp, GSList **objects, GError **perror)
 {
 
 	ECalBackendExchange *cbex;
@@ -1234,7 +1224,6 @@ get_object_list (ECalBackendSync *backend, EDataCal *cal,
 	match_data.query = sexp;
 	match_data.obj_list = NULL;
 	match_data.backend = E_CAL_BACKEND (backend);
-	match_data.default_zone = cbex->priv->default_timezone;
 
 	if (!strcmp (sexp, "#t"))
 		match_data.search_needed = FALSE;
@@ -1254,17 +1243,6 @@ get_object_list (ECalBackendSync *backend, EDataCal *cal,
 	g_object_unref (match_data.obj_sexp);
 }
 
-icaltimezone *
-e_cal_backend_exchange_get_default_time_zone (ECalBackendSync *backend)
-{
-	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
-	ECalBackendExchangePrivate *priv;
-
-	priv = cbex->priv;
-
-	return priv->default_timezone;
-}
-
 void
 e_cal_backend_exchange_add_timezone (ECalBackendExchange *cbex,
 				     icalcomponent *vtzcomp, GError **perror)
@@ -1298,7 +1276,7 @@ e_cal_backend_exchange_add_timezone (ECalBackendExchange *cbex,
 }
 
 static void
-add_timezone (ECalBackendSync *backend, EDataCal *cal,
+add_timezone (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
 	      const gchar *tzobj, GError **perror)
 {
 	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
@@ -1331,68 +1309,24 @@ add_timezone (ECalBackendSync *backend, EDataCal *cal,
 }
 
 static void
-set_default_zone (ECalBackendSync *backend, EDataCal *cal, const gchar *tz, GError **perror)
-{
-	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
-	icalcomponent *icalcomp = icalparser_parse_string (tz);
-	icaltimezone *zone = NULL;
-
-	d(printf("ecbe_set_default_zone(%p, %p, %s)\n", backend, cal, tz));
-	/*
-	   We call this function before calling e_cal_open in client and
-	   hence we set the timezone directly.  In the implementation of
-	   e_cal_open, we set this timezone to every-objects that we create.
-	*/
-
-	if (icalcomp) {
-		const gchar *tzid;
-
-		zone = icaltimezone_new ();
-		icaltimezone_set_component (zone, icalcomp);
-
-		tzid = icaltimezone_get_tzid (zone);
-
-		if (tzid) {
-			icaltimezone *known_zone;
-
-			known_zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
-			if (!known_zone)
-				known_zone = g_hash_table_lookup (cbex->priv->timezones, tzid);
-
-			if (known_zone) {
-				icaltimezone_free (zone, 1);
-				zone = known_zone;
-			} else {
-				g_hash_table_insert (cbex->priv->timezones, g_strdup (tzid), zone);
-			}
-		} else {
-			icaltimezone_free (zone, 1);
-			zone = NULL;
-		}
-	}
-
-	cbex->priv->default_timezone = zone;
-}
-
-static void
-start_query (ECalBackend *backend, EDataCalView *view)
+start_view (ECalBackend *backend, EDataCalView *view)
 {
 	const gchar *sexp = NULL;
-	GList *m, *objects = NULL;
+	GSList *objects = NULL;
 	GError *error = NULL;
 
-	d(printf("ecbe_start_query(%p, %p)\n", backend, view));
+	d(printf("ecbe_start_view(%p, %p)\n", backend, view));
 
 	sexp = e_data_cal_view_get_text (view);
 	if (!sexp) {
 		error = EDC_ERROR (InvalidQuery);
-		e_data_cal_view_notify_done (view, error);
+		e_data_cal_view_notify_complete (view, error);
 		g_error_free (error);
 		return;
 	}
-	get_object_list (E_CAL_BACKEND_SYNC (backend), NULL, sexp, &objects, &error);
+	get_object_list (E_CAL_BACKEND_SYNC (backend), NULL, NULL, sexp, &objects, &error);
 	if (error) {
-		e_data_cal_view_notify_done (view, error);
+		e_data_cal_view_notify_complete (view, error);
 		g_error_free (error);
 		return;
 	}
@@ -1400,51 +1334,15 @@ start_query (ECalBackend *backend, EDataCalView *view)
 	if (objects) {
 		e_data_cal_view_notify_objects_added (view, objects);
 
-		for (m = objects; m; m = m->next)
-			g_free (m->data);
-		g_list_free (objects);
+		g_slist_foreach (objects, (GFunc) g_free, NULL);
+		g_slist_free (objects);
 	}
 
-	e_data_cal_view_notify_done (view, NULL /* Success */);
-}
-
-gboolean
-e_cal_backend_exchange_is_online (ECalBackendExchange *cbex)
-{
-	if (cbex->priv->mode == CAL_MODE_LOCAL)
-		return FALSE;
-	else
-		return TRUE;
-}
-
-static gboolean
-is_loaded (ECalBackend *backend)
-{
-	ECalBackendExchange *cbex;
-	ECalBackendExchangePrivate *priv;
-
-	cbex = E_CAL_BACKEND_EXCHANGE (backend);
-	priv = cbex->priv;
-
-	return priv->is_loaded;
-}
-
-static CalMode
-get_mode (ECalBackend *backend)
-{
-	ECalBackendExchange *cbex;
-	ECalBackendExchangePrivate *priv;
-
-	cbex = E_CAL_BACKEND_EXCHANGE (backend);
-	priv = cbex->priv;
-
-	d(printf("ecbe_get_mode(%p)\n", backend));
-
-	return priv->mode;
+	e_data_cal_view_notify_complete (view, NULL /* Success */);
 }
 
 static void
-set_mode (ECalBackend *backend, CalMode mode)
+set_online (ECalBackend *backend, gboolean is_online)
 {
 	ECalBackendExchange *cbex;
 	ECalBackendExchangePrivate *priv;
@@ -1453,53 +1351,28 @@ set_mode (ECalBackend *backend, CalMode mode)
 	cbex = E_CAL_BACKEND_EXCHANGE (backend);
 	priv = cbex->priv;
 
-	d(printf("ecbe_set_mode(%p) : mode : %d\n", backend, mode));
+	d(printf("ecbe_set_online(%p) : online : %d\n", backend, is_online ? 1 :0));
 
-	if (priv->mode == mode) {
-		e_cal_backend_notify_mode (
-			backend, ModeSet,
-			cal_mode_to_corba (mode));
-	}
+	re_open = is_online && !e_cal_backend_is_online (backend);
+	e_cal_backend_notify_online (backend, is_online);
 
 	g_mutex_lock (priv->set_lock);
-	if ((priv->mode == CAL_MODE_LOCAL) && (mode == CAL_MODE_REMOTE))
-		re_open = TRUE;
-
-	switch (mode) {
 
-	case CAL_MODE_REMOTE:
-			e_cal_backend_notify_mode (backend,
-				ModeSet,
-				Remote);
-			/* FIXME : Test if available for read already */
-			priv->read_only = FALSE;
-			priv->mode = CAL_MODE_REMOTE;
+	if (is_online) {
+		priv->read_only = FALSE;
 
-			if (is_loaded (backend) && re_open)
-				e_cal_backend_notify_auth_required (backend);
-			break;
-
-	case CAL_MODE_LOCAL:
-			d(printf ("set mode to offline\n"));
-					priv->mode = CAL_MODE_LOCAL;
-			priv->read_only = TRUE;
-			e_cal_backend_notify_mode (backend,
-				ModeSet,
-				Local);
-			break;
-
-	default :
-		e_cal_backend_notify_mode (
-			backend, ModeNotSupported,
-			cal_mode_to_corba (mode));
+		if (e_cal_backend_is_opened (backend) && re_open)
+			e_cal_backend_notify_auth_required (backend, TRUE, NULL);
+	} else {
+		priv->read_only = TRUE;
 	}
 	g_mutex_unlock (priv->set_lock);
 }
 
 static void
-get_freebusy (ECalBackendSync *backend, EDataCal *cal,
-	      GList *users, time_t start, time_t end,
-	      GList **freebusy, GError **perror)
+get_freebusy (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable,
+	      const GSList *users, time_t start, time_t end, GSList **freebusyobjs,
+	      GError **perror)
 {
 	d(printf("ecbe_get_free_busy(%p, %p)\n", backend, cal));
 
@@ -1551,7 +1424,7 @@ e_cal_backend_exchange_get_from (ECalBackendSync *backend, ECalComponent *comp,
 		*email = g_strdup (org.value);
 	} else {
 		get_cal_owner (backend, name);
-		get_cal_address (backend, NULL, email, NULL);
+		get_backend_property (backend, NULL, NULL, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS, email, NULL);
 	}
 }
 
@@ -1644,92 +1517,6 @@ e_cal_backend_exchange_get_owner_name (ECalBackendSync *backend)
 	return g_strdup (hier->owner_name);
 }
 
-struct ChangeData {
-	EXmlHash *ehash;
-	GList *adds;
-	GList *modifies;
-};
-
-static void
-check_change_type (gpointer key, gpointer value, gpointer data)
-{
-	ECalBackendExchangeComponent *ecomp = value;
-	struct ChangeData *change_data = data;
-	gchar *calobj;
-	ECalComponent *comp = NULL;
-	gchar *uid = key;
-	GList *l = NULL;
-	icalcomponent *icomp = NULL;
-
-	/*
-	   In case of detached instances with no master object,
-	   ecomp->icomp will be NULL and hence should be skipped
-	   from matching.
-	*/
-	if (!ecomp)
-		return;
-	l = ecomp->instances;
-	for (icomp = ecomp->icomp; l; icomp = l->data, l = l->next) {
-		if (!icomp)
-			continue;
-
-		comp = e_cal_component_new ();
-		/*
-		  e_cal_component_set_icalcomponent does a icalcomponent_free of
-		  previous icalcomponent before setting the new one.
-		 */
-		e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icomp));
-
-		calobj = e_cal_component_get_as_string (comp);
-		switch (e_xmlhash_compare (change_data->ehash, uid, calobj)) {
-		case E_XMLHASH_STATUS_SAME:
-			break;
-		case E_XMLHASH_STATUS_NOT_FOUND:
-			change_data->adds = g_list_prepend (change_data->adds, g_strdup (calobj));
-			e_xmlhash_add (change_data->ehash, uid, calobj);
-			break;
-		case E_XMLHASH_STATUS_DIFFERENT:
-			change_data->modifies = g_list_prepend (change_data->modifies, g_strdup (calobj));
-			e_xmlhash_add (change_data->ehash, uid, calobj);
-		}
-
-		g_free (calobj);
-		g_object_unref (comp);
-	}
-}
-
-struct cbe_data {
-	ECalBackendExchange *cbex;
-	icalcomponent_kind kind;
-	GList *deletes;
-	EXmlHash *ehash;
-};
-
-static gboolean
-e_cal_backend_exchange_compute_changes_foreach_key (const gchar *key, const gchar *value, gpointer data)
-{
-	struct cbe_data *cbedata = data;
-	ECalBackendExchangeComponent *ecomp;
-	ecomp = g_hash_table_lookup (cbedata->cbex->priv->objects, key);
-
-	if (ecomp) {
-		ECalComponent *comp;
-		comp = e_cal_component_new ();
-		if (ecomp->icomp)
-			e_cal_component_set_icalcomponent (comp,
-							   icalcomponent_new_clone (ecomp->icomp));
-		if (cbedata->kind == ICAL_VTODO_COMPONENT)
-			e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_TODO);
-		else
-			e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT);
-		e_cal_component_set_uid (comp, key);
-		cbedata->deletes = g_list_prepend (cbedata->deletes, e_cal_component_get_as_string (comp));
-		g_object_unref (comp);
-		return TRUE;
-	}
-	return FALSE;
-}
-
 /* Attachments */
 static gchar *
 save_attach_file (const gchar *dest_file, gchar *file_contents, gint len)
@@ -2151,72 +1938,6 @@ build_msg ( ECalBackendExchange *cbex, ECalComponent *comp, const gchar *subject
 	return buffer;
 }
 
-static void
-get_changes (ECalBackendSync *backend, EDataCal *cal,
-	     const gchar *change_id,
-	     GList **adds, GList **modifies, GList **deletes, GError **error)
-{
-	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
-	gchar *path, *filename;
-	EXmlHash *ehash;
-	struct ChangeData data;
-	struct cbe_data cbedata;
-
-	d(printf("ecbe_get_changes(%p, %p, %s)\n", backend, cal, change_id));
-
-	e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_EXCHANGE (cbex), InvalidArg);
-	e_return_data_cal_error_if_fail (change_id != NULL, ObjectNotFound);
-
-	/* open the changes file */
-	filename = g_strdup_printf ("%s.changes", change_id);
-	path = e_folder_exchange_get_storage_file (cbex->folder, filename);
-	ehash = e_xmlhash_new (path);
-	g_free (path);
-	g_free (filename);
-
-	/*calculate add/mod*/
-	data.ehash = ehash;
-	data.adds = NULL;
-	data.modifies = NULL;
-	g_hash_table_foreach (cbex->priv->objects, check_change_type, &data);
-
-	*adds = data.adds;
-	*modifies = data.modifies;
-	ehash = data.ehash;
-
-	/*deletes*/
-	cbedata.cbex = cbex;
-	cbedata.kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbex));
-	cbedata.deletes = NULL;
-	cbedata.ehash = ehash;
-	e_xmlhash_foreach_key_remove (ehash, (EXmlHashRemoveFunc) e_cal_backend_exchange_compute_changes_foreach_key, &cbedata);
-
-	*deletes = cbedata.deletes;
-
-	e_xmlhash_write (ehash);
-	e_xmlhash_destroy (ehash);
-}
-
-static icaltimezone *
-internal_get_default_timezone (ECalBackend *backend)
-{
-	ECalBackendExchange *cbex = E_CAL_BACKEND_EXCHANGE (backend);
-
-	/* FIXME : This should never happen. Sometimes gets triggered while moving
-	between online and offline. */
-	if (!cbex->account)
-		return NULL;
-
-	if (!cbex->priv->default_timezone &&
-	    cbex->account->default_timezone) {
-		cbex->priv->default_timezone =
-			g_hash_table_lookup (cbex->priv->timezones,
-					     cbex->account->default_timezone);
-	}
-
-	return cbex->priv->default_timezone;
-}
-
 static icaltimezone *
 internal_get_timezone (ECalBackend *backend, const gchar *tzid)
 {
@@ -2348,30 +2069,21 @@ class_init (ECalBackendExchangeClass *klass)
 
 	object_class = (GObjectClass *) klass;
 
-	sync_class->is_read_only_sync = is_read_only;
-	sync_class->get_cal_address_sync = get_cal_address;
-	sync_class->get_alarm_email_address_sync = get_alarm_email_address;
-	sync_class->get_ldap_attribute_sync = get_ldap_attribute;
-	sync_class->get_static_capabilities_sync = get_static_capabilities;
+	sync_class->get_backend_property_sync = get_backend_property;
 	sync_class->open_sync = open_calendar;
+	sync_class->authenticate_user_sync = authenticate_user;
 	sync_class->remove_sync = remove_calendar;
 	sync_class->discard_alarm_sync = discard_alarm;
 	sync_class->send_objects_sync = send_objects;
-	sync_class->get_default_object_sync = get_default_object;
 	sync_class->get_object_sync = get_object;
 	sync_class->get_object_list_sync = get_object_list;
 	sync_class->add_timezone_sync = add_timezone;
-	sync_class->set_default_zone_sync = set_default_zone;
-	sync_class->get_freebusy_sync = get_freebusy;
-	sync_class->get_changes_sync = get_changes;
+	sync_class->get_free_busy_sync = get_freebusy;
 	sync_class->create_object_sync = create_object;
 	sync_class->modify_object_sync = modify_object;
 
-	backend_class->start_query = start_query;
-	backend_class->get_mode = get_mode;
-	backend_class->set_mode = set_mode;
-	backend_class->is_loaded = is_loaded;
-	backend_class->internal_get_default_timezone = internal_get_default_timezone;
+	backend_class->start_view = start_view;
+	backend_class->set_online = set_online;
 	backend_class->internal_get_timezone = internal_get_timezone;
 
 	object_class->dispose = dispose;
diff --git a/calendar/e-cal-backend-exchange.h b/calendar/e-cal-backend-exchange.h
index df394c9..74e1e54 100644
--- a/calendar/e-cal-backend-exchange.h
+++ b/calendar/e-cal-backend-exchange.h
@@ -79,8 +79,6 @@ void  e_cal_backend_exchange_add_timezone     (ECalBackendExchange *cbex,
 						   icalcomponent       *vtzcomp,
 						   GError **perror);
 
-icaltimezone * e_cal_backend_exchange_get_default_time_zone (ECalBackendSync *backend);
-
 gchar *	  e_cal_backend_exchange_lf_to_crlf	(const gchar *in);
 gchar *	  e_cal_backend_exchange_make_timestamp_rfc822	(time_t when);
 
@@ -105,7 +103,6 @@ gchar * e_cal_backend_exchange_get_from_string (ECalBackendSync *backend, ECalCo
 void e_cal_backend_exchange_get_sender (ECalBackendSync *backend, ECalComponent *comp,
 					gchar **from_name, gchar **from_addr);
 gchar * e_cal_backend_exchange_get_sender_string (ECalBackendSync *backend, ECalComponent *comp);
-gboolean e_cal_backend_exchange_is_online (ECalBackendExchange *cbex);
 GSList * get_attachment (ECalBackendExchange *cbex, const gchar *uid, const gchar *body, gint len);
 GSList *receive_attachments (ECalBackendExchange *cbex, ECalComponent *comp);
 void process_delegated_cal_object (icalcomponent *icalcomp, const gchar *delegator_name,
diff --git a/configure.ac b/configure.ac
index 6f5678b..21a3f3a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,8 +38,6 @@ AS_COMPILER_FLAGS(WARNING_FLAGS,
 	-DPANGO_DISABLE_DEPRECATED
 	-DGDK_DISABLE_DEPRECATED
 	-DGDK_PIXBUF_DISABLE_DEPRECATED
-	-DE_BOOK_DISABLE_DEPRECATED
-	-DE_CAL_DISABLE_DEPRECATED
 	-DG_DISABLE_SINGLE_INCLUDES
 	-DGTK_DISABLE_SINGLE_INCLUDES
 	-DGSEAL_ENABLE
@@ -55,6 +53,10 @@ AS_COMPILER_FLAGS(WARNING_FLAGS,
 	-Wredundant-decls -Wundef -Wwrite-strings")
 AC_SUBST(WARNING_FLAGS)
 
+dnl Disable these later
+dnl	-DE_BOOK_DISABLE_DEPRECATED
+dnl	-DE_CAL_DISABLE_DEPRECATED
+dnl
 dnl Other useful compiler warnings for test builds only.
 dnl These may produce warnings we have no control over,
 dnl or false positives we don't always want to see.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]