[evolution-mapi] Adapt to Camel API changes.



commit 4c69558f4af8975a78ae12e45b7b41bd0fc6b2a6
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sat Sep 18 22:07:44 2010 -0400

    Adapt to Camel API changes.

 src/camel/camel-mapi-folder.c                  | 1049 ++++++------
 src/camel/camel-mapi-folder.h                  |    4 +-
 src/camel/camel-mapi-notifications.c           |    5 +-
 src/camel/camel-mapi-store.c                   | 2168 ++++++++++++------------
 src/camel/camel-mapi-transport.c               |   12 +-
 src/camel/camel-mapi-utils.c                   |   30 +-
 src/camel/camel-mapi-utils.h                   |    2 +-
 src/libexchangemapi/exchange-mapi-connection.c |    3 +-
 src/libexchangemapi/exchange-mapi-mail-utils.c |    6 +-
 9 files changed, 1678 insertions(+), 1601 deletions(-)
---
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index 402959a..10803b4 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -69,7 +69,13 @@ typedef struct {
 /*For collecting summary info from server*/
 
 static void mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **changeinfo,
-			       GError **error, gboolean uid_flag);
+			       GCancellable *cancellable, GError **error, gboolean uid_flag);
+
+static gboolean		mapi_folder_synchronize_sync
+						(CamelFolder *folder,
+						 gboolean expunge,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_DEFINE_TYPE (CamelMapiFolder, camel_mapi_folder, CAMEL_TYPE_OFFLINE_FOLDER)
 
@@ -140,15 +146,6 @@ update_store_summary (CamelFolder *folder, GError **error)
 }
 
 static gboolean
-mapi_refresh_info (CamelFolder *folder, GError **error)
-{
-	if (!mapi_refresh_folder (folder, error))
-		return FALSE;
-
-	return update_store_summary (folder, error);
-}
-
-static gboolean
 fetch_items_summary_cb (FetchItemsCallbackData *item_data, gpointer data)
 {
 	fetch_items_data *fi_data = (fetch_items_data *)data;
@@ -231,7 +228,7 @@ fetch_items_summary_cb (FetchItemsCallbackData *item_data, gpointer data)
 	/*Write summary to db in batches of SUMMARY_FETCH_BATCH_COUNT items.*/
 	if ((item_data->index % SUMMARY_FETCH_BATCH_COUNT == 0) ||
 	     item_data->index == item_data->total-1) {
-		mapi_update_cache (fi_data->folder, *slist, &fi_data->changes, NULL, false);
+		mapi_update_cache (fi_data->folder, *slist, &fi_data->changes, NULL, NULL, false);
 		g_slist_foreach (*slist, (GFunc)mail_item_free, NULL);
 		g_slist_free (*slist);
 		*slist = NULL;
@@ -322,7 +319,7 @@ mapi_set_message_references (CamelMapiMessageInfo *mapi_mi, const gchar *referen
 
 static void
 mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **changeinfo,
-		   GError **error, gboolean uid_flag)
+		   GCancellable *cancellable, GError **error, gboolean uid_flag)
 {
 	CamelMapiMessageInfo *mi = NULL;
 	CamelMessageInfo *pmi = NULL;
@@ -352,8 +349,9 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
 		return;
 	}
 
-	camel_operation_start (
-		NULL, _("Updating local summary cache for new messages in %s"),
+	camel_operation_push_message (
+		cancellable,
+		_("Updating local summary cache for new messages in %s"),
 		camel_folder_get_name (folder));
 
 	for (; item_list != NULL; item_list = g_slist_next (item_list) ) {
@@ -371,7 +369,7 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
 			item = temp_item;
 		}
 
-		camel_operation_progress (NULL, (100*i)/total_items);
+		camel_operation_progress (cancellable, (100*i)/total_items);
 
 		/************************ First populate summary *************************/
 		mi = NULL;
@@ -515,7 +513,7 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
 		g_free (msg_uid);
 		i++;
 	}
-	camel_operation_end (NULL);
+	camel_operation_pop_message (cancellable);
 
 	g_string_free (str, TRUE);
 }
@@ -582,13 +580,13 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
 	mapi_folder = CAMEL_MAPI_FOLDER (m->folder);
 	mapi_store = CAMEL_MAPI_STORE (parent_store);
 
-	if (((CamelOfflineStore *) mapi_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL ||
+	if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)) ||
 			((CamelService *)mapi_store)->status == CAMEL_SERVICE_DISCONNECTED) {
 
 		return;
 	}
 
-	camel_operation_start (
+	camel_operation_push_message (
 		NULL, _("Retrieving message IDs from server for %s"),
 		camel_folder_get_name (m->folder));
 
@@ -605,7 +603,7 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
 					       deleted_items_sync_cb, server_messages,
 					       options | MAPI_OPTIONS_DONT_OPEN_MESSAGE, NULL);
 
-	camel_operation_end (NULL);
+	camel_operation_pop_message (NULL);
 
 	camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
@@ -618,7 +616,7 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
 	changes = camel_folder_change_info_new ();
 
 	count = camel_folder_summary_count (m->folder->summary);
-	camel_operation_start (
+	camel_operation_push_message (
 		NULL, _("Removing deleted messages from cache in %s"),
 		camel_folder_get_name (m->folder));
 
@@ -672,7 +670,7 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
 		}
 	}
 
-	camel_operation_end (NULL);
+	camel_operation_pop_message (NULL);
 
 	if (camel_folder_change_info_changed (changes)) {
 		if (flags_changed)
@@ -704,7 +702,8 @@ mapi_sync_deleted_free (CamelSession *session, CamelSessionThreadMsg *msg)
 			mapi_summary->sync_time_stamp = NULL;
 			camel_service_unlock (CAMEL_SERVICE (parent_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-			if (!mapi_refresh_folder (m->folder, &local_error)) {
+			/* FIXME Need to pass a GCancellable here. */
+			if (!mapi_refresh_folder (m->folder, NULL, &local_error)) {
 				g_warning ("%s: %s", G_STRFUNC, local_error->message);
 				g_error_free (local_error);
 			}
@@ -720,200 +719,6 @@ static CamelSessionThreadOps deleted_items_sync_ops = {
 };
 
 static gboolean
-mapi_sync (CamelFolder *folder, gboolean expunge, GError **error)
-{
-	CamelMapiStore *mapi_store;
-	CamelMapiFolder *mapi_folder;
-	CamelMessageInfo *info = NULL;
-	CamelMapiMessageInfo *mapi_info = NULL;
-	CamelStore *parent_store;
-
-	GSList *read_items = NULL, *unread_items = NULL, *to_free = NULL, *junk_items = NULL, *deleted_items = NULL, *l;
-	flags_diff_t diff, unset_flags;
-	const gchar *folder_id;
-	const gchar *full_name;
-	mapi_id_t fid, deleted_items_fid;
-	gint count, i;
-	guint32 options =0;
-	gboolean is_junk_folder;
-	gboolean success;
-
-	full_name = camel_folder_get_full_name (folder);
-	parent_store = camel_folder_get_parent_store (folder);
-
-	mapi_folder = CAMEL_MAPI_FOLDER (folder);
-	mapi_store = CAMEL_MAPI_STORE (parent_store);
-
-	if (((CamelOfflineStore *) mapi_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL ||
-			((CamelService *)mapi_store)->status == CAMEL_SERVICE_DISCONNECTED) {
-		return update_store_summary (folder, error);
-	}
-
-	if (((CamelMapiFolder *)folder)->type & CAMEL_MAPI_FOLDER_PUBLIC)
-		options |= MAPI_OPTIONS_USE_PFSTORE;
-
-	folder_id =  camel_mapi_store_folder_id_lookup (mapi_store, full_name);
-	exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
-
-	camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	if (!camel_mapi_store_connected (mapi_store, NULL)) {
-		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-		return TRUE;
-	}
-	camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-
-	is_junk_folder = (mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_JUNK;
-
-	camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-	camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
-
-	count = camel_folder_summary_count (folder->summary);
-	for (i=0; i < count; i++) {
-		info = camel_folder_summary_index (folder->summary, i);
-		mapi_info = (CamelMapiMessageInfo *) info;
-
-		if (mapi_info && (mapi_info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
-			const gchar *uid;
-			mapi_id_t *mid = g_new0 (mapi_id_t, 1); /* FIXME : */
-			mapi_id_t temp_fid;
-			guint32 flags;
-			gboolean used = FALSE;
-
-			uid = camel_message_info_uid (info);
-			flags= camel_message_info_flags (info);
-
-			/* Why are we getting so much noise here :-/ */
-			if (!exchange_mapi_util_mapi_ids_from_uid (uid, &temp_fid, mid)) {
-				camel_message_info_free (info);
-				g_free (mid);
-				continue;
-			}
-
-			mapi_utils_do_flags_diff (&diff, mapi_info->server_flags, mapi_info->info.flags);
-			mapi_utils_do_flags_diff (&unset_flags, flags, mapi_info->server_flags);
-
-			diff.changed &= folder->permanent_flags;
-			if (!diff.changed) {
-				camel_message_info_free (info);
-				g_free (mid);
-				continue;
-			}
-			if (diff.bits & CAMEL_MESSAGE_DELETED) {
-				deleted_items = g_slist_prepend (deleted_items, mid);
-				used = TRUE;
-			} else if (!is_junk_folder && (diff.bits & CAMEL_MESSAGE_JUNK) != 0) {
-				junk_items = g_slist_prepend (junk_items, mid);
-				used = TRUE;
-			}
-
-			if (diff.bits & CAMEL_MESSAGE_SEEN) {
-				read_items = g_slist_prepend (read_items, mid);
-				used = TRUE;
-			} else if (unset_flags.bits & CAMEL_MESSAGE_SEEN) {
-				unread_items = g_slist_prepend (unread_items, mid);
-				used = TRUE;
-			}
-
-			if (used)
-				to_free = g_slist_prepend (to_free, mid);
-			else
-				g_free (mid);
-
-			mapi_info->server_flags = mapi_info->info.flags;
-		}
-
-		if (info)
-			camel_message_info_free (info);
-	}
-
-	camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
-	/*
-	   Sync up the READ changes before deleting the message.
-	   Note that if a message is marked as unread and then deleted,
-	   Evo doesnt not take care of it, as I find that scenario to be impractical.
-	*/
-
-	if (read_items) {
-		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-		exchange_mapi_connection_set_flags (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, read_items, 0, NULL);
-		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	}
-
-	if (unread_items) {
-		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-		exchange_mapi_connection_set_flags (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, unread_items, CLEAR_READ_FLAG, NULL);
-		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	}
-
-	/* Remove messages from server*/
-	if (deleted_items) {
-		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-		if ((mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
-			exchange_mapi_connection_remove_items (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, deleted_items, NULL);
-		} else {
-			GError *err = NULL;
-
-			exchange_mapi_util_mapi_id_from_string (camel_mapi_store_system_folder_fid (mapi_store, olFolderDeletedItems), &deleted_items_fid);
-			exchange_mapi_connection_move_items (camel_mapi_store_get_exchange_connection (mapi_store), fid, options, deleted_items_fid, 0, deleted_items, &err);
-
-			if (err) {
-				g_warning ("%s: Failed to move deleted items: %s", G_STRFUNC, err->message);
-				g_error_free (err);
-			}
-		}
-
-		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	}
-
-	if (junk_items) {
-		mapi_id_t junk_fid = 0;
-		GError *err = NULL;
-
-		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-		exchange_mapi_util_mapi_id_from_string (camel_mapi_store_system_folder_fid (mapi_store, olFolderJunk), &junk_fid);
-		exchange_mapi_connection_move_items (camel_mapi_store_get_exchange_connection (mapi_store), fid, options, junk_fid, 0, junk_items, &err);
-		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-
-		/* in junk_items are only emails which are not deleted */
-		deleted_items = g_slist_concat (deleted_items, g_slist_copy (junk_items));
-
-		if (err) {
-			g_warning ("%s: Failed to move junk items: %s", G_STRFUNC, err->message);
-			g_error_free (err);
-		}
-	}
-
-	/*Remove messages from local cache*/
-	for (l = deleted_items; l; l = l->next) {
-		gchar * deleted_msg_uid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X%016" G_GINT64_MODIFIER "X", fid, *(mapi_id_t *)l->data);
-
-		camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-		camel_folder_summary_remove_uid (folder->summary, deleted_msg_uid);
-		camel_data_cache_remove(mapi_folder->cache, "cache", deleted_msg_uid, NULL);
-		camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-	}
-
-	g_slist_free (read_items);
-	g_slist_free (unread_items);
-	g_slist_free (deleted_items);
-	g_slist_free (junk_items);
-
-	g_slist_foreach (to_free, (GFunc) g_free, NULL);
-	g_slist_free (to_free);
-
-	if (expunge) {
-		/* TODO */
-	}
-
-	camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	success = update_store_summary (folder, error);
-	camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-
-	return success;
-}
-
-static gboolean
 mapi_camel_get_summary_list (ExchangeMapiConnection *conn, mapi_id_t fid, TALLOC_CTX *mem_ctx, struct SPropTagArray *props, gpointer data)
 {
 	static const uint32_t summary_prop_list[] = {
@@ -942,14 +747,14 @@ mapi_camel_get_summary_list (ExchangeMapiConnection *conn, mapi_id_t fid, TALLOC
 
 gboolean
 camel_mapi_folder_fetch_summary (CamelStore *store, CamelFolder *folder, const mapi_id_t fid, struct mapi_SRestriction *res,
-				 struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GError **mapi_error)
+				 struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GCancellable *cancellable, GError **mapi_error)
 {
 	gboolean status;
 	CamelMapiStore *mapi_store = (CamelMapiStore *) store;
 
 	/*TODO : Check for online state*/
 
-	camel_operation_start (NULL, _("Fetching summary information for new messages in %s"), camel_folder_get_name (folder));
+	camel_operation_push_message (cancellable, _("Fetching summary information for new messages in %s"), camel_folder_get_name (folder));
 
 	camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
@@ -960,13 +765,13 @@ camel_mapi_folder_fetch_summary (CamelStore *store, CamelFolder *folder, const m
 
 	camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	camel_operation_end (NULL);
+	camel_operation_pop_message (cancellable);
 
 	return status;
 }
 
 gboolean
-mapi_refresh_folder(CamelFolder *folder, GError **error)
+mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **error)
 {
 
 	CamelMapiStore *mapi_store;
@@ -998,12 +803,12 @@ mapi_refresh_folder(CamelFolder *folder, GError **error)
 	is_proxy = parent_store->flags & CAMEL_STORE_PROXY;
 	session = CAMEL_SERVICE (parent_store)->session;
 
-	if (((CamelOfflineStore *) mapi_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+	if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)))
 		goto end1;
 
 	/* Sync-up the (un)read changes before getting updates,
 	so that the getFolderList will reflect the most recent changes too */
-	mapi_sync (folder, FALSE, NULL);
+	mapi_folder_synchronize_sync (folder, FALSE, cancellable, NULL);
 
 	//creating a copy
 	folder_id = camel_mapi_store_folder_id_lookup (mapi_store, full_name);
@@ -1083,7 +888,7 @@ mapi_refresh_folder(CamelFolder *folder, GError **error)
 			options |= MAPI_OPTIONS_USE_PFSTORE;
 
 		status = camel_mapi_folder_fetch_summary ((CamelStore *)mapi_store, folder, temp_folder_id, res, sort,
-							  fetch_data, options, &mapi_error);
+							  fetch_data, options, cancellable, &mapi_error);
 
 		if (!status) {
 			if (mapi_error) {
@@ -1138,8 +943,334 @@ end1:
 	return success;
 }
 
+static void
+mapi_folder_search_free (CamelFolder *folder, GPtrArray *uids)
+{
+	CamelMapiFolder *mapi_folder = CAMEL_MAPI_FOLDER(folder);
+
+	g_return_if_fail (mapi_folder->search);
+
+	CAMEL_MAPI_FOLDER_LOCK(mapi_folder, search_lock);
+
+	camel_folder_search_free_result (mapi_folder->search, uids);
+
+	CAMEL_MAPI_FOLDER_UNLOCK(mapi_folder, search_lock);
+
+}
+
+#if 0
+static CamelMessageInfo*
+mapi_get_message_info(CamelFolder *folder, const gchar *uid)
+{
+	CamelMessageInfo	*msg_info = NULL;
+	CamelMessageInfoBase	*mi = (CamelMessageInfoBase *)msg;
+	gint			status = 0;
+	oc_message_headers_t	headers;
+
+	if (folder->summary) {
+		msg_info = camel_folder_summary_uid(folder->summary, uid);
+	}
+	if (msg_info != NULL) {
+		mi = (CamelMessageInfoBase *)msg_info;
+		return (msg_info);
+	}
+	/* Go online and fetch message summary. */
+
+	msg_info = camel_message_info_new(folder->summary);
+	mi = (CamelMessageInfoBase *)msg_info;
+
+	if (headers.subject) mi->subject = (gchar *)camel_pstring_strdup(headers.subject);
+	if (headers.from) mi->from = (gchar *)camel_pstring_strdup(headers.from);
+	if (headers.to) mi->to = (gchar *)camel_pstring_strdup(headers.to);
+	if (headers.cc) mi->cc = (gchar *)camel_pstring_strdup(headers.cc);
+	mi->flags = headers.flags;
+
+	mi->user_flags = NULL;
+	mi->user_tags = NULL;
+	mi->date_received = 0;
+	mi->date_sent = headers.send;
+	mi->content = NULL;
+	mi->summary = folder->summary;
+	if (uid) mi->uid = g_strdup(uid);
+	oc_message_headers_release(&headers);
+	return (msg);
+}
+#endif
+
+static void
+mapi_folder_rename (CamelFolder *folder, const gchar *new)
+{
+	((CamelFolderClass *)camel_mapi_folder_parent_class)->rename(folder, new);
+}
+
+static gint
+mapi_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
+{
+	g_return_val_if_fail (uid1 != NULL, 0);
+	g_return_val_if_fail (uid2 != NULL, 0);
+
+	return strcmp (uid1, uid2);
+}
+
+static gboolean
+mapi_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set)
+{
+	CamelMessageInfo *info;
+	gint res;
+
+	g_return_val_if_fail (folder->summary != NULL, FALSE);
+
+	info = camel_folder_summary_uid (folder->summary, uid);
+	if (info == NULL)
+		return FALSE;
+
+	res = camel_message_info_set_flags (info, flags, set);
+
+	camel_message_info_free (info);
+	return res;
+}
+
+static void
+mapi_folder_dispose (GObject *object)
+{
+	CamelMapiFolder *mapi_folder = CAMEL_MAPI_FOLDER (object);
+
+	if (mapi_folder->cache != NULL) {
+		g_object_unref (mapi_folder->cache);
+		mapi_folder->cache = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (camel_mapi_folder_parent_class)->dispose (object);
+}
+
+static void
+mapi_folder_constructed (GObject *object)
+{
+	CamelFolder *folder;
+	CamelStore *parent_store;
+	CamelURL *url;
+	const gchar *full_name;
+	gchar *description;
+
+	folder = CAMEL_FOLDER (object);
+	full_name = camel_folder_get_full_name (folder);
+	parent_store = camel_folder_get_parent_store (folder);
+	url = CAMEL_SERVICE (parent_store)->url;
+
+	description = g_strdup_printf (
+		"%s %s:%s", url->user, url->host, full_name);
+	camel_folder_set_description (folder, description);
+	g_free (description);
+}
+
+static gboolean
+mapi_folder_append_message_sync (CamelFolder *folder,
+                                 CamelMimeMessage *message,
+                                 CamelMessageInfo *info,
+                                 gchar **appended_uid,
+                                 GCancellable *cancellable,
+                                 GError **error)
+{
+	CamelMapiStore *mapi_store;
+	CamelOfflineStore *offline;
+	CamelAddress *from = NULL;
+	CamelStoreInfo *si;
+	CamelStore *parent_store;
+	MailItem *item = NULL;
+	mapi_id_t fid = 0, mid = 0;
+	const gchar *folder_id;
+	const gchar *full_name;
+	guint32 folder_flags = 0;
+	GError *mapi_error = NULL;
+
+	full_name = camel_folder_get_full_name (folder);
+	parent_store = camel_folder_get_parent_store (folder);
+
+	mapi_store = CAMEL_MAPI_STORE (parent_store);
+	offline = CAMEL_OFFLINE_STORE (parent_store);
+
+	/*Reject outbox / sent & trash*/
+	si = camel_store_summary_path ((CamelStoreSummary *)mapi_store->summary, full_name);
+	if (si) {
+		folder_flags = si->flags;
+		camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
+	}
+
+	if (((folder_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) ||
+	    ((folder_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_OUTBOX)) {
+		g_set_error (
+			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+			_("Cannot append message to folder '%s'"),
+			full_name);
+		return FALSE;
+	}
+
+	if (!camel_offline_store_get_online (offline)) {
+		g_set_error (
+			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+			_("Offline."));
+		return FALSE;
+	}
+
+	folder_id =  camel_mapi_store_folder_id_lookup (mapi_store, full_name);
+
+	exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
+
+	/* Convert MIME to Item */
+	from = (CamelAddress *) camel_mime_message_get_from (message);
+
+	item = camel_mapi_utils_mime_to_item (message, from, cancellable, error);
+	if (item == NULL)
+		return FALSE;
+
+	mid = exchange_mapi_connection_create_item (camel_mapi_store_get_exchange_connection (mapi_store), -1, fid,
+					 camel_mapi_utils_create_item_build_props, item,
+					 item->recipients, item->attachments,
+					 item->generic_streams, 0, &mapi_error);
+
+	if (!mid) {
+		if (mapi_error) {
+			g_set_error_literal (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, mapi_error->message);
+			g_error_free (mapi_error);
+		} else {
+			g_set_error (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Offline."));
+		}
+
+		return FALSE;
+	}
+
+	if (appended_uid)
+		*appended_uid = exchange_mapi_util_mapi_ids_to_uid(fid, mid);
+
+	return TRUE;
+}
+
+static gboolean
+mapi_folder_expunge_sync (CamelFolder *folder,
+                          GCancellable *cancellable,
+                          GError **error)
+{
+	CamelMapiStore *mapi_store;
+	CamelMapiFolder *mapi_folder;
+	CamelMapiMessageInfo *minfo;
+	CamelMessageInfo *info;
+	CamelFolderChangeInfo *changes;
+	CamelStore *parent_store;
+
+	mapi_id_t fid;
+
+	gint i, count;
+	gboolean delete = FALSE, status = FALSE;
+	gchar *folder_id;
+	GSList *deleted_items, *deleted_head;
+	GSList *deleted_items_uid, *deleted_items_uid_head;
+	const gchar *full_name;
+
+	deleted_items = deleted_head = NULL;
+	deleted_items_uid = deleted_items_uid_head = NULL;
+
+	full_name = camel_folder_get_full_name (folder);
+	parent_store = camel_folder_get_parent_store (folder);
+
+	mapi_folder = CAMEL_MAPI_FOLDER (folder);
+	mapi_store = CAMEL_MAPI_STORE (parent_store);
+
+	folder_id =  g_strdup (camel_mapi_store_folder_id_lookup (mapi_store, full_name));
+	exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
+
+	if ((mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
+		GError *mapi_error = NULL;
+
+		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+		status = exchange_mapi_connection_empty_folder (camel_mapi_store_get_exchange_connection (mapi_store), fid, 0, &mapi_error);
+		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+		if (status) {
+			camel_folder_freeze (folder);
+			mapi_summary_clear (folder->summary, TRUE);
+			camel_folder_thaw (folder);
+		} else if (mapi_error) {
+			g_set_error (
+				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+				_("Failed to empty Trash: %s"), mapi_error->message);
+			g_error_free (mapi_error);
+		} else {
+			g_set_error_literal (
+				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+				_("Failed to empty Trash"));
+		}
+
+		return status;
+	}
+
+	changes = camel_folder_change_info_new ();
+	count = camel_folder_summary_count (folder->summary);
+
+	/*Collect UIDs of deleted messages.*/
+	for (i = 0; i < count; i++) {
+		info = camel_folder_summary_index (folder->summary, i);
+		minfo = (CamelMapiMessageInfo *) info;
+		if (minfo && (minfo->info.flags & CAMEL_MESSAGE_DELETED)) {
+			const gchar *uid = camel_message_info_uid (info);
+			mapi_id_t *mid = g_new0 (mapi_id_t, 1);
+
+			if (!exchange_mapi_util_mapi_ids_from_uid (uid, &fid, mid))
+				continue;
+
+			if (deleted_items)
+				deleted_items = g_slist_prepend (deleted_items, mid);
+			else {
+				g_slist_free (deleted_head);
+				deleted_head = NULL;
+				deleted_head = deleted_items = g_slist_prepend (deleted_items, mid);
+			}
+			deleted_items_uid = g_slist_prepend (deleted_items_uid, (gpointer) uid);
+		}
+		camel_message_info_free (info);
+	}
+
+	deleted_items_uid_head = deleted_items_uid;
+
+	if (deleted_items) {
+		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+		status = exchange_mapi_connection_remove_items (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, 0, deleted_items, NULL);
+
+		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+		if (status) {
+			while (deleted_items_uid) {
+				const gchar *uid = (gchar *)deleted_items_uid->data;
+				camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+				camel_folder_change_info_remove_uid (changes, uid);
+				camel_folder_summary_remove_uid (folder->summary, uid);
+				camel_data_cache_remove(mapi_folder->cache, "cache", uid, NULL);
+				camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+				deleted_items_uid = g_slist_next (deleted_items_uid);
+			}
+		}
+		delete = TRUE;
+
+		g_slist_foreach (deleted_head, (GFunc)g_free, NULL);
+		g_slist_free (deleted_head);
+		g_slist_free (deleted_items_uid_head);
+	}
+
+	if (delete)
+		camel_folder_changed (folder, changes);
+
+	g_free (folder_id);
+	camel_folder_change_info_free (changes);
+
+	return TRUE;
+}
+
 static CamelMimeMessage *
-mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
+mapi_folder_get_message_sync (CamelFolder *folder,
+                              const gchar *uid,
+                              GCancellable *cancellable,
+                              GError **error )
 {
 	CamelMimeMessage *msg = NULL;
 	CamelMapiFolder *mapi_folder;
@@ -1178,9 +1309,9 @@ mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
 
 		msg = camel_mime_message_new ();
 		camel_stream_reset (stream, NULL);
-		camel_stream_write_to_stream (cache_stream, stream, NULL);
+		camel_stream_write_to_stream (cache_stream, stream, cancellable, NULL);
 		camel_stream_reset (stream, NULL);
-		if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, stream, &local_error) == -1) {
+		if (!camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, stream, cancellable, &local_error)) {
 			if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
 				g_object_unref (msg);
 				g_object_unref (cache_stream);
@@ -1203,7 +1334,7 @@ mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
 		return msg;
 	}
 
-	if (((CamelOfflineStore *) mapi_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+	if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store))) {
 		g_set_error (
 			error, CAMEL_SERVICE_ERROR,
 			CAMEL_SERVICE_ERROR_UNAVAILABLE,
@@ -1271,8 +1402,8 @@ mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
 	/* add to cache */
 	camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 	if ((cache_stream = camel_data_cache_add (mapi_folder->cache, "cache", uid, NULL))) {
-		if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) msg, cache_stream, NULL) == -1
-				|| camel_stream_flush (cache_stream, NULL) == -1) {
+		if (camel_data_wrapper_write_to_stream_sync ((CamelDataWrapper *) msg, cache_stream, cancellable, NULL) == -1
+				|| camel_stream_flush (cache_stream, cancellable, NULL) == -1) {
 			camel_data_cache_remove (mapi_folder->cache, "cache", uid, NULL);
 		} else {
 			CamelMimeMessage *msg2;
@@ -1283,7 +1414,7 @@ mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
 			   they appear properly in the UI. */
 			msg2 = camel_mime_message_new ();
 			camel_stream_reset (cache_stream, NULL);
-			if (camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg2), cache_stream, NULL) == -1) {
+			if (!camel_data_wrapper_construct_from_stream_sync (CAMEL_DATA_WRAPPER (msg2), cache_stream, cancellable, NULL)) {
 				g_object_unref (msg2);
 			} else {
 				g_object_unref (msg);
@@ -1300,81 +1431,38 @@ mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
 	return msg;
 }
 
-static void
-mapi_folder_search_free (CamelFolder *folder, GPtrArray *uids)
-{
-	CamelMapiFolder *mapi_folder = CAMEL_MAPI_FOLDER(folder);
-
-	g_return_if_fail (mapi_folder->search);
-
-	CAMEL_MAPI_FOLDER_LOCK(mapi_folder, search_lock);
-
-	camel_folder_search_free_result (mapi_folder->search, uids);
-
-	CAMEL_MAPI_FOLDER_UNLOCK(mapi_folder, search_lock);
-
-}
-
-#if 0
-static CamelMessageInfo*
-mapi_get_message_info(CamelFolder *folder, const gchar *uid)
+static gboolean
+mapi_folder_refresh_info_sync (CamelFolder *folder,
+                               GCancellable *cancellable,
+                               GError **error)
 {
-	CamelMessageInfo	*msg_info = NULL;
-	CamelMessageInfoBase	*mi = (CamelMessageInfoBase *)msg;
-	gint			status = 0;
-	oc_message_headers_t	headers;
-
-	if (folder->summary) {
-		msg_info = camel_folder_summary_uid(folder->summary, uid);
-	}
-	if (msg_info != NULL) {
-		mi = (CamelMessageInfoBase *)msg_info;
-		return (msg_info);
-	}
-	/* Go online and fetch message summary. */
-
-	msg_info = camel_message_info_new(folder->summary);
-	mi = (CamelMessageInfoBase *)msg_info;
-
-	if (headers.subject) mi->subject = (gchar *)camel_pstring_strdup(headers.subject);
-	if (headers.from) mi->from = (gchar *)camel_pstring_strdup(headers.from);
-	if (headers.to) mi->to = (gchar *)camel_pstring_strdup(headers.to);
-	if (headers.cc) mi->cc = (gchar *)camel_pstring_strdup(headers.cc);
-	mi->flags = headers.flags;
+	if (!mapi_refresh_folder (folder, cancellable, error))
+		return FALSE;
 
-	mi->user_flags = NULL;
-	mi->user_tags = NULL;
-	mi->date_received = 0;
-	mi->date_sent = headers.send;
-	mi->content = NULL;
-	mi->summary = folder->summary;
-	if (uid) mi->uid = g_strdup(uid);
-	oc_message_headers_release(&headers);
-	return (msg);
+	return update_store_summary (folder, error);
 }
-#endif
 
 static gboolean
-mapi_expunge (CamelFolder *folder, GError **error)
+mapi_folder_synchronize_sync (CamelFolder *folder,
+                              gboolean expunge,
+                              GCancellable *cancellable,
+                              GError **error)
 {
 	CamelMapiStore *mapi_store;
 	CamelMapiFolder *mapi_folder;
-	CamelMapiMessageInfo *minfo;
-	CamelMessageInfo *info;
-	CamelFolderChangeInfo *changes;
+	CamelMessageInfo *info = NULL;
+	CamelMapiMessageInfo *mapi_info = NULL;
 	CamelStore *parent_store;
 
-	mapi_id_t fid;
-
-	gint i, count;
-	gboolean delete = FALSE, status = FALSE;
-	gchar *folder_id;
-	GSList *deleted_items, *deleted_head;
-	GSList *deleted_items_uid, *deleted_items_uid_head;
+	GSList *read_items = NULL, *unread_items = NULL, *to_free = NULL, *junk_items = NULL, *deleted_items = NULL, *l;
+	flags_diff_t diff, unset_flags;
+	const gchar *folder_id;
 	const gchar *full_name;
-
-	deleted_items = deleted_head = NULL;
-	deleted_items_uid = deleted_items_uid_head = NULL;
+	mapi_id_t fid, deleted_items_fid;
+	gint count, i;
+	guint32 options =0;
+	gboolean is_junk_folder;
+	gboolean success;
 
 	full_name = camel_folder_get_full_name (folder);
 	parent_store = camel_folder_get_parent_store (folder);
@@ -1382,100 +1470,183 @@ mapi_expunge (CamelFolder *folder, GError **error)
 	mapi_folder = CAMEL_MAPI_FOLDER (folder);
 	mapi_store = CAMEL_MAPI_STORE (parent_store);
 
-	folder_id =  g_strdup (camel_mapi_store_folder_id_lookup (mapi_store, full_name));
-	exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
+	if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)) ||
+			((CamelService *)mapi_store)->status == CAMEL_SERVICE_DISCONNECTED) {
+		return update_store_summary (folder, error);
+	}
 
-	if ((mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
-		GError *mapi_error = NULL;
+	if (((CamelMapiFolder *)folder)->type & CAMEL_MAPI_FOLDER_PUBLIC)
+		options |= MAPI_OPTIONS_USE_PFSTORE;
 
-		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-		status = exchange_mapi_connection_empty_folder (camel_mapi_store_get_exchange_connection (mapi_store), fid, 0, &mapi_error);
+	folder_id =  camel_mapi_store_folder_id_lookup (mapi_store, full_name);
+	exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
+
+	camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	if (!camel_mapi_store_connected (mapi_store, NULL)) {
 		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+		return TRUE;
+	}
+	camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-		if (status) {
-			camel_folder_freeze (folder);
-			mapi_summary_clear (folder->summary, TRUE);
-			camel_folder_thaw (folder);
-		} else if (mapi_error) {
-			g_set_error (
-				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-				_("Failed to empty Trash: %s"), mapi_error->message);
-			g_error_free (mapi_error);
-		} else {
-			g_set_error_literal (
-				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-				_("Failed to empty Trash"));
-		}
+	is_junk_folder = (mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_JUNK;
 
-		return status;
-	}
+	camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+	camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
 
-	changes = camel_folder_change_info_new ();
 	count = camel_folder_summary_count (folder->summary);
-
-	/*Collect UIDs of deleted messages.*/
-	for (i = 0; i < count; i++) {
+	for (i=0; i < count; i++) {
 		info = camel_folder_summary_index (folder->summary, i);
-		minfo = (CamelMapiMessageInfo *) info;
-		if (minfo && (minfo->info.flags & CAMEL_MESSAGE_DELETED)) {
-			const gchar *uid = camel_message_info_uid (info);
-			mapi_id_t *mid = g_new0 (mapi_id_t, 1);
+		mapi_info = (CamelMapiMessageInfo *) info;
 
-			if (!exchange_mapi_util_mapi_ids_from_uid (uid, &fid, mid))
+		if (mapi_info && (mapi_info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
+			const gchar *uid;
+			mapi_id_t *mid = g_new0 (mapi_id_t, 1); /* FIXME : */
+			mapi_id_t temp_fid;
+			guint32 flags;
+			gboolean used = FALSE;
+
+			uid = camel_message_info_uid (info);
+			flags= camel_message_info_flags (info);
+
+			/* Why are we getting so much noise here :-/ */
+			if (!exchange_mapi_util_mapi_ids_from_uid (uid, &temp_fid, mid)) {
+				camel_message_info_free (info);
+				g_free (mid);
 				continue;
+			}
 
-			if (deleted_items)
+			mapi_utils_do_flags_diff (&diff, mapi_info->server_flags, mapi_info->info.flags);
+			mapi_utils_do_flags_diff (&unset_flags, flags, mapi_info->server_flags);
+
+			diff.changed &= folder->permanent_flags;
+			if (!diff.changed) {
+				camel_message_info_free (info);
+				g_free (mid);
+				continue;
+			}
+			if (diff.bits & CAMEL_MESSAGE_DELETED) {
 				deleted_items = g_slist_prepend (deleted_items, mid);
-			else {
-				g_slist_free (deleted_head);
-				deleted_head = NULL;
-				deleted_head = deleted_items = g_slist_prepend (deleted_items, mid);
+				used = TRUE;
+			} else if (!is_junk_folder && (diff.bits & CAMEL_MESSAGE_JUNK) != 0) {
+				junk_items = g_slist_prepend (junk_items, mid);
+				used = TRUE;
 			}
-			deleted_items_uid = g_slist_prepend (deleted_items_uid, (gpointer) uid);
+
+			if (diff.bits & CAMEL_MESSAGE_SEEN) {
+				read_items = g_slist_prepend (read_items, mid);
+				used = TRUE;
+			} else if (unset_flags.bits & CAMEL_MESSAGE_SEEN) {
+				unread_items = g_slist_prepend (unread_items, mid);
+				used = TRUE;
+			}
+
+			if (used)
+				to_free = g_slist_prepend (to_free, mid);
+			else
+				g_free (mid);
+
+			mapi_info->server_flags = mapi_info->info.flags;
 		}
-		camel_message_info_free (info);
+
+		if (info)
+			camel_message_info_free (info);
 	}
 
-	deleted_items_uid_head = deleted_items_uid;
+	camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+	/*
+	   Sync up the READ changes before deleting the message.
+	   Note that if a message is marked as unread and then deleted,
+	   Evo doesnt not take care of it, as I find that scenario to be impractical.
+	*/
 
+	if (read_items) {
+		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+		exchange_mapi_connection_set_flags (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, read_items, 0, NULL);
+		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	}
+
+	if (unread_items) {
+		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+		exchange_mapi_connection_set_flags (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, unread_items, CLEAR_READ_FLAG, NULL);
+		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	}
+
+	/* Remove messages from server*/
 	if (deleted_items) {
 		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+		if ((mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
+			exchange_mapi_connection_remove_items (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, deleted_items, NULL);
+		} else {
+			GError *err = NULL;
 
-		status = exchange_mapi_connection_remove_items (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, 0, deleted_items, NULL);
+			exchange_mapi_util_mapi_id_from_string (camel_mapi_store_system_folder_fid (mapi_store, olFolderDeletedItems), &deleted_items_fid);
+			exchange_mapi_connection_move_items (camel_mapi_store_get_exchange_connection (mapi_store), fid, options, deleted_items_fid, 0, deleted_items, &err);
+
+			if (err) {
+				g_warning ("%s: Failed to move deleted items: %s", G_STRFUNC, err->message);
+				g_error_free (err);
+			}
+		}
 
 		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	}
 
-		if (status) {
-			while (deleted_items_uid) {
-				const gchar *uid = (gchar *)deleted_items_uid->data;
-				camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-				camel_folder_change_info_remove_uid (changes, uid);
-				camel_folder_summary_remove_uid (folder->summary, uid);
-				camel_data_cache_remove(mapi_folder->cache, "cache", uid, NULL);
-				camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-				deleted_items_uid = g_slist_next (deleted_items_uid);
-			}
+	if (junk_items) {
+		mapi_id_t junk_fid = 0;
+		GError *err = NULL;
+
+		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+		exchange_mapi_util_mapi_id_from_string (camel_mapi_store_system_folder_fid (mapi_store, olFolderJunk), &junk_fid);
+		exchange_mapi_connection_move_items (camel_mapi_store_get_exchange_connection (mapi_store), fid, options, junk_fid, 0, junk_items, &err);
+		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+		/* in junk_items are only emails which are not deleted */
+		deleted_items = g_slist_concat (deleted_items, g_slist_copy (junk_items));
+
+		if (err) {
+			g_warning ("%s: Failed to move junk items: %s", G_STRFUNC, err->message);
+			g_error_free (err);
 		}
-		delete = TRUE;
+	}
 
-		g_slist_foreach (deleted_head, (GFunc)g_free, NULL);
-		g_slist_free (deleted_head);
-		g_slist_free (deleted_items_uid_head);
+	/*Remove messages from local cache*/
+	for (l = deleted_items; l; l = l->next) {
+		gchar * deleted_msg_uid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X%016" G_GINT64_MODIFIER "X", fid, *(mapi_id_t *)l->data);
+
+		camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+		camel_folder_summary_remove_uid (folder->summary, deleted_msg_uid);
+		camel_data_cache_remove(mapi_folder->cache, "cache", deleted_msg_uid, NULL);
+		camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 	}
 
-	if (delete)
-		camel_folder_changed (folder, changes);
+	g_slist_free (read_items);
+	g_slist_free (unread_items);
+	g_slist_free (deleted_items);
+	g_slist_free (junk_items);
 
-	g_free (folder_id);
-	camel_folder_change_info_free (changes);
+	g_slist_foreach (to_free, (GFunc) g_free, NULL);
+	g_slist_free (to_free);
 
-	return TRUE;
+	if (expunge) {
+		/* TODO */
+	}
+
+	camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	success = update_store_summary (folder, error);
+	camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+	return success;
 }
 
 static gboolean
-mapi_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
-		CamelFolder *destination, GPtrArray **transferred_uids,
-		gboolean delete_originals, GError **error)
+mapi_folder_transfer_messages_to_sync (CamelFolder *source,
+                                       GPtrArray *uids,
+                                       CamelFolder *destination,
+                                       gboolean delete_originals,
+                                       GPtrArray **transferred_uids,
+                                       GCancellable *cancellable,
+                                       GError **error)
 {
 	mapi_id_t src_fid, dest_fid;
 	guint32 src_fid_options, dest_fid_options;
@@ -1500,9 +1671,9 @@ mapi_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 		/* because cannot use MAPI to copy/move messages with public folders,
 		   thus fallback to per-message copy/move */
 		folder_class = CAMEL_FOLDER_CLASS (camel_mapi_folder_parent_class);
-		return folder_class->transfer_messages_to (
-			source, uids, destination, transferred_uids,
-			delete_originals, error);
+		return folder_class->transfer_messages_to_sync (
+			source, uids, destination, delete_originals,
+			transferred_uids, cancellable, error);
 	}
 
 	source_full_name = camel_folder_get_full_name (source);
@@ -1515,7 +1686,7 @@ mapi_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 	offline = CAMEL_OFFLINE_STORE (destination_parent_store);
 
 	/* check for offline operation */
-	if (offline->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+	if (!camel_offline_store_get_online (offline))
 		return FALSE;
 
 	folder_id =  camel_mapi_store_folder_id_lookup (mapi_store, source_full_name);
@@ -1575,152 +1746,6 @@ mapi_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 }
 
 static void
-mapi_folder_rename (CamelFolder *folder, const gchar *new)
-{
-	((CamelFolderClass *)camel_mapi_folder_parent_class)->rename(folder, new);
-}
-
-static gint
-mapi_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
-{
-	g_return_val_if_fail (uid1 != NULL, 0);
-	g_return_val_if_fail (uid2 != NULL, 0);
-
-	return strcmp (uid1, uid2);
-}
-
-static gboolean
-mapi_append_message (CamelFolder *folder, CamelMimeMessage *message,
-		const CamelMessageInfo *info, gchar **appended_uid,
-		GError **error)
-{
-	CamelMapiStore *mapi_store;
-	CamelOfflineStore *offline;
-	CamelAddress *from = NULL;
-	CamelStoreInfo *si;
-	CamelStore *parent_store;
-	MailItem *item = NULL;
-	mapi_id_t fid = 0, mid = 0;
-	const gchar *folder_id;
-	const gchar *full_name;
-	guint32 folder_flags = 0;
-	GError *mapi_error = NULL;
-
-	full_name = camel_folder_get_full_name (folder);
-	parent_store = camel_folder_get_parent_store (folder);
-
-	mapi_store = CAMEL_MAPI_STORE (parent_store);
-	offline = CAMEL_OFFLINE_STORE (parent_store);
-
-	/*Reject outbox / sent & trash*/
-	si = camel_store_summary_path ((CamelStoreSummary *)mapi_store->summary, full_name);
-	if (si) {
-		folder_flags = si->flags;
-		camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
-	}
-
-	if (((folder_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) ||
-	    ((folder_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_OUTBOX)) {
-		g_set_error (
-			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			_("Cannot append message to folder '%s'"),
-			full_name);
-		return FALSE;
-	}
-
-	if (offline->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
-		g_set_error (
-			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			_("Offline."));
-		return FALSE;
-	}
-
-	folder_id =  camel_mapi_store_folder_id_lookup (mapi_store, full_name);
-
-	exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
-
-	/* Convert MIME to Item */
-	from = (CamelAddress *) camel_mime_message_get_from (message);
-
-	item = camel_mapi_utils_mime_to_item (message, from, error);
-	if (item == NULL)
-		return FALSE;
-
-	mid = exchange_mapi_connection_create_item (camel_mapi_store_get_exchange_connection (mapi_store), -1, fid,
-					 camel_mapi_utils_create_item_build_props, item,
-					 item->recipients, item->attachments,
-					 item->generic_streams, 0, &mapi_error);
-
-	if (!mid) {
-		if (mapi_error) {
-			g_set_error_literal (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, mapi_error->message);
-			g_error_free (mapi_error);
-		} else {
-			g_set_error (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Offline."));
-		}
-
-		return FALSE;
-	}
-
-	if (appended_uid)
-		*appended_uid = exchange_mapi_util_mapi_ids_to_uid(fid, mid);
-
-	return TRUE;
-}
-
-static gboolean
-mapi_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set)
-{
-	CamelMessageInfo *info;
-	gint res;
-
-	g_return_val_if_fail (folder->summary != NULL, FALSE);
-
-	info = camel_folder_summary_uid (folder->summary, uid);
-	if (info == NULL)
-		return FALSE;
-
-	res = camel_message_info_set_flags (info, flags, set);
-
-	camel_message_info_free (info);
-	return res;
-}
-
-static void
-mapi_folder_dispose (GObject *object)
-{
-	CamelMapiFolder *mapi_folder = CAMEL_MAPI_FOLDER (object);
-
-	if (mapi_folder->cache != NULL) {
-		g_object_unref (mapi_folder->cache);
-		mapi_folder->cache = NULL;
-	}
-
-	/* Chain up to parent's dispose() method. */
-	G_OBJECT_CLASS (camel_mapi_folder_parent_class)->dispose (object);
-}
-
-static void
-mapi_folder_constructed (GObject *object)
-{
-	CamelFolder *folder;
-	CamelStore *parent_store;
-	CamelURL *url;
-	const gchar *full_name;
-	gchar *description;
-
-	folder = CAMEL_FOLDER (object);
-	full_name = camel_folder_get_full_name (folder);
-	parent_store = camel_folder_get_parent_store (folder);
-	url = CAMEL_SERVICE (parent_store)->url;
-
-	description = g_strdup_printf (
-		"%s %s:%s", url->user, url->host, full_name);
-	camel_folder_set_description (folder, description);
-	g_free (description);
-}
-
-static void
 camel_mapi_folder_class_init (CamelMapiFolderClass *class)
 {
 	GObjectClass *object_class;
@@ -1733,18 +1758,18 @@ camel_mapi_folder_class_init (CamelMapiFolderClass *class)
 	object_class->constructed = mapi_folder_constructed;
 
 	folder_class = CAMEL_FOLDER_CLASS (class);
-	folder_class->get_message = mapi_folder_get_message;
 	folder_class->rename = mapi_folder_rename;
 	folder_class->search_by_expression = mapi_folder_search_by_expression;
 	folder_class->cmp_uids = mapi_cmp_uids;
 	folder_class->search_by_uids = mapi_folder_search_by_uids;
 	folder_class->search_free = mapi_folder_search_free;
-	folder_class->append_message = mapi_append_message;
-	folder_class->refresh_info = mapi_refresh_info;
-	folder_class->sync = mapi_sync;
 	folder_class->set_message_flags = mapi_set_message_flags;
-	folder_class->expunge = mapi_expunge;
-	folder_class->transfer_messages_to = mapi_transfer_messages_to;
+	folder_class->append_message_sync = mapi_folder_append_message_sync;
+	folder_class->expunge_sync = mapi_folder_expunge_sync;
+	folder_class->get_message_sync = mapi_folder_get_message_sync;
+	folder_class->refresh_info_sync = mapi_folder_refresh_info_sync;
+	folder_class->synchronize_sync = mapi_folder_synchronize_sync;
+	folder_class->transfer_messages_to_sync = mapi_folder_transfer_messages_to_sync;
 }
 
 static void
diff --git a/src/camel/camel-mapi-folder.h b/src/camel/camel-mapi-folder.h
index ab8f604..3216906 100644
--- a/src/camel/camel-mapi-folder.h
+++ b/src/camel/camel-mapi-folder.h
@@ -91,9 +91,9 @@ CamelFolder *
 camel_mapi_folder_new(CamelStore *store, const gchar *folder_name, const gchar *folder_dir, guint32 flags, GError **error);
 
 void mapi_update_summary ( CamelFolder *folder, GList *item_list,GError **error);
-gboolean mapi_refresh_folder(CamelFolder *folder, GError **error);
+gboolean mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **error);
 gboolean camel_mapi_folder_fetch_summary (CamelStore *store, CamelFolder *folder, const mapi_id_t fid, struct mapi_SRestriction *res,
-					  struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GError **mapi_error);
+					  struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GCancellable *cancellable, GError **mapi_error);
 
 G_END_DECLS
 
diff --git a/src/camel/camel-mapi-notifications.c b/src/camel/camel-mapi-notifications.c
index 21fc3dc..f12d6e4 100644
--- a/src/camel/camel-mapi-notifications.c
+++ b/src/camel/camel-mapi-notifications.c
@@ -95,7 +95,8 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
 		info_count--;
 	}
 
-	folder = camel_store_get_folder ((CamelStore *)store, folder_name, 0, NULL);
+	folder = camel_store_get_folder_sync (
+		(CamelStore *)store, folder_name, 0, NULL, NULL);
 
 	/* Abort on failure*/
 	if (!folder)
@@ -117,7 +118,7 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
 	fetch_data->folder = folder;
 
 	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	camel_mapi_folder_fetch_summary ((CamelStore *)store, folder, new_mail_notif->FID, res, NULL, fetch_data, options, NULL);
+	camel_mapi_folder_fetch_summary ((CamelStore *)store, folder, new_mail_notif->FID, res, NULL, fetch_data, options, NULL, NULL);
 	camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	camel_folder_summary_touch (folder->summary);
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index 587d621..cc59cdb 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -82,26 +82,14 @@ static gboolean	mapi_construct(CamelService *, CamelSession *,
 				     CamelProvider *, CamelURL *,
 				     GError **);
 static gchar	*mapi_get_name(CamelService *, gboolean );
-static gboolean	mapi_connect(CamelService *, GError **);
-static gboolean	mapi_disconnect(CamelService *, gboolean , GError **);
-static GList	*mapi_query_auth_types(CamelService *, GError **);
+static gboolean	mapi_connect_sync(CamelService *, GCancellable *cancellable, GError **);
+static gboolean	mapi_disconnect_sync(CamelService *, gboolean , GCancellable *cancellable, GError **);
+static GList	*mapi_query_auth_types_sync(CamelService *, GCancellable *cancellable, GError **);
 
 /* store methods */
-static CamelFolder	*mapi_get_folder(CamelStore *, const gchar *, guint32, GError **);
-static CamelFolderInfo	*mapi_create_folder(CamelStore *, const gchar *, const gchar *, GError **);
-static gboolean		mapi_delete_folder(CamelStore *, const gchar *, GError **);
-static gboolean		mapi_rename_folder(CamelStore *, const gchar *, const gchar *, GError **);
-static CamelFolderInfo	*mapi_get_folder_info(CamelStore *, const gchar *, guint32, GError **);
-static gboolean		mapi_subscribe_folder(CamelStore *, const gchar *, GError **);
-static gboolean mapi_folder_is_subscribed (CamelStore *store, const gchar *folder_name);
-static gboolean		mapi_unsubscribe_folder(CamelStore *, const gchar *, GError **);
-static gboolean		mapi_noop(CamelStore *, GError **);
 static CamelFolderInfo * mapi_build_folder_info(CamelMapiStore *mapi_store, const gchar *parent_name, const gchar *folder_name);
 static gboolean mapi_fid_is_system_folder (CamelMapiStore *mapi_store, const gchar *fid);
 static void mapi_update_hash_table_type (CamelMapiStore *store, const gchar *full_name, guint *folder_type);
-static CamelFolder *mapi_get_trash (CamelStore *store, GError **error);
-static CamelFolder *mapi_get_junk (CamelStore *store, GError **error);
-static gboolean mapi_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError **error);
 
 static void mapi_update_folder_hash_tables (CamelMapiStore *store, const gchar *name, const gchar *fid, const gchar *parent_id);
 guint mapi_folders_hash_table_type_lookup (CamelMapiStore *store, const gchar *name);
@@ -110,6 +98,12 @@ guint mapi_folders_hash_table_type_lookup (CamelMapiStore *store, const gchar *n
 static const gchar * mapi_folders_hash_table_fid_lookup (CamelMapiStore *store, const gchar *name, gboolean use_cache);
 #endif
 
+static CamelFolderInfo *
+		mapi_store_create_folder_sync	(CamelStore *store,
+						 const gchar *parent_name,
+						 const gchar *folder_name,
+						 GCancellable *cancellable,
+						 GError **error);
 #if 0
 static void
 dump_summary (CamelMapiStore *mstore)
@@ -145,368 +139,712 @@ dump_summary (CamelMapiStore *mstore)
 }
 #endif
 
-static guint
-mapi_hash_folder_name(gconstpointer key)
+static gboolean
+check_for_connection (CamelService *service, GError **error)
 {
-	return g_str_hash(key);
+	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+
+	return store && store->priv->conn && exchange_mapi_connection_connected (store->priv->conn);
 }
 
-static gint
-mapi_compare_folder_name(gconstpointer a, gconstpointer b)
+static CamelFolder *
+mapi_get_folder_with_type (CamelStore *store, guint folder_type, GCancellable *cancellable, GError **error)
 {
-	gconstpointer	aname = a;
-	gconstpointer	bname = b;
+	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+	CamelFolderInfo *all_fi, *fi;
+	CamelFolder *folder = NULL;
 
-	return g_str_equal(aname, bname);
-}
+	g_return_val_if_fail (mapi_store != NULL, NULL);
+	g_return_val_if_fail (mapi_store->priv != NULL, NULL);
 
-static void
-mapi_store_dispose (GObject *object)
-{
-	CamelMapiStorePrivate *priv;
+	all_fi = camel_store_get_folder_info_sync (
+		store, NULL, CAMEL_STORE_FOLDER_INFO_RECURSIVE,
+		cancellable, error);
+	if (all_fi == NULL)
+		return NULL;
 
-	priv = CAMEL_MAPI_STORE_GET_PRIVATE (object);
+	fi = all_fi;
+	while (fi) {
+		CamelFolderInfo *next;
 
-	if (priv->conn != NULL) {
-		g_object_unref (priv->conn);
-		priv->conn = NULL;
+		if ((fi->flags & CAMEL_FOLDER_TYPE_MASK) == folder_type) {
+			folder = camel_store_get_folder_sync (
+				store, fi->full_name, 0, cancellable, error);
+			break;
+		}
+
+		/* move to the next, depth-first search */
+		next = fi->child;
+		if (!next)
+			next = fi->next;
+		if (!next) {
+			next = fi->parent;
+			while (next) {
+				CamelFolderInfo *sibl = next->next;
+				if (sibl) {
+					next = sibl;
+					break;
+				} else {
+					next = next->parent;
+				}
+			}
+		}
+
+		fi = next;
 	}
 
-	/* Chain up to parent's dispose() method. */
-	G_OBJECT_CLASS (camel_mapi_store_parent_class)->dispose (object);
+	camel_store_free_folder_info (store, all_fi);
+
+	return folder;
 }
 
-static void
-mapi_store_finalize (GObject *object)
+static CamelFolderInfo *
+mapi_convert_to_folder_info (CamelMapiStore *store, ExchangeMAPIFolder *folder, const gchar *url, GError **error)
 {
-	CamelMapiStorePrivate *priv;
+	const gchar *name = NULL;
+	gchar *parent, *id = NULL;
+	mapi_id_t mapi_id_folder;
 
-	priv = CAMEL_MAPI_STORE_GET_PRIVATE (object);
+	const gchar *par_name = NULL;
+	CamelFolderInfo *fi;
 
-	g_free (priv->profile);
-	g_free (priv->storage_path);
-	g_free (priv->base_url);
+	name = exchange_mapi_folder_get_name (folder);
 
-	if (priv->id_hash != NULL)
-		g_hash_table_destroy (priv->id_hash);
+	id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_fid (folder));
 
-	if (priv->name_hash != NULL)
-		g_hash_table_destroy (priv->name_hash);
+	fi = camel_folder_info_new ();
 
-	if (priv->parent_hash != NULL)
-		g_hash_table_destroy (priv->parent_hash);
+	if (folder->is_default) {
+		switch (folder->default_type) {
+		case olFolderTopInformationStore:
+			fi->flags |= CAMEL_FOLDER_NOSELECT;
+			break;
+		case olFolderInbox:
+			fi->flags |= CAMEL_FOLDER_TYPE_INBOX;
+			break;
+		case olFolderSentMail:
+			fi->flags |= CAMEL_FOLDER_TYPE_SENT;
+			break;
+		case olFolderDeletedItems:
+			fi->flags |= CAMEL_FOLDER_TYPE_TRASH;
+			break;
+		case olFolderOutbox:
+			fi->flags |= CAMEL_FOLDER_TYPE_OUTBOX;
+			break;
+		case olFolderJunk:
+			fi->flags |= CAMEL_FOLDER_TYPE_JUNK;
+			break;
+		}
 
-	if (priv->default_folders != NULL)
-		g_hash_table_destroy (priv->default_folders);
-	if (priv->container_hash != NULL)
-		g_hash_table_destroy (priv->container_hash);
-	/* Chain up to parent's finalize() method. */
-	G_OBJECT_CLASS (camel_mapi_store_parent_class)->finalize (object);
-}
+		fi->flags |= CAMEL_FOLDER_SYSTEM;
+	}
 
-static void
-camel_mapi_store_class_init (CamelMapiStoreClass *class)
-{
-	GObjectClass *object_class;
-	CamelServiceClass *service_class;
-	CamelStoreClass *store_class;
+	if (folder->category == MAPI_PERSONAL_FOLDER) {
+		fi->flags |= CAMEL_MAPI_FOLDER_PERSONAL;
+		fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED; /*Set this default for mailbox.*/
+	} else if (folder->category == MAPI_FAVOURITE_FOLDER)
+		fi->flags |= CAMEL_MAPI_FOLDER_PUBLIC;
 
-	g_type_class_add_private (class, sizeof (CamelMapiStorePrivate));
+	if (folder->child_count <=0)
+		fi->flags |= CAMEL_FOLDER_NOCHILDREN;
+	/*
+	   parent_hash contains the "parent id <-> folder id" combination. So we form
+	   the path for the full name in camelfolder info by looking up the hash table until
+	   NULL is found
+	 */
 
-	object_class = G_OBJECT_CLASS (class);
-	object_class->dispose = mapi_store_dispose;
-	object_class->finalize = mapi_store_finalize;
+	mapi_id_folder = exchange_mapi_folder_get_parent_id (folder);
+	parent = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", mapi_id_folder);
 
-	service_class = CAMEL_SERVICE_CLASS (class);
-	service_class->construct = mapi_construct;
-	service_class->get_name = mapi_get_name;
-	service_class->connect = mapi_connect;
-	service_class->disconnect = mapi_disconnect;
-	service_class->query_auth_types = mapi_query_auth_types;
+	fi->name =  g_strdup (name);
 
-	store_class = CAMEL_STORE_CLASS (class);
-	store_class->hash_folder_name = mapi_hash_folder_name;
-	store_class->compare_folder_name = mapi_compare_folder_name;
-	store_class->get_folder = mapi_get_folder;
-	store_class->create_folder = mapi_create_folder;
-	store_class->delete_folder = mapi_delete_folder;
-	store_class->rename_folder = mapi_rename_folder;
-	store_class->get_folder_info = mapi_get_folder_info;
-	store_class->free_folder_info = camel_store_free_folder_info_full;
-	store_class->subscribe_folder = mapi_subscribe_folder;
-	store_class->folder_is_subscribed = mapi_folder_is_subscribed;
-	store_class->unsubscribe_folder = mapi_unsubscribe_folder;
-	store_class->noop = mapi_noop;
-	store_class->get_trash = mapi_get_trash;
-	store_class->get_junk = mapi_get_junk;
-	store_class->can_refresh_folder = mapi_can_refresh_folder;
+	par_name = mapi_folders_hash_table_name_lookup (store, parent, TRUE);
+	if (par_name != NULL) {
+		gchar *str = g_strconcat (par_name, "/", name, NULL);
+
+		fi->full_name = str; /* takes ownership of the string */
+		fi->uri = g_strconcat (url, str, NULL);
+	} else {
+		fi->full_name = g_strdup (name);
+		fi->uri = g_strconcat (url, "", name, NULL);
+	}
+
+	/*name_hash returns the container id given the name */
+	mapi_update_folder_hash_tables (store, fi->full_name, id, parent);
+
+	g_free (parent);
+	g_free (id);
+
+	fi->total = folder->total;
+	fi->unread = folder->unread_count;
+
+	return fi;
 }
 
-/*
-** store is already initilyse to NULL or 0 value
-** class already have a parent_class
-** nothing must be doing here
-*/
 static void
-camel_mapi_store_init (CamelMapiStore *mapi_store)
+remove_path_from_store_summary (const gchar *path, gpointer value, CamelMapiStore *mstore)
 {
-	mapi_store->priv = CAMEL_MAPI_STORE_GET_PRIVATE (mapi_store);
+	const gchar *folder_id;
+	CamelStoreInfo *si;
+
+	g_return_if_fail (path != NULL);
+	g_return_if_fail (mstore != NULL);
+
+	folder_id = g_hash_table_lookup (mstore->priv->name_hash, path);
+	if (folder_id) {
+		/* name_hash as the second, because folder_id is from there */
+		g_hash_table_remove (mstore->priv->id_hash, folder_id);
+		g_hash_table_remove (mstore->priv->name_hash, path);
+	}
+
+	si = camel_store_summary_path ((CamelStoreSummary *)mstore->summary, path);
+	if (si) {
+		CamelFolderInfo *fi;
+
+		fi = camel_folder_info_new ();
+		fi->unread = -1;
+		fi->total = -1;
+		fi->uri = g_strdup (camel_store_info_uri (mstore->summary, si));
+		fi->name = g_strdup (camel_store_info_name (mstore->summary, si));
+		fi->full_name = g_strdup (camel_mapi_store_info_full_name (mstore->summary, si));
+		if (!fi->name && fi->full_name) {
+			fi->name = strrchr (fi->full_name, '/');
+			if (fi->name)
+				fi->name = g_strdup (fi->name + 1);
+		}
+
+		camel_store_folder_unsubscribed (CAMEL_STORE (mstore), fi);
+		camel_store_folder_deleted (CAMEL_STORE (mstore), fi);
+		camel_folder_info_free (fi);
+
+		camel_store_summary_info_free ((CamelStoreSummary *)mstore->summary, si);
+	}
+
+	camel_store_summary_remove_path ((CamelStoreSummary *)mstore->summary, path);
 }
 
-/* service methods */
-static gboolean mapi_construct(CamelService *service, CamelSession *session,
-				 CamelProvider *provider, CamelURL *url,
-				 GError **error)
+static gboolean
+mapi_folders_sync (CamelMapiStore *store, guint32 flags, GError **error)
 {
-	CamelMapiStore	*mapi_store = CAMEL_MAPI_STORE (service);
-	CamelStore *store = CAMEL_STORE (service);
-	CamelMapiStorePrivate *priv = mapi_store->priv;
-	gchar *path = NULL;
+	CamelMapiStorePrivate  *priv = store->priv;
+	gboolean status;
+	GSList *folder_list = NULL, *temp_list = NULL, *list = NULL;
+	gchar *url, *temp_url;
+	gboolean subscription_list = FALSE;
+	CamelFolderInfo *info = NULL;
+	CamelMapiStoreInfo *mapi_si = NULL;
+	guint32 count, i;
+	CamelStoreInfo *si = NULL;
+	GHashTable *old_cache_folders;
+	GError *err = NULL;
 
-	if (!CAMEL_SERVICE_CLASS (camel_mapi_store_parent_class)->construct (service, session, provider, url, error))
+	if (!camel_mapi_store_connected (store, NULL)) {
+		g_set_error (
+			error, CAMEL_SERVICE_ERROR,
+			CAMEL_SERVICE_ERROR_UNAVAILABLE,
+			_("Folder list not available in offline mode."));
 		return FALSE;
+	}
 
-	/*storage path*/
-	priv->storage_path = camel_session_get_storage_path (session, service, error);
-	if (!priv->storage_path)
-		return FALSE;
+	status = exchange_mapi_connection_get_folders_list (priv->conn, &folder_list, &err);
 
-	/*store summary*/
-	path = g_alloca (strlen (priv->storage_path) + 32);
-	sprintf (path, "%s/.summary", priv->storage_path);
+	if (!status) {
+		g_warning ("Could not get folder list (%s)\n", err ? err->message : "Unknown error");
+		if (err)
+			g_error_free (err);
+		return TRUE;
+	}
 
-	mapi_store->summary = camel_mapi_store_summary_new ();
-	camel_store_summary_set_filename ((CamelStoreSummary *)mapi_store->summary, path);
+	/* remember all folders in cache before update */
+	old_cache_folders = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+	count = camel_store_summary_count ((CamelStoreSummary *)store->summary);
+	for (i = 0; i < count; i++) {
+		si = camel_store_summary_index ((CamelStoreSummary *)store->summary, i);
+		if (si == NULL)
+			continue;
 
-	camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
-	camel_store_summary_load ((CamelStoreSummary *) mapi_store->summary);
+		/* those whose left in old_cache_folders are removed at the end,
+		   which is not good for public folders, thus preserve them from
+		   an automatic removal */
+		if ((si->flags & CAMEL_MAPI_FOLDER_PUBLIC) == 0 || (si->flags & CAMEL_FOLDER_SUBSCRIBED) == 0)
+			g_hash_table_insert (old_cache_folders, g_strdup (camel_store_info_path (store->summary, si)), GINT_TO_POINTER (1));
 
-	/*user and profile*/
-	priv->profile = g_strdup (camel_url_get_param(url, "profile"));
+		camel_store_summary_info_free ((CamelStoreSummary *)store->summary, si);
+	}
 
-	/*base url*/
-	priv->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD |
-						       CAMEL_URL_HIDE_PARAMS   |
-						       CAMEL_URL_HIDE_AUTH)  );
+	subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
+	if (subscription_list) {
+		GError *err = NULL;
 
-	/*filter*/
-	if (camel_url_get_param (url, "filter"))
-		store->flags |= CAMEL_STORE_FILTER_INBOX;
+		/*Consult the name <-> fid hash table for a FID.*/
+		status = exchange_mapi_connection_get_pf_folders_list (priv->conn, &folder_list, &err);
+		if (!status)
+			g_warning ("Could not get Public folder list (%s)\n", err ? err->message : "Unknown error");
 
-	/*Hash Table*/
-	priv->id_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* folder ID to folder Full name */
-	priv->name_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* folder Full name to folder ID */
-	/*priv->parent_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); / * folder ID to its parent folder ID */
-	priv->default_folders = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_free); /* default folder type to folder ID */
-	priv->container_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-	store->flags &= ~CAMEL_STORE_VJUNK;
-	store->flags &= ~CAMEL_STORE_VTRASH;
+		if (err)
+			g_error_free (err);
+	}
 
-	store->flags |= CAMEL_STORE_SUBSCRIPTIONS | CAMEL_STORE_REAL_JUNK_FOLDER;
+	temp_list = folder_list;
+	list = folder_list;
+
+	url = camel_url_to_string (CAMEL_SERVICE(store)->url,
+				   (CAMEL_URL_HIDE_PASSWORD|
+				    CAMEL_URL_HIDE_PARAMS|
+				    CAMEL_URL_HIDE_AUTH));
+	if ( url[strlen(url) - 1] != '/') {
+		temp_url = g_strconcat (url, "/", NULL);
+		g_free ((gchar *)url);
+		url = temp_url;
+	}
+
+	/*populate the hash table for finding the mapping from container id <-> folder name*/
+	for (;temp_list != NULL; temp_list = g_slist_next (temp_list) ) {
+		const gchar *full_name = NULL;
+		gchar *fid = NULL, *parent_id = NULL, *tmp = NULL;
+		guint *folder_type = g_new0 (guint, 1);
+
+		fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(temp_list->data)));
+		parent_id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_parent_id ((ExchangeMAPIFolder *)(temp_list->data)));
+		full_name = g_hash_table_lookup (priv->id_hash, fid);
+		if (!full_name) {
+			const gchar *par_full_name;
+
+			par_full_name = g_hash_table_lookup (priv->id_hash, parent_id);
+			if (par_full_name) {
+				tmp = g_strconcat (par_full_name, "/", exchange_mapi_folder_get_name (temp_list->data), NULL);
+				full_name = tmp;
+			} else {
+				full_name = exchange_mapi_folder_get_name (temp_list->data);
+			}
+		}
+
+		/* remove from here; what lefts is not on the server any more */
+		g_hash_table_remove (old_cache_folders, full_name);
+		*folder_type = ((ExchangeMAPIFolder *)(temp_list->data))->container_class;
+		mapi_update_folder_hash_tables (store, full_name, fid, parent_id);
+		mapi_update_hash_table_type (store, full_name, folder_type);
+		if (((ExchangeMAPIFolder *)(temp_list->data))->is_default) {
+			guint *type = g_new0 (guint, 1);
+			*type = ((ExchangeMAPIFolder *)(temp_list->data))->default_type;
+			g_hash_table_insert (priv->default_folders, type,
+					     g_strdup(fid));
+		}
+		g_free (fid);
+		g_free (parent_id);
+		g_free (tmp);
+	}
+
+	for (;folder_list != NULL; folder_list = g_slist_next (folder_list)) {
+		ExchangeMAPIFolder *folder = (ExchangeMAPIFolder *) folder_list->data;
+
+		if (folder->default_type == olPublicFoldersAllPublicFolders)
+			continue;
+
+		if ( folder->container_class == MAPI_FOLDER_TYPE_MAIL) {
+			info = mapi_convert_to_folder_info (store, folder, (const gchar *)url, NULL);
+			info->flags |= CAMEL_MAPI_FOLDER_MAIL;
+			mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name);
+
+			if (!mapi_si) {
+				gchar *fid, *pfid = NULL;
+
+				fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
+						       exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
+				pfid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
+							exchange_mapi_folder_get_parent_id((ExchangeMAPIFolder *)(folder_list->data)));
+
+				mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/', fid, pfid);
+				g_free (fid);
+				g_free (pfid);
+				if (mapi_si == NULL)
+					continue;
+
+				camel_store_summary_info_ref ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
+
+				if (!subscription_list) {
+					camel_store_folder_created (CAMEL_STORE (store), info);
+					camel_store_folder_subscribed (CAMEL_STORE (store), info);
+				}
+			}
+
+			mapi_si->info.flags |= info->flags;
+			mapi_si->info.total = info->total;
+			mapi_si->info.unread = info->unread;
+
+			camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
+			camel_folder_info_free (info);
+		} else if (folder->category == MAPI_FAVOURITE_FOLDER) {
+			gchar *fid, *pfid = NULL;
+			info = mapi_convert_to_folder_info (store, folder, (const gchar *)url, NULL);
+			mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name);
+			fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
+						exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
+			pfid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
+						exchange_mapi_folder_get_parent_id((ExchangeMAPIFolder *)(folder_list->data)));
+			mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/', fid, pfid);
+			g_free (fid);
+			g_free (pfid);
+
+			if (mapi_si == NULL)
+				continue;
+
+			camel_store_summary_info_ref ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
+			mapi_si->info.flags |= info->flags;
+			camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
+			camel_folder_info_free (info);
+		}
+	}
+
+	/* Weed out deleted folders */
+	g_hash_table_foreach (old_cache_folders, (GHFunc) remove_path_from_store_summary, store);
+	g_hash_table_destroy (old_cache_folders);
+
+	camel_store_summary_touch ((CamelStoreSummary *)store->summary);
+	camel_store_summary_save ((CamelStoreSummary *)store->summary);
+
+	g_free (url);
+
+	g_slist_foreach (list, (GFunc) exchange_mapi_folder_free, NULL);
+	g_slist_free (list);
+
+	priv->folders_synced = TRUE;
+
+	//	g_hash_table_foreach (present, get_folders_free, NULL);
+	//	g_hash_table_destroy (present);
+
+	/* FIXME : This place is not right! */
+	/* Start Push Notification listener */
+	/* event_mask = fnevNewMail | fnevObjectCreated | fnevObjectDeleted | */
+	/*	fnevObjectModified | fnevObjectMoved | fnevObjectCopied; */
+
+	/* camel_mapi_notfication_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE); */
 
 	return TRUE;
 }
 
-static char
-*mapi_get_name(CamelService *service, gboolean brief)
+static gchar *
+mapi_concat ( const gchar *prefix, const gchar *suffix)
 {
-	if (brief) {
-		/* Translators: The %s is replaced with a server's host name */
-		return g_strdup_printf(_("Exchange MAPI server %s"), service->url->host);
-	} else {
-		/*To translators : Example string : Exchange MAPI service for
-		  _username_ on _server host name__*/
-		return g_strdup_printf(_("Exchange MAPI service for %s on %s"),
-				       service->url->user, service->url->host);
-	}
+	gsize len;
+
+	len = strlen (prefix);
+	if (len == 0 || prefix[len - 1] == '/')
+		return g_strdup_printf ("%s%s", prefix, suffix);
+	else
+		return g_strdup_printf ("%s%c%s", prefix, '/', suffix);
 }
 
-static gboolean
-check_for_connection (CamelService *service, GError **error)
+//do we realy need this. move to utils then !
+static gint
+match_path(const gchar *path, const gchar *name)
 {
-	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+	gchar p, n;
 
-	return store && store->priv->conn && exchange_mapi_connection_connected (store->priv->conn);
+	p = *path++;
+	n = *name++;
+	while (n && p) {
+		if (n == p) {
+			p = *path++;
+			n = *name++;
+		} else if (p == '%') {
+			if (n != '/') {
+				n = *name++;
+			} else {
+				p = *path++;
+			}
+		} else if (p == '*') {
+			return TRUE;
+		} else
+			return FALSE;
+	}
+
+	return n == 0 && (p == '%' || p == 0);
 }
 
-static gboolean
-mapi_auth_loop (CamelService *service, GError **error)
+static CamelFolderInfo *
+mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
+			 guint32 flags, GError **error)
 {
-	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
-	CamelSession *session = camel_service_get_session (service);
+	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+	CamelFolderInfo *fi;
+	GPtrArray *folders;
+	gchar *path, *name;
+	gint i;
+	gboolean subscribed, favourites = FALSE, subscription_list = FALSE;
 
-	gchar *errbuf = NULL;
-	gboolean authenticated = FALSE;
-	guint32 prompt_flags = CAMEL_SESSION_PASSWORD_SECRET;
+	subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
+	subscribed = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED);
 
-	service->url->passwd = NULL;
+	folders = g_ptr_array_new ();
 
-	while (!authenticated) {
-		GError *mapi_error = NULL;
+	if (top == NULL)
+		top = "";
 
-		if (errbuf) {
-			/* We need to un-cache the password before prompting again */
-			prompt_flags |= CAMEL_SESSION_PASSWORD_REPROMPT;
-			g_free (service->url->passwd);
-			service->url->passwd = NULL;
+	/* get starting point */
+	if (top[0] == 0) {
+			name = g_strdup("");
+	} else {
+		name = camel_mapi_store_summary_full_from_path(mapi_store->summary, top);
+		if (name == NULL)
+			name = camel_mapi_store_summary_path_to_full(mapi_store->summary, top, '/');
+	}
+
+	path = mapi_concat (name, "*");
+
+	for (i=0;i<camel_store_summary_count((CamelStoreSummary *)mapi_store->summary);i++) {
+		CamelStoreInfo *si = camel_store_summary_index((CamelStoreSummary *)mapi_store->summary, i);
+
+		if (si == NULL)
+			continue;
+
+		/* Allow only All Public Folders heirarchy */
+		if (subscription_list && (!(si->flags & CAMEL_MAPI_FOLDER_PUBLIC))) {
+			camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
+			continue;
 		}
 
-		if (!service->url->passwd ) {
-			gchar *prompt;
+		/*Allow Mailbox and Favourites (Subscribed public folders)*/
+		if (subscribed && (!(si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED))) {
+			camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
+			continue;
+		}
 
-			/*To translators : First %s : is the error text or the reason
-			  for prompting the user if it is available.
-			 Second %s is : Username.
-			 Third %s is : Server host name.*/
-			prompt = g_strdup_printf (_("%s Please enter the MAPI password for %s %s"),
-						  errbuf ? errbuf : "",
-						  service->url->user,
-						  service->url->host);
-			service->url->passwd =
-				camel_session_get_password (session, service, E_PASSWORD_COMPONENT,
-							    prompt, "password", prompt_flags, NULL);
-			g_free (prompt);
-			g_free (errbuf);
-			errbuf = NULL;
+		if (!subscription_list && !(si->flags & CAMEL_MAPI_FOLDER_MAIL) && si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED &&
+												si->flags & CAMEL_MAPI_FOLDER_PUBLIC)
+			continue;
+		if (!strcmp(name, camel_mapi_store_info_full_name (mapi_store->summary, si))
+		     || match_path (path, camel_mapi_store_info_full_name (mapi_store->summary, si))) {
 
-			if (!service->url->passwd) {
-				g_set_error (
-					error, G_IO_ERROR,
-					G_IO_ERROR_CANCELLED,
-					_("You did not enter a password."));
-				return FALSE;
+			const gchar *store_info_path = camel_store_info_path((CamelStoreSummary *)mapi_store->summary, si);
+			gchar *parent_name = NULL;
+			const gchar *folder_name = NULL;
+
+			/* TODO : UTF8 / i18n*/
+			if (g_str_has_prefix (store_info_path, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) && subscribed) {
+				parent_name = DISPLAY_NAME_FAVOURITES;
+
+				folder_name = strrchr(store_info_path,'/');
+				if (folder_name != NULL)
+					store_info_path = ++folder_name;
+
+				favourites = TRUE;
 			}
-		}
 
-		store->priv->conn = exchange_mapi_connection_new (store->priv->profile, service->url->passwd, &mapi_error);
-		if (!store->priv->conn || !exchange_mapi_connection_connected (store->priv->conn)) {
-			if (mapi_error) {
-				errbuf = g_strdup_printf (_("Unable to authenticate to Exchange MAPI server: %s"), mapi_error->message);
-				g_error_free (mapi_error);
-			} else {
-				errbuf = g_strdup (_("Unable to authenticate to Exchange MAPI server"));
+			fi = mapi_build_folder_info(mapi_store, parent_name, store_info_path);
+			if (favourites) {
+				CamelURL *url;
+				url = camel_url_new(mapi_store->priv->base_url,NULL);
+				url->path = g_strdup_printf("/%s", camel_store_info_path((CamelStoreSummary *)mapi_store->summary, si));
+				g_free (fi->uri);
+				fi->uri = camel_url_to_string(url,CAMEL_URL_HIDE_ALL);
+				camel_url_free (url);
 			}
-		} else
-			authenticated = TRUE;
 
+			fi->unread = si->unread;
+			fi->total = si->total;
+			fi->flags = si->flags;
+
+			g_ptr_array_add (folders, fi);
+		}
+		camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
 	}
-	return TRUE;
+
+	if (!(subscription_list) && top[0] == '\0') {
+		fi = mapi_build_folder_info(mapi_store, NULL, DISPLAY_NAME_FAVOURITES);
+		fi->flags |= CAMEL_FOLDER_NOSELECT;
+		fi->flags |= CAMEL_FOLDER_SYSTEM;
+
+		g_ptr_array_add (folders, fi);
+	}
+
+	g_free(name);
+	g_free (path);
+	fi = camel_folder_info_build (folders, top, '/', TRUE);
+	g_ptr_array_free (folders, TRUE);
+	return fi;
 }
 
 static gboolean
-mapi_connect(CamelService *service, GError **error)
+mapi_forget_folder (CamelMapiStore *mapi_store, const gchar *folder_name, GError **error)
 {
-	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
-	CamelMapiStorePrivate *priv = store->priv;
-	guint16 event_mask = 0;
+	CamelMapiStorePrivate *priv = mapi_store->priv;
+	gchar *state_file;
+	gchar *folder_dir, *storage_path;
+	CamelFolderInfo *fi;
+	const gchar *name;
 
-	if (service->status == CAMEL_SERVICE_DISCONNECTED) {
-		return FALSE;
-	}
+	name = folder_name;
 
-	if (!priv) {
-		store->priv = g_new0 (CamelMapiStorePrivate, 1);
-		priv = store->priv;
-		if (!camel_service_construct (service, service->session, service->provider, service->url, error))
-			return FALSE;
-	}
+	storage_path = g_strdup_printf ("%s/folders", priv->storage_path);
 
-	camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
-	if (check_for_connection (service, NULL)) {
-		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
-		return TRUE;
-	}
+	/* Fixme Path - e_*-to_path */
+	folder_dir = g_strconcat (storage_path, "/", folder_name, NULL);
+	g_free (storage_path);
 
-	if (!mapi_auth_loop (service, error)) {
-		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
-		camel_service_disconnect (service, TRUE, NULL);
-		return FALSE;
+	if (g_access(folder_dir, F_OK) != 0) {
+		g_free(folder_dir);
+		return TRUE;
 	}
 
-	service->status = CAMEL_SERVICE_CONNECTED;
-	((CamelOfflineStore *) store)->state = CAMEL_OFFLINE_STORE_NETWORK_AVAIL;
-
-	/* Start event monitor */
-	event_mask = fnevNewMail | fnevObjectCreated | fnevObjectDeleted |
-		fnevObjectModified | fnevObjectMoved | fnevObjectCopied;
+	state_file = g_strdup_printf ("%s/cmeta", folder_dir);
+	g_unlink (state_file);
+	g_free (state_file);
 
-	/* use MAPI_LISTEN_NOTIFY=1 to enable notifications */
-	if (!store->priv->notification_data && g_getenv ("MAPI_LISTEN_NOTIFY") != NULL)
-		store->priv->notification_data = camel_mapi_notification_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE);
+	g_rmdir (folder_dir);
+	g_free (folder_dir);
 
-	camel_store_summary_save ((CamelStoreSummary *) store->summary);
+	camel_store_summary_remove_path ((CamelStoreSummary *)mapi_store->summary, folder_name);
+	camel_store_summary_save ((CamelStoreSummary *)mapi_store->summary);
 
-	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+	fi = mapi_build_folder_info (mapi_store, NULL, folder_name);
+	camel_store_folder_deleted (CAMEL_STORE (mapi_store), fi);
+	camel_folder_info_free (fi);
 
 	return TRUE;
 }
 
-void
-camel_mapi_store_unset_notification_data (CamelMapiStore *mstore)
+static void
+mapi_rename_folder_infos (CamelMapiStore *mapi_store, const gchar *old_name, const gchar *new_name)
 {
-	g_return_if_fail (mstore != NULL);
-	g_return_if_fail (CAMEL_IS_MAPI_STORE (mstore));
+	gint sz, i, olen;
+	CamelStoreInfo *si = NULL;
 
-	mstore->priv->notification_data = NULL;
+	g_return_if_fail (mapi_store != NULL);
+	g_return_if_fail (old_name != NULL);
+	g_return_if_fail (new_name != NULL);
+
+	olen = strlen (old_name);
+	sz = camel_store_summary_count ((CamelStoreSummary*) mapi_store->summary);
+	for (i = 0; i < sz; i++) {
+		const gchar *full_name;
+
+		si = camel_store_summary_index ((CamelStoreSummary *) mapi_store->summary, i);
+		if (!si)
+			continue;
+
+		full_name = camel_mapi_store_info_full_name (mapi_store->summary, si);
+		if (full_name && g_str_has_prefix (full_name, old_name) && !g_str_equal (full_name, old_name) &&
+		    full_name [olen] == '/' && full_name [olen + 1] != '\0') {
+			/* it's a subfolder of old_name */
+			const gchar *fid = camel_mapi_store_info_folder_id (mapi_store->summary, si);
+
+			if (fid) {
+				gchar *new_full_name;
+
+				/* do not remove it from name_hash yet, because this function
+				   will be called for it again */
+				/* g_hash_table_remove (mapi_store->priv->name_hash, full_name); */
+				g_hash_table_remove (mapi_store->priv->id_hash, fid);
+
+				/* parent is still the same, only the path changed */
+				new_full_name = g_strconcat (new_name, full_name + olen + (g_str_has_suffix (new_name, "/") ? 1 : 0), NULL);
+
+				mapi_update_folder_hash_tables (mapi_store, new_full_name, fid, NULL);
+
+				camel_store_info_set_string ((CamelStoreSummary *)mapi_store->summary, si, CAMEL_STORE_INFO_PATH, new_full_name);
+				camel_store_info_set_string ((CamelStoreSummary *)mapi_store->summary, si, CAMEL_MAPI_STORE_INFO_FULL_NAME, new_full_name);
+				camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
+
+				g_free (new_full_name);
+			}
+		}
+		camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
+	}
 }
 
-static gboolean
-mapi_disconnect(CamelService *service, gboolean clean, GError **error)
+static void
+mapi_store_dispose (GObject *object)
 {
-	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+	CamelMapiStorePrivate *priv;
 
-	/* Disconnect from event monitor */
-	if (store->priv->notification_data) {
-		camel_mapi_notification_listener_stop (store, store->priv->notification_data);
-		store->priv->notification_data = NULL;
-	}
+	priv = CAMEL_MAPI_STORE_GET_PRIVATE (object);
 
-	if (store->priv->conn) {
-		/* Close the mapi subsystem */
-		g_object_unref (store->priv->conn);
-		store->priv->conn = NULL;
+	if (priv->conn != NULL) {
+		g_object_unref (priv->conn);
+		priv->conn = NULL;
 	}
 
-	store->priv->folders_synced = FALSE;
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (camel_mapi_store_parent_class)->dispose (object);
+}
 
-	((CamelOfflineStore *) store)->state = CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL;
-	service->status = CAMEL_SERVICE_DISCONNECTED;
+static void
+mapi_store_finalize (GObject *object)
+{
+	CamelMapiStorePrivate *priv;
 
-	return TRUE;
+	priv = CAMEL_MAPI_STORE_GET_PRIVATE (object);
+
+	g_free (priv->profile);
+	g_free (priv->storage_path);
+	g_free (priv->base_url);
+
+	if (priv->id_hash != NULL)
+		g_hash_table_destroy (priv->id_hash);
+
+	if (priv->name_hash != NULL)
+		g_hash_table_destroy (priv->name_hash);
+
+	if (priv->parent_hash != NULL)
+		g_hash_table_destroy (priv->parent_hash);
+
+	if (priv->default_folders != NULL)
+		g_hash_table_destroy (priv->default_folders);
+	if (priv->container_hash != NULL)
+		g_hash_table_destroy (priv->container_hash);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (camel_mapi_store_parent_class)->finalize (object);
 }
 
-static GList *mapi_query_auth_types(CamelService *service, GError **error)
+static guint
+mapi_store_hash_folder_name (gconstpointer key)
 {
-	return NULL;
+	return g_str_hash(key);
 }
 
-static gboolean
-hash_check_fid_presence (gpointer key, gpointer value, gpointer folder_id)
+static gint
+mapi_store_compare_folder_name (gconstpointer a,
+                          gconstpointer b)
 {
-	return (g_ascii_strcasecmp (value, folder_id) == 0);
+	gconstpointer	aname = a;
+	gconstpointer	bname = b;
+
+	return g_str_equal(aname, bname);
 }
 
 static gboolean
-mapi_fid_is_system_folder (CamelMapiStore *mapi_store, const gchar *fid)
+mapi_store_can_refresh_folder (CamelStore *store,
+                               CamelFolderInfo *info,
+                               GError **error)
 {
-	CamelMapiStorePrivate *priv = mapi_store->priv;
-
-	if (!(fid && *fid))
-		return FALSE;
-
-	return (g_hash_table_find (priv->default_folders, hash_check_fid_presence, (gpointer) fid) != NULL);
+	return CAMEL_STORE_CLASS(camel_mapi_store_parent_class)->can_refresh_folder (store, info, error) ||
+	      (camel_url_get_param (((CamelService *)store)->url, "check_all") != NULL);
 }
 
-static const gchar *
-mapi_system_folder_fid (CamelMapiStore *mapi_store, gint folder_type)
+static gboolean
+mapi_store_folder_is_subscribed (CamelStore *store,
+                                 const gchar *folder_name)
 {
-	CamelMapiStorePrivate *priv = mapi_store->priv;
+	CamelMapiStore *mapi_store = (CamelMapiStore *) store;
+	CamelStoreInfo *si;
+	gint truth = FALSE;
 
-	return g_hash_table_lookup (priv->default_folders, &folder_type);
+	if ((si = camel_store_summary_path ((CamelStoreSummary *) mapi_store->summary, folder_name))) {
+		truth = (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) != 0;
+		camel_store_summary_info_free ((CamelStoreSummary *) mapi_store->summary, si);
+	}
+
+	return truth;
 }
 
 static CamelFolder *
-mapi_get_folder(CamelStore *store, const gchar *folder_name, guint32 flags, GError **error)
+mapi_store_get_folder_sync (CamelStore *store,
+                            const gchar *folder_name,
+                            guint32 flags,
+                            GCancellable *cancellable,
+                            GError **error)
 {
 	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
 	CamelMapiStorePrivate *priv = mapi_store->priv;
@@ -529,7 +867,8 @@ mapi_get_folder(CamelStore *store, const gchar *folder_name, guint32 flags, GErr
 			parent = tmp;
 		}
 
-		folder_info = mapi_create_folder (store, parent, name, error);
+		folder_info = mapi_store_create_folder_sync (
+			store, parent, name, cancellable, error);
 		g_free (tmp);
 
 		if (!folder_info)
@@ -549,7 +888,71 @@ mapi_get_folder(CamelStore *store, const gchar *folder_name, guint32 flags, GErr
 }
 
 static CamelFolderInfo*
-mapi_create_folder(CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error)
+mapi_store_get_folder_info_sync (CamelStore *store,
+                                 const gchar *top,
+                                 guint32 flags,
+                                 GCancellable *cancellable,
+                                 GError **error)
+{
+	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+
+	/*
+	 * Thanks to Michael, for his cached folders implementation in IMAP
+	 * is used as is here.
+	 */
+
+	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+	if (camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
+		if (((CamelService *)store)->status == CAMEL_SERVICE_DISCONNECTED) {
+			((CamelService *)store)->status = CAMEL_SERVICE_CONNECTING;
+			mapi_connect_sync ((CamelService *)store, cancellable, NULL);
+		}
+	}
+
+	/* update folders from the server only when asking for the top most or the 'top' is not known;
+	   otherwise believe the local cache, because folders sync is pretty slow operation to be done
+	   one every single question on the folder info */
+	if (((flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST) != 0 ||
+	     (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) ||
+	     (!mapi_store->priv->folders_synced) ||
+	     (top && *top && !camel_mapi_store_folder_id_lookup (mapi_store, top))) &&
+	    (check_for_connection ((CamelService *)store, NULL) || ((CamelService *)store)->status == CAMEL_SERVICE_CONNECTING)) {
+		if (!mapi_folders_sync (mapi_store, flags, error)) {
+			camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+			return NULL;
+		}
+		camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
+		camel_store_summary_save ((CamelStoreSummary *)mapi_store->summary);
+	}
+
+	camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+	return mapi_get_folder_info_offline (store, top, flags, error);
+}
+
+static CamelFolder *
+mapi_store_get_junk_folder_sync (CamelStore *store,
+                                 GCancellable *cancellable,
+                                 GError **error)
+{
+	return mapi_get_folder_with_type (store, CAMEL_FOLDER_TYPE_JUNK, cancellable, error);
+}
+
+static CamelFolder *
+mapi_store_get_trash_folder_sync (CamelStore *store,
+                                  GCancellable *cancellable,
+                                  GError **error)
+{
+	return mapi_get_folder_with_type (store, CAMEL_FOLDER_TYPE_TRASH, cancellable, error);
+}
+
+static CamelFolderInfo *
+mapi_store_create_folder_sync (CamelStore *store,
+                               const gchar *parent_name,
+                               const gchar *folder_name,
+                               GCancellable *cancellable,
+                               GError **error)
 {
 	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
 	CamelMapiStorePrivate  *priv = mapi_store->priv;
@@ -558,7 +961,7 @@ mapi_create_folder(CamelStore *store, const gchar *parent_name, const gchar *fol
 	mapi_id_t parent_fid, new_folder_id;
 	GError *mapi_error = NULL;
 
-	if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+	if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
 		g_set_error (
 			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
 			_("Cannot create MAPI folders in offline mode."));
@@ -578,7 +981,7 @@ mapi_create_folder(CamelStore *store, const gchar *parent_name, const gchar *fol
 	else
 		parent_id = g_strdup ("");
 
-	if (!mapi_connect (CAMEL_SERVICE(store), NULL)) {
+	if (!mapi_connect_sync (CAMEL_SERVICE(store), cancellable, NULL)) {
 		g_set_error (
 			error, CAMEL_SERVICE_ERROR,
 			CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
@@ -622,46 +1025,10 @@ mapi_create_folder(CamelStore *store, const gchar *parent_name, const gchar *fol
 }
 
 static gboolean
-mapi_forget_folder (CamelMapiStore *mapi_store, const gchar *folder_name, GError **error)
-{
-	CamelMapiStorePrivate *priv = mapi_store->priv;
-	gchar *state_file;
-	gchar *folder_dir, *storage_path;
-	CamelFolderInfo *fi;
-	const gchar *name;
-
-	name = folder_name;
-
-	storage_path = g_strdup_printf ("%s/folders", priv->storage_path);
-
-	/* Fixme Path - e_*-to_path */
-	folder_dir = g_strconcat (storage_path, "/", folder_name, NULL);
-	g_free (storage_path);
-
-	if (g_access(folder_dir, F_OK) != 0) {
-		g_free(folder_dir);
-		return TRUE;
-	}
-
-	state_file = g_strdup_printf ("%s/cmeta", folder_dir);
-	g_unlink (state_file);
-	g_free (state_file);
-
-	g_rmdir (folder_dir);
-	g_free (folder_dir);
-
-	camel_store_summary_remove_path ((CamelStoreSummary *)mapi_store->summary, folder_name);
-	camel_store_summary_save ((CamelStoreSummary *)mapi_store->summary);
-
-	fi = mapi_build_folder_info (mapi_store, NULL, folder_name);
-	camel_store_folder_deleted (CAMEL_STORE (mapi_store), fi);
-	camel_folder_info_free (fi);
-
-	return TRUE;
-}
-
-static gboolean
-mapi_delete_folder(CamelStore *store, const gchar *folder_name, GError **error)
+mapi_store_delete_folder_sync (CamelStore *store,
+                               const gchar *folder_name,
+                               GCancellable *cancellable,
+                               GError **error)
 {
 	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
 	CamelMapiStorePrivate  *priv = mapi_store->priv;
@@ -722,57 +1089,12 @@ mapi_delete_folder(CamelStore *store, const gchar *folder_name, GError **error)
 	return success;
 }
 
-static void
-mapi_rename_folder_infos (CamelMapiStore *mapi_store, const gchar *old_name, const gchar *new_name)
-{
-	gint sz, i, olen;
-	CamelStoreInfo *si = NULL;
-
-	g_return_if_fail (mapi_store != NULL);
-	g_return_if_fail (old_name != NULL);
-	g_return_if_fail (new_name != NULL);
-
-	olen = strlen (old_name);
-	sz = camel_store_summary_count ((CamelStoreSummary*) mapi_store->summary);
-	for (i = 0; i < sz; i++) {
-		const gchar *full_name;
-
-		si = camel_store_summary_index ((CamelStoreSummary *) mapi_store->summary, i);
-		if (!si)
-			continue;
-
-		full_name = camel_mapi_store_info_full_name (mapi_store->summary, si);
-		if (full_name && g_str_has_prefix (full_name, old_name) && !g_str_equal (full_name, old_name) &&
-		    full_name [olen] == '/' && full_name [olen + 1] != '\0') {
-			/* it's a subfolder of old_name */
-			const gchar *fid = camel_mapi_store_info_folder_id (mapi_store->summary, si);
-
-			if (fid) {
-				gchar *new_full_name;
-
-				/* do not remove it from name_hash yet, because this function
-				   will be called for it again */
-				/* g_hash_table_remove (mapi_store->priv->name_hash, full_name); */
-				g_hash_table_remove (mapi_store->priv->id_hash, fid);
-
-				/* parent is still the same, only the path changed */
-				new_full_name = g_strconcat (new_name, full_name + olen + (g_str_has_suffix (new_name, "/") ? 1 : 0), NULL);
-
-				mapi_update_folder_hash_tables (mapi_store, new_full_name, fid, NULL);
-
-				camel_store_info_set_string ((CamelStoreSummary *)mapi_store->summary, si, CAMEL_STORE_INFO_PATH, new_full_name);
-				camel_store_info_set_string ((CamelStoreSummary *)mapi_store->summary, si, CAMEL_MAPI_STORE_INFO_FULL_NAME, new_full_name);
-				camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
-
-				g_free (new_full_name);
-			}
-		}
-		camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
-	}
-}
-
 static gboolean
-mapi_rename_folder(CamelStore *store, const gchar *old_name, const gchar *new_name, GError **error)
+mapi_store_rename_folder_sync (CamelStore *store,
+                               const gchar *old_name,
+                               const gchar *new_name,
+                               GCancellable *cancellable,
+                               GError **error)
 {
 	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
 	CamelMapiStorePrivate  *priv = mapi_store->priv;
@@ -985,6 +1307,429 @@ mapi_rename_folder(CamelStore *store, const gchar *old_name, const gchar *new_na
 	return TRUE;
 }
 
+static gboolean
+mapi_store_subscribe_folder_sync (CamelStore *store,
+                                  const gchar *folder_name,
+                                  GCancellable *cancellable,
+                                  GError **error)
+{
+	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+	CamelFolderInfo *fi;
+	CamelStoreInfo *si = NULL;
+	const gchar *parent_name = NULL, *use_folder_name = folder_name, *fid = NULL;
+	gboolean favourites = FALSE;
+	/* TODO : exchange_mapi_add_to_favorites (); */
+
+	fid = camel_mapi_store_folder_id_lookup(mapi_store, folder_name);
+
+	if (g_str_has_prefix (folder_name, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) ) {
+		const gchar *f_name = NULL;
+
+		parent_name = DISPLAY_NAME_FAVOURITES;
+
+		f_name = strrchr (folder_name,'/');
+		if (!f_name) {
+			/* Don't process All Public Folder. */
+			return TRUE;
+		}
+
+		use_folder_name = ++f_name;
+		favourites = TRUE;
+	}
+	si = camel_store_summary_path((CamelStoreSummary *)mapi_store->summary, folder_name);
+
+	if (si != NULL) {
+		if ((si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) == 0) {
+			si->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+			si->flags |= CAMEL_FOLDER_SUBSCRIBED;
+			camel_store_summary_touch((CamelStoreSummary *)mapi_store->summary);
+		}
+	}
+
+	if (si->flags & CAMEL_MAPI_FOLDER_MAIL) {
+		fi = mapi_build_folder_info (mapi_store, parent_name, use_folder_name);
+		if (favourites) {
+			CamelURL *url;
+			url = camel_url_new (mapi_store->priv->base_url, NULL);
+			url->path = g_strdup_printf ("/%s", camel_store_info_path (mapi_store->summary, si));
+			g_free (fi->uri);
+			fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
+			camel_url_free (url);
+		}
+
+		fi->unread = si->unread;
+		fi->total = si->total;
+		fi->flags = si->flags;
+		fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
+		fi->flags |= CAMEL_FOLDER_NOCHILDREN;
+		fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+		camel_store_folder_subscribed (store, fi);
+		camel_folder_info_free (fi);
+	} else {
+		guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, folder_name);
+		exchange_mapi_add_esource (CAMEL_SERVICE(mapi_store)->url, use_folder_name, fid, folder_type);
+	}
+	camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
+	return TRUE;
+}
+
+static gboolean
+mapi_store_unsubscribe_folder_sync (CamelStore *store,
+                                    const gchar *folder_name,
+                                    GCancellable *cancellable,
+                                    GError **error)
+{
+	CamelFolderInfo *fi;
+	CamelStoreInfo *si;
+	gchar *parent_name = NULL;
+	const gchar *fid = NULL, *use_folder_name = folder_name;
+	gchar *f_name = NULL;
+
+	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+	CamelURL *url = CAMEL_SERVICE (mapi_store)->url;
+	fid = camel_mapi_store_folder_id_lookup(mapi_store, folder_name);
+	si = camel_store_summary_path((CamelStoreSummary *)mapi_store->summary, folder_name);
+	if (si) {
+		if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
+			si->flags &= ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+			camel_store_summary_touch((CamelStoreSummary *)mapi_store->summary);
+			camel_store_summary_save((CamelStoreSummary *)mapi_store->summary);
+		}
+	}
+
+	if (g_str_has_prefix (folder_name, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) ) {
+		parent_name = DISPLAY_NAME_FAVOURITES;
+
+		f_name = strrchr(folder_name,'/');
+		if (f_name != NULL)
+			folder_name = ++f_name;
+		else //Don't process All Public Folder.
+			return TRUE;
+	}
+	if (si->flags & CAMEL_MAPI_FOLDER_MAIL) {
+		fi = mapi_build_folder_info (mapi_store, parent_name, folder_name);
+		camel_store_folder_unsubscribed (store, fi);
+		camel_folder_info_free (fi);
+	} else {
+		guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, use_folder_name);
+		exchange_mapi_remove_esource(url, folder_name, fid, folder_type);
+	}
+	camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
+
+	return TRUE;
+}
+
+static gboolean
+mapi_store_noop_sync (CamelStore *store,
+                      GCancellable *cancellable,
+                      GError **error)
+{
+	return TRUE;
+}
+
+static void
+camel_mapi_store_class_init (CamelMapiStoreClass *class)
+{
+	GObjectClass *object_class;
+	CamelServiceClass *service_class;
+	CamelStoreClass *store_class;
+
+	g_type_class_add_private (class, sizeof (CamelMapiStorePrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->dispose = mapi_store_dispose;
+	object_class->finalize = mapi_store_finalize;
+
+	service_class = CAMEL_SERVICE_CLASS (class);
+	service_class->construct = mapi_construct;
+	service_class->get_name = mapi_get_name;
+	service_class->connect_sync = mapi_connect_sync;
+	service_class->disconnect_sync = mapi_disconnect_sync;
+	service_class->query_auth_types_sync = mapi_query_auth_types_sync;
+
+	store_class = CAMEL_STORE_CLASS (class);
+	store_class->hash_folder_name = mapi_store_hash_folder_name;
+	store_class->compare_folder_name = mapi_store_compare_folder_name;
+	store_class->can_refresh_folder = mapi_store_can_refresh_folder;
+	store_class->folder_is_subscribed = mapi_store_folder_is_subscribed;
+	store_class->free_folder_info = camel_store_free_folder_info_full;
+	store_class->get_folder_sync = mapi_store_get_folder_sync;
+	store_class->get_folder_info_sync = mapi_store_get_folder_info_sync;
+	store_class->get_junk_folder_sync = mapi_store_get_junk_folder_sync;
+	store_class->get_trash_folder_sync = mapi_store_get_trash_folder_sync;
+	store_class->create_folder_sync = mapi_store_create_folder_sync;
+	store_class->delete_folder_sync = mapi_store_delete_folder_sync;
+	store_class->rename_folder_sync = mapi_store_rename_folder_sync;
+	store_class->subscribe_folder_sync = mapi_store_subscribe_folder_sync;
+	store_class->unsubscribe_folder_sync = mapi_store_unsubscribe_folder_sync;
+	store_class->noop_sync = mapi_store_noop_sync;
+}
+
+/*
+** store is already initilyse to NULL or 0 value
+** class already have a parent_class
+** nothing must be doing here
+*/
+static void
+camel_mapi_store_init (CamelMapiStore *mapi_store)
+{
+	mapi_store->priv = CAMEL_MAPI_STORE_GET_PRIVATE (mapi_store);
+}
+
+/* service methods */
+static gboolean mapi_construct(CamelService *service, CamelSession *session,
+				 CamelProvider *provider, CamelURL *url,
+				 GError **error)
+{
+	CamelMapiStore	*mapi_store = CAMEL_MAPI_STORE (service);
+	CamelStore *store = CAMEL_STORE (service);
+	CamelMapiStorePrivate *priv = mapi_store->priv;
+	gchar *path = NULL;
+
+	if (!CAMEL_SERVICE_CLASS (camel_mapi_store_parent_class)->construct (service, session, provider, url, error))
+		return FALSE;
+
+	/*storage path*/
+	priv->storage_path = camel_session_get_storage_path (session, service, error);
+	if (!priv->storage_path)
+		return FALSE;
+
+	/*store summary*/
+	path = g_alloca (strlen (priv->storage_path) + 32);
+	sprintf (path, "%s/.summary", priv->storage_path);
+
+	mapi_store->summary = camel_mapi_store_summary_new ();
+	camel_store_summary_set_filename ((CamelStoreSummary *)mapi_store->summary, path);
+
+	camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
+	camel_store_summary_load ((CamelStoreSummary *) mapi_store->summary);
+
+	/*user and profile*/
+	priv->profile = g_strdup (camel_url_get_param(url, "profile"));
+
+	/*base url*/
+	priv->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD |
+						       CAMEL_URL_HIDE_PARAMS   |
+						       CAMEL_URL_HIDE_AUTH)  );
+
+	/*filter*/
+	if (camel_url_get_param (url, "filter"))
+		store->flags |= CAMEL_STORE_FILTER_INBOX;
+
+	/*Hash Table*/
+	priv->id_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* folder ID to folder Full name */
+	priv->name_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* folder Full name to folder ID */
+	/*priv->parent_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); / * folder ID to its parent folder ID */
+	priv->default_folders = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_free); /* default folder type to folder ID */
+	priv->container_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+	store->flags &= ~CAMEL_STORE_VJUNK;
+	store->flags &= ~CAMEL_STORE_VTRASH;
+
+	store->flags |= CAMEL_STORE_SUBSCRIPTIONS | CAMEL_STORE_REAL_JUNK_FOLDER;
+
+	return TRUE;
+}
+
+static char
+*mapi_get_name(CamelService *service, gboolean brief)
+{
+	if (brief) {
+		/* Translators: The %s is replaced with a server's host name */
+		return g_strdup_printf(_("Exchange MAPI server %s"), service->url->host);
+	} else {
+		/*To translators : Example string : Exchange MAPI service for
+		  _username_ on _server host name__*/
+		return g_strdup_printf(_("Exchange MAPI service for %s on %s"),
+				       service->url->user, service->url->host);
+	}
+}
+
+static gboolean
+mapi_auth_loop (CamelService *service, GError **error)
+{
+	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+	CamelSession *session = camel_service_get_session (service);
+
+	gchar *errbuf = NULL;
+	gboolean authenticated = FALSE;
+	guint32 prompt_flags = CAMEL_SESSION_PASSWORD_SECRET;
+
+	service->url->passwd = NULL;
+
+	while (!authenticated) {
+		GError *mapi_error = NULL;
+
+		if (errbuf) {
+			/* We need to un-cache the password before prompting again */
+			prompt_flags |= CAMEL_SESSION_PASSWORD_REPROMPT;
+			g_free (service->url->passwd);
+			service->url->passwd = NULL;
+		}
+
+		if (!service->url->passwd ) {
+			gchar *prompt;
+
+			/*To translators : First %s : is the error text or the reason
+			  for prompting the user if it is available.
+			 Second %s is : Username.
+			 Third %s is : Server host name.*/
+			prompt = g_strdup_printf (_("%s Please enter the MAPI password for %s %s"),
+						  errbuf ? errbuf : "",
+						  service->url->user,
+						  service->url->host);
+			service->url->passwd =
+				camel_session_get_password (session, service, E_PASSWORD_COMPONENT,
+							    prompt, "password", prompt_flags, NULL);
+			g_free (prompt);
+			g_free (errbuf);
+			errbuf = NULL;
+
+			if (!service->url->passwd) {
+				g_set_error (
+					error, G_IO_ERROR,
+					G_IO_ERROR_CANCELLED,
+					_("You did not enter a password."));
+				return FALSE;
+			}
+		}
+
+		store->priv->conn = exchange_mapi_connection_new (store->priv->profile, service->url->passwd, &mapi_error);
+		if (!store->priv->conn || !exchange_mapi_connection_connected (store->priv->conn)) {
+			if (mapi_error) {
+				errbuf = g_strdup_printf (_("Unable to authenticate to Exchange MAPI server: %s"), mapi_error->message);
+				g_error_free (mapi_error);
+			} else {
+				errbuf = g_strdup (_("Unable to authenticate to Exchange MAPI server"));
+			}
+		} else
+			authenticated = TRUE;
+
+	}
+	return TRUE;
+}
+
+static gboolean
+mapi_connect_sync (CamelService *service,
+                   GCancellable *cancellable,
+                   GError **error)
+{
+	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+	CamelMapiStorePrivate *priv = store->priv;
+	guint16 event_mask = 0;
+
+	if (service->status == CAMEL_SERVICE_DISCONNECTED) {
+		return FALSE;
+	}
+
+	if (!priv) {
+		store->priv = g_new0 (CamelMapiStorePrivate, 1);
+		priv = store->priv;
+		if (!camel_service_construct (service, service->session, service->provider, service->url, error))
+			return FALSE;
+	}
+
+	camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+	if (check_for_connection (service, NULL)) {
+		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+		return TRUE;
+	}
+
+	if (!mapi_auth_loop (service, error)) {
+		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+		camel_service_disconnect_sync (service, TRUE, NULL);
+		return FALSE;
+	}
+
+	service->status = CAMEL_SERVICE_CONNECTED;
+	camel_offline_store_set_online_sync (
+		CAMEL_OFFLINE_STORE (store), TRUE, cancellable, NULL);
+
+	/* Start event monitor */
+	event_mask = fnevNewMail | fnevObjectCreated | fnevObjectDeleted |
+		fnevObjectModified | fnevObjectMoved | fnevObjectCopied;
+
+	/* use MAPI_LISTEN_NOTIFY=1 to enable notifications */
+	if (!store->priv->notification_data && g_getenv ("MAPI_LISTEN_NOTIFY") != NULL)
+		store->priv->notification_data = camel_mapi_notification_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE);
+
+	camel_store_summary_save ((CamelStoreSummary *) store->summary);
+
+	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+	return TRUE;
+}
+
+void
+camel_mapi_store_unset_notification_data (CamelMapiStore *mstore)
+{
+	g_return_if_fail (mstore != NULL);
+	g_return_if_fail (CAMEL_IS_MAPI_STORE (mstore));
+
+	mstore->priv->notification_data = NULL;
+}
+
+static gboolean
+mapi_disconnect_sync (CamelService *service,
+                      gboolean clean,
+                      GCancellable *cancellable,
+                      GError **error)
+{
+	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+
+	/* Disconnect from event monitor */
+	if (store->priv->notification_data) {
+		camel_mapi_notification_listener_stop (store, store->priv->notification_data);
+		store->priv->notification_data = NULL;
+	}
+
+	if (store->priv->conn) {
+		/* Close the mapi subsystem */
+		g_object_unref (store->priv->conn);
+		store->priv->conn = NULL;
+	}
+
+	store->priv->folders_synced = FALSE;
+
+	camel_offline_store_set_online_sync (
+		CAMEL_OFFLINE_STORE (store), FALSE, cancellable, NULL);
+	service->status = CAMEL_SERVICE_DISCONNECTED;
+
+	return TRUE;
+}
+
+static GList *
+mapi_query_auth_types_sync (CamelService *service,
+                            GCancellable *cancellable,
+                            GError **error)
+{
+	return NULL;
+}
+
+static gboolean
+hash_check_fid_presence (gpointer key, gpointer value, gpointer folder_id)
+{
+	return (g_ascii_strcasecmp (value, folder_id) == 0);
+}
+
+static gboolean
+mapi_fid_is_system_folder (CamelMapiStore *mapi_store, const gchar *fid)
+{
+	CamelMapiStorePrivate *priv = mapi_store->priv;
+
+	if (!(fid && *fid))
+		return FALSE;
+
+	return (g_hash_table_find (priv->default_folders, hash_check_fid_presence, (gpointer) fid) != NULL);
+}
+
+static const gchar *
+mapi_system_folder_fid (CamelMapiStore *mapi_store, gint folder_type)
+{
+	CamelMapiStorePrivate *priv = mapi_store->priv;
+
+	return g_hash_table_lookup (priv->default_folders, &folder_type);
+}
+
 static guint32 hexnib(guint32 c)
 {
 	if (c >= '0' && c <= '9')
@@ -1066,45 +1811,6 @@ camel_mapi_store_summary_path_to_full(CamelMapiStoreSummary *s, const gchar *pat
 	return f;
 }
 
-//do we realy need this. move to utils then !
-static gint
-match_path(const gchar *path, const gchar *name)
-{
-	gchar p, n;
-
-	p = *path++;
-	n = *name++;
-	while (n && p) {
-		if (n == p) {
-			p = *path++;
-			n = *name++;
-		} else if (p == '%') {
-			if (n != '/') {
-				n = *name++;
-			} else {
-				p = *path++;
-			}
-		} else if (p == '*') {
-			return TRUE;
-		} else
-			return FALSE;
-	}
-
-	return n == 0 && (p == '%' || p == 0);
-}
-
-static gchar *
-mapi_concat ( const gchar *prefix, const gchar *suffix)
-{
-	gsize len;
-
-	len = strlen (prefix);
-	if (len == 0 || prefix[len - 1] == '/')
-		return g_strdup_printf ("%s%s", prefix, suffix);
-	else
-		return g_strdup_printf ("%s%c%s", prefix, '/', suffix);
-}
-
 static CamelFolderInfo *
 mapi_build_folder_info(CamelMapiStore *mapi_store, const gchar *parent_name, const gchar *folder_name)
 {
@@ -1145,197 +1851,11 @@ mapi_build_folder_info(CamelMapiStore *mapi_store, const gchar *parent_name, con
 	return fi;
 }
 
-static CamelFolderInfo *
-mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
-			 guint32 flags, GError **error)
-{
-	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
-	CamelFolderInfo *fi;
-	GPtrArray *folders;
-	gchar *path, *name;
-	gint i;
-	gboolean subscribed, favourites = FALSE, subscription_list = FALSE;
-
-	subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
-	subscribed = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED);
-
-	folders = g_ptr_array_new ();
-
-	if (top == NULL)
-		top = "";
-
-	/* get starting point */
-	if (top[0] == 0) {
-			name = g_strdup("");
-	} else {
-		name = camel_mapi_store_summary_full_from_path(mapi_store->summary, top);
-		if (name == NULL)
-			name = camel_mapi_store_summary_path_to_full(mapi_store->summary, top, '/');
-	}
-
-	path = mapi_concat (name, "*");
-
-	for (i=0;i<camel_store_summary_count((CamelStoreSummary *)mapi_store->summary);i++) {
-		CamelStoreInfo *si = camel_store_summary_index((CamelStoreSummary *)mapi_store->summary, i);
-
-		if (si == NULL)
-			continue;
-
-		/* Allow only All Public Folders heirarchy */
-		if (subscription_list && (!(si->flags & CAMEL_MAPI_FOLDER_PUBLIC))) {
-			camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
-			continue;
-		}
-
-		/*Allow Mailbox and Favourites (Subscribed public folders)*/
-		if (subscribed && (!(si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED))) {
-			camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
-			continue;
-		}
-
-		if (!subscription_list && !(si->flags & CAMEL_MAPI_FOLDER_MAIL) && si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED &&
-												si->flags & CAMEL_MAPI_FOLDER_PUBLIC)
-			continue;
-		if (!strcmp(name, camel_mapi_store_info_full_name (mapi_store->summary, si))
-		     || match_path (path, camel_mapi_store_info_full_name (mapi_store->summary, si))) {
-
-			const gchar *store_info_path = camel_store_info_path((CamelStoreSummary *)mapi_store->summary, si);
-			gchar *parent_name = NULL;
-			const gchar *folder_name = NULL;
-
-			/* TODO : UTF8 / i18n*/
-			if (g_str_has_prefix (store_info_path, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) && subscribed) {
-				parent_name = DISPLAY_NAME_FAVOURITES;
-
-				folder_name = strrchr(store_info_path,'/');
-				if (folder_name != NULL)
-					store_info_path = ++folder_name;
-
-				favourites = TRUE;
-			}
-
-			fi = mapi_build_folder_info(mapi_store, parent_name, store_info_path);
-			if (favourites) {
-				CamelURL *url;
-				url = camel_url_new(mapi_store->priv->base_url,NULL);
-				url->path = g_strdup_printf("/%s", camel_store_info_path((CamelStoreSummary *)mapi_store->summary, si));
-				g_free (fi->uri);
-				fi->uri = camel_url_to_string(url,CAMEL_URL_HIDE_ALL);
-				camel_url_free (url);
-			}
-
-			fi->unread = si->unread;
-			fi->total = si->total;
-			fi->flags = si->flags;
-
-			g_ptr_array_add (folders, fi);
-		}
-		camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
-	}
-
-	if (!(subscription_list) && top[0] == '\0') {
-		fi = mapi_build_folder_info(mapi_store, NULL, DISPLAY_NAME_FAVOURITES);
-		fi->flags |= CAMEL_FOLDER_NOSELECT;
-		fi->flags |= CAMEL_FOLDER_SYSTEM;
-
-		g_ptr_array_add (folders, fi);
-	}
-
-	g_free(name);
-	g_free (path);
-	fi = camel_folder_info_build (folders, top, '/', TRUE);
-	g_ptr_array_free (folders, TRUE);
-	return fi;
-}
-
-static CamelFolderInfo *
-mapi_convert_to_folder_info (CamelMapiStore *store, ExchangeMAPIFolder *folder, const gchar *url, GError **error)
-{
-	const gchar *name = NULL;
-	gchar *parent, *id = NULL;
-	mapi_id_t mapi_id_folder;
-
-	const gchar *par_name = NULL;
-	CamelFolderInfo *fi;
-
-	name = exchange_mapi_folder_get_name (folder);
-
-	id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_fid (folder));
-
-	fi = camel_folder_info_new ();
-
-	if (folder->is_default) {
-		switch (folder->default_type) {
-		case olFolderTopInformationStore:
-			fi->flags |= CAMEL_FOLDER_NOSELECT;
-			break;
-		case olFolderInbox:
-			fi->flags |= CAMEL_FOLDER_TYPE_INBOX;
-			break;
-		case olFolderSentMail:
-			fi->flags |= CAMEL_FOLDER_TYPE_SENT;
-			break;
-		case olFolderDeletedItems:
-			fi->flags |= CAMEL_FOLDER_TYPE_TRASH;
-			break;
-		case olFolderOutbox:
-			fi->flags |= CAMEL_FOLDER_TYPE_OUTBOX;
-			break;
-		case olFolderJunk:
-			fi->flags |= CAMEL_FOLDER_TYPE_JUNK;
-			break;
-		}
-
-		fi->flags |= CAMEL_FOLDER_SYSTEM;
-	}
-
-	if (folder->category == MAPI_PERSONAL_FOLDER) {
-		fi->flags |= CAMEL_MAPI_FOLDER_PERSONAL;
-		fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED; /*Set this default for mailbox.*/
-	} else if (folder->category == MAPI_FAVOURITE_FOLDER)
-		fi->flags |= CAMEL_MAPI_FOLDER_PUBLIC;
-
-	if (folder->child_count <=0)
-		fi->flags |= CAMEL_FOLDER_NOCHILDREN;
-	/*
-	   parent_hash contains the "parent id <-> folder id" combination. So we form
-	   the path for the full name in camelfolder info by looking up the hash table until
-	   NULL is found
-	 */
-
-	mapi_id_folder = exchange_mapi_folder_get_parent_id (folder);
-	parent = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", mapi_id_folder);
-
-	fi->name =  g_strdup (name);
-
-	par_name = mapi_folders_hash_table_name_lookup (store, parent, TRUE);
-	if (par_name != NULL) {
-		gchar *str = g_strconcat (par_name, "/", name, NULL);
-
-		fi->full_name = str; /* takes ownership of the string */
-		fi->uri = g_strconcat (url, str, NULL);
-	} else {
-		fi->full_name = g_strdup (name);
-		fi->uri = g_strconcat (url, "", name, NULL);
-	}
-
-	/*name_hash returns the container id given the name */
-	mapi_update_folder_hash_tables (store, fi->full_name, id, parent);
-
-	g_free (parent);
-	g_free (id);
-
-	fi->total = folder->total;
-	fi->unread = folder->unread_count;
-
-	return fi;
-}
-
 gboolean
 camel_mapi_store_connected (CamelMapiStore *store, GError **error)
 {
-	return (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL
-	    && camel_service_connect ((CamelService *)store, error));
+	return camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))
+	    && camel_service_connect_sync ((CamelService *)store, error);
 }
 
 static void
@@ -1430,288 +1950,6 @@ mapi_folders_hash_table_fid_lookup (CamelMapiStore *store, const gchar *name,
 }
 #endif
 
-static void
-remove_path_from_store_summary (const gchar *path, gpointer value, CamelMapiStore *mstore)
-{
-	const gchar *folder_id;
-	CamelStoreInfo *si;
-
-	g_return_if_fail (path != NULL);
-	g_return_if_fail (mstore != NULL);
-
-	folder_id = g_hash_table_lookup (mstore->priv->name_hash, path);
-	if (folder_id) {
-		/* name_hash as the second, because folder_id is from there */
-		g_hash_table_remove (mstore->priv->id_hash, folder_id);
-		g_hash_table_remove (mstore->priv->name_hash, path);
-	}
-
-	si = camel_store_summary_path ((CamelStoreSummary *)mstore->summary, path);
-	if (si) {
-		CamelFolderInfo *fi;
-
-		fi = camel_folder_info_new ();
-		fi->unread = -1;
-		fi->total = -1;
-		fi->uri = g_strdup (camel_store_info_uri (mstore->summary, si));
-		fi->name = g_strdup (camel_store_info_name (mstore->summary, si));
-		fi->full_name = g_strdup (camel_mapi_store_info_full_name (mstore->summary, si));
-		if (!fi->name && fi->full_name) {
-			fi->name = strrchr (fi->full_name, '/');
-			if (fi->name)
-				fi->name = g_strdup (fi->name + 1);
-		}
-
-		camel_store_folder_unsubscribed (CAMEL_STORE (mstore), fi);
-		camel_store_folder_deleted (CAMEL_STORE (mstore), fi);
-		camel_folder_info_free (fi);
-
-		camel_store_summary_info_free ((CamelStoreSummary *)mstore->summary, si);
-	}
-
-	camel_store_summary_remove_path ((CamelStoreSummary *)mstore->summary, path);
-}
-
-static gboolean
-mapi_folders_sync (CamelMapiStore *store, guint32 flags, GError **error)
-{
-	CamelMapiStorePrivate  *priv = store->priv;
-	gboolean status;
-	GSList *folder_list = NULL, *temp_list = NULL, *list = NULL;
-	gchar *url, *temp_url;
-	gboolean subscription_list = FALSE;
-	CamelFolderInfo *info = NULL;
-	CamelMapiStoreInfo *mapi_si = NULL;
-	guint32 count, i;
-	CamelStoreInfo *si = NULL;
-	GHashTable *old_cache_folders;
-	GError *err = NULL;
-
-	if (!camel_mapi_store_connected (store, NULL)) {
-		g_set_error (
-			error, CAMEL_SERVICE_ERROR,
-			CAMEL_SERVICE_ERROR_UNAVAILABLE,
-			_("Folder list not available in offline mode."));
-		return FALSE;
-	}
-
-	status = exchange_mapi_connection_get_folders_list (priv->conn, &folder_list, &err);
-
-	if (!status) {
-		g_warning ("Could not get folder list (%s)\n", err ? err->message : "Unknown error");
-		if (err)
-			g_error_free (err);
-		return TRUE;
-	}
-
-	/* remember all folders in cache before update */
-	old_cache_folders = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-	count = camel_store_summary_count ((CamelStoreSummary *)store->summary);
-	for (i = 0; i < count; i++) {
-		si = camel_store_summary_index ((CamelStoreSummary *)store->summary, i);
-		if (si == NULL)
-			continue;
-
-		/* those whose left in old_cache_folders are removed at the end,
-		   which is not good for public folders, thus preserve them from
-		   an automatic removal */
-		if ((si->flags & CAMEL_MAPI_FOLDER_PUBLIC) == 0 || (si->flags & CAMEL_FOLDER_SUBSCRIBED) == 0)
-			g_hash_table_insert (old_cache_folders, g_strdup (camel_store_info_path (store->summary, si)), GINT_TO_POINTER (1));
-
-		camel_store_summary_info_free ((CamelStoreSummary *)store->summary, si);
-	}
-
-	subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
-	if (subscription_list) {
-		GError *err = NULL;
-
-		/*Consult the name <-> fid hash table for a FID.*/
-		status = exchange_mapi_connection_get_pf_folders_list (priv->conn, &folder_list, &err);
-		if (!status)
-			g_warning ("Could not get Public folder list (%s)\n", err ? err->message : "Unknown error");
-
-		if (err)
-			g_error_free (err);
-	}
-
-	temp_list = folder_list;
-	list = folder_list;
-
-	url = camel_url_to_string (CAMEL_SERVICE(store)->url,
-				   (CAMEL_URL_HIDE_PASSWORD|
-				    CAMEL_URL_HIDE_PARAMS|
-				    CAMEL_URL_HIDE_AUTH));
-	if ( url[strlen(url) - 1] != '/') {
-		temp_url = g_strconcat (url, "/", NULL);
-		g_free ((gchar *)url);
-		url = temp_url;
-	}
-
-	/*populate the hash table for finding the mapping from container id <-> folder name*/
-	for (;temp_list != NULL; temp_list = g_slist_next (temp_list) ) {
-		const gchar *full_name = NULL;
-		gchar *fid = NULL, *parent_id = NULL, *tmp = NULL;
-		guint *folder_type = g_new0 (guint, 1);
-
-		fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(temp_list->data)));
-		parent_id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_parent_id ((ExchangeMAPIFolder *)(temp_list->data)));
-		full_name = g_hash_table_lookup (priv->id_hash, fid);
-		if (!full_name) {
-			const gchar *par_full_name;
-
-			par_full_name = g_hash_table_lookup (priv->id_hash, parent_id);
-			if (par_full_name) {
-				tmp = g_strconcat (par_full_name, "/", exchange_mapi_folder_get_name (temp_list->data), NULL);
-				full_name = tmp;
-			} else {
-				full_name = exchange_mapi_folder_get_name (temp_list->data);
-			}
-		}
-
-		/* remove from here; what lefts is not on the server any more */
-		g_hash_table_remove (old_cache_folders, full_name);
-		*folder_type = ((ExchangeMAPIFolder *)(temp_list->data))->container_class;
-		mapi_update_folder_hash_tables (store, full_name, fid, parent_id);
-		mapi_update_hash_table_type (store, full_name, folder_type);
-		if (((ExchangeMAPIFolder *)(temp_list->data))->is_default) {
-			guint *type = g_new0 (guint, 1);
-			*type = ((ExchangeMAPIFolder *)(temp_list->data))->default_type;
-			g_hash_table_insert (priv->default_folders, type,
-					     g_strdup(fid));
-		}
-		g_free (fid);
-		g_free (parent_id);
-		g_free (tmp);
-	}
-
-	for (;folder_list != NULL; folder_list = g_slist_next (folder_list)) {
-		ExchangeMAPIFolder *folder = (ExchangeMAPIFolder *) folder_list->data;
-
-		if (folder->default_type == olPublicFoldersAllPublicFolders)
-			continue;
-
-		if ( folder->container_class == MAPI_FOLDER_TYPE_MAIL) {
-			info = mapi_convert_to_folder_info (store, folder, (const gchar *)url, NULL);
-			info->flags |= CAMEL_MAPI_FOLDER_MAIL;
-			mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name);
-
-			if (!mapi_si) {
-				gchar *fid, *pfid = NULL;
-
-				fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
-						       exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
-				pfid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
-							exchange_mapi_folder_get_parent_id((ExchangeMAPIFolder *)(folder_list->data)));
-
-				mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/', fid, pfid);
-				g_free (fid);
-				g_free (pfid);
-				if (mapi_si == NULL)
-					continue;
-
-				camel_store_summary_info_ref ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
-
-				if (!subscription_list) {
-					camel_store_folder_created (CAMEL_STORE (store), info);
-					camel_store_folder_subscribed (CAMEL_STORE (store), info);
-				}
-			}
-
-			mapi_si->info.flags |= info->flags;
-			mapi_si->info.total = info->total;
-			mapi_si->info.unread = info->unread;
-
-			camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
-			camel_folder_info_free (info);
-		} else if (folder->category == MAPI_FAVOURITE_FOLDER) {
-			gchar *fid, *pfid = NULL;
-			info = mapi_convert_to_folder_info (store, folder, (const gchar *)url, NULL);
-			mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name);
-			fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
-						exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
-			pfid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
-						exchange_mapi_folder_get_parent_id((ExchangeMAPIFolder *)(folder_list->data)));
-			mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/', fid, pfid);
-			g_free (fid);
-			g_free (pfid);
-
-			if (mapi_si == NULL)
-				continue;
-
-			camel_store_summary_info_ref ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
-			mapi_si->info.flags |= info->flags;
-			camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
-			camel_folder_info_free (info);
-		}
-	}
-
-	/* Weed out deleted folders */
-	g_hash_table_foreach (old_cache_folders, (GHFunc) remove_path_from_store_summary, store);
-	g_hash_table_destroy (old_cache_folders);
-
-	camel_store_summary_touch ((CamelStoreSummary *)store->summary);
-	camel_store_summary_save ((CamelStoreSummary *)store->summary);
-
-	g_free (url);
-
-	g_slist_foreach (list, (GFunc) exchange_mapi_folder_free, NULL);
-	g_slist_free (list);
-
-	priv->folders_synced = TRUE;
-
-	//	g_hash_table_foreach (present, get_folders_free, NULL);
-	//	g_hash_table_destroy (present);
-
-	/* FIXME : This place is not right! */
-	/* Start Push Notification listener */
-	/* event_mask = fnevNewMail | fnevObjectCreated | fnevObjectDeleted | */
-	/*	fnevObjectModified | fnevObjectMoved | fnevObjectCopied; */
-
-	/* camel_mapi_notfication_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE); */
-
-	return TRUE;
-}
-
-static CamelFolderInfo*
-mapi_get_folder_info(CamelStore *store, const gchar *top, guint32 flags, GError **error)
-{
-	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
-
-	/*
-	 * Thanks to Michael, for his cached folders implementation in IMAP
-	 * is used as is here.
-	 */
-
-	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-
-	if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL) {
-		if (((CamelService *)store)->status == CAMEL_SERVICE_DISCONNECTED) {
-			((CamelService *)store)->status = CAMEL_SERVICE_CONNECTING;
-			mapi_connect ((CamelService *)store, NULL);
-		}
-	}
-
-	/* update folders from the server only when asking for the top most or the 'top' is not known;
-	   otherwise believe the local cache, because folders sync is pretty slow operation to be done
-	   one every single question on the folder info */
-	if (((flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST) != 0 ||
-	     (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) ||
-	     (!mapi_store->priv->folders_synced) ||
-	     (top && *top && !camel_mapi_store_folder_id_lookup (mapi_store, top))) &&
-	    (check_for_connection ((CamelService *)store, NULL) || ((CamelService *)store)->status == CAMEL_SERVICE_CONNECTING)) {
-		if (!mapi_folders_sync (mapi_store, flags, error)) {
-			camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-			return NULL;
-		}
-		camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
-		camel_store_summary_save ((CamelStoreSummary *)mapi_store->summary);
-	}
-
-	camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-
-	return mapi_get_folder_info_offline (store, top, flags, error);
-}
-
 const gchar *
 camel_mapi_store_folder_id_lookup_offline (CamelMapiStore *mapi_store, const gchar *folder_name)
 {
@@ -1762,133 +2000,6 @@ camel_mapi_store_get_profile_name (CamelMapiStore *mapi_store)
 	return priv->profile;
 }
 
-static gboolean
-mapi_subscribe_folder(CamelStore *store, const gchar *folder_name, GError **error)
-{
-	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
-	CamelFolderInfo *fi;
-	CamelStoreInfo *si = NULL;
-	const gchar *parent_name = NULL, *use_folder_name = folder_name, *fid = NULL;
-	gboolean favourites = FALSE;
-	/* TODO : exchange_mapi_add_to_favorites (); */
-
-	fid = camel_mapi_store_folder_id_lookup(mapi_store, folder_name);
-
-	if (g_str_has_prefix (folder_name, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) ) {
-		const gchar *f_name = NULL;
-
-		parent_name = DISPLAY_NAME_FAVOURITES;
-
-		f_name = strrchr (folder_name,'/');
-		if (!f_name) {
-			/* Don't process All Public Folder. */
-			return TRUE;
-		}
-
-		use_folder_name = ++f_name;
-		favourites = TRUE;
-	}
-	si = camel_store_summary_path((CamelStoreSummary *)mapi_store->summary, folder_name);
-
-	if (si != NULL) {
-		if ((si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) == 0) {
-			si->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
-			si->flags |= CAMEL_FOLDER_SUBSCRIBED;
-			camel_store_summary_touch((CamelStoreSummary *)mapi_store->summary);
-		}
-	}
-
-	if (si->flags & CAMEL_MAPI_FOLDER_MAIL) {
-		fi = mapi_build_folder_info (mapi_store, parent_name, use_folder_name);
-		if (favourites) {
-			CamelURL *url;
-			url = camel_url_new (mapi_store->priv->base_url, NULL);
-			url->path = g_strdup_printf ("/%s", camel_store_info_path (mapi_store->summary, si));
-			g_free (fi->uri);
-			fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
-			camel_url_free (url);
-		}
-
-		fi->unread = si->unread;
-		fi->total = si->total;
-		fi->flags = si->flags;
-		fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
-		fi->flags |= CAMEL_FOLDER_NOCHILDREN;
-		fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
-		camel_store_folder_subscribed (store, fi);
-		camel_folder_info_free (fi);
-	} else {
-		guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, folder_name);
-		exchange_mapi_add_esource (CAMEL_SERVICE(mapi_store)->url, use_folder_name, fid, folder_type);
-	}
-	camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
-	return TRUE;
-}
-
-static gboolean
-mapi_folder_is_subscribed (CamelStore *store, const gchar *folder_name)
-{
-	CamelMapiStore *mapi_store = (CamelMapiStore *) store;
-	CamelStoreInfo *si;
-	gint truth = FALSE;
-
-	if ((si = camel_store_summary_path ((CamelStoreSummary *) mapi_store->summary, folder_name))) {
-		truth = (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) != 0;
-		camel_store_summary_info_free ((CamelStoreSummary *) mapi_store->summary, si);
-	}
-
-	return truth;
-}
-
-static gboolean
-mapi_unsubscribe_folder(CamelStore *store, const gchar *folder_name, GError **error)
-{
-	CamelFolderInfo *fi;
-	CamelStoreInfo *si;
-	gchar *parent_name = NULL;
-	const gchar *fid = NULL, *use_folder_name = folder_name;
-	gchar *f_name = NULL;
-
-	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
-	CamelURL *url = CAMEL_SERVICE (mapi_store)->url;
-	fid = camel_mapi_store_folder_id_lookup(mapi_store, folder_name);
-	si = camel_store_summary_path((CamelStoreSummary *)mapi_store->summary, folder_name);
-	if (si) {
-		if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
-			si->flags &= ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
-			camel_store_summary_touch((CamelStoreSummary *)mapi_store->summary);
-			camel_store_summary_save((CamelStoreSummary *)mapi_store->summary);
-		}
-	}
-
-	if (g_str_has_prefix (folder_name, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) ) {
-		parent_name = DISPLAY_NAME_FAVOURITES;
-
-		f_name = strrchr(folder_name,'/');
-		if (f_name != NULL)
-			folder_name = ++f_name;
-		else //Don't process All Public Folder.
-			return TRUE;
-	}
-	if (si->flags & CAMEL_MAPI_FOLDER_MAIL) {
-		fi = mapi_build_folder_info (mapi_store, parent_name, folder_name);
-		camel_store_folder_unsubscribed (store, fi);
-		camel_folder_info_free (fi);
-	} else {
-		guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, use_folder_name);
-		exchange_mapi_remove_esource(url, folder_name, fid, folder_type);
-	}
-	camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
-
-	return TRUE;
-}
-
-static gboolean
-mapi_noop(CamelStore *store, GError **error)
-{
-	return TRUE;
-}
-
 ExchangeMapiConnection *
 camel_mapi_store_get_exchange_connection (CamelMapiStore *mapi_store)
 {
@@ -1899,70 +2010,3 @@ camel_mapi_store_get_exchange_connection (CamelMapiStore *mapi_store)
 	return mapi_store->priv->conn;
 }
 
-static CamelFolder *
-mapi_get_folder_with_type (CamelStore *store, guint folder_type, GError **error)
-{
-	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
-	CamelFolderInfo *all_fi, *fi;
-	CamelFolder *folder = NULL;
-
-	g_return_val_if_fail (mapi_store != NULL, NULL);
-	g_return_val_if_fail (mapi_store->priv != NULL, NULL);
-
-	all_fi = camel_store_get_folder_info (
-		store, NULL, CAMEL_STORE_FOLDER_INFO_RECURSIVE, error);
-	if (all_fi == NULL)
-		return NULL;
-
-	fi = all_fi;
-	while (fi) {
-		CamelFolderInfo *next;
-
-		if ((fi->flags & CAMEL_FOLDER_TYPE_MASK) == folder_type) {
-			folder = camel_store_get_folder (store, fi->full_name, 0, error);
-			break;
-		}
-
-		/* move to the next, depth-first search */
-		next = fi->child;
-		if (!next)
-			next = fi->next;
-		if (!next) {
-			next = fi->parent;
-			while (next) {
-				CamelFolderInfo *sibl = next->next;
-				if (sibl) {
-					next = sibl;
-					break;
-				} else {
-					next = next->parent;
-				}
-			}
-		}
-
-		fi = next;
-	}
-
-	camel_store_free_folder_info (store, all_fi);
-
-	return folder;
-}
-
-static CamelFolder *
-mapi_get_trash (CamelStore *store, GError **error)
-{
-	return mapi_get_folder_with_type (store, CAMEL_FOLDER_TYPE_TRASH, error);
-}
-
-static CamelFolder *
-mapi_get_junk (CamelStore *store, GError **error)
-{
-	return mapi_get_folder_with_type (store, CAMEL_FOLDER_TYPE_JUNK, error);
-}
-
-static gboolean
-mapi_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError **error)
-{
-	return CAMEL_STORE_CLASS(camel_mapi_store_parent_class)->can_refresh_folder (store, info, error) ||
-	      (camel_url_get_param (((CamelService *)store)->url, "check_all") != NULL);
-}
diff --git a/src/camel/camel-mapi-transport.c b/src/camel/camel-mapi-transport.c
index 1467a1e..c322a1c 100644
--- a/src/camel/camel-mapi-transport.c
+++ b/src/camel/camel-mapi-transport.c
@@ -71,8 +71,12 @@ mapi_message_item_send (ExchangeMapiConnection *conn, MailItem *item, GError **p
 }
 
 static gboolean
-mapi_send_to (CamelTransport *transport, CamelMimeMessage *message,
-	      CamelAddress *from, CamelAddress *recipients, GError **error)
+mapi_send_to_sync (CamelTransport *transport,
+                   CamelMimeMessage *message,
+                   CamelAddress *from,
+                   CamelAddress *recipients,
+                   GCancellable *cancellable,
+                   GError **error)
 {
 	ExchangeMapiConnection *conn;
 	MailItem *item = NULL;
@@ -101,7 +105,7 @@ mapi_send_to (CamelTransport *transport, CamelMimeMessage *message,
 	}
 
 	/* Convert MIME to MailItem, attacment lists and recipient list.*/
-	item = camel_mapi_utils_mime_to_item (message, from, NULL);
+	item = camel_mapi_utils_mime_to_item (message, from, cancellable, NULL);
 
 	/* send */
 	st = mapi_message_item_send (conn, item, error);
@@ -148,7 +152,7 @@ camel_mapi_transport_class_init (CamelMapiTransportClass *class)
 	service_class->get_name = mapi_transport_get_name;
 
 	transport_class = CAMEL_TRANSPORT_CLASS (class);
-	transport_class->send_to = mapi_send_to;
+	transport_class->send_to_sync = mapi_send_to_sync;
 }
 
 static void
diff --git a/src/camel/camel-mapi-utils.c b/src/camel/camel-mapi-utils.c
index 863f01e..889d157 100644
--- a/src/camel/camel-mapi-utils.c
+++ b/src/camel/camel-mapi-utils.c
@@ -118,7 +118,7 @@ mail_item_set_subject(MailItem *item, const gchar *subject)
 #define MAX_READ_SIZE 0x1000
 
 static void
-mail_item_set_body_stream (MailItem *item, CamelStream *body, MailItemPartType part_type)
+mail_item_set_body_stream (MailItem *item, CamelStream *body, MailItemPartType part_type, GCancellable *cancellable)
 {
 	guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
 	guint32	read_size = 0, i;
@@ -129,7 +129,7 @@ mail_item_set_body_stream (MailItem *item, CamelStream *body, MailItemPartType p
 
 	stream->value = g_byte_array_new ();
 
-	while (read_size = camel_stream_read (body, (gchar *)buf, STREAM_SIZE, NULL), read_size > 0) {
+	while (read_size = camel_stream_read (body, (gchar *)buf, STREAM_SIZE, cancellable, NULL), read_size > 0) {
 		stream->value = g_byte_array_append (stream->value, buf, read_size);
 
 		is_null_terminated = buf [read_size - 1] == 0;
@@ -186,7 +186,7 @@ mail_item_set_body_stream (MailItem *item, CamelStream *body, MailItemPartType p
 }
 
 static gboolean
-mail_item_add_attach (MailItem *item, CamelMimePart *part, CamelStream *content_stream)
+mail_item_add_attach (MailItem *item, CamelMimePart *part, CamelStream *content_stream, GCancellable *cancellable)
 {
 	guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
 	const gchar *content_id = NULL;
@@ -248,7 +248,7 @@ mail_item_add_attach (MailItem *item, CamelMimePart *part, CamelStream *content_
 	stream->value = g_byte_array_new ();
 
 	camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET, NULL);
-	while (read_size = camel_stream_read(content_stream, (gchar *)buf, STREAM_SIZE, NULL), read_size > 0) {
+	while (read_size = camel_stream_read(content_stream, (gchar *)buf, STREAM_SIZE, cancellable, NULL), read_size > 0) {
 		stream->value = g_byte_array_append (stream->value, buf, read_size);
 	}
 
@@ -259,7 +259,7 @@ mail_item_add_attach (MailItem *item, CamelMimePart *part, CamelStream *content_
 }
 
 static gboolean
-mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first)
+mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first, GCancellable *cancellable)
 {
 	CamelDataWrapper *dw;
 	CamelStream *content_stream;
@@ -280,7 +280,7 @@ mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first)
 		dw = camel_medium_get_content (CAMEL_MEDIUM (part));
 		if (CAMEL_IS_MULTIPART(dw)) {
 			/* recursive */
-			if (!mapi_do_multipart (CAMEL_MULTIPART (dw), item, is_first))
+			if (!mapi_do_multipart (CAMEL_MULTIPART (dw), item, is_first, cancellable))
 				return FALSE;
 			continue;
 		}
@@ -288,7 +288,8 @@ mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first)
 		filename = camel_mime_part_get_filename(part);
 
 		content_stream = camel_stream_mem_new();
-		content_size = camel_data_wrapper_decode_to_stream (dw, (CamelStream *) content_stream, NULL);
+		content_size = camel_data_wrapper_decode_to_stream_sync (
+			dw, (CamelStream *) content_stream, cancellable, NULL);
 
 		camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET, NULL);
 
@@ -298,12 +299,12 @@ mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first)
 		type = camel_mime_part_get_content_type(part);
 
 		if (i_part == 0 && (*is_first) && camel_content_type_is (type, "text", "plain")) {
-			mail_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
+			mail_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT, cancellable);
 			*is_first = FALSE;
 		} else if (camel_content_type_is (type, "text", "html")) {
-			mail_item_set_body_stream (item, content_stream, PART_TYPE_TEXT_HTML);
+			mail_item_set_body_stream (item, content_stream, PART_TYPE_TEXT_HTML, cancellable);
 		} else {
-			mail_item_add_attach (item, part, content_stream);
+			mail_item_add_attach (item, part, content_stream, cancellable);
 		}
 	}
 
@@ -311,7 +312,7 @@ mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first)
 }
 
 MailItem *
-camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GError **error)
+camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GCancellable *cancellable, GError **error)
 {
 	CamelDataWrapper *dw = NULL;
 	CamelContentType *type;
@@ -371,7 +372,7 @@ camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GE
 
 	if (CAMEL_IS_MULTIPART(multipart)) {
 		gboolean is_first = TRUE;
-		if (!mapi_do_multipart (CAMEL_MULTIPART(multipart), item, &is_first))
+		if (!mapi_do_multipart (CAMEL_MULTIPART(multipart), item, &is_first, cancellable))
 			printf("camel message multi part error\n");
 	} else {
 		dw = camel_medium_get_content (CAMEL_MEDIUM (message));
@@ -380,9 +381,10 @@ camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GE
 			content_type = camel_content_type_simple (type);
 
 			content_stream = (CamelStream *)camel_stream_mem_new();
-			content_size = camel_data_wrapper_decode_to_stream(dw, (CamelStream *)content_stream, NULL);
+			content_size = camel_data_wrapper_decode_to_stream_sync (
+				dw, (CamelStream *)content_stream, cancellable, NULL);
 
-			mail_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
+			mail_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT, cancellable);
 		}
 	}
 
diff --git a/src/camel/camel-mapi-utils.h b/src/camel/camel-mapi-utils.h
index 6205b72..4aa59cf 100644
--- a/src/camel/camel-mapi-utils.h
+++ b/src/camel/camel-mapi-utils.h
@@ -31,7 +31,7 @@ G_BEGIN_DECLS
 #include <camel/camel.h>
 
 MailItem *
-camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GError **error);
+camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GCancellable *cancellable, GError **error);
 
 gboolean
 camel_mapi_utils_create_item_build_props (ExchangeMapiConnection *conn, mapi_id_t fid, TALLOC_CTX *mem_ctx, struct SPropValue **values, uint32_t *n_values, gpointer data);
diff --git a/src/libexchangemapi/exchange-mapi-connection.c b/src/libexchangemapi/exchange-mapi-connection.c
index d39e6c1..45c9976 100644
--- a/src/libexchangemapi/exchange-mapi-connection.c
+++ b/src/libexchangemapi/exchange-mapi-connection.c
@@ -908,7 +908,8 @@ obj_message_to_camel_mime (ExchangeMapiConnection *conn, mapi_id_t fid, mapi_obj
 
 		mem = camel_stream_mem_new ();
 		camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (mem), res);
-		camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (msg), mem, NULL);
+		camel_data_wrapper_write_to_stream_sync (
+			CAMEL_DATA_WRAPPER (msg), mem, NULL, NULL);
 
 		g_object_unref (mem);
 		g_object_unref (msg);
diff --git a/src/libexchangemapi/exchange-mapi-mail-utils.c b/src/libexchangemapi/exchange-mapi-mail-utils.c
index 29a0e09..e608753 100644
--- a/src/libexchangemapi/exchange-mapi-mail-utils.c
+++ b/src/libexchangemapi/exchange-mapi-mail-utils.c
@@ -384,7 +384,7 @@ mapi_mime_set_msg_headers (ExchangeMapiConnection *conn, CamelMimeMessage *msg,
 		camel_mime_parser_scan_from (parser, FALSE);
 		g_object_unref (stream);
 
-		if (camel_mime_part_construct_from_parser (part, parser, NULL) != -1) {
+		if (camel_mime_part_construct_from_parser_sync (part, parser, NULL, NULL)) {
 			struct _camel_header_raw *h;
 
 			for (h = part->headers; h; h = h->next) {
@@ -783,7 +783,7 @@ mapi_mime_classify_attachments (ExchangeMapiConnection *conn, mapi_id_t fid, con
 			CamelStream *mem;
 
 			mem = camel_stream_mem_new ();
-			camel_stream_write (mem, (const gchar *) stream->value->data, stream->value->len, NULL);
+			camel_stream_write (mem, (const gchar *) stream->value->data, stream->value->len, NULL, NULL);
 			camel_stream_reset (mem, NULL);
 
 			parser = camel_mime_parser_new ();
@@ -797,7 +797,7 @@ mapi_mime_classify_attachments (ExchangeMapiConnection *conn, mapi_id_t fid, con
 				part = camel_mime_part_new ();
 
 				camel_data_wrapper_set_mime_type_field (CAMEL_DATA_WRAPPER (part), camel_mime_parser_content_type (parser));
-				camel_mime_part_construct_content_from_parser (part, parser, NULL);
+				camel_mime_part_construct_content_from_parser (part, parser, NULL, NULL);
 			} else {
 				is_smime = FALSE;
 			}



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