[evolution-mapi] Use callback for Restrictions generation



commit 151dbf0b661d9b2075ff1b583c32897f7e83a063
Author: Milan Crha <mcrha redhat com>
Date:   Wed Nov 2 13:07:36 2011 +0100

    Use callback for Restrictions generation
    
    Good, because of provided talloc's mem_ctx into the callback

 src/addressbook/e-book-backend-mapi-contacts.c |   55 ++++--
 src/addressbook/e-book-backend-mapi-gal.c      |    6 +-
 src/addressbook/e-book-backend-mapi.c          |   72 ++++----
 src/addressbook/e-book-backend-mapi.h          |    2 +-
 src/calendar/e-cal-backend-mapi.c              |  226 +++++++++++++++---------
 src/camel/camel-mapi-folder.c                  |   83 ++++++----
 src/camel/camel-mapi-folder.h                  |    2 +-
 src/camel/camel-mapi-notifications.c           |   43 +++--
 src/libexchangemapi/e-mapi-cal-utils.c         |   82 ++++++---
 src/libexchangemapi/e-mapi-connection.c        |  184 +++++---------------
 src/libexchangemapi/e-mapi-connection.h        |   22 ++-
 11 files changed, 415 insertions(+), 362 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-mapi-contacts.c b/src/addressbook/e-book-backend-mapi-contacts.c
index 05df282..ddac53c 100644
--- a/src/addressbook/e-book-backend-mapi-contacts.c
+++ b/src/addressbook/e-book-backend-mapi-contacts.c
@@ -57,14 +57,24 @@ struct _EBookBackendMAPIContactsPrivate
 };
 
 static gboolean
-build_restriction_emails_contains (struct mapi_SRestriction *res, const gchar *query)
+build_restriction_emails_contains (EMapiConnection *conn,
+				   mapi_id_t fid,
+				   TALLOC_CTX *mem_ctx,
+				   struct mapi_SRestriction **restrictions,
+				   gpointer user_data,
+				   GCancellable *cancellable,
+				   GError **perror)
 {
-	gchar *email=NULL, *tmp, *tmp1;
+	struct mapi_SRestriction *restriction;
+	const gchar *query = user_data;
+	gchar *email = NULL, *to_free, *tmp, *tmp1;
+
+	g_return_val_if_fail (query != NULL, FALSE);
 
 	/* This currently supports "email foo bar soo" */
-	tmp = strdup (query);
+	to_free = strdup (query);
 
-	tmp = strstr (tmp, "email");
+	tmp = strstr (to_free, "email");
 	if (tmp ) {
 		tmp = strchr (tmp, '\"');
 		if (tmp && ++tmp) {
@@ -80,14 +90,28 @@ build_restriction_emails_contains (struct mapi_SRestriction *res, const gchar *q
 		}
 	}
 
-	if (email==NULL || !strchr (email, '@'))
+	if (email == NULL || !strchr (email, '@')) {
+		g_free (to_free);
 		return FALSE;
+	}
+
+	if (!restrictions) {
+		g_free (to_free);
+		return TRUE;
+	}
+
+	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 = PROP_TAG(PT_UNICODE, 0x801f); /* EMAIL */
+	restriction->res.resProperty.lpProp.ulPropTag = PROP_TAG(PT_UNICODE, 0x801f); /* EMAIL*/
+	restriction->res.resProperty.lpProp.value.lpszA = talloc_strdup (mem_ctx, email);
+
+	*restrictions = restriction;
 
-	res->rt = RES_PROPERTY;
-	res->res.resProperty.relop = RES_PROPERTY;
-	res->res.resProperty.ulPropTag = PROP_TAG(PT_UNICODE, 0x801f); /* EMAIL */
-	res->res.resProperty.lpProp.ulPropTag = PROP_TAG(PT_UNICODE, 0x801f); /* EMAIL*/
-	res->res.resProperty.lpProp.value.lpszA = email;
+	g_free (to_free);
 
 	return TRUE;
 }
@@ -1019,7 +1043,6 @@ ebbm_contacts_get_contact_list (EBookBackendMAPI *ebma, GCancellable *cancellabl
 	guint32 options;
 	struct CreateContactListData ccld = { 0 };
 	GError *mapi_error = NULL;
-	struct mapi_SRestriction res;
 	gboolean get_all;
 
 	e_return_data_book_error_if_fail (ebma != NULL, E_DATA_BOOK_STATUS_INVALID_ARG);
@@ -1063,14 +1086,14 @@ ebbm_contacts_get_contact_list (EBookBackendMAPI *ebma, GCancellable *cancellabl
 	ccld.vCards = vCards;
 
 	get_all = g_ascii_strcasecmp (query, "(contains \"x-evolution-any-field\" \"\")") == 0;
-	if (!get_all && !build_restriction_emails_contains (&res, query)) {
+	if (!get_all && !build_restriction_emails_contains (NULL, 0, NULL, NULL, (gpointer) query, NULL, NULL)) {
 		e_book_backend_mapi_unlock_connection (ebma);
 		/* g_propagate_error (error, EDB_ERROR (OTHER_ERROR)); */
 
 		return;
 	}
 
-	if (!e_mapi_connection_fetch_items (conn, priv->fid, get_all ? NULL : &res, NULL,
+	if (!e_mapi_connection_fetch_items (conn, priv->fid, get_all ? NULL : build_restriction_emails_contains, (gpointer) query, NULL,
 		priv->is_public_folder ? NULL : mapi_book_utils_get_prop_list, GET_ALL_KNOWN_IDS,
 		create_contact_list_cb, &ccld, options, cancellable, &mapi_error)) {
 		mapi_error_to_edb_error (error, mapi_error, E_DATA_BOOK_STATUS_OTHER_ERROR, _("Failed to fetch items from a server"));
@@ -1100,7 +1123,7 @@ ebbm_contacts_get_status_message (EBookBackendMAPI *ebma, gint index, gint total
 }
 
 static void
-ebbm_contacts_fetch_contacts (EBookBackendMAPI *ebma, struct mapi_SRestriction *restriction, EDataBookView *book_view, gpointer notify_contact_data, GError **error)
+ebbm_contacts_fetch_contacts (EBookBackendMAPI *ebma, BuildRestrictionsCB build_rs_cb, gpointer build_rs_cb_data, EDataBookView *book_view, gpointer notify_contact_data, GError **error)
 {
 	EBookBackendMAPIContacts *ebmac;
 	EBookBackendMAPIContactsPrivate *priv;
@@ -1136,7 +1159,7 @@ ebbm_contacts_fetch_contacts (EBookBackendMAPI *ebma, struct mapi_SRestriction *
 	if (priv->is_public_folder)
 		options |= MAPI_OPTIONS_USE_PFSTORE;
 
-	if (!e_mapi_connection_fetch_items (conn, priv->fid, restriction, NULL,
+	if (!e_mapi_connection_fetch_items (conn, priv->fid, build_rs_cb, build_rs_cb_data, NULL,
 		mapi_book_utils_get_prop_list, GET_ALL_KNOWN_IDS,
 		fetch_contacts_cb, &fcd, options, NULL, &mapi_error)) {
 		mapi_error_to_edb_error (error, mapi_error, E_DATA_BOOK_STATUS_OTHER_ERROR, _("Failed to fetch items from a server"));
@@ -1185,7 +1208,7 @@ ebbm_contacts_fetch_known_uids (EBookBackendMAPI *ebma, GCancellable *cancellabl
 	fcud.cancellable = cancellable;
 	fcud.uids = uids;
 
-	e_mapi_connection_fetch_items (conn, priv->fid, NULL, NULL,
+	e_mapi_connection_fetch_items (conn, priv->fid, NULL, NULL, NULL,
 		mapi_book_utils_get_prop_list, GET_UIDS_ONLY,
 		fetch_contacts_uids_cb, &fcud, options, cancellable, &mapi_error);
 
diff --git a/src/addressbook/e-book-backend-mapi-gal.c b/src/addressbook/e-book-backend-mapi-gal.c
index c8ab7d9..bf37fab 100644
--- a/src/addressbook/e-book-backend-mapi-gal.c
+++ b/src/addressbook/e-book-backend-mapi-gal.c
@@ -175,7 +175,7 @@ ebbm_gal_get_status_message (EBookBackendMAPI *ebma, gint index, gint total)
 }
 
 static void
-ebbm_gal_fetch_contacts (EBookBackendMAPI *ebma, struct mapi_SRestriction *restriction, EDataBookView *book_view, gpointer notify_contact_data, GError **error)
+ebbm_gal_fetch_contacts (EBookBackendMAPI *ebma, BuildRestrictionsCB build_rs_cb, gpointer build_rs_cb_data, EDataBookView *book_view, gpointer notify_contact_data, GError **error)
 {
 	GError *mapi_error = NULL;
 	struct FetchGalData fgd = { 0 };
@@ -215,7 +215,7 @@ ebbm_gal_fetch_contacts (EBookBackendMAPI *ebma, struct mapi_SRestriction *restr
 	fgd.notify_contact_data = notify_contact_data;
 	fgd.fid = e_mapi_connection_get_default_folder_id (conn, olFolderContacts, NULL, NULL);
 
-	fetch_successful = e_mapi_connection_fetch_gal (conn, restriction,
+	fetch_successful = e_mapi_connection_fetch_gal (conn, build_rs_cb, build_rs_cb_data,
 		mapi_book_utils_get_prop_list, GET_ALL_KNOWN_IDS,
 		fetch_gal_cb, &fgd, NULL, &mapi_error);
 
@@ -263,7 +263,7 @@ ebbm_gal_fetch_known_uids (EBookBackendMAPI *ebma, GCancellable *cancellable, GH
 	fgud.uids = uids;
 	fgud.fid = e_mapi_connection_get_default_folder_id (conn, olFolderContacts, cancellable, NULL);
 
-	e_mapi_connection_fetch_gal (conn, NULL,
+	e_mapi_connection_fetch_gal (conn, NULL, NULL,
 		mapi_book_utils_get_prop_list, GET_UIDS_ONLY,
 		fetch_gal_uids_cb, &fgud, cancellable, &mapi_error);
 
diff --git a/src/addressbook/e-book-backend-mapi.c b/src/addressbook/e-book-backend-mapi.c
index 5e21a22..0faff1b 100644
--- a/src/addressbook/e-book-backend-mapi.c
+++ b/src/addressbook/e-book-backend-mapi.c
@@ -235,7 +235,7 @@ ebbm_notify_connection_status (EBookBackendMAPI *ebma, gboolean is_online)
 }
 
 static void
-ebbm_fetch_contacts (EBookBackendMAPI *ebma, struct mapi_SRestriction *restriction, EDataBookView *book_view, glong *last_modification_secs, GError **error)
+ebbm_fetch_contacts (EBookBackendMAPI *ebma, BuildRestrictionsCB build_rs_cb, gpointer build_rs_cb_data, EDataBookView *book_view, glong *last_modification_secs, GError **error)
 {
 	EBookBackendMAPIClass *ebmac;
 	struct FetchContactsData notify_data = { 0 };
@@ -248,34 +248,54 @@ ebbm_fetch_contacts (EBookBackendMAPI *ebma, struct mapi_SRestriction *restricti
 	g_return_if_fail (ebmac != NULL);
 	g_return_if_fail (ebmac->op_fetch_contacts != NULL);
 
-	ebmac->op_fetch_contacts (ebma, restriction, book_view, &notify_data, error);
+	ebmac->op_fetch_contacts (ebma, build_rs_cb, build_rs_cb_data, book_view, &notify_data, error);
 
 	if (last_modification_secs && *last_modification_secs < notify_data.last_modification)
 		*last_modification_secs = notify_data.last_modification;
 }
 
-static struct mapi_SRestriction *
-ebbm_build_cache_update_restriction (EBookBackendMAPI *ebma, TALLOC_CTX *mem_ctx)
+static gboolean
+unref_backend_idle_cb (gpointer data)
 {
+	EBookBackendMAPI *ebma = data;
+
+	g_return_val_if_fail (ebma != NULL, FALSE);
+
+	g_object_unref (ebma);
+
+	return FALSE;
+}
+
+static gboolean
+ebbm_build_cache_update_restriction (EMapiConnection *conn,
+				     mapi_id_t fid,
+				     TALLOC_CTX *mem_ctx,
+				     struct mapi_SRestriction **restrictions,
+				     gpointer user_data,
+				     GCancellable *cancellable,
+				     GError **perror)
+{
+	EBookBackendMAPI *ebma = user_data;
 	struct mapi_SRestriction *restriction;
 	EBookBackendMAPIPrivate *priv;
 	struct SPropValue sprop;
 	struct timeval t = { 0 };
 	glong last_update_secs = 0;
 
-	g_return_val_if_fail (ebma != NULL, NULL);
-	g_return_val_if_fail (mem_ctx != NULL, NULL);
-	g_return_val_if_fail (E_IS_BOOK_BACKEND_MAPI (ebma), NULL);
+	g_return_val_if_fail (ebma != NULL, FALSE);
+	g_return_val_if_fail (mem_ctx != NULL, FALSE);
+	g_return_val_if_fail (E_IS_BOOK_BACKEND_MAPI (ebma), FALSE);
+	g_return_val_if_fail (restrictions != NULL, FALSE);
 
 	priv = ebma->priv;
-	g_return_val_if_fail (priv != NULL, NULL);
-	g_return_val_if_fail (priv->db != NULL, NULL);
+	g_return_val_if_fail (priv != NULL, FALSE);
+	g_return_val_if_fail (priv->db != NULL, FALSE);
 
 	if (!ebbm_get_cache_time (ebma, &last_update_secs) || last_update_secs <= 0)
-		return NULL;
+		return TRUE;
 
 	restriction = talloc_zero (mem_ctx, struct mapi_SRestriction);
-	g_assert (restriction != NULL);
+	g_return_val_if_fail (restriction != NULL, FALSE);
 
 	restriction->rt = RES_PROPERTY;
 	restriction->res.resProperty.relop = RELOP_GE;
@@ -285,23 +305,11 @@ ebbm_build_cache_update_restriction (EBookBackendMAPI *ebma, TALLOC_CTX *mem_ctx
 	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);
 
-	cast_mapi_SPropValue (mem_ctx, &(restriction->res.resProperty.lpProp),
-			      &sprop);
-
-	return restriction;
-}
-
-static gboolean
-unref_backend_idle_cb (gpointer data)
-{
-	EBookBackendMAPI *ebma = data;
-
-	g_return_val_if_fail (ebma != NULL, FALSE);
+	*restrictions = restriction;
 
-	g_object_unref (ebma);
-
-	return FALSE;
+	return TRUE;
 }
 
 static gpointer
@@ -327,20 +335,12 @@ ebbm_update_cache_cb (gpointer data)
 	g_cancellable_reset (priv->update_cache);
 
 	if (!g_cancellable_is_cancelled (priv->update_cache) && ebmac->op_fetch_contacts) {
-		TALLOC_CTX *mem_ctx;
-		struct mapi_SRestriction *restriction;
-
-		mem_ctx = talloc_init (G_STRFUNC);
-		restriction = ebbm_build_cache_update_restriction (ebma, mem_ctx);
-
 		/* get time stored in a cache, to always use the latest last modification time */
 		if (!ebbm_get_cache_time (ebma, &last_modification_secs))
 			last_modification_secs = 0;
 
-		ebbm_fetch_contacts (ebma, restriction, NULL, &last_modification_secs, &error);
+		ebbm_fetch_contacts (ebma, ebbm_build_cache_update_restriction, ebma, NULL, &last_modification_secs, &error);
 		e_book_backend_sqlitedb_set_is_populated (priv->db, EMA_EBB_CACHE_FOLDERID, error != NULL, NULL);
-
-		talloc_free (mem_ctx);
 	}
 
 	if (!error && !g_cancellable_is_cancelled (priv->update_cache) && ebmac->op_fetch_known_uids) {
@@ -751,7 +751,7 @@ ebbm_book_view_thread (gpointer data)
 			/* todo: create restriction based on the book_view */
 			if (!error) {
 				g_cancellable_reset (priv->update_cache);
-				ebbm_fetch_contacts (bvtd->ebma, NULL, bvtd->book_view, NULL, &error);
+				ebbm_fetch_contacts (bvtd->ebma, NULL, NULL, bvtd->book_view, NULL, &error);
 				g_cancellable_cancel (priv->update_cache);
 			}
 
diff --git a/src/addressbook/e-book-backend-mapi.h b/src/addressbook/e-book-backend-mapi.h
index 83fc1b3..ffce6d5 100644
--- a/src/addressbook/e-book-backend-mapi.h
+++ b/src/addressbook/e-book-backend-mapi.h
@@ -79,7 +79,7 @@ typedef struct
 	/* function called to populate cache or similar operations;
 	   restriction and book_view can be NULL, call e_book_backend_mapi_notify_contact_update for each
 	   fetched contact with this book_view and notify_contact_data */
-	void (*op_fetch_contacts) (EBookBackendMAPI *ebma, struct mapi_SRestriction *restriction, EDataBookView *book_view, gpointer notify_contact_data, GError **error);
+	void (*op_fetch_contacts) (EBookBackendMAPI *ebma, BuildRestrictionsCB build_rs_cb, gpointer build_rs_cb_data, EDataBookView *book_view, gpointer notify_contact_data, GError **error);
 
 	/* function to fetch list of known uids (strings) on the server;
 	   it's used to synchronize local cache with deleted items;
diff --git a/src/calendar/e-cal-backend-mapi.c b/src/calendar/e-cal-backend-mapi.c
index 5b198a9..2ead0a7 100644
--- a/src/calendar/e-cal-backend-mapi.c
+++ b/src/calendar/e-cal-backend-mapi.c
@@ -594,6 +594,86 @@ mapi_cal_get_idlist (EMapiConnection *conn,
 	return e_mapi_utils_add_props_to_props_array (mem_ctx, props, cal_IDList, G_N_ELEMENTS (cal_IDList));
 }
 
+static gboolean
+ecbm_build_last_modification_restriction (EMapiConnection *conn,
+					  mapi_id_t fid,
+					  TALLOC_CTX *mem_ctx,
+					  struct mapi_SRestriction **restrictions,
+					  gpointer user_data,
+					  GCancellable *cancellable,
+					  GError **perror)
+{
+	icaltimetype *itt_cache = user_data;
+
+	g_return_val_if_fail (restrictions != NULL, FALSE);
+
+	if (itt_cache && !icaltime_is_null_time (*itt_cache)) {
+		struct mapi_SRestriction *restriction;
+		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_GE;
+		restriction->res.resProperty.ulPropTag = PR_LAST_MODIFICATION_TIME;
+
+		t.tv_sec = icaltime_as_timet_with_zone (*itt_cache, icaltimezone_get_utc_timezone ());
+		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;
+}
+
+static gboolean
+ecbm_build_restriction_unknown_mids (EMapiConnection *conn,
+				     mapi_id_t fid,
+				     TALLOC_CTX *mem_ctx,
+				     struct mapi_SRestriction **restrictions,
+				     gpointer user_data,
+				     GCancellable *cancellable,
+				     GError **perror)
+{
+	GSList *unknown_mids = user_data, *iter;
+	gint ii;
+
+	g_return_val_if_fail (restrictions != NULL, FALSE);
+
+	if (unknown_mids) {
+		struct mapi_SRestriction *restriction;
+		struct mapi_SRestriction_or *or_res;
+
+		or_res = talloc_zero_array (mem_ctx, struct mapi_SRestriction_or, g_slist_length (unknown_mids));
+		g_return_val_if_fail (or_res != NULL, FALSE);
+
+		for (ii = 0, iter = unknown_mids; iter; ii++, iter = iter->next) {
+			mapi_id_t *pmid = iter->data;
+
+			or_res[ii].rt = RES_PROPERTY;
+			or_res[ii].res.resProperty.relop = RELOP_EQ;
+			or_res[ii].res.resProperty.ulPropTag = PR_MID;
+			or_res[ii].res.resProperty.lpProp.ulPropTag = PR_MID;
+			or_res[ii].res.resProperty.lpProp.value.dbl = *pmid;
+		}
+
+		restriction = talloc_zero (mem_ctx, struct mapi_SRestriction);
+		g_return_val_if_fail (restriction != NULL, FALSE);
+
+		restriction->rt = RES_OR;
+		restriction->res.resOr.cRes = g_slist_length (unknown_mids);
+		restriction->res.resOr.res = or_res;
+
+		*restrictions = restriction;
+	}
+
+	return TRUE;
+}
+
 /* Simple workflow for fetching deltas:
  * Poke cache for server_utc_time -> if exists, fetch all items modified after that time,
  * note current time before fetching and update cache with the same after fetching.
@@ -613,14 +693,12 @@ get_deltas (gpointer handle)
 	gchar *time_string = NULL;
 	gchar t_str [26];
 	const gchar *serv_time;
-	struct mapi_SRestriction res;
-	gboolean use_restriction = FALSE;
+	gboolean use_restriction = TRUE;
 	GSList *ls = NULL;
 	struct deleted_items_data did;
 	ESource *source = NULL;
 	guint32 options= MAPI_OPTIONS_FETCH_ALL;
 	gboolean is_public = FALSE;
-	TALLOC_CTX *mem_ctx = NULL;
 	GError *mapi_error = NULL;
 
 	if (!handle)
@@ -639,23 +717,6 @@ get_deltas (gpointer handle)
 	if (serv_time)
 		itt_cache = icaltime_from_string (serv_time);
 
-	if (!icaltime_is_null_time (itt_cache)) {
-		struct SPropValue sprop;
-		struct timeval t;
-
-		mem_ctx = talloc_init ("ExchangeMAPI_get_deltas_cal");
-		use_restriction = TRUE;
-		res.rt = RES_PROPERTY;
-		res.res.resProperty.relop = RELOP_GE;
-		res.res.resProperty.ulPropTag = PR_LAST_MODIFICATION_TIME;
-
-		t.tv_sec = icaltime_as_timet_with_zone (itt_cache, icaltimezone_get_utc_timezone ());
-		t.tv_usec = 0;
-		set_SPropValue_proptag_date_timeval (&sprop, PR_LAST_MODIFICATION_TIME, &t);
-		cast_mapi_SPropValue (mem_ctx, &(res.res.resProperty.lpProp),
-				      &sprop);
-	}
-
 	itt_current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
 	current_time = icaltime_as_timet_with_zone (itt_current, icaltimezone_get_utc_timezone ());
 	gmtime_r (&current_time, &tm);
@@ -667,7 +728,7 @@ get_deltas (gpointer handle)
 		use_restriction = FALSE;
 	}
 
-	if (!e_mapi_connection_fetch_items (priv->conn, priv->fid, use_restriction ? &res : NULL, NULL,
+	if (!e_mapi_connection_fetch_items (priv->conn, priv->fid, use_restriction ? ecbm_build_last_modification_restriction : NULL, &itt_cache, NULL,
 					is_public ? NULL : e_mapi_cal_utils_get_props_cb, GINT_TO_POINTER (kind),
 					mapi_cal_get_changes_cb, cbmapi,
 					options, NULL, &mapi_error)) {
@@ -681,8 +742,6 @@ get_deltas (gpointer handle)
 		}
 
 		g_mutex_unlock (priv->updating_mutex);
-		if (mem_ctx)
-			talloc_free (mem_ctx);
 		return FALSE;
 	}
 
@@ -692,10 +751,6 @@ get_deltas (gpointer handle)
 	e_cal_backend_store_put_key_value (priv->store, SERVER_UTC_TIME, time_string);
 	g_free (time_string);
 
-	if (mem_ctx) {
-		talloc_free (mem_ctx);
-		mem_ctx = NULL;
-	}
 	/* handle deleted items here by going over the entire cache and
 	 * checking for deleted items.*/
 
@@ -711,7 +766,7 @@ get_deltas (gpointer handle)
 	if (g_strcmp0 (e_source_get_property (source, "public"), "yes") == 0)
 		options = MAPI_OPTIONS_USE_PFSTORE;
 
-	if (!e_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
+	if (!e_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL, NULL,
 						mapi_cal_get_idlist, NULL,
 						handle_deleted_items_cb, &did,
 						options, NULL, &mapi_error)) {
@@ -762,36 +817,18 @@ get_deltas (gpointer handle)
 	g_slist_free (did.cache_ids);
 
 	if (did.unknown_mids) {
-		gint i;
-		struct mapi_SRestriction_or *or_res = g_new0 (struct mapi_SRestriction_or, g_slist_length (did.unknown_mids));
-
-		for (i = 0, ls = did.unknown_mids; ls; i++, ls = ls->next) {
-			mapi_id_t *pmid = ls->data;
-
-			or_res[i].rt = RES_PROPERTY;
-			or_res[i].res.resProperty.relop = RELOP_EQ;
-			or_res[i].res.resProperty.ulPropTag = PR_MID;
-			or_res[i].res.resProperty.lpProp.ulPropTag = PR_MID;
-			or_res[i].res.resProperty.lpProp.value.dbl = *pmid;
-		}
-
-		memset (&res, 0, sizeof (struct mapi_SRestriction));
-		res.rt = RES_OR;
-		res.res.resOr.cRes = g_slist_length (did.unknown_mids);
-		res.res.resOr.res = or_res;
-
-		g_slist_foreach (did.unknown_mids, (GFunc) g_free, NULL);
-		g_slist_free (did.unknown_mids);
-
 		if (g_strcmp0 (e_source_get_property (source, "public"), "yes") == 0) {
 			options |= MAPI_OPTIONS_USE_PFSTORE;
 			is_public = TRUE;
 		}
 
-		if (!e_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
+		if (!e_mapi_connection_fetch_items (priv->conn, priv->fid, ecbm_build_restriction_unknown_mids, did.unknown_mids, NULL,
 					is_public ? NULL : e_mapi_cal_utils_get_props_cb, GINT_TO_POINTER (kind),
 					mapi_cal_get_changes_cb, cbmapi,
 					options, NULL, &mapi_error)) {
+			g_slist_foreach (did.unknown_mids, (GFunc) g_free, NULL);
+			g_slist_free (did.unknown_mids);
+
 			if (mapi_error) {
 				gchar *msg = g_strdup_printf (_("Failed to fetch changes from a server: %s"), mapi_error->message);
 				e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), msg);
@@ -801,11 +838,11 @@ get_deltas (gpointer handle)
 				e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Failed to fetch changes from a server"));
 			}
 
-			g_free (or_res);
 			g_mutex_unlock (priv->updating_mutex);
 			return FALSE;
 		}
-		g_free (or_res);
+		g_slist_foreach (did.unknown_mids, (GFunc) g_free, NULL);
+		g_slist_free (did.unknown_mids);
 	}
 
 	g_mutex_unlock (priv->updating_mutex);
@@ -1134,7 +1171,7 @@ populate_cache (ECalBackendMAPI *cbmapi, GError **perror)
 		is_public = TRUE;
 	}
 
-	if (!e_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
+	if (!e_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL, NULL,
 					is_public ? NULL : e_mapi_cal_utils_get_props_cb, GINT_TO_POINTER (kind),
 					mapi_cal_cache_create_cb, cbmapi,
 					options, NULL, &mapi_error)) {
@@ -1481,39 +1518,37 @@ get_comp_mid (icalcomponent *icalcomp, mapi_id_t *mid)
 	}
 }
 
-/* should call free_server_data() before done with cbdata */
-static void
-get_server_data (ECalBackendMAPI *cbmapi, ECalComponent *comp, struct cal_cbdata *cbdata)
-{
-	ECalBackendMAPIPrivate *priv = cbmapi->priv;
-	icalcomponent *icalcomp;
-	const gchar *uid;
-	mapi_id_t mid;
-	struct mapi_SRestriction res;
-	struct SPropValue sprop;
+static gboolean
+ecbm_build_global_id_restriction (EMapiConnection *conn,
+				  mapi_id_t fid,
+				  TALLOC_CTX *mem_ctx,
+				  struct mapi_SRestriction **restrictions,
+				  gpointer user_data,
+				  GCancellable *cancellable,
+				  GError **perror)
+{
+	ECalComponent *comp = user_data;
 	struct Binary_r sb;
-	uint32_t proptag = 0x0;
+	struct SPropValue sprop;
+	struct mapi_SRestriction *restriction;
 	gchar *propval;
-	TALLOC_CTX *mem_ctx;
+	uint32_t proptag;
 
-	icalcomp = e_cal_component_get_icalcomponent (comp);
-	uid = icalcomponent_get_uid (icalcomp);
-	get_comp_mid (icalcomp, &mid);
-	if (e_mapi_connection_fetch_item (priv->conn, priv->fid, mid,
-					mapi_cal_get_required_props, NULL,
-					capture_req_props, cbdata,
-					MAPI_OPTIONS_FETCH_GENERIC_STREAMS, NULL, NULL))
+	g_return_val_if_fail (restrictions != NULL, FALSE);
+	g_return_val_if_fail (comp != NULL, FALSE);
 
-		return;
+	proptag = e_mapi_connection_resolve_named_prop (conn, fid, PidLidCleanGlobalObjectId, cancellable, perror);
+	if (proptag == MAPI_E_RESERVED)
+		proptag = PidLidCleanGlobalObjectId;
 
-	proptag = e_mapi_connection_resolve_named_prop (priv->conn, priv->fid, PidLidCleanGlobalObjectId, NULL, NULL);
-	if (proptag == MAPI_E_RESERVED) proptag = PidLidCleanGlobalObjectId;
+	restriction = talloc_zero (mem_ctx, struct mapi_SRestriction);
+	g_return_val_if_fail (restriction != NULL, FALSE);
 
-	res.rt = RES_PROPERTY;
-	res.res.resProperty.relop = RELOP_EQ;
-	res.res.resProperty.ulPropTag = proptag;
+	restriction->rt = RES_PROPERTY;
+	restriction->res.resProperty.relop = RELOP_EQ;
+	restriction->res.resProperty.ulPropTag = proptag;
 
-	propval = e_mapi_cal_utils_get_icomp_x_prop (icalcomp, "X-EVOLUTION-MAPI-GLOBALID");
+	propval = e_mapi_cal_utils_get_icomp_x_prop (e_cal_component_get_icalcomponent (comp), "X-EVOLUTION-MAPI-GLOBALID");
 	if (propval && *propval) {
 		gsize len = 0;
 
@@ -1522,6 +1557,9 @@ get_server_data (ECalBackendMAPI *cbmapi, ECalComponent *comp, struct cal_cbdata
 	} else {
 		struct icaltimetype ical_creation_time = { 0 };
 		struct FILETIME creation_time = { 0 };
+		const gchar *uid;
+
+		uid = icalcomponent_get_uid (e_cal_component_get_icalcomponent (comp));
 
 		e_cal_component_get_dtstamp (comp, &ical_creation_time);
 
@@ -1530,16 +1568,36 @@ get_server_data (ECalBackendMAPI *cbmapi, ECalComponent *comp, struct cal_cbdata
 	}
 	g_free (propval);
 
-	mem_ctx = talloc_init ("ExchangeMAPI_cal_get_server_data");
-	set_SPropValue_proptag (&sprop, proptag, (gconstpointer ) &sb);
-	cast_mapi_SPropValue (mem_ctx, &(res.res.resProperty.lpProp), &sprop);
+	set_SPropValue_proptag (&sprop, proptag, &sb);
+	cast_mapi_SPropValue (mem_ctx, &(restriction->res.resProperty.lpProp), &sprop);
+
+	*restrictions = restriction;
 
-	e_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
+	return TRUE;
+}
+
+/* should call free_server_data() before done with cbdata */
+static void
+get_server_data (ECalBackendMAPI *cbmapi, ECalComponent *comp, struct cal_cbdata *cbdata)
+{
+	ECalBackendMAPIPrivate *priv = cbmapi->priv;
+	icalcomponent *icalcomp;
+	mapi_id_t mid;
+
+	icalcomp = e_cal_component_get_icalcomponent (comp);
+	get_comp_mid (icalcomp, &mid);
+
+	if (e_mapi_connection_fetch_item (priv->conn, priv->fid, mid,
 					mapi_cal_get_required_props, NULL,
 					capture_req_props, cbdata,
-					MAPI_OPTIONS_FETCH_GENERIC_STREAMS, NULL, NULL);
+					MAPI_OPTIONS_FETCH_GENERIC_STREAMS, NULL, NULL))
 
-	talloc_free (mem_ctx);
+		return;
+
+	e_mapi_connection_fetch_items (priv->conn, priv->fid, ecbm_build_global_id_restriction, comp, NULL,
+					mapi_cal_get_required_props, NULL,
+					capture_req_props, cbdata,
+					MAPI_OPTIONS_FETCH_GENERIC_STREAMS, NULL, NULL);
 }
 
 /* frees data members allocated in get_server_data(), not the cbdata itself */
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index 045d088..8add094 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -592,7 +592,7 @@ mapi_sync_deleted (CamelSession *session,
 	server_messages = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
 	/*Get the UID list from server.*/
-	e_mapi_connection_fetch_items (camel_mapi_store_get_connection (mapi_store), data->folder_id, NULL, NULL,
+	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);
@@ -735,7 +735,7 @@ mapi_camel_get_summary_list (EMapiConnection *conn,
 }
 
 gboolean
-camel_mapi_folder_fetch_summary (CamelStore *store, CamelFolder *folder, const mapi_id_t fid, struct mapi_SRestriction *res,
+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 status;
@@ -747,7 +747,7 @@ camel_mapi_folder_fetch_summary (CamelStore *store, CamelFolder *folder, const m
 
 	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, res, sort,
+	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);
@@ -759,6 +759,47 @@ camel_mapi_folder_fetch_summary (CamelStore *store, CamelFolder *folder, const m
 	return status;
 }
 
+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;
+
+	g_return_val_if_fail (restrictions != NULL, FALSE);
+
+	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;
+
+		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_GE;
+		restriction->res.resProperty.ulPropTag = PR_LAST_MODIFICATION_TIME;
+
+		t.tv_sec = last_modification_time.tv_sec;
+		t.tv_usec = last_modification_time.tv_usec;
+
+		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;
+}
+
 gboolean
 mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **error)
 {
@@ -775,8 +816,6 @@ mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **err
 	gboolean status;
 	gboolean success = TRUE;
 
-	TALLOC_CTX *mem_ctx = NULL;
-	struct mapi_SRestriction *res = NULL;
 	struct SSortOrderSet *sort = NULL;
 	fetch_items_data *fetch_data = g_new0 (fetch_items_data, 1);
 	const gchar *folder_id = NULL;
@@ -825,31 +864,11 @@ mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **err
 		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)) {
-			struct SPropValue sprop;
-			struct timeval t;
-
-			mem_ctx = talloc_init ("ExchangeMAPI_mapi_refresh_folder");
-			res = g_new0 (struct mapi_SRestriction, 1);
-			res->rt = RES_PROPERTY;
-			/*RELOP_GE acts more like >=. Few extra items are being fetched.*/
-			res->res.resProperty.relop = RELOP_GE;
-			res->res.resProperty.ulPropTag = PR_LAST_MODIFICATION_TIME;
+		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);
 
-			t.tv_sec = fetch_data->last_modification_time.tv_sec;
-			t.tv_usec = fetch_data->last_modification_time.tv_usec;
-
-			//Creation time ?
-			set_SPropValue_proptag_date_timeval (&sprop, PR_LAST_MODIFICATION_TIME, &t);
-			cast_mapi_SPropValue (mem_ctx,
-					      &(res->res.resProperty.lpProp),
-					      &sprop);
-
-		}
-
-		/*Initialize other fetch_data fields*/
+	        /*Initialize other fetch_data fields*/
 		fetch_data->changes = camel_folder_change_info_new ();
 		fetch_data->folder = folder;
 
@@ -877,7 +896,8 @@ mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **err
 		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, res, sort,
+		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) {
@@ -929,9 +949,6 @@ end1:
 	g_slist_free (fetch_data->items_list);
 	g_free (fetch_data);
 
-	if (mem_ctx)
-		talloc_free (mem_ctx);
-
 	return success;
 }
 
diff --git a/src/camel/camel-mapi-folder.h b/src/camel/camel-mapi-folder.h
index 7af155f..39baae6 100644
--- a/src/camel/camel-mapi-folder.h
+++ b/src/camel/camel-mapi-folder.h
@@ -94,7 +94,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, struct mapi_SRestriction *res,
+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);
 
 G_END_DECLS
diff --git a/src/camel/camel-mapi-notifications.c b/src/camel/camel-mapi-notifications.c
index feb6197..25c9d24 100644
--- a/src/camel/camel-mapi-notifications.c
+++ b/src/camel/camel-mapi-notifications.c
@@ -57,12 +57,39 @@ 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)
 {
-	struct mapi_SRestriction *res = NULL;
 	guint32 options = 0;
-
 	fetch_items_data *fetch_data;
 	CamelFolder *folder = NULL;
 	CamelStore *parent_store;
@@ -101,21 +128,12 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
 
 	parent_store = camel_folder_get_parent_store (folder);
 
-	/*Use restriction to fetch the message summary based on MID*/
-	res = g_new0 (struct mapi_SRestriction, 1);
-
-	res->rt = RES_PROPERTY;
-	res->res.resProperty.relop = RES_PROPERTY;
-	res->res.resProperty.ulPropTag = PR_MID;
-	res->res.resProperty.lpProp.ulPropTag = PR_MID;
-	res->res.resProperty.lpProp.value.dbl = new_mail_notif->MID;
-
 	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, res, NULL, fetch_data, options, NULL, NULL);
+	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_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	camel_folder_summary_touch (folder->summary);
@@ -127,7 +145,6 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
 	camel_folder_changed (folder, fetch_data->changes);
 
 	camel_folder_change_info_free (fetch_data->changes);
-	g_free (res);
 }
 
 static gint
diff --git a/src/libexchangemapi/e-mapi-cal-utils.c b/src/libexchangemapi/e-mapi-cal-utils.c
index 8fc5774..de2662e 100644
--- a/src/libexchangemapi/e-mapi-cal-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-utils.c
@@ -2029,37 +2029,71 @@ e_mapi_cal_utils_write_props_cb (EMapiConnection *conn,
 	return TRUE;
 }
 
+static gboolean
+emcu_build_restriction (EMapiConnection *conn,
+			mapi_id_t fid,
+			TALLOC_CTX *mem_ctx,
+			struct mapi_SRestriction **restrictions,
+			gpointer user_data,
+			GCancellable *cancellable,
+			GError **perror)
+{
+	struct mapi_SRestriction *restriction;
+	struct SPropValue sprop;
+	uint32_t *id = user_data;
+
+	g_return_val_if_fail (conn != NULL, FALSE);
+	g_return_val_if_fail (mem_ctx != NULL, FALSE);
+	g_return_val_if_fail (restrictions != NULL, FALSE);
+	g_return_val_if_fail (id != 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 = RELOP_EQ;
+	restriction->res.resProperty.ulPropTag = PR_OWNER_APPT_ID;
+
+	set_SPropValue_proptag (&sprop, PR_OWNER_APPT_ID, id);
+	cast_mapi_SPropValue (mem_ctx, &(restriction->res.resProperty.lpProp), &sprop);
+
+	*restrictions = restriction;
+
+	return TRUE;
+}
+
+static gboolean
+emcu_check_id_exists_cb (EMapiConnection *conn,
+			 mapi_id_t fid,
+			 TALLOC_CTX *mem_ctx,
+			 const ListItemsData *item_data,
+			 guint32 item_index,
+			 guint32 items_total,
+			 gpointer user_data,
+			 GCancellable *cancellable,
+			 GError **perror)
+{
+	gboolean *unused = user_data;
+
+	g_return_val_if_fail (unused != NULL, FALSE);
+
+	*unused = FALSE;
+
+	return FALSE;
+}
+
 uint32_t
 e_mapi_cal_util_get_new_appt_id (EMapiConnection *conn, mapi_id_t fid)
 {
-	struct mapi_SRestriction res;
-	struct SPropValue sprop;
 	uint32_t id;
-	gboolean found = FALSE;
-
-	res.rt = RES_PROPERTY;
-	res.res.resProperty.relop = RELOP_EQ;
-	res.res.resProperty.ulPropTag = PR_OWNER_APPT_ID;
+	gboolean unused = TRUE;
 
-	while (!found) {
+	while (!unused) {
 		id = g_random_int ();
 		if (id) {
-			GSList *ids = NULL;
-			TALLOC_CTX *mem_ctx = talloc_init ("ExchangeMAPI_get_new_appt_id");
-
-			set_SPropValue_proptag (&sprop, PR_OWNER_APPT_ID, (gconstpointer ) &id);
-			cast_mapi_SPropValue (mem_ctx,
-					      &(res.res.resProperty.lpProp),
-					      &sprop);
-			ids = e_mapi_connection_check_restriction (conn, fid, 0, &res, NULL, NULL);
-			if (ids) {
-				GSList *l;
-				for (l = ids; l; l = l->next)
-					g_free (l->data);
-			} else
-				found = TRUE;
-
-			talloc_free (mem_ctx);
+			unused = TRUE;
+			if (!e_mapi_connection_list_items (conn, fid, 0, emcu_build_restriction, &id, emcu_check_id_exists_cb, &unused, NULL, NULL))
+				break;
 		}
 	};
 
diff --git a/src/libexchangemapi/e-mapi-connection.c b/src/libexchangemapi/e-mapi-connection.c
index c99e844..bcfcbd2 100644
--- a/src/libexchangemapi/e-mapi-connection.c
+++ b/src/libexchangemapi/e-mapi-connection.c
@@ -1358,7 +1358,8 @@ e_mapi_util_get_attachments (EMapiConnection *conn,
 
 gboolean
 e_mapi_connection_fetch_gal (EMapiConnection *conn,
-			     struct mapi_SRestriction *restrictions,
+			     BuildRestrictionsCB build_rs_cb,
+			     gpointer build_rs_cb_data,
 			     BuildReadPropsCB build_props,
 			     gpointer brp_data,
 			     FetchGALCallback cb,
@@ -1663,129 +1664,6 @@ e_mapi_connection_get_folder_properties (EMapiConnection *conn,
 	return res;
 }
 
-GSList *
-e_mapi_connection_check_restriction (EMapiConnection *conn,
-				     mapi_id_t fid,
-				     guint32 fid_options,
-				     struct mapi_SRestriction *res,
-				     GCancellable *cancellable,
-				     GError **perror)
-{
-	enum MAPISTATUS ms;
-	TALLOC_CTX *mem_ctx;
-	mapi_object_t obj_folder;
-	mapi_object_t obj_table;
-	struct SPropTagArray *SPropTagArray, *GetPropsTagArray;
-	struct SRowSet SRowSet;
-	uint32_t count, i;
-	GSList *mids = NULL;
-
-	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, NULL);
-	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, NULL);
-
-	e_mapi_debug_print("%s: Entering %s: folder-id %016" G_GINT64_MODIFIER "X ", G_STRLOC, G_STRFUNC, fid);
-
-	LOCK ();
-	mem_ctx = talloc_init("ExchangeMAPI_CheckRestriction");
-	mapi_object_init(&obj_folder);
-	mapi_object_init(&obj_table);
-
-	/* Attempt to open the folder */
-	ms = open_folder (conn, 0, &fid, fid_options, &obj_folder, perror);
-	if (ms != MAPI_E_SUCCESS) {
-		goto cleanup;
-	}
-
-	if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-		goto cleanup;
-
-	/* Get a handle on the container */
-	ms = GetContentsTable (&obj_folder, &obj_table, 0, NULL);
-	if (ms != MAPI_E_SUCCESS) {
-		make_mapi_error (perror, "GetContentsTable", ms);
-		goto cleanup;
-	}
-
-	if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-		goto cleanup;
-
-	GetPropsTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
-	GetPropsTagArray->cValues = 0;
-
-	// FIXME : Why are we fetching all these props ?
-
-	SPropTagArray = set_SPropTagArray(mem_ctx, 0xA,
-					  PR_FID,
-					  PR_MID,
-					  PR_INST_ID,
-					  PR_INSTANCE_NUM,
-					  PR_SUBJECT_UNICODE,
-					  PR_MESSAGE_CLASS,
-					  PR_LAST_MODIFICATION_TIME,
-					  PR_HASATTACH,
-					  PR_RULE_MSG_PROVIDER,
-					  PR_RULE_MSG_NAME);
-
-	/* Set primary columns to be fetched */
-	ms = SetColumns (&obj_table, SPropTagArray);
-	if (ms != MAPI_E_SUCCESS) {
-		make_mapi_error (perror, "SetColumns", ms);
-		goto cleanup;
-	}
-
-	if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-		goto cleanup;
-
-	if (res) {
-		/* Applying any restriction that are set. */
-		ms = Restrict (&obj_table, res, NULL);
-		if (ms != MAPI_E_SUCCESS) {
-			make_mapi_error (perror, "Restrict", ms);
-			goto cleanup;
-		}
-
-		if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-			goto cleanup;
-	}
-
-	/* Number of items in the container */
-	ms = QueryPosition (&obj_table, NULL, &count);
-	if (ms != MAPI_E_SUCCESS) {
-		make_mapi_error (perror, "GetRowCount", ms);
-		goto cleanup;
-	}
-
-	if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-		goto cleanup;
-
-	if (!count)
-		goto cleanup;
-
-	/* Fill the table columns with data from the rows */
-	ms = QueryRows (&obj_table, count, TBL_ADVANCE, &SRowSet);
-	if (ms != MAPI_E_SUCCESS) {
-		make_mapi_error (perror, "QueryRows", ms);
-		goto cleanup;
-	}
-
-	for (i = 0; i < SRowSet.cRows; i++) {
-		mapi_id_t *pmid = (mapi_id_t *) get_SPropValue_SRow_data(&SRowSet.aRow[i], PR_MID);
-		struct id_list *id_list = g_new0 (struct id_list, 1);
-		id_list->id = *pmid;
-		mids = g_slist_prepend (mids, id_list);
-	}
-
- cleanup:
-	mapi_object_release(&obj_folder);
-	mapi_object_release(&obj_table);
-	talloc_free (mem_ctx);
-	UNLOCK();
-
-	e_mapi_debug_print("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
-
-	return mids;
-}
-
 typedef gboolean (*ForeachTableRowCB) (EMapiConnection *conn, mapi_id_t fid, TALLOC_CTX *mem_ctx, struct SRow *srow, guint32 row_index, guint32 rows_total, gpointer user_data, GCancellable *cancellable, GError **perror);
 
 static enum MAPISTATUS
@@ -1888,7 +1766,8 @@ gboolean
 e_mapi_connection_list_items (EMapiConnection *conn,
 			      mapi_id_t fid,
 			      guint32 options,
-			      struct mapi_SRestriction *restrictions,
+			      BuildRestrictionsCB build_rs_cb,
+			      gpointer build_rs_cb_data,
 			      ListItemsCB cb,
 			      gpointer user_data,
 			      GCancellable *cancellable,
@@ -1945,17 +1824,27 @@ e_mapi_connection_list_items (EMapiConnection *conn,
 		goto cleanup;
 	}
 
-	if (restrictions) {
-		/* Applying any restriction that are set. */
-		ms = Restrict (&obj_table, restrictions, NULL);
-		if (ms != MAPI_E_SUCCESS) {
-			make_mapi_error (perror, "Restrict", ms);
+	if (build_rs_cb) {
+		struct mapi_SRestriction *restrictions = NULL;
+
+		if (!build_rs_cb (conn, fid, mem_ctx, &restrictions, build_rs_cb_data, cancellable, perror)) {
+			ms = MAPI_E_CALL_FAILED;
+			make_mapi_error (perror, "build_restrictions", ms);
 			goto cleanup;
 		}
 
-		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-			ms = MAPI_E_USER_CANCEL;
-			goto cleanup;
+		if (restrictions) {
+			/* Applying any restriction that are set. */
+			ms = Restrict (&obj_table, restrictions, NULL);
+			if (ms != MAPI_E_SUCCESS) {
+				make_mapi_error (perror, "Restrict", ms);
+				goto cleanup;
+			}
+
+			if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
+				ms = MAPI_E_USER_CANCEL;
+				goto cleanup;
+			}
 		}
 	}
 
@@ -1976,7 +1865,8 @@ e_mapi_connection_list_items (EMapiConnection *conn,
 gboolean
 e_mapi_connection_fetch_items  (EMapiConnection *conn,
 				mapi_id_t fid,
-				struct mapi_SRestriction *res,
+				BuildRestrictionsCB build_rs_cb,
+				gpointer build_rs_cb_data,
 				struct SSortOrderSet *sort_order,
 				BuildReadPropsCB build_props,
 				gpointer brp_data,
@@ -2047,17 +1937,27 @@ e_mapi_connection_fetch_items  (EMapiConnection *conn,
 		goto cleanup;
 	}
 
-	if (res) {
-		/* Applying any restriction that are set. */
-		ms = Restrict (&obj_table, res, NULL);
-		if (ms != MAPI_E_SUCCESS) {
-			make_mapi_error (perror, "Restrict", ms);
+	if (build_rs_cb) {
+		struct mapi_SRestriction *restrictions = NULL;
+
+		if (!build_rs_cb (conn, fid, mem_ctx, &restrictions, build_rs_cb_data, cancellable, perror)) {
+			ms = MAPI_E_CALL_FAILED;
+			make_mapi_error (perror, "build_restrictions", ms);
 			goto cleanup;
 		}
 
-		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-			ms = MAPI_E_USER_CANCEL;
-			goto cleanup;
+		if (restrictions) {
+			/* Applying any restriction that are set. */
+			ms = Restrict (&obj_table, restrictions, NULL);
+			if (ms != MAPI_E_SUCCESS) {
+				make_mapi_error (perror, "Restrict", ms);
+				goto cleanup;
+			}
+
+			if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
+				ms = MAPI_E_USER_CANCEL;
+				goto cleanup;
+			}
 		}
 	}
 
diff --git a/src/libexchangemapi/e-mapi-connection.h b/src/libexchangemapi/e-mapi-connection.h
index 319f525..3097599 100644
--- a/src/libexchangemapi/e-mapi-connection.h
+++ b/src/libexchangemapi/e-mapi-connection.h
@@ -174,6 +174,13 @@ typedef gboolean (*BuildReadPropsCB)		(EMapiConnection *conn,
 						 gpointer data,
 						 GCancellable *cancellable,
 						 GError **perror);
+typedef gboolean (*BuildRestrictionsCB)		(EMapiConnection *conn,
+						 mapi_id_t fid,
+						 TALLOC_CTX *mem_ctx,
+						 struct mapi_SRestriction **restrictions,
+						 gpointer user_data,
+						 GCancellable *cancellable,
+						 GError **perror);
 typedef gboolean (*ListItemsCB)			(EMapiConnection *conn,
 						 mapi_id_t fid,
 						 TALLOC_CTX *mem_ctx,
@@ -236,7 +243,8 @@ gboolean		e_mapi_connection_get_folder_properties	(EMapiConnection *conn,
 gboolean		e_mapi_connection_list_items		(EMapiConnection *conn,
 								 mapi_id_t fid,
 								 guint32 options,
-								 struct mapi_SRestriction *restrictions,
+								 BuildRestrictionsCB build_rs_cb,
+								 gpointer build_rs_cb_data,
 								 ListItemsCB cb,
 								 gpointer user_data,
 								 GCancellable *cancellable,
@@ -268,7 +276,8 @@ gboolean		e_mapi_connection_fetch_item		(EMapiConnection *conn,
 
 gboolean		e_mapi_connection_fetch_items		(EMapiConnection *conn,
 								 mapi_id_t fid,
-								 struct mapi_SRestriction *res,
+								 BuildRestrictionsCB build_rs_cb,
+								 gpointer build_rs_cb_data,
 								 struct SSortOrderSet *sort_order,
 								 BuildReadPropsCB build_props,
 								 gpointer brp_data,
@@ -279,7 +288,8 @@ gboolean		e_mapi_connection_fetch_items		(EMapiConnection *conn,
 								 GError **perror);
 
 gboolean		e_mapi_connection_fetch_gal		(EMapiConnection *conn,
-								 struct mapi_SRestriction *restrictions,
+								 BuildRestrictionsCB build_rs_cb,
+								 gpointer build_rs_cb_data,
 								 BuildReadPropsCB build_props,
 								 gpointer brp_data,
 								 FetchGALCallback cb,
@@ -324,12 +334,6 @@ gboolean		e_mapi_connection_move_folder		(EMapiConnection *conn,
 								 const gchar *new_name,
 								 GCancellable *cancellable,
 								 GError **perror);
-GSList *		e_mapi_connection_check_restriction	(EMapiConnection *conn,
-								 mapi_id_t fid,
-								 guint32 fid_options,
-								 struct mapi_SRestriction *res,
-								 GCancellable *cancellable,
-								 GError **perror);
 mapi_id_t		e_mapi_connection_get_default_folder_id	(EMapiConnection *conn,
 								 uint32_t olFolder,
 								 GCancellable *cancellable,



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