[evolution-mapi] Different approach for CamelMapiFolder's summary fetching



commit 98a632f7c9cb532ec05119160a8945b9de4b65fb
Author: Milan Crha <mcrha redhat com>
Date:   Tue Nov 8 11:09:58 2011 +0100

    Different approach for CamelMapiFolder's summary fetching

 src/camel/camel-mapi-folder-summary.c   |   59 +--
 src/camel/camel-mapi-folder-summary.h   |    9 +-
 src/camel/camel-mapi-folder.c           |  961 +++++++++++++++----------------
 src/camel/camel-mapi-folder.h           |    5 +-
 src/camel/camel-mapi-notifications.c    |   43 +--
 src/camel/camel-mapi-store-summary.c    |   20 +-
 src/camel/camel-mapi-store-summary.h    |   10 +-
 src/camel/camel-mapi-store.c            |   33 +-
 src/libexchangemapi/e-mapi-connection.c |  175 ++++++
 src/libexchangemapi/e-mapi-connection.h |    8 +
 10 files changed, 700 insertions(+), 623 deletions(-)
---
diff --git a/src/camel/camel-mapi-folder-summary.c b/src/camel/camel-mapi-folder-summary.c
index 9082c3d..ae49547 100644
--- a/src/camel/camel-mapi-folder-summary.c
+++ b/src/camel/camel-mapi-folder-summary.c
@@ -54,10 +54,6 @@ G_DEFINE_TYPE (CamelMapiFolderSummary, camel_mapi_folder_summary, CAMEL_TYPE_FOL
 static void
 mapi_summary_finalize (GObject *object)
 {
-	CamelMapiFolderSummary *mapi_summary = CAMEL_MAPI_FOLDER_SUMMARY (object);
-
-	g_free (mapi_summary->sync_time_stamp);
-
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (camel_mapi_folder_summary_parent_class)->finalize (object);
 }
@@ -74,6 +70,7 @@ mapi_message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
 
 	to = (CamelMapiMessageInfo *)folder_summary_class->message_info_clone(s, mi);
 	to->server_flags = from->server_flags;
+	to->last_modified = from->last_modified;
 
 	/* FIXME: parent clone should do this */
 	to->info.content = camel_folder_summary_content_info_new(s);
@@ -105,6 +102,7 @@ camel_mapi_folder_summary_class_init (CamelMapiFolderSummaryClass *class)
 static void
 camel_mapi_folder_summary_init (CamelMapiFolderSummary *mapi_summary)
 {
+	mapi_summary->latest_last_modify = 0;
 }
 
 /**
@@ -124,7 +122,7 @@ camel_mapi_folder_summary_new (CamelFolder *folder, const gchar *filename)
 
 	summary = g_object_new (CAMEL_TYPE_MAPI_FOLDER_SUMMARY, "folder", folder, NULL);
 
-	camel_folder_summary_set_build_content (summary, TRUE);
+	camel_folder_summary_set_build_content (summary, FALSE);
 	camel_folder_summary_set_filename (summary, filename);
 
 	if (!camel_folder_summary_load_from_db (summary, &local_error)) {
@@ -139,44 +137,6 @@ camel_mapi_folder_summary_new (CamelFolder *folder, const gchar *filename)
 	return summary;
 }
 
-void
-camel_mapi_folder_summary_update_store_info_counts (CamelMapiFolderSummary *mapi_summary)
-{
-	CamelFolderSummary *summary;
-
-	g_return_if_fail (mapi_summary != NULL);
-
-	summary = CAMEL_FOLDER_SUMMARY (mapi_summary);
-	g_return_if_fail (summary != NULL);
-
-	if (camel_folder_summary_get_folder (summary)) {
-		CamelMapiStore *mapi_store;
-
-		mapi_store = CAMEL_MAPI_STORE (camel_folder_get_parent_store (camel_folder_summary_get_folder (summary)));
-		if (mapi_store && mapi_store->summary) {
-			CamelStoreInfo *si;
-			CamelStoreSummary *store_summary = CAMEL_STORE_SUMMARY (mapi_store->summary);
-			CamelFolder*folder;
-
-			g_return_if_fail (store_summary != NULL);
-
-			folder = camel_folder_summary_get_folder (summary);
-			si = camel_store_summary_path (store_summary, camel_folder_get_full_name (folder));
-			if (si) {
-				if (si->unread != camel_folder_summary_get_unread_count (summary) ||
-				    si->total != camel_folder_summary_get_saved_count (summary)) {
-					si->unread = camel_folder_summary_get_unread_count (summary);
-					si->total = camel_folder_summary_get_saved_count (summary);
-
-					camel_store_summary_touch (store_summary);
-				}
-
-				camel_store_summary_info_free (store_summary, si);
-			}
-		}
-	}
-}
-
 static gboolean
 mapi_summary_header_from_db (CamelFolderSummary *summary, CamelFIRecord *fir)
 {
@@ -195,18 +155,12 @@ mapi_summary_header_from_db (CamelFolderSummary *summary, CamelFIRecord *fir)
 	if (part)
 		mapi_summary->version = bdata_extract_digit (&part);
 
-	if (part && *part && part++) {
-		g_free (mapi_summary->sync_time_stamp);
-		mapi_summary->sync_time_stamp = g_strdup (part);
-	}
-
 	return TRUE;
 }
 
 static CamelFIRecord *
 mapi_summary_header_to_db (CamelFolderSummary *summary, GError **error)
 {
-	CamelMapiFolderSummary *mapi_summary = CAMEL_MAPI_FOLDER_SUMMARY(summary);
 	CamelFolderSummaryClass *folder_summary_class;
 	struct _CamelFIRecord *fir;
 
@@ -218,9 +172,7 @@ mapi_summary_header_to_db (CamelFolderSummary *summary, GError **error)
 	if (!fir)
 		return NULL;
 
-	fir->bdata = g_strdup_printf ("%d %s", CAMEL_MAPI_FOLDER_SUMMARY_VERSION, mapi_summary->sync_time_stamp);
-
-	camel_mapi_folder_summary_update_store_info_counts (mapi_summary);
+	fir->bdata = g_strdup_printf ("%d", CAMEL_MAPI_FOLDER_SUMMARY_VERSION);
 
 	return fir;
 }
@@ -242,6 +194,7 @@ mapi_message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
 
 			m_info = (CamelMapiMessageInfo *) info;
 			m_info->server_flags = bdata_extract_digit (&part);
+			m_info->last_modified = bdata_extract_digit (&part);
 		}
 	}
 
@@ -260,7 +213,7 @@ mapi_message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info)
 
 	mir = folder_summary_class->message_info_to_db (s, info);
 	if (mir)
-		mir->bdata = g_strdup_printf ("%u", m_info->server_flags);
+		mir->bdata = g_strdup_printf ("%u %u", m_info->server_flags, (guint32) m_info->last_modified);
 
 	return mir;
 }
diff --git a/src/camel/camel-mapi-folder-summary.h b/src/camel/camel-mapi-folder-summary.h
index 713619d..e6e023f 100644
--- a/src/camel/camel-mapi-folder-summary.h
+++ b/src/camel/camel-mapi-folder-summary.h
@@ -52,16 +52,11 @@ typedef struct _CamelMapiFolderSummaryClass CamelMapiFolderSummaryClass;
 typedef struct _CamelMapiMessageInfo CamelMapiMessageInfo;
 typedef struct _CamelMapiMessageContentInfo CamelMapiMessageContentInfo;
 
-/* extra summary flags*/
-enum {
-	CAMEL_GW_MESSAGE_JUNK = 1<<17,
-	CAMEL_GW_MESSAGE_NOJUNK = 1<<18,
-};
-
 struct _CamelMapiMessageInfo {
 	CamelMessageInfoBase info;
 
 	guint32 server_flags;
+	time_t last_modified; /* PidTagLastModificationTime of this message */
 };
 
 struct _CamelMapiMessageContentInfo {
@@ -71,7 +66,7 @@ struct _CamelMapiMessageContentInfo {
 struct _CamelMapiFolderSummary {
 	CamelFolderSummary parent;
 
-	gchar *sync_time_stamp;
+	time_t latest_last_modify;
 	guint32 version;
 	guint32 validity;
 };
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index bb2c1f2..4c3221b 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -51,9 +51,7 @@ extern gint camel_application_is_exiting;
 
 struct _CamelMapiFolderPrivate {
 
-//#ifdef ENABLE_THREADS
 	GStaticMutex search_lock;	/* for locking the search object */
-//#endif
 
 };
 
@@ -107,136 +105,6 @@ mapi_folder_search_by_uids (CamelFolder *folder, const gchar *expression, GPtrAr
 	return matches;
 }
 
-static gboolean
-update_store_summary (CamelFolder *folder, GError **error)
-{
-	CamelStore *parent_store;
-	CamelStoreSummary *store_summary;
-	CamelStoreInfo *si;
-	const gchar *full_name;
-	gboolean retval;
-
-	full_name = camel_folder_get_full_name (folder);
-	parent_store = camel_folder_get_parent_store (folder);
-	store_summary = ((CamelMapiStore *) parent_store)->summary;
-
-	si = camel_store_summary_path (store_summary, full_name);
-
-	if (si) {
-		guint32 unread, total;
-
-		unread = camel_folder_summary_get_unread_count (folder->summary);
-		total = camel_folder_summary_count (folder->summary);
-
-		if (si->total != total || si->unread != unread) {
-			si->total = total;
-			si->unread = unread;
-			camel_store_summary_touch (store_summary);
-		}
-		camel_store_summary_info_free (store_summary, si);
-	}
-
-	retval = camel_folder_summary_save_to_db (folder->summary, error);
-	camel_store_summary_save (store_summary);
-
-	return retval;
-}
-
-static gboolean
-fetch_items_summary_cb (FetchItemsCallbackData *item_data,
-			gpointer data,
-			GCancellable *cancellable,
-			GError **perror)
-{
-	fetch_items_data *fi_data = (fetch_items_data *)data;
-
-	GSList **slist = &(fi_data->items_list);
-
-	long *flags = NULL;
-	struct FILETIME *delivery_date = NULL;
-	struct FILETIME *last_modification_time = NULL;
-	struct timeval item_modification_time = { 0 };
-	struct timeval fi_data_mod_time = { 0 };
-	guint32 j = 0;
-
-	MailItem *item = g_new0(MailItem , 1);
-
-	if (camel_debug_start("mapi:folder")) {
-		e_mapi_debug_dump_properties (item_data->conn, item_data->fid, item_data->properties, 3);
-		camel_debug_end();
-	}
-
-	item->fid = item_data->fid;
-	item->mid = item_data->mid;
-
-	/*Hold a reference to Recipient List*/
-	item->recipients = item_data->recipients;
-
-	for (j = 0; j < item_data->properties->cValues; j++) {
-		gconstpointer prop_data = get_mapi_SPropValue_data(&item_data->properties->lpProps[j]);
-
-		if (fetch_read_item_common_data (item, item_data->properties->lpProps[j].ulPropTag, prop_data))
-			continue;
-
-		switch (item_data->properties->lpProps[j].ulPropTag) {
-		case PR_MESSAGE_DELIVERY_TIME:
-			delivery_date = (struct FILETIME *) prop_data;
-			break;
-		case PR_LAST_MODIFICATION_TIME:
-			last_modification_time = (struct FILETIME *) prop_data;
-			break;
-		case PR_MESSAGE_FLAGS:
-			flags = (long *) prop_data;
-			break;
-		default:
-			break;
-		}
-	}
-
-	/* item->header.from = camel_internet_address_format_address (from_name, from_email); */
-
-	if (delivery_date) {
-		item->header.recieved_time = e_mapi_util_filetime_to_time_t (delivery_date);
-	}
-
-	if (last_modification_time) {
-		item_modification_time.tv_sec = e_mapi_util_filetime_to_time_t (last_modification_time);
-		item_modification_time.tv_usec = 0;
-	}
-
-	fi_data_mod_time.tv_sec = fi_data->last_modification_time.tv_sec;
-	fi_data_mod_time.tv_usec = fi_data->last_modification_time.tv_usec;
-
-	if (timeval_compare (&item_modification_time, &fi_data_mod_time) == 1) {
-		fi_data->last_modification_time.tv_sec = item_modification_time.tv_sec;
-		fi_data->last_modification_time.tv_usec = item_modification_time.tv_usec;
-	}
-
-	if ((*flags & MSGFLAG_READ) != 0)
-		item->header.flags |= CAMEL_MESSAGE_SEEN;
-	if ((*flags & MSGFLAG_HASATTACH) != 0)
-		item->header.flags |= CAMEL_MESSAGE_ATTACHMENTS;
-
-	*slist = g_slist_prepend (*slist, item);
-
-	/*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, NULL);
-		g_slist_foreach (*slist, (GFunc)mail_item_free, NULL);
-		g_slist_free (*slist);
-		*slist = NULL;
-	}
-
-	if (item_data->total > 0)
-               camel_operation_progress (NULL, (item_data->index * 100)/item_data->total);
-
-	if (camel_application_is_exiting)
-		return FALSE;
-
-	return TRUE;
-}
-
 static void
 mapi_set_message_id (CamelMapiMessageInfo *mapi_mi, const gchar *message_id)
 {
@@ -362,7 +230,7 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
 		/************************ First populate summary *************************/
 		mi = NULL;
 		pmi = NULL;
-		msg_uid = e_mapi_util_mapi_ids_to_uid (item->fid, item->mid);
+		msg_uid = e_mapi_util_mapi_id_to_string (item->mid);
 		pmi = camel_folder_summary_get (folder->summary, msg_uid);
 
 		if (pmi) {
@@ -387,7 +255,7 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
 			guint32 count_to = 0, count_cc =0;
 			gchar *to = NULL, *cc = NULL;
 
-			mi->info.uid = e_mapi_util_mapi_ids_to_uid(item->fid, item->mid);
+			mi->info.uid = e_mapi_util_mapi_id_to_string (item->mid);
 			mi->info.subject = camel_pstring_strdup(item->header.subject);
 			mi->info.date_sent = mi->info.date_received = item->header.recieved_time;
 			mi->info.size = (guint32) item->header.size;
@@ -509,329 +377,515 @@ mapi_utils_do_flags_diff (flags_diff_t *diff, guint32 old, guint32 _new)
 	diff->bits = _new & diff->changed;
 }
 
-typedef struct _SyncDeletedData SyncDeletedData;
+static gboolean
+build_last_modify_restriction (EMapiConnection *conn,
+		               mapi_id_t fid,
+			       TALLOC_CTX *mem_ctx,
+			       struct mapi_SRestriction **restrictions,
+			       gpointer user_data,
+			       GCancellable *cancellable,
+			       GError **perror)
+{
+	const time_t *latest_last_modify = user_data;
+	struct mapi_SRestriction *restriction = NULL;
 
-struct _SyncDeletedData {
-	CamelFolder *folder;
-	mapi_id_t folder_id;
-	gboolean need_refresh;
+	g_return_val_if_fail (restrictions != NULL, FALSE);
+
+	if (latest_last_modify && *latest_last_modify > 0) {
+		struct SPropValue sprop;
+		struct timeval t;
+
+		restriction = talloc_zero (mem_ctx, struct mapi_SRestriction);
+		g_return_val_if_fail (restriction != NULL, FALSE);
+
+		restriction->rt = RES_PROPERTY;
+		restriction->res.resProperty.relop = RELOP_GT;
+		restriction->res.resProperty.ulPropTag = PR_LAST_MODIFICATION_TIME;
+
+		t.tv_sec = *latest_last_modify;
+		t.tv_usec = 0;
+
+		set_SPropValue_proptag_date_timeval (&sprop, PR_LAST_MODIFICATION_TIME, &t);
+		cast_mapi_SPropValue (mem_ctx, &(restriction->res.resProperty.lpProp), &sprop);
+	}
+
+	*restrictions = restriction;
+
+	return TRUE;
+}
+
+struct GatherChangedObjectsData
+{
+	CamelFolderSummary *summary;
+	mapi_id_t fid;
+	GSList *to_update;
+	GHashTable *removed_uids;
+	time_t latest_last_modify;
 };
 
 static gboolean
-deleted_items_sync_cb (FetchItemsCallbackData *item_data,
-		       gpointer data,
-		       GCancellable *cancellable,
-		       GError **perror)
+gather_changed_objects_to_slist (EMapiConnection *conn,
+				 mapi_id_t fid,
+				 TALLOC_CTX *mem_ctx,
+				 const ListObjectsData *object_data,
+				 guint32 obj_index,
+				 guint32 obj_total,
+				 gpointer user_data,
+				 GCancellable *cancellable,
+				 GError **perror)
 {
-	guint32 msg_flags = CAMEL_MESSAGE_FOLDER_FLAGGED; /* to not have 0 in the hash table */
-	GHashTable *uids = data;
-	gchar *msg_uid = e_mapi_util_mapi_ids_to_uid (item_data->fid,
-							     item_data->mid);
+	struct GatherChangedObjectsData *gco = user_data;
+	ListObjectsData *copy;
+	gchar *uid_str;
+	gboolean update = FALSE;
 
-	if ((item_data->msg_flags & MSGFLAG_READ) != 0)
-		msg_flags |= CAMEL_MESSAGE_SEEN;
-	if ((item_data->msg_flags & MSGFLAG_HASATTACH) != 0)
-		msg_flags |= CAMEL_MESSAGE_ATTACHMENTS;
+	g_return_val_if_fail (gco != NULL, FALSE);
+	g_return_val_if_fail (object_data != NULL, FALSE);
 
-	g_hash_table_insert (uids, msg_uid, GINT_TO_POINTER (msg_flags));
+	uid_str = e_mapi_util_mapi_id_to_string (object_data->mid);
+	if (!uid_str)
+		return FALSE;
 
-	/* Progress update */
-	if (item_data->total > 0)
-		camel_operation_progress (NULL, (item_data->index * 100)/item_data->total);
+	if (camel_folder_summary_check_uid (gco->summary, uid_str)) {
+		CamelMessageInfo *info;
 
-	/* Check if we have to stop */
-	if (camel_application_is_exiting)
-		return FALSE;
+		if (gco->removed_uids)
+			g_hash_table_remove (gco->removed_uids, uid_str);
+
+		info = camel_folder_summary_get (gco->summary, uid_str);
+		if (info) {
+			CamelMapiMessageInfo *minfo = (CamelMapiMessageInfo *) info;
+
+			if (minfo->last_modified != object_data->last_modified) {
+				update = TRUE;
+			} else {
+				guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS, flags = 0;
+
+				if ((object_data->msg_flags & MSGFLAG_READ) != 0)
+					flags |= CAMEL_MESSAGE_SEEN;
+				if ((object_data->msg_flags & MSGFLAG_HASATTACH) != 0)
+					flags |= CAMEL_MESSAGE_ATTACHMENTS;
+
+				if ((minfo->info.flags & mask) != (flags & mask)) {
+					camel_message_info_set_flags (info, mask, flags);
+					minfo->server_flags = camel_message_info_flags (info);
+					minfo->info.dirty = TRUE;
+				}
+			}
+
+			camel_message_info_free (info);
+		}
+	} else {
+		update = TRUE;
+	}
+
+	if (update) {
+		copy = g_new0 (ListObjectsData, 1);
+		*copy = *object_data;
+
+		gco->to_update = g_slist_prepend (gco->to_update, copy);
+	}
+
+	if (gco->latest_last_modify < object_data->last_modified)
+		gco->latest_last_modify = object_data->last_modified;
+
+	if (obj_total > 0)
+		camel_operation_progress (cancellable, obj_index * 100 / obj_total);
+
+	g_free (uid_str);
 
 	return TRUE;
 }
 
+struct GatherObjectSummaryData
+{
+	CamelFolder *folder;
+	CamelFolderChangeInfo *changes;
+};
+
 static void
-mapi_sync_deleted (CamelSession *session,
-                   GCancellable *cancellable,
-                   SyncDeletedData *data,
-                   GError **error)
+remove_removed_uids_cb (gpointer uid_str, gpointer value, gpointer user_data)
 {
-	CamelMapiStore *mapi_store;
-	CamelMapiFolder *mapi_folder;
-	CamelFolderChangeInfo *changes = NULL;
-	CamelMessageInfo *info = NULL;
-	CamelStore *parent_store;
-	CamelServiceConnectionStatus status;
-	CamelService *service;
-	GPtrArray *known_uids = NULL;
-	guint32 index, options = 0;
-	GHashTable *server_messages = NULL;
-	const gchar *uid = NULL;
-	gboolean flags_changed = FALSE;
+	struct GatherObjectSummaryData *gos = user_data;
 
-	parent_store = camel_folder_get_parent_store (data->folder);
+	g_return_if_fail (gos != NULL);
+	g_return_if_fail (gos->folder != NULL);
+	g_return_if_fail (gos->changes != NULL);
 
-	mapi_folder = CAMEL_MAPI_FOLDER (data->folder);
-	mapi_store = CAMEL_MAPI_STORE (parent_store);
+	camel_folder_change_info_remove_uid (gos->changes, uid_str);
+	camel_folder_summary_remove_uid (gos->folder->summary, uid_str);
+	camel_data_cache_remove (CAMEL_MAPI_FOLDER (gos->folder)->cache, "cache", uid_str, NULL);
+}
 
-	service = CAMEL_SERVICE (mapi_store);
-	status = camel_service_get_connection_status (service);
+static gboolean
+gather_object_summary_cb (EMapiConnection *conn,
+			  TALLOC_CTX *mem_ctx,
+			  /* const */ EMapiObject *object,
+			  guint32 obj_index,
+			  guint32 obj_total,
+			  gpointer user_data,
+			  GCancellable *cancellable,
+			  GError **perror)
+{
+	struct GatherObjectSummaryData *gos = user_data;
+	gchar *uid_str;
+	const mapi_id_t *pmid;
+	const uint32_t *pmsg_flags;
+	const struct FILETIME *last_modified;
+	const gchar *transport_headers;
+	uint32_t msg_flags;
+	CamelMessageInfo *info;
+	gboolean is_new = FALSE;
 
-	if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)) ||
-			status == CAMEL_SERVICE_DISCONNECTED) {
+	g_return_val_if_fail (gos != NULL, FALSE);
+	g_return_val_if_fail (gos->folder != NULL, FALSE);
+	g_return_val_if_fail (object != NULL, FALSE);
+
+	pmid = e_mapi_util_find_array_propval (&object->properties, PR_MID);
+	pmsg_flags = e_mapi_util_find_array_propval (&object->properties, PR_MESSAGE_FLAGS);
+	last_modified = e_mapi_util_find_array_propval (&object->properties, PR_LAST_MODIFICATION_TIME);
+	transport_headers = e_mapi_util_find_array_propval (&object->properties, PR_TRANSPORT_MESSAGE_HEADERS_UNICODE);
 
-		goto exit;
+	if (!pmid) {
+		g_debug ("%s: Received message [%d/%d] without PR_MID", G_STRFUNC, obj_index, obj_total);
+		e_mapi_debug_dump_object (object, TRUE, 3);
+		return TRUE;
 	}
 
-	camel_operation_push_message (
-		cancellable,
-		_("Retrieving message IDs from server for %s"),
-		camel_folder_get_display_name (data->folder));
+	if (!last_modified) {
+		g_debug ("%s: Received message [%d/%d] without PR_LAST_MODIFICATION_TIME", G_STRFUNC, obj_index, obj_total);
+		e_mapi_debug_dump_object (object, TRUE, 3);
+	}
 
-	camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+	uid_str = e_mapi_util_mapi_id_to_string (*pmid);
+	if (!uid_str)
+		return FALSE;
 
-	if (mapi_folder->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC)
-		options |= MAPI_OPTIONS_USE_PFSTORE;
+	msg_flags = pmsg_flags ? *pmsg_flags : 0;
 
-	server_messages = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+	info = camel_folder_summary_get (gos->folder->summary, uid_str);
+	if (!info) {
+		is_new = TRUE;
 
-	/*Get the UID list from server.*/
-	e_mapi_connection_fetch_items (camel_mapi_store_get_connection (mapi_store), data->folder_id, NULL, NULL, NULL,
-					       NULL, NULL,
-					       deleted_items_sync_cb, server_messages,
-					       options | MAPI_OPTIONS_DONT_OPEN_MESSAGE, cancellable, NULL);
+		if (transport_headers && *transport_headers) {
+			CamelMimePart *part = camel_mime_part_new ();
+			CamelStream *stream;
+			CamelMimeParser *parser;
 
-	camel_operation_pop_message (cancellable);
+			stream = camel_stream_mem_new_with_buffer (transport_headers, strlen (transport_headers));
+			parser = camel_mime_parser_new ();
+			camel_mime_parser_init_with_stream (parser, stream, NULL);
+			camel_mime_parser_scan_from (parser, FALSE);
+			g_object_unref (stream);
 
-	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+			if (camel_mime_part_construct_from_parser_sync (part, parser, NULL, NULL)) {
+				info = camel_folder_summary_info_new_from_header (gos->folder->summary, part->headers);
+				if (info) {
+					CamelMapiMessageInfo *minfo = (CamelMapiMessageInfo *) info;
 
-	/* Check if we have to stop */
-	if (g_cancellable_is_cancelled (cancellable) || camel_application_is_exiting) {
-		g_hash_table_destroy (server_messages);
-		goto exit;
-	}
+					minfo->info.uid = camel_pstring_strdup (uid_str);
+				}
+			}
 
-	changes = camel_folder_change_info_new ();
+			g_object_unref (parser);
+			g_object_unref (part);
+		}
 
-	camel_operation_push_message (
-		cancellable,
-		_("Removing deleted messages from cache in %s"),
-		camel_folder_get_display_name (data->folder));
+		if (!info) {
+			CamelMapiMessageInfo *minfo;
+			const gchar *subject, *message_id, *references, *in_reply_to, *display_to, *display_cc;
+			const gchar *from_addr_type, *from_name, *from_email;
+			const struct FILETIME *delivery_time;
+			const uint32_t *msg_size;
+			EMapiRecipient *recipient;
+			gchar *to = NULL, *cc = NULL, *formatted_addr;
+
+			subject = e_mapi_util_find_array_propval (&object->properties, PR_SUBJECT_UNICODE);
+			delivery_time = e_mapi_util_find_array_propval (&object->properties, PR_MESSAGE_DELIVERY_TIME);
+			msg_size = e_mapi_util_find_array_propval (&object->properties, PR_MESSAGE_SIZE);
+			message_id = e_mapi_util_find_array_propval (&object->properties, PR_INTERNET_MESSAGE_ID);
+			references = e_mapi_util_find_array_propval (&object->properties, PR_INTERNET_REFERENCES);
+			in_reply_to = e_mapi_util_find_array_propval (&object->properties, PR_IN_REPLY_TO_ID);
+			display_to = e_mapi_util_find_array_propval (&object->properties, PR_DISPLAY_TO_UNICODE);
+			display_cc = e_mapi_util_find_array_propval (&object->properties, PR_DISPLAY_CC_UNICODE);
+			from_addr_type = e_mapi_util_find_array_propval (&object->properties, PR_SENT_REPRESENTING_ADDRTYPE);
+			from_name = e_mapi_util_find_array_propval (&object->properties, PR_SENT_REPRESENTING_NAME_UNICODE);
+			from_email = e_mapi_util_find_array_propval (&object->properties, PR_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE);
+
+			info = camel_message_info_new (gos->folder->summary);
+			minfo = (CamelMapiMessageInfo *) info;
+
+			minfo->info.uid = camel_pstring_strdup (uid_str);
+			minfo->info.subject = camel_pstring_strdup (subject);
+			minfo->info.date_sent = minfo->info.date_received = e_mapi_util_filetime_to_time_t (delivery_time);
+			minfo->info.size = msg_size ? *msg_size : 0;
+
+			/* Threading related properties */
+			mapi_set_message_id (minfo, message_id);
+			if (references || in_reply_to)
+				mapi_set_message_references (minfo, references, in_reply_to);
+
+			/* Recipients */
+			for (recipient = object->recipients; recipient; recipient = recipient->next) {
+				const uint32_t *recip_type = e_mapi_util_find_array_propval (&recipient->properties, PR_RECIPIENT_TYPE);
+				const gchar *name, *email;
+				gchar **dest = NULL;
+
+				if (!recip_type)
+					continue;
+
+				switch (*recip_type) {
+				case MAPI_TO:
+					dest = &to;
+					break;
+				case MAPI_CC:
+					dest = &cc;
+					break;
+				default:
+					break;
+				}
 
-	/* Iterate over cache and check if the UID is in server */
-	known_uids = camel_folder_summary_get_array (data->folder->summary);
-	for (index = 0; known_uids && index < known_uids->len; index++) {
-		guint32 msg_flags;
+				if (!dest)
+					continue;
+
+				/* PidTagNickname for Recipients table */
+				name = e_mapi_util_find_array_propval (&recipient->properties, PROP_TAG (PT_UNICODE, 0x6001));
+				name = name ? name : e_mapi_util_find_array_propval (&recipient->properties, PidTagNickname);
+				name = name ? name : e_mapi_util_find_array_propval (&recipient->properties, PR_DISPLAY_NAME_UNICODE);
+				name = name ? name : e_mapi_util_find_array_propval (&recipient->properties, PR_RECIPIENT_DISPLAY_NAME_UNICODE);
+				name = name ? name : e_mapi_util_find_array_propval (&recipient->properties, PR_7BIT_DISPLAY_NAME_UNICODE);
+
+				email = e_mapi_util_find_array_propval (&recipient->properties, PidTagPrimarySmtpAddress);
+				email = email ? email : e_mapi_util_find_array_propval (&recipient->properties, PidTagSmtpAddress);
+
+				formatted_addr = camel_internet_address_format_address (name, email ? email : "");
+				if (*dest) {
+					gchar *tmp = *dest;
+					*dest = g_strconcat (*dest, ", ", formatted_addr, NULL);
+					g_free (formatted_addr);
+					g_free (tmp);
+				} else {
+					*dest = formatted_addr;
+				}
+			}
 
-		/* Iterate in a reverse order, thus removal will not hurt */
-		info = camel_folder_summary_get (data->folder->summary, g_ptr_array_index (known_uids, index));
-		if (!info) continue; /*This is bad. *Should* not happen*/
+			minfo->info.to = to ? camel_pstring_strdup (to) : camel_pstring_strdup (display_to);
+			minfo->info.cc = cc ? camel_pstring_strdup (cc) : camel_pstring_strdup (display_cc);
 
-		uid = camel_message_info_uid (info);
-		if (!uid) {
-			camel_message_info_free (info);
-			continue;
-		}
+			if (from_addr_type && g_ascii_strcasecmp (from_addr_type, "EX") == 0) {
+				gchar *email = NULL, *name = NULL;
 
-		msg_flags = GPOINTER_TO_INT (g_hash_table_lookup (server_messages, uid));
+				email = e_mapi_connection_ex_to_smtp (conn, from_email, &name, cancellable, perror);
+				if (email && *email) {
+					gchar *from = camel_internet_address_format_address (name, email);
 
-		/* If it is not in server list, clean our cache */
-		if (!msg_flags) {
-			camel_folder_summary_lock (data->folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-			camel_folder_summary_remove_uid (data->folder->summary, uid);
-			camel_data_cache_remove (mapi_folder->cache, "cache", uid, NULL);
-			camel_folder_change_info_remove_uid (changes, uid);
-			camel_folder_summary_unlock (data->folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-		} else {
-			CamelMapiMessageInfo *mapi_info = (CamelMapiMessageInfo *) info;
-
-			msg_flags = msg_flags & (~CAMEL_MESSAGE_FOLDER_FLAGGED);
-			if (mapi_info->server_flags != msg_flags) {
-				mapi_info->server_flags = msg_flags;
-				camel_message_info_set_flags (info, msg_flags, CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS);
-				camel_folder_change_info_change_uid (changes, uid);
-				flags_changed = TRUE;
-			}
-		}
+					minfo->info.from = camel_pstring_strdup (from);
 
-		camel_message_info_free (info);
+					g_free (from);
+				} else if (from_name && *from_name) {
+					minfo->info.from = camel_pstring_strdup (from_name);
+				}
 
-		/* Progress update */
-		camel_operation_progress (cancellable, (index * 100) / known_uids->len);
+				g_free (name);
+				g_free (email);
+			} else if (from_email) {
+				gchar *from = camel_internet_address_format_address (from_name, from_email);
 
-		/* Check if we have to stop */
-		if (g_cancellable_is_cancelled (cancellable) || camel_application_is_exiting) {
-			g_hash_table_destroy (server_messages);
-			if (camel_folder_change_info_changed (changes))
-				camel_folder_changed (data->folder, changes);
-			camel_folder_change_info_free (changes);
-			goto exit;
-		}
-	}
+				minfo->info.from = camel_pstring_strdup (from);
 
-	camel_operation_pop_message (cancellable);
+				g_free (from);
+			}
 
-	if (camel_folder_change_info_changed (changes)) {
-		if (flags_changed)
-			camel_mapi_folder_summary_update_store_info_counts (CAMEL_MAPI_FOLDER_SUMMARY (CAMEL_FOLDER (mapi_folder)->summary));
-		camel_folder_changed (data->folder, changes);
+			g_free (to);
+			g_free (cc);
+		}
 	}
-	camel_folder_change_info_free (changes);
 
-	data->need_refresh = camel_folder_summary_count (data->folder->summary) != g_hash_table_size (server_messages);
+	if (info) {
+		CamelMapiMessageInfo *minfo = (CamelMapiMessageInfo *) info;
+		guint32 flags = 0, mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS;
 
-	g_hash_table_destroy (server_messages);
+		if (last_modified) {
+			minfo->last_modified = e_mapi_util_filetime_to_time_t (last_modified);
+		} else {
+			minfo->last_modified = 0;
+		}
 
- exit:
-	camel_folder_summary_free_array (known_uids);
+		if ((msg_flags & MSGFLAG_READ) != 0)
+			flags |= CAMEL_MESSAGE_SEEN;
+		if ((msg_flags & MSGFLAG_HASATTACH) != 0)
+			flags |= CAMEL_MESSAGE_ATTACHMENTS;
 
-	if (data->need_refresh) {
-		CamelMapiFolderSummary *mapi_summary = CAMEL_MAPI_FOLDER_SUMMARY (data->folder->summary);
-		if (mapi_summary) {
-			camel_service_lock (CAMEL_SERVICE (parent_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-			g_free (mapi_summary->sync_time_stamp);
-			mapi_summary->sync_time_stamp = NULL;
-			camel_service_unlock (CAMEL_SERVICE (parent_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+		if ((camel_message_info_flags (info) & mask) != flags) {
+			if (is_new)
+				minfo->info.flags = flags;
+			else
+				camel_message_info_set_flags (info, mask, flags);
+			minfo->server_flags = camel_message_info_flags (info);
+			minfo->info.dirty = TRUE;
+		}
+
+		if (is_new) {
+			camel_folder_summary_add (gos->folder->summary, info);
+			camel_folder_change_info_add_uid (gos->changes, camel_message_info_uid (info));
+			camel_folder_change_info_recent_uid (gos->changes, camel_message_info_uid (info));
 
-			mapi_refresh_folder (data->folder, cancellable, error);
+			camel_message_info_ref (info);
+		} else {
+			camel_folder_change_info_change_uid (gos->changes, camel_message_info_uid (info));
 		}
+
+		camel_message_info_free (info);
 	}
-}
 
-static void
-mapi_sync_deleted_data_free (SyncDeletedData *data)
-{
-	g_object_unref (data->folder);
-	g_slice_free (SyncDeletedData, data);
-}
+	if (obj_total > 0)
+		camel_operation_progress (cancellable, obj_index * 100 / obj_total);
 
-static gboolean
-mapi_camel_get_summary_list (EMapiConnection *conn,
-			     mapi_id_t fid,
-			     TALLOC_CTX *mem_ctx,
-			     struct SPropTagArray *props,
-			     gpointer data,
-			     GCancellable *cancellable,
-			     GError **perror)
-{
-	static const uint32_t summary_prop_list[] = {
-		PR_INTERNET_CPID,
-		PR_SUBJECT_UNICODE,
-		PR_MESSAGE_SIZE,
-		PR_MESSAGE_DELIVERY_TIME,
-		PR_MESSAGE_FLAGS,
-		PR_SENT_REPRESENTING_NAME_UNICODE,
-		PR_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE,
-		PR_SENT_REPRESENTING_ADDRTYPE_UNICODE,
-		PR_LAST_MODIFICATION_TIME,
-		PR_INTERNET_MESSAGE_ID,
-		PR_INTERNET_REFERENCES,
-		PR_IN_REPLY_TO_ID,
-		PR_DISPLAY_TO_UNICODE,
-		PR_DISPLAY_CC_UNICODE,
-		PR_DISPLAY_BCC_UNICODE,
-		PR_TRANSPORT_MESSAGE_HEADERS_UNICODE
-	};
-
-	g_return_val_if_fail (props != NULL, FALSE);
-
-	return e_mapi_utils_add_props_to_props_array (mem_ctx, props, summary_prop_list, G_N_ELEMENTS (summary_prop_list));
+	g_free (uid_str);
+
+	return TRUE;
 }
 
 gboolean
-camel_mapi_folder_fetch_summary (CamelStore *store, CamelFolder *folder, const mapi_id_t fid, BuildRestrictionsCB build_rs_cb, gpointer build_rs_cb_data,
-				 struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GCancellable *cancellable, GError **mapi_error)
+camel_mapi_folder_fetch_summary (CamelFolder *folder, GCancellable *cancellable, GError **mapi_error)
 {
 	gboolean status;
-	CamelMapiStore *mapi_store = (CamelMapiStore *) store;
+	gboolean full_download;
+	CamelSettings *settings;
+	CamelStore *store = camel_folder_get_parent_store (folder);
+	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+	CamelMapiFolder *mapi_folder = CAMEL_MAPI_FOLDER (folder);
+	CamelMapiFolderSummary *mapi_summary = CAMEL_MAPI_FOLDER_SUMMARY (folder->summary);
+	EMapiConnection *conn = camel_mapi_store_get_connection (mapi_store);
+	struct GatherChangedObjectsData gco;
+	mapi_object_t obj_folder;
+
+	if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store)))
+		return FALSE;
 
-	/*TODO : Check for online state*/
+	camel_folder_freeze (folder);
 
-	camel_operation_push_message (cancellable, _("Fetching summary information for new messages in %s"), camel_folder_get_display_name (folder));
+	settings = camel_service_get_settings (CAMEL_SERVICE (store));
+	full_download =
+		camel_offline_settings_get_stay_synchronized (CAMEL_OFFLINE_SETTINGS (settings)) ||
+		camel_offline_folder_get_offline_sync (CAMEL_OFFLINE_FOLDER (folder));
+
+	if (full_download)
+		camel_operation_push_message (cancellable, _("Downloading messages in folder '%s'"), camel_folder_get_display_name (folder));
+	else
+		camel_operation_push_message (cancellable, _("Refreshing folder '%s'"), camel_folder_get_display_name (folder));
 
 	camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	status = e_mapi_connection_fetch_items  (camel_mapi_store_get_connection (mapi_store), fid, build_rs_cb, build_rs_cb_data, sort,
-							mapi_camel_get_summary_list, NULL,
-							fetch_items_summary_cb, fetch_data,
-							options, cancellable, mapi_error);
+	if ((CAMEL_MAPI_FOLDER (folder)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0)
+		status = e_mapi_connection_open_public_folder (conn, mapi_folder->folder_id, &obj_folder, cancellable, mapi_error);
+	else
+		status = e_mapi_connection_open_personal_folder (conn, mapi_folder->folder_id, &obj_folder, cancellable, mapi_error);
 
-	camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	gco.latest_last_modify = 0;
+	gco.fid = mapi_object_get_id (&obj_folder);
+	gco.summary = folder->summary;
+	gco.to_update = NULL;
+	gco.removed_uids = NULL;
 
-	camel_operation_pop_message (cancellable);
+	if (mapi_summary->latest_last_modify <= 0) {
+		GPtrArray *known_uids;
 
-	return status;
-}
+		camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
 
-static gboolean
-cmf_build_last_modify_restriction (EMapiConnection *conn,
-				   mapi_id_t fid,
-				   TALLOC_CTX *mem_ctx,
-				   struct mapi_SRestriction **restrictions,
-				   gpointer user_data,
-				   GCancellable *cancellable,
-				   GError **perror)
-{
-	const gchar *sync_time_stamp = user_data;
-	GTimeVal last_modification_time;
+		gco.removed_uids = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free, NULL);
+		known_uids = camel_folder_summary_get_array (folder->summary);
+		if (known_uids) {
+			gint ii;
 
-	g_return_val_if_fail (restrictions != NULL, FALSE);
+			for (ii = 0; ii < known_uids->len; ii++) {
+				g_hash_table_insert (gco.removed_uids, (gpointer) camel_pstring_strdup (g_ptr_array_index (known_uids, ii)), GINT_TO_POINTER (1));
+			}
 
-	if (sync_time_stamp && *sync_time_stamp &&
-	    g_time_val_from_iso8601 (sync_time_stamp,
-				     &last_modification_time)) {
-		struct mapi_SRestriction *restriction;
-		struct SPropValue sprop;
-		struct timeval t;
+			camel_folder_summary_free_array (known_uids);
+		}
+	}
 
-		restriction = talloc_zero (mem_ctx, struct mapi_SRestriction);
-		g_return_val_if_fail (restriction != NULL, FALSE);
+	if (status) {
+		status = e_mapi_connection_list_objects (conn, &obj_folder,
+			full_download ? NULL : build_last_modify_restriction, &mapi_summary->latest_last_modify,
+			gather_changed_objects_to_slist, &gco, cancellable, mapi_error);
+	}
 
-		restriction->rt = RES_PROPERTY;
-		restriction->res.resProperty.relop = RELOP_GE;
-		restriction->res.resProperty.ulPropTag = PR_LAST_MODIFICATION_TIME;
+	if (status && gco.to_update) {
+		GSList *uids = NULL, *iter;
+		struct GatherObjectSummaryData gos;
 
-		t.tv_sec = last_modification_time.tv_sec;
-		t.tv_usec = last_modification_time.tv_usec;
+		for (iter = gco.to_update; iter; iter = iter->next) {
+			ListObjectsData *data = iter->data;
 
-		set_SPropValue_proptag_date_timeval (&sprop, PR_LAST_MODIFICATION_TIME, &t);
-		cast_mapi_SPropValue (mem_ctx, &(restriction->res.resProperty.lpProp), &sprop);
+			if (data)
+				uids = g_slist_prepend (uids, &data->mid);
+		}
+
+		gos.folder = folder;
+		gos.changes = camel_folder_change_info_new ();
+
+		if (gco.removed_uids)
+			g_hash_table_foreach (gco.removed_uids, remove_removed_uids_cb, &gos);
+
+		status = e_mapi_connection_transfer_summary (conn, &obj_folder, uids, gather_object_summary_cb, &gos, cancellable, mapi_error);
+
+		g_slist_free (uids);
+
+		if (camel_folder_change_info_changed (gos.changes))
+			camel_folder_changed (folder, gos.changes);
+		camel_folder_change_info_free (gos.changes);
+	} else if (status && gco.removed_uids) {
+		struct GatherObjectSummaryData gos;
+
+		gos.folder = folder;
+		gos.changes = camel_folder_change_info_new ();
 
-		*restrictions = restriction;
+		g_hash_table_foreach (gco.removed_uids, remove_removed_uids_cb, &gos);
 
+		if (camel_folder_change_info_changed (gos.changes))
+			camel_folder_changed (folder, gos.changes);
+		camel_folder_change_info_free (gos.changes);
 	}
 
-	return TRUE;
+	e_mapi_connection_close_folder (conn, &obj_folder, cancellable, mapi_error);
+
+	g_slist_free_full (gco.to_update, g_free);
+	if (gco.removed_uids)
+		g_hash_table_destroy (gco.removed_uids);
+
+	camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+	camel_operation_pop_message (cancellable);
+
+	if (status && gco.latest_last_modify > 0) {
+		mapi_summary->latest_last_modify = gco.latest_last_modify;
+	}
+
+	camel_folder_thaw (folder);
+
+	return status;
 }
 
 gboolean
-mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **error)
+mapi_refresh_folder (CamelFolder *folder, GCancellable *cancellable, GError **error)
 {
 
 	CamelMapiStore *mapi_store;
 	CamelMapiFolder *mapi_folder;
-	CamelMapiFolderSummary *mapi_summary;
 	CamelService *service;
-	CamelSession *session;
 	CamelStore *parent_store;
-
-	gboolean is_proxy;
 	gboolean is_locked = FALSE;
 	gboolean status;
 	gboolean success = TRUE;
+	GError *mapi_error = NULL;
 
-	struct SSortOrderSet *sort = NULL;
-	fetch_items_data *fetch_data = g_new0 (fetch_items_data, 1);
-	const gchar *folder_id = NULL;
-	const gchar *full_name;
-
-	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);
-	mapi_summary = CAMEL_MAPI_FOLDER_SUMMARY (folder->summary);
-
-	is_proxy = parent_store->flags & CAMEL_STORE_PROXY;
-
 	service = CAMEL_SERVICE (parent_store);
-	session = camel_service_get_session (service);
 
 	if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)))
 		goto end1;
@@ -840,14 +894,12 @@ mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **err
 	so that the getFolderList will reflect the most recent changes too */
 	mapi_folder_synchronize_sync (folder, FALSE, cancellable, NULL);
 
-	//creating a copy
-	folder_id = camel_mapi_store_folder_id_lookup (mapi_store, full_name);
-	if (!folder_id) {
+	if (!mapi_folder->folder_id) {
 		d(printf ("\nERROR - Folder id not present. Cannot refresh info for %s\n", full_name));
 		goto end1;
 	}
 
-	if (camel_folder_is_frozen (folder) ) {
+	if (camel_folder_is_frozen (folder)) {
 		mapi_folder->need_refresh = TRUE;
 	}
 
@@ -857,98 +909,42 @@ mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **err
 	if (!camel_mapi_store_connected (mapi_store, NULL))
 		goto end1;
 
-	/*Get the New Items*/
-	if (!is_proxy) {
-		SyncDeletedData *sync_data;
-		mapi_id_t temp_folder_id;
-		guint32 options = 0;
-		GError *mapi_error = NULL;
-
-		if (mapi_summary->sync_time_stamp && *mapi_summary->sync_time_stamp)
-			g_time_val_from_iso8601 (mapi_summary->sync_time_stamp,
-						 &fetch_data->last_modification_time);
-
-	        /*Initialize other fetch_data fields*/
-		fetch_data->changes = camel_folder_change_info_new ();
-		fetch_data->folder = folder;
-
-		/*Set sort order*/
-		sort = g_new0 (struct SSortOrderSet, 1);
-		sort->cSorts = 1;
-		sort->aSort = g_new0 (struct SSortOrder, sort->cSorts);
-		sort->aSort[0].ulPropTag = PR_LAST_MODIFICATION_TIME;
-		sort->aSort[0].ulOrder = TABLE_SORT_ASCEND;
+	if (!camel_mapi_store_connected (mapi_store, NULL)) {
+		/*BUG : Fix exception string.*/
+		g_set_error (
+			error, CAMEL_SERVICE_ERROR,
+			CAMEL_SERVICE_ERROR_UNAVAILABLE,
+			_("This message is not available in offline mode."));
+		success = FALSE;
+		goto end1;
+	}
 
-		e_mapi_util_mapi_id_from_string (folder_id, &temp_folder_id);
+	status = camel_mapi_folder_fetch_summary (folder, cancellable, &mapi_error);
 
-		if (!camel_mapi_store_connected (mapi_store, NULL)) {
-			/*BUG : Fix exception string.*/
+	if (!status) {
+		if (mapi_error) {
 			g_set_error (
-				error, CAMEL_SERVICE_ERROR,
-				CAMEL_SERVICE_ERROR_UNAVAILABLE,
-				_("This message is not available in offline mode."));
-			success = FALSE;
-			goto end1;
-		}
-
-		options |= MAPI_OPTIONS_FETCH_RECIPIENTS;
-
-		if (((CamelMapiFolder *)folder)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC)
-			options |= MAPI_OPTIONS_USE_PFSTORE;
-
-		status = camel_mapi_folder_fetch_summary ((CamelStore *)mapi_store, folder, temp_folder_id,
-							  cmf_build_last_modify_restriction, mapi_summary->sync_time_stamp, sort,
-							  fetch_data, options, cancellable, &mapi_error);
-
-		if (!status) {
-			if (mapi_error) {
-				g_set_error (
-					error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_INVALID,
-					_("Fetching items failed: %s"), mapi_error->message);
-				g_error_free (mapi_error);
-			} else {
-				g_set_error_literal (
-					error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_INVALID,
-					_("Fetching items failed"));
-			}
-			success = FALSE;
-			goto end1;
+				error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_INVALID,
+				_("Fetching items failed: %s"), mapi_error->message);
+			g_error_free (mapi_error);
+		} else {
+			g_set_error_literal (
+				error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_INVALID,
+				_("Fetching items failed"));
 		}
+		success = FALSE;
+		goto end1;
+	}
 
-		/*Preserve last_modification_time from this fetch for later use with restrictions.*/
-		g_free (mapi_summary->sync_time_stamp);
-		mapi_summary->sync_time_stamp = g_time_val_to_iso8601 (&fetch_data->last_modification_time);
-
-		camel_folder_summary_touch (folder->summary);
-		update_store_summary (folder, NULL);
+	camel_folder_summary_touch (folder->summary);
 
-		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
-		is_locked = FALSE;
-
-		/* Downsync deleted items */
-		sync_data = g_slice_new0 (SyncDeletedData);
-		sync_data->folder = g_object_ref (folder);
-		sync_data->folder_id = temp_folder_id;
-		sync_data->need_refresh = FALSE;
-
-		camel_session_submit_job (
-			session,
-			(CamelSessionCallback) mapi_sync_deleted,
-			sync_data,
-			(GDestroyNotify) mapi_sync_deleted_data_free);
-
-		camel_folder_changed (folder, fetch_data->changes);
-		camel_folder_change_info_free (fetch_data->changes);
-	}
+	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+	is_locked = FALSE;
 
-end1:
+ end1:
 	if (is_locked)
 		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	g_slist_foreach (fetch_data->items_list, (GFunc) mail_item_free, NULL);
-	g_slist_free (fetch_data->items_list);
-	g_free (fetch_data);
-
 	return success;
 }
 
@@ -1197,7 +1193,7 @@ mapi_folder_append_message_sync (CamelFolder *folder,
 	}
 
 	if (appended_uid)
-		*appended_uid = e_mapi_util_mapi_ids_to_uid(fid, mid);
+		*appended_uid = e_mapi_util_mapi_id_to_string (mid);
 
 	return TRUE;
 }
@@ -1213,27 +1209,20 @@ mapi_folder_expunge_sync (CamelFolder *folder,
 	CamelMessageInfo *info;
 	CamelFolderChangeInfo *changes;
 	CamelStore *parent_store;
-	mapi_id_t fid;
 	GPtrArray *known_uids;
 	gint i;
 	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));
-	e_mapi_util_mapi_id_from_string (folder_id, &fid);
-
 	if ((mapi_folder->camel_folder_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
 		GError *mapi_error = NULL;
 		GPtrArray *folders;
@@ -1259,7 +1248,7 @@ mapi_folder_expunge_sync (CamelFolder *folder,
 		g_ptr_array_free (folders, TRUE);
 
 		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-		status = e_mapi_connection_empty_folder (camel_mapi_store_get_connection (mapi_store), fid, 0, cancellable, &mapi_error);
+		status = e_mapi_connection_empty_folder (camel_mapi_store_get_connection (mapi_store), mapi_folder->folder_id, 0, cancellable, &mapi_error);
 		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 		if (status) {
@@ -1291,7 +1280,7 @@ mapi_folder_expunge_sync (CamelFolder *folder,
 			const gchar *uid = camel_message_info_uid (info);
 			mapi_id_t *mid = g_new0 (mapi_id_t, 1);
 
-			if (!e_mapi_util_mapi_ids_from_uid (uid, &fid, mid))
+			if (!e_mapi_util_mapi_id_from_string (uid, mid))
 				continue;
 
 			if (deleted_items)
@@ -1313,7 +1302,7 @@ mapi_folder_expunge_sync (CamelFolder *folder,
 	if (deleted_items) {
 		camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-		status = e_mapi_connection_remove_items (camel_mapi_store_get_connection (mapi_store), 0, fid, 0, deleted_items, cancellable, NULL);
+		status = e_mapi_connection_remove_items (camel_mapi_store_get_connection (mapi_store), 0, mapi_folder->folder_id, 0, deleted_items, cancellable, NULL);
 
 		camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
@@ -1338,7 +1327,6 @@ mapi_folder_expunge_sync (CamelFolder *folder,
 	if (delete)
 		camel_folder_changed (folder, changes);
 
-	g_free (folder_id);
 	camel_folder_change_info_free (changes);
 
 	return TRUE;
@@ -1394,7 +1382,6 @@ mapi_folder_get_message_sync (CamelFolder *folder,
 	CamelMapiMessageInfo *mi = NULL;
 	CamelStream *cache_stream;
 	CamelStore *parent_store;
-	mapi_id_t id_folder;
 	mapi_id_t id_message;
 	MailItem *item = NULL;
 	guint32 options = 0;
@@ -1447,14 +1434,14 @@ mapi_folder_get_message_sync (CamelFolder *folder,
 	options = MAPI_OPTIONS_FETCH_ALL | MAPI_OPTIONS_FETCH_BODY_STREAM |
 		MAPI_OPTIONS_GETBESTBODY | MAPI_OPTIONS_FETCH_RECIPIENTS;
 
-	e_mapi_util_mapi_ids_from_uid (uid, &id_folder, &id_message);
+	e_mapi_util_mapi_id_from_string (uid, &id_message);
 
 	if (((CamelMapiFolder *)folder)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) {
 		options |= MAPI_OPTIONS_USE_PFSTORE;
 	}
 
 	camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	e_mapi_connection_fetch_item (camel_mapi_store_get_connection (mapi_store), id_folder, id_message,
+	e_mapi_connection_fetch_item (camel_mapi_store_get_connection (mapi_store), mapi_folder->folder_id, id_message,
 					mapi_mail_get_item_prop_list, NULL,
 					fetch_props_to_mail_item_cb, &item,
 					options, cancellable, &mapi_error);
@@ -1527,10 +1514,7 @@ mapi_folder_refresh_info_sync (CamelFolder *folder,
                                GCancellable *cancellable,
                                GError **error)
 {
-	if (!mapi_refresh_folder (folder, cancellable, error))
-		return FALSE;
-
-	return update_store_summary (folder, error);
+	return mapi_refresh_folder (folder, cancellable, error);
 }
 
 static gboolean
@@ -1556,7 +1540,6 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
 	gint 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);
@@ -1568,8 +1551,8 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
 	status = camel_service_get_connection_status (service);
 
 	if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)) ||
-			status == CAMEL_SERVICE_DISCONNECTED) {
-		return update_store_summary (folder, error);
+	    status == CAMEL_SERVICE_DISCONNECTED) {
+		return TRUE;
 	}
 
 	if (((CamelMapiFolder *)folder)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC)
@@ -1598,7 +1581,6 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
 		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;
 
@@ -1606,7 +1588,7 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
 			flags= camel_message_info_flags (info);
 
 			/* Why are we getting so much noise here :-/ */
-			if (!e_mapi_util_mapi_ids_from_uid (uid, &temp_fid, mid)) {
+			if (!e_mapi_util_mapi_id_from_string (uid, mid)) {
 				camel_message_info_free (info);
 				g_free (mid);
 				continue;
@@ -1739,11 +1721,7 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
 		/* TODO */
 	}
 
-	camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
-	success = update_store_summary (folder, error);
-	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
-
-	return success;
+	return TRUE;
 }
 
 static gboolean
@@ -1755,7 +1733,6 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
                                        GCancellable *cancellable,
                                        GError **error)
 {
-	mapi_id_t src_fid, dest_fid;
 	guint32 src_fid_options, dest_fid_options;
 
 	CamelOfflineStore *offline;
@@ -1763,9 +1740,7 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
 	CamelFolderChangeInfo *changes = NULL;
 	CamelStore *source_parent_store;
 	CamelStore *destination_parent_store;
-	const gchar *folder_id = NULL;
-	const gchar *source_full_name;
-	const gchar *destination_full_name;
+	CamelMapiFolder *src_mapi_folder, *des_mapi_folder;
 	gint i = 0;
 	GSList *src_msg_ids = NULL;
 	gboolean success = TRUE;
@@ -1789,10 +1764,7 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
 			transferred_uids, cancellable, error);
 	}
 
-	source_full_name = camel_folder_get_full_name (source);
 	source_parent_store = camel_folder_get_parent_store (source);
-
-	destination_full_name = camel_folder_get_full_name (destination);
 	destination_parent_store = camel_folder_get_parent_store (destination);
 
 	mapi_store = CAMEL_MAPI_STORE (source_parent_store);
@@ -1802,17 +1774,15 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
 	if (!camel_offline_store_get_online (offline))
 		return FALSE;
 
-	folder_id =  camel_mapi_store_folder_id_lookup (mapi_store, source_full_name);
-	e_mapi_util_mapi_id_from_string (folder_id, &src_fid);
-	src_fid_options = (CAMEL_MAPI_FOLDER (source)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0 ? MAPI_OPTIONS_USE_PFSTORE : 0;
+	src_mapi_folder = CAMEL_MAPI_FOLDER (source);
+	src_fid_options = (src_mapi_folder->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0 ? MAPI_OPTIONS_USE_PFSTORE : 0;
 
-	folder_id = camel_mapi_store_folder_id_lookup (mapi_store, destination_full_name);
-	e_mapi_util_mapi_id_from_string (folder_id, &dest_fid);
-	dest_fid_options = (CAMEL_MAPI_FOLDER (destination)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0 ? MAPI_OPTIONS_USE_PFSTORE : 0;
+	des_mapi_folder = CAMEL_MAPI_FOLDER (destination);
+	dest_fid_options = (des_mapi_folder->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0 ? MAPI_OPTIONS_USE_PFSTORE : 0;
 
 	for (i=0; i < uids->len; i++) {
 		mapi_id_t *mid = g_new0 (mapi_id_t, 1); /* FIXME : */
-		if (!e_mapi_util_mapi_ids_from_uid (g_ptr_array_index (uids, i), &src_fid, mid))
+		if (!e_mapi_util_mapi_id_from_string (g_ptr_array_index (uids, i), mid))
 			continue;
 
 		src_msg_ids = g_slist_prepend (src_msg_ids, mid);
@@ -1821,7 +1791,7 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
 	if (delete_originals) {
 		GError *err = NULL;
 
-		if (!e_mapi_connection_move_items (camel_mapi_store_get_connection (mapi_store), src_fid, src_fid_options, dest_fid, dest_fid_options, src_msg_ids, cancellable, &err)) {
+		if (!e_mapi_connection_move_items (camel_mapi_store_get_connection (mapi_store), src_mapi_folder->folder_id, src_fid_options, des_mapi_folder->folder_id, dest_fid_options, src_msg_ids, cancellable, &err)) {
 			g_set_error (
 				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
 				"%s", err ? err->message : _("Unknown error"));
@@ -1842,7 +1812,7 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
 	} else {
 		GError *err = NULL;
 
-		if (!e_mapi_connection_copy_items (camel_mapi_store_get_connection (mapi_store), src_fid, src_fid_options, dest_fid, dest_fid_options, src_msg_ids, cancellable, &err)) {
+		if (!e_mapi_connection_copy_items (camel_mapi_store_get_connection (mapi_store), src_mapi_folder->folder_id, src_fid_options, des_mapi_folder->folder_id, dest_fid_options, src_msg_ids, cancellable, &err)) {
 			g_set_error (
 				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
 				"%s", err ? err->message : _("Unknown error"));
@@ -2004,6 +1974,7 @@ camel_mapi_folder_new (CamelStore *store, const gchar *folder_name, const gchar
 
 		mapi_folder->mapi_folder_flags = msi->mapi_folder_flags;
 		mapi_folder->camel_folder_flags = msi->camel_folder_flags;
+		mapi_folder->folder_id = msi->folder_id;
 
 		if ((si->flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH)
 			folder->folder_flags |= CAMEL_FOLDER_IS_TRASH;
diff --git a/src/camel/camel-mapi-folder.h b/src/camel/camel-mapi-folder.h
index 39baae6..b0fb595 100644
--- a/src/camel/camel-mapi-folder.h
+++ b/src/camel/camel-mapi-folder.h
@@ -61,6 +61,8 @@ struct _CamelMapiFolder {
 	CamelOfflineFolder parent;
 	CamelMapiFolderPrivate *priv;
 
+	mapi_id_t folder_id;
+
 	CamelFolderSearch *search;
 
 	CamelOfflineJournal *journal;
@@ -94,8 +96,7 @@ camel_mapi_folder_new(CamelStore *store, const gchar *folder_name, const gchar *
 
 void mapi_update_summary ( CamelFolder *folder, GList *item_list,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, BuildRestrictionsCB build_rs_cb, gpointer build_rs_cb_data,
-					  struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GCancellable *cancellable, GError **mapi_error);
+gboolean camel_mapi_folder_fetch_summary (CamelFolder *folder, 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 25c9d24..21e9bcd 100644
--- a/src/camel/camel-mapi-notifications.c
+++ b/src/camel/camel-mapi-notifications.c
@@ -57,40 +57,9 @@ struct mapi_push_notification_data {
 	GThread *thread;
 };
 
-static gboolean
-cmn_build_mid_restriction (EMapiConnection *conn,
-			   mapi_id_t fid,
-			   TALLOC_CTX *mem_ctx,
-			   struct mapi_SRestriction **restrictions,
-			   gpointer user_data,
-			   GCancellable *cancellable,
-			   GError **perror)
-{
-	mapi_id_t *pmid = user_data;
-	struct mapi_SRestriction *restriction;
-
-	g_return_val_if_fail (pmid != NULL, FALSE);
-	g_return_val_if_fail (restrictions != NULL, FALSE);
-
-	restriction = talloc_zero (mem_ctx, struct mapi_SRestriction);
-	g_return_val_if_fail (restriction != NULL, FALSE);
-
-	restriction->rt = RES_PROPERTY;
-	restriction->res.resProperty.relop = RES_PROPERTY;
-	restriction->res.resProperty.ulPropTag = PR_MID;
-	restriction->res.resProperty.lpProp.ulPropTag = PR_MID;
-	restriction->res.resProperty.lpProp.value.dbl = *pmid;
-
-	*restrictions = restriction;
-
-	return TRUE;
-}
-
 static void
 process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *new_mail_notif)
 {
-	guint32 options = 0;
-	fetch_items_data *fetch_data;
 	CamelFolder *folder = NULL;
 	CamelStore *parent_store;
 	gint info_count = -1;
@@ -111,7 +80,7 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
 	while (info_count >= 0) {
 		si = camel_store_summary_index (store->summary, info_count);
 		msi = (CamelMapiStoreInfo *) si;
-		if (si && msi->folder_mid == new_mail_notif->FID) {
+		if (si && msi->folder_id == new_mail_notif->FID) {
 			folder_name = camel_store_info_path (store->summary, si);
 			info_count = 0;
 		}
@@ -128,12 +97,8 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
 
 	parent_store = camel_folder_get_parent_store (folder);
 
-	fetch_data = g_new0 (fetch_items_data, 1);
-	fetch_data->changes = camel_folder_change_info_new ();
-	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, cmn_build_mid_restriction, &new_mail_notif->MID, NULL, fetch_data, options, NULL, NULL);
+	camel_mapi_folder_fetch_summary (folder, NULL, NULL);
 	camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	camel_folder_summary_touch (folder->summary);
@@ -141,10 +106,6 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
 	camel_folder_summary_save_to_db (folder->summary, NULL);
 	camel_store_summary_touch (((CamelMapiStore *)parent_store)->summary);
 	camel_store_summary_save (((CamelMapiStore *)parent_store)->summary);
-
-	camel_folder_changed (folder, fetch_data->changes);
-
-	camel_folder_change_info_free (fetch_data->changes);
 }
 
 static gint
diff --git a/src/camel/camel-mapi-store-summary.c b/src/camel/camel-mapi-store-summary.c
index 35cf80d..162c3c5 100644
--- a/src/camel/camel-mapi-store-summary.c
+++ b/src/camel/camel-mapi-store-summary.c
@@ -138,8 +138,8 @@ store_info_load (CamelStoreSummary *s, FILE *in)
 		    || camel_file_util_decode_uint32 (in, &msi->camel_folder_flags) == -1
 		    || camel_file_util_decode_uint32 (in, &msi->mapi_folder_flags) == -1
 		    || camel_file_util_decode_string (in, &msi->foreign_user_name) == -1
-		    || !e_mapi_util_mapi_id_from_string (folder_id_str, &msi->folder_mid)
-		    || !e_mapi_util_mapi_id_from_string (parent_id_str, &msi->parent_mid)) {
+		    || !e_mapi_util_mapi_id_from_string (folder_id_str, &msi->folder_id)
+		    || !e_mapi_util_mapi_id_from_string (parent_id_str, &msi->parent_id)) {
 			camel_store_summary_info_free (s, si);
 			si = NULL;
 		} else {
@@ -166,8 +166,8 @@ store_info_save (CamelStoreSummary *s, FILE *out, CamelStoreInfo *si)
 
 	store_summary_class = CAMEL_STORE_SUMMARY_CLASS (camel_mapi_store_summary_parent_class);
 
-	folder_id_str = e_mapi_util_mapi_id_to_string (msi->folder_mid);
-	parent_id_str = e_mapi_util_mapi_id_to_string (msi->parent_mid);
+	folder_id_str = e_mapi_util_mapi_id_to_string (msi->folder_id);
+	parent_id_str = e_mapi_util_mapi_id_to_string (msi->parent_id);
 
 	if (store_summary_class->store_info_save (s, out, si) == -1
 	    || camel_file_util_encode_string (out, folder_id_str) == -1
@@ -229,8 +229,8 @@ camel_mapi_store_summary_new (void)
 CamelStoreInfo *
 camel_mapi_store_summary_add_from_full (CamelStoreSummary *s,
 					const gchar *path,
-					mapi_id_t folder_mid,
-					mapi_id_t parent_mid,
+					mapi_id_t folder_id,
+					mapi_id_t parent_id,
 					guint32 camel_folder_flags,
 					guint32 mapi_folder_flags,
 					const gchar *foreign_user_name)
@@ -247,8 +247,8 @@ camel_mapi_store_summary_add_from_full (CamelStoreSummary *s,
 	if (si) {
 		CamelMapiStoreInfo *msi = (CamelMapiStoreInfo *) si;
 
-		msi->folder_mid = folder_mid;
-		msi->parent_mid = parent_mid;
+		msi->folder_id = folder_id;
+		msi->parent_id = parent_id;
 		msi->camel_folder_flags = camel_folder_flags;
 		msi->mapi_folder_flags = mapi_folder_flags;
 		msi->foreign_user_name = g_strdup ((foreign_user_name && *foreign_user_name) ? foreign_user_name : "");
@@ -259,7 +259,7 @@ camel_mapi_store_summary_add_from_full (CamelStoreSummary *s,
 
 /* free the returned pointer with camel_store_summary_info_free(), if not NULL */
 CamelStoreInfo *
-camel_mapi_store_summary_get_folder_id (CamelStoreSummary *s, mapi_id_t folder_mid)
+camel_mapi_store_summary_get_folder_id (CamelStoreSummary *s, mapi_id_t folder_id)
 {
 	gint ii, count;
 
@@ -271,7 +271,7 @@ camel_mapi_store_summary_get_folder_id (CamelStoreSummary *s, mapi_id_t folder_m
 		if (si == NULL)
 			continue;
 
-		if (msi->folder_mid == folder_mid)
+		if (msi->folder_id == folder_id)
 			return si;
 
 		camel_store_summary_info_free (s, si);
diff --git a/src/camel/camel-mapi-store-summary.h b/src/camel/camel-mapi-store-summary.h
index 2124232..9715d79 100644
--- a/src/camel/camel-mapi-store-summary.h
+++ b/src/camel/camel-mapi-store-summary.h
@@ -67,8 +67,8 @@ enum {
 
 struct _CamelMapiStoreInfo {
 	CamelStoreInfo info;
-	mapi_id_t folder_mid;
-	mapi_id_t parent_mid;
+	mapi_id_t folder_id;
+	mapi_id_t parent_id;
 	guint32 camel_folder_flags; /* CamelFolderInfo::flags */
 	guint32 mapi_folder_flags; /* bit-or of CamelMapiStoreFolderFlags */
 	gchar *foreign_user_name; /* only if CAMEL_MAPI_STORE_FOLDER_FLAG_FOREIGN is set */
@@ -87,13 +87,13 @@ GType			camel_mapi_store_summary_get_type	(void);
 CamelStoreSummary *	camel_mapi_store_summary_new		(void);
 CamelStoreInfo *	camel_mapi_store_summary_add_from_full	(CamelStoreSummary *s,
 								 const gchar *path,
-								 mapi_id_t folder_mid,
-								 mapi_id_t parent_mid,
+								 mapi_id_t folder_id,
+								 mapi_id_t parent_id,
 								 guint32 camel_folder_flags, /* CamelFolderInfo::flags */
 								 guint32 mapi_folder_flags, /* bit-or of CamelMapiStoreFolderFlags */
 								 const gchar *foreign_user_name); /* only if CAMEL_MAPI_STORE_FOLDER_FLAG_FOREIGN is set */
 CamelStoreInfo *	camel_mapi_store_summary_get_folder_id	(CamelStoreSummary *s,
-								 mapi_id_t folder_mid);
+								 mapi_id_t folder_id);
 
 G_END_DECLS
 
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index b719667..8057860 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -769,7 +769,7 @@ mapi_rename_folder_infos (CamelMapiStore *mapi_store, const gchar *old_name, con
 		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 */
-			mapi_id_t fid = ((CamelMapiStoreInfo *)si)->folder_mid;
+			mapi_id_t fid = ((CamelMapiStoreInfo *)si)->folder_id;
 
 			if (fid) {
 				gchar *new_full_name;
@@ -943,12 +943,14 @@ mapi_update_folder_info_cb (CamelSession *session,
 
 	name = camel_service_get_name (service, TRUE);
 	camel_operation_push_message (cancellable, _("Scanning folders in '%s'"), name);
-	g_free (name);
 
 	status = camel_service_get_connection_status (service);
 	if (camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
-		if (status == CAMEL_SERVICE_DISCONNECTED)
+		if (status == CAMEL_SERVICE_DISCONNECTED) {
+			camel_operation_push_message (cancellable, _("Connecting to '%s'"), name);
 			camel_service_connect_sync (service, NULL);
+			camel_operation_pop_message (cancellable); 
+		}
 
 		/* 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
@@ -962,6 +964,7 @@ mapi_update_folder_info_cb (CamelSession *session,
 		}
 	}
 
+	g_free (name);
 	camel_operation_pop_message (cancellable); 
 
 	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -982,6 +985,10 @@ mapi_store_get_folder_info_sync (CamelStore *store,
 	camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	if (camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
+		CamelServiceConnectionStatus status;
+
+		status = camel_service_get_connection_status (service);
+
 		/* 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 */
@@ -989,10 +996,6 @@ mapi_store_get_folder_info_sync (CamelStore *store,
 		    (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) ||
 		    (top && *top && !camel_mapi_store_folder_id_lookup (mapi_store, top)) ||
 		    camel_store_summary_count (mapi_store->summary) <= 1) {
-			CamelServiceConnectionStatus status;
-
-			status = camel_service_get_connection_status (service);
-
 			if (status == CAMEL_SERVICE_DISCONNECTED)
 				camel_service_connect_sync (service, NULL);
 
@@ -1003,6 +1006,8 @@ mapi_store_get_folder_info_sync (CamelStore *store,
 				}
 			}
 		} else if (!mapi_store->priv->folders_synced) {
+			mapi_store->priv->folders_synced = TRUE;
+
 			camel_session_submit_job (
 				camel_service_get_session (CAMEL_SERVICE (store)),
 				mapi_update_folder_info_cb,
@@ -1379,7 +1384,7 @@ mapi_store_rename_folder_sync (CamelStore *store,
 
 		camel_store_info_set_string (mapi_store->summary, si, CAMEL_STORE_INFO_PATH, new_name);
 		if (new_parent_fid_str && e_mapi_util_mapi_id_from_string (new_parent_fid_str, &new_parent_fid))
-			((CamelMapiStoreInfo *) si)->parent_mid = new_parent_fid;
+			((CamelMapiStoreInfo *) si)->parent_id = new_parent_fid;
 		camel_store_summary_info_free (mapi_store->summary, si);
 		camel_store_summary_touch (mapi_store->summary);
 	}
@@ -1704,6 +1709,7 @@ mapi_connect_sync (CamelService *service,
 	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
 	CamelServiceConnectionStatus status;
 	CamelSession *session;
+	gchar *name;
 	guint16 event_mask = 0;
 
 	session = camel_service_get_session (service);
@@ -1719,12 +1725,19 @@ mapi_connect_sync (CamelService *service,
 		return TRUE;
 	}
 
+	name = camel_service_get_name (service, TRUE);
+	camel_operation_push_message (cancellable, _("Connecting to '%s'"), name);
+	g_free (name);
+
 	if (!camel_session_authenticate_sync (session, service, NULL, cancellable, error)) {
+		camel_operation_pop_message (cancellable);
 		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 		camel_service_disconnect_sync (service, TRUE, NULL);
 		return FALSE;
 	}
 
+	camel_operation_pop_message (cancellable);
+
 	camel_offline_store_set_online_sync (
 		CAMEL_OFFLINE_STORE (store), TRUE, cancellable, NULL);
 
@@ -1950,8 +1963,8 @@ mapi_folders_update_hash_tables_from_cache (CamelMapiStore *store)
 		if (msi == NULL)
 			continue;
 
-		fid = e_mapi_util_mapi_id_to_string (msi->folder_mid);
-		pid = e_mapi_util_mapi_id_to_string (msi->parent_mid);
+		fid = e_mapi_util_mapi_id_to_string (msi->folder_id);
+		pid = e_mapi_util_mapi_id_to_string (msi->parent_id);
 
 		mapi_update_folder_hash_tables (store, camel_store_info_path (summary, msi), fid, pid);
 
diff --git a/src/libexchangemapi/e-mapi-connection.c b/src/libexchangemapi/e-mapi-connection.c
index f078650..5aefef7 100644
--- a/src/libexchangemapi/e-mapi-connection.c
+++ b/src/libexchangemapi/e-mapi-connection.c
@@ -2213,6 +2213,7 @@ e_mapi_connection_transfer_objects (EMapiConnection *conn,
 	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
 	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
 	e_return_val_mapi_error_if_fail (cb != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+	e_return_val_mapi_error_if_fail (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
 
 	LOCK ();
 	mem_ctx = talloc_new (priv->session);
@@ -2247,6 +2248,180 @@ e_mapi_connection_transfer_objects (EMapiConnection *conn,
 	return ms == MAPI_E_SUCCESS;
 }
 
+struct GetSummaryData {
+	guint32 obj_index;
+	guint32 obj_total;
+	struct SPropValue *lpProps;
+	uint32_t prop_count;
+	TransferObjectCB cb;
+	gpointer cb_user_data;
+};
+
+static gboolean
+internal_get_summary_cb (EMapiConnection *conn,
+			 TALLOC_CTX *mem_ctx,
+			 /* const */ EMapiObject *object,
+			 guint32 obj_index,
+			 guint32 obj_total,
+			 gpointer user_data,
+			 GCancellable *cancellable,
+			 GError **perror)
+{
+	struct GetSummaryData *gsd = user_data;
+
+	g_return_val_if_fail (gsd != NULL, FALSE);
+	g_return_val_if_fail (gsd->cb != NULL, FALSE);
+	g_return_val_if_fail (object != NULL, FALSE);
+
+	/* also include properties received from GetProps,
+	   as those like PR_MID are not included by default */
+	if (gsd->lpProps && gsd->prop_count > 0) {
+		uint32_t ii;
+
+		for (ii = 0; ii < gsd->prop_count; ii++) {
+			/* skip errors and already included properties */
+			if ((gsd->lpProps[ii].ulPropTag & 0xFFFF) == PT_ERROR
+			    || e_mapi_util_find_array_propval (&object->properties, gsd->lpProps[ii].ulPropTag))
+				continue;
+
+			object->properties.cValues++;
+			object->properties.lpProps = talloc_realloc (mem_ctx,
+					    object->properties.lpProps,
+					    struct mapi_SPropValue,
+					    object->properties.cValues + 1);
+			cast_mapi_SPropValue (mem_ctx, &object->properties.lpProps[object->properties.cValues - 1], &gsd->lpProps[ii]);
+			object->properties.lpProps[object->properties.cValues].ulPropTag = 0;
+		}
+	}
+
+	return gsd->cb (conn, mem_ctx, object, gsd->obj_index, gsd->obj_total, gsd->cb_user_data, cancellable, perror);
+}
+
+/* transfers items summary, which is either PR_TRANSPORT_MESSAGE_HEADERS_UNICODE or
+   the object without attachment */
+gboolean
+e_mapi_connection_transfer_summary (EMapiConnection *conn,
+				    mapi_object_t *obj_folder,
+				    const GSList *mids,
+				    TransferObjectCB cb,
+				    gpointer cb_user_data,
+				    GCancellable *cancellable,
+				    GError **perror)
+{
+	enum MAPISTATUS ms;
+	TALLOC_CTX *mem_ctx;
+	const GSList *iter;
+	guint32 index, total;
+
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+	e_return_val_mapi_error_if_fail (cb != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+	e_return_val_mapi_error_if_fail (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+
+	LOCK ();
+	mem_ctx = talloc_new (priv->session);
+
+	ms = MAPI_E_SUCCESS;
+	total = g_slist_length ((GSList *) mids);
+	for (iter = mids, index = 0; iter && ms == MAPI_E_SUCCESS; iter = iter->next, index++) {
+		mapi_id_t *pmid = iter->data;
+
+		if (pmid) {
+			mapi_object_t obj_message;
+			struct SPropTagArray *tags;
+			struct SPropValue *lpProps = NULL;
+			uint32_t prop_count = 0, ii;
+
+			mapi_object_init (&obj_message);
+
+			ms = OpenMessage (obj_folder, mapi_object_get_id (obj_folder), *pmid, &obj_message, 0);
+			if (ms != MAPI_E_SUCCESS && ms != MAPI_E_NOT_FOUND) {
+				make_mapi_error (perror, "OpenMessage", ms);
+				goto cleanup;
+			}
+
+			tags = set_SPropTagArray (mem_ctx, 6,
+				PR_FID,
+				PR_MID,
+				PR_MESSAGE_FLAGS,
+				PR_LAST_MODIFICATION_TIME,
+				PR_MESSAGE_CLASS,
+				PR_TRANSPORT_MESSAGE_HEADERS_UNICODE);
+
+			ms = GetProps (&obj_message, MAPI_PROPS_SKIP_NAMEDID_CHECK | MAPI_UNICODE, tags, &lpProps, &prop_count);
+			if (ms == MAPI_E_SUCCESS) {
+				ms = MAPI_E_NOT_FOUND;
+				if (lpProps && prop_count > 0) {
+					const gchar *headers = e_mapi_util_find_SPropVal_array_propval (lpProps, PR_TRANSPORT_MESSAGE_HEADERS_UNICODE);
+
+					if (headers && *headers) {
+						EMapiObject *object;
+
+						ms = MAPI_E_SUCCESS;
+
+						object = e_mapi_object_new (mem_ctx);
+						for (ii = 0; ii < prop_count; ii++) {
+							object->properties.cValues++;
+							object->properties.lpProps = talloc_realloc (mem_ctx,
+									    object->properties.lpProps,
+									    struct mapi_SPropValue,
+									    object->properties.cValues + 1);
+							cast_mapi_SPropValue (mem_ctx, &object->properties.lpProps[object->properties.cValues - 1], &lpProps[ii]);
+							object->properties.lpProps[object->properties.cValues].ulPropTag = 0;
+						}
+
+						if (!cb (conn, mem_ctx, object, index, total, cb_user_data, cancellable, perror)) {
+							ms = MAPI_E_USER_CANCEL;
+							e_mapi_object_free (object);
+							mapi_object_release (&obj_message);
+							goto cleanup;
+						}
+
+						e_mapi_object_free (object);
+					}
+				}
+			}
+
+			if (ms == MAPI_E_NOT_FOUND) {
+				struct GetSummaryData gsd;
+
+				gsd.obj_index = index;
+				gsd.obj_total = total;
+				gsd.lpProps = lpProps;
+				gsd.prop_count = prop_count;
+				gsd.cb = cb;
+				gsd.cb_user_data = cb_user_data;
+
+				ms = e_mapi_fast_transfer_object (conn, mem_ctx, &obj_message, E_MAPI_FAST_TRANSFER_FLAG_RECIPIENTS, internal_get_summary_cb, &gsd, cancellable, perror);
+				if (ms != MAPI_E_SUCCESS) {
+					make_mapi_error (perror, "transfer_object", ms);
+					mapi_object_release (&obj_message);
+					goto cleanup;
+				}
+			}
+
+			mapi_object_release (&obj_message);
+			talloc_free (tags);
+		}
+
+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
+			ms = MAPI_E_USER_CANCEL;
+			goto cleanup;
+		}
+	}
+
+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
+		ms = MAPI_E_USER_CANCEL;
+		goto cleanup;
+	}
+
+ cleanup:
+	talloc_free (mem_ctx);
+	UNLOCK ();
+
+	return ms == MAPI_E_SUCCESS;
+}
+
 gboolean
 e_mapi_connection_fetch_items  (EMapiConnection *conn,
 				mapi_id_t fid,
diff --git a/src/libexchangemapi/e-mapi-connection.h b/src/libexchangemapi/e-mapi-connection.h
index b0f919a..15afe6a 100644
--- a/src/libexchangemapi/e-mapi-connection.h
+++ b/src/libexchangemapi/e-mapi-connection.h
@@ -328,6 +328,14 @@ gboolean		e_mapi_connection_transfer_objects	(EMapiConnection *conn,
 								 GCancellable *cancellable,
 								 GError **perror);
 
+gboolean		e_mapi_connection_transfer_summary	(EMapiConnection *conn,
+								 mapi_object_t *obj_folder,
+								 const GSList *mids,
+								 TransferObjectCB cb,
+								 gpointer cb_user_data,
+								 GCancellable *cancellable,
+								 GError **perror);
+
 gboolean		e_mapi_connection_fetch_object_props	(EMapiConnection *conn,
 								 mapi_object_t *obj_folder,
 								 mapi_id_t fid,



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