r2448 - /experimental/evolution-mapi/debian/patches/revert-openchange-2.0.patch

biebl at users.alioth.debian.org biebl at users.alioth.debian.org
Sun Sep 8 00:37:24 UTC 2013


Author: biebl
Date: Sun Sep  8 00:37:24 2013
New Revision: 2448

URL: http://svn.debian.org/wsvn/pkg-evolution/?sc=1&rev=2448
Log:
Dont create src/libexchangemapi/e-mapi-connection.c.orig
as part of the revert patch. This shrinks the size of the patch considerably.

Modified:
    experimental/evolution-mapi/debian/patches/revert-openchange-2.0.patch

Modified: experimental/evolution-mapi/debian/patches/revert-openchange-2.0.patch
URL: http://svn.debian.org/wsvn/pkg-evolution/experimental/evolution-mapi/debian/patches/revert-openchange-2.0.patch?rev=2448&op=diff
==============================================================================
--- experimental/evolution-mapi/debian/patches/revert-openchange-2.0.patch	(original)
+++ experimental/evolution-mapi/debian/patches/revert-openchange-2.0.patch	Sun Sep  8 00:37:24 2013
@@ -6,8 +6,8 @@
 
 Index: evolution-mapi-3.8.5/configure.ac
 ===================================================================
---- evolution-mapi-3.8.5.orig/configure.ac	2013-09-08 02:06:59.026196227 +0200
-+++ evolution-mapi-3.8.5/configure.ac	2013-09-08 02:06:59.018196129 +0200
+--- evolution-mapi-3.8.5.orig/configure.ac	2013-09-08 02:35:40.223726352 +0200
++++ evolution-mapi-3.8.5/configure.ac	2013-09-08 02:35:40.215726251 +0200
 @@ -27,7 +27,7 @@
  dnl *******************
  m4_define([eds_minimum_version], [ema_version])
@@ -19,8 +19,8 @@
  m4_define([glib_minimum_version], [2.34])
 Index: evolution-mapi-3.8.5/src/configuration/e-mail-config-mapi-backend.c
 ===================================================================
---- evolution-mapi-3.8.5.orig/src/configuration/e-mail-config-mapi-backend.c	2013-09-08 02:06:59.026196227 +0200
-+++ evolution-mapi-3.8.5/src/configuration/e-mail-config-mapi-backend.c	2013-09-08 02:06:59.018196129 +0200
+--- evolution-mapi-3.8.5.orig/src/configuration/e-mail-config-mapi-backend.c	2013-09-08 02:35:40.223726352 +0200
++++ evolution-mapi-3.8.5/src/configuration/e-mail-config-mapi-backend.c	2013-09-08 02:35:40.215726251 +0200
 @@ -102,7 +102,7 @@
  struct ECreateProfileData
  {
@@ -61,8 +61,8 @@
  			return i;
 Index: evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-connection.c
 ===================================================================
---- evolution-mapi-3.8.5.orig/src/libexchangemapi/e-mapi-connection.c	2013-09-08 02:06:59.026196227 +0200
-+++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-connection.c	2013-09-08 02:06:59.018196129 +0200
+--- evolution-mapi-3.8.5.orig/src/libexchangemapi/e-mapi-connection.c	2013-09-08 02:35:40.223726352 +0200
++++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-connection.c	2013-09-08 02:35:40.215726251 +0200
 @@ -3733,7 +3733,6 @@
  	enum MAPISTATUS	ms;
  	struct SPropTagArray *tags;
@@ -368,7753 +368,10 @@
  
  		if (account_name && g_strcmp0 (username, account_name) == 0)
  			return ii;
-Index: evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-connection.c.orig
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-connection.c.orig	2013-09-08 02:06:59.022196179 +0200
-@@ -0,0 +1,7738 @@
-+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-+/*
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) version 3.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
-+ *
-+ *
-+ * Authors:
-+ *    Srinivasa Ragavan <sragavan at novell.com>
-+ *    Suman Manjunath <msuman at novell.com>
-+ *
-+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
-+ *
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+#include <config.h>
-+#endif
-+
-+#include <glib/gi18n-lib.h>
-+#include <camel/camel.h>
-+#include <libedataserver/libedataserver.h>
-+
-+#include <tevent.h>
-+
-+#include "e-mapi-connection.h"
-+#include "e-mapi-folder.h"
-+#include "e-mapi-utils.h"
-+#include "e-mapi-book-utils.h"
-+#include "e-mapi-mail-utils.h"
-+#include "e-mapi-fast-transfer.h"
-+
-+/* how many bytes can be written within one property with SetProps() call;
-+   if its size exceeds this limit, it's converted into an EMapiStreamedProp */
-+#define MAX_PROPERTY_WRITE_SIZE	2048
-+
-+/* how may contacts in one chunk can GAL ask to fetch */
-+#define MAX_GAL_CHUNK 50
-+
-+static void register_connection (EMapiConnection *conn);
-+static void unregister_connection (EMapiConnection *conn);
-+static gboolean mapi_profile_create (struct mapi_context *mapi_ctx, const EMapiProfileData *empd, mapi_profile_callback_t callback, gconstpointer data, GCancellable *cancellable, GError **perror, gboolean use_locking);
-+static struct mapi_session *mapi_profile_load (ESourceRegistry *registry, struct mapi_context *mapi_ctx, const gchar *profname, const gchar *password, GCancellable *cancellable, GError **perror);
-+
-+/* GObject foo - begin */
-+
-+G_DEFINE_TYPE (EMapiConnection, e_mapi_connection, G_TYPE_OBJECT)
-+
-+/* These three macros require 'priv' variable of type EMapiConnectionPrivate */
-+#define LOCK(_cclb,_err,_ret) G_STMT_START { 						\
-+	e_mapi_debug_print ("%s: %s: lock(session & global)", G_STRLOC, G_STRFUNC);	\
-+	if (!e_mapi_cancellable_rec_mutex_lock (&priv->session_lock, _cclb, _err)) {	\
-+		e_mapi_debug_print ("   %s: %s: cancelled before got session lock)", G_STRLOC, G_STRFUNC); \
-+		return _ret;								\
-+	}										\
-+	if (!e_mapi_utils_global_lock (_cclb, _err)) {					\
-+		e_mapi_cancellable_rec_mutex_unlock (&priv->session_lock);		\
-+		e_mapi_debug_print ("   %s: %s: cancelled before got global lock)", G_STRLOC, G_STRFUNC); \
-+		return _ret;								\
-+	}										\
-+	} G_STMT_END
-+
-+#define LOCK_VOID(_cclb,_err) G_STMT_START { 						\
-+	e_mapi_debug_print ("%s: %s: lock(session & global)", G_STRLOC, G_STRFUNC);	\
-+	if (!e_mapi_cancellable_rec_mutex_lock (&priv->session_lock, _cclb, _err)) {	\
-+		e_mapi_debug_print ("   %s: %s: cancelled before got session lock)", G_STRLOC, G_STRFUNC); \
-+		return;									\
-+	}										\
-+	if (!e_mapi_utils_global_lock (_cclb, _err)) {					\
-+		e_mapi_cancellable_rec_mutex_unlock (&priv->session_lock);		\
-+		e_mapi_debug_print ("   %s: %s: cancelled before got global lock)", G_STRLOC, G_STRFUNC); \
-+		return;									\
-+	}										\
-+	} G_STMT_END
-+
-+#define UNLOCK() G_STMT_START {								\
-+	e_mapi_debug_print ("%s: %s: unlock(session & global)", G_STRLOC, G_STRFUNC);	\
-+	e_mapi_utils_global_unlock ();							\
-+	e_mapi_cancellable_rec_mutex_unlock (&priv->session_lock);			\
-+	} G_STMT_END
-+
-+#define e_return_val_mapi_error_if_fail(expr, _code, _val)				\
-+	G_STMT_START {									\
-+		if (G_LIKELY(expr)) {							\
-+		} else {								\
-+			g_log (G_LOG_DOMAIN,						\
-+				G_LOG_LEVEL_CRITICAL,					\
-+				"file %s: line %d (%s): assertion `%s' failed",		\
-+				__FILE__, __LINE__, G_STRFUNC, #expr);			\
-+			if (perror)							\
-+				g_set_error (perror, E_MAPI_ERROR, (_code),		\
-+					"file %s: line %d (%s): assertion `%s' failed",	\
-+					__FILE__, __LINE__, G_STRFUNC, #expr);		\
-+			return (_val);							\
-+		}									\
-+	} G_STMT_END
-+
-+/* Create the EDataCal error quark */
-+GQuark
-+e_mapi_error_quark (void)
-+{
-+	static GQuark quark = 0;
-+	if (!quark)
-+		quark = g_quark_from_static_string ("e_mapi_error");
-+	return quark;
-+}
-+
-+void
-+make_mapi_error (GError **perror, const gchar *context, enum MAPISTATUS mapi_status)
-+{
-+	const gchar *error_msg = NULL, *status_name;
-+	gchar *to_free = NULL;
-+	GQuark error_domain;
-+	GError *error;
-+
-+	if (!perror)
-+		return;
-+
-+	/* do not overwrite already set error */
-+	if (*perror != NULL)
-+		return;
-+
-+	switch (mapi_status) {
-+	case MAPI_E_SUCCESS:
-+		return;
-+	#define err(_code, _str)		\
-+		case _code:			\
-+			error_msg = _str;	\
-+			break
-+
-+	err (MAPI_E_LOGON_FAILED,			_("Failed to login into the server"));
-+	err (MAPI_E_SESSION_LIMIT,			_("Cannot create more sessions, session limit was reached"));
-+	err (MAPI_E_USER_CANCEL,			_("User cancelled operation"));
-+	err (MAPI_E_UNABLE_TO_ABORT,			_("Unable to abort"));
-+	err (MAPI_E_NETWORK_ERROR,			_("Network error"));
-+	err (MAPI_E_DISK_ERROR,				_("Disk error"));
-+	err (MAPI_E_PASSWORD_CHANGE_REQUIRED,		_("Password change required"));
-+	err (MAPI_E_PASSWORD_EXPIRED,			_("Password expired"));
-+	err (MAPI_E_INVALID_WORKSTATION_ACCOUNT,	_("Invalid workstation account"));
-+	err (MAPI_E_INVALID_ACCESS_TIME,		_("Invalid access time"));
-+	err (MAPI_E_ACCOUNT_DISABLED,			_("Account is disabled"));
-+	err (MAPI_E_END_OF_SESSION,			_("End of session"));
-+	err (MAPI_E_NOT_INITIALIZED,			_("MAPI is not initialized or connected"));
-+	err (MAPI_E_NO_ACCESS,				_("Permission denied"));
-+	err (ecShutoffQuotaExceeded,			_("Mailbox quota exceeded"));
-+
-+	#undef err
-+
-+	default:
-+		status_name = mapi_get_errstr (mapi_status);
-+		if (!status_name)
-+			status_name = "";
-+		to_free = g_strdup_printf (_("MAPI error %s (0x%x) occurred"), status_name, mapi_status);
-+		error_msg = to_free;
-+	}
-+
-+	g_return_if_fail (error_msg != NULL);
-+
-+	error_domain = E_MAPI_ERROR;
-+
-+	if (mapi_status == MAPI_E_USER_CANCEL) {
-+		error_domain = G_IO_ERROR;
-+		mapi_status = G_IO_ERROR_CANCELLED;
-+	}
-+
-+	if (context && *context) {
-+		/* Translators: The first '%s' is replaced with an error context,
-+		   aka where the error occurred, the second '%s' is replaced with
-+		   the error message. */
-+		error = g_error_new (error_domain, mapi_status, C_("EXCHANGEMAPI_ERROR", "%s: %s"), context, error_msg);
-+	} else {
-+		error = g_error_new_literal (error_domain, mapi_status, error_msg);
-+	}
-+
-+	g_free (to_free);
-+
-+	g_propagate_error (perror, error);
-+}
-+
-+struct _EMapiConnectionPrivate {
-+	ESourceRegistry *registry;
-+
-+	struct mapi_context *mapi_ctx;
-+	struct mapi_session *session;
-+	EMapiCancellableRecMutex session_lock;
-+
-+	gchar *profile;			/* profile name, where the session is connected to */
-+	mapi_object_t msg_store;	/* valid only when session != NULL */
-+
-+	gboolean has_public_store;	/* whether is 'public_store' filled */
-+	mapi_object_t public_store;
-+
-+	GHashTable *foreign_stores;	/* username (gchar *) => msg_store (mapi_object_t *); opened foreign stores */
-+
-+	GSList *folders;		/* list of ExchangeMapiFolder pointers */
-+	GRecMutex folders_lock;		/* lock for 'folders' variable */
-+
-+	GHashTable *named_ids;		/* cache of named ids; key is a folder ID, value is a hash table
-+					   of named_id to prop_id in that respective folder */
-+
-+	GHashTable *known_notifications;/* mapi_id_t * -> uint32_t for Unsubscribe call */
-+	GThread *notification_thread;
-+	EFlag *notification_flag;
-+	enum MAPISTATUS	register_notification_result; /* MAPI_E_RESERVED if not called yet */
-+	gint notification_poll_seconds; /* delay between polls, in seconds */
-+};
-+
-+enum {
-+	SERVER_NOTIFICATION,
-+	LAST_SIGNAL
-+};
-+
-+static guint signals[LAST_SIGNAL];
-+
-+static gboolean
-+stop_notification (EMapiConnectionPrivate *priv,
-+		   uint32_t conn_id,
-+		   GCancellable *cancellable,
-+		   GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+
-+	e_return_val_mapi_error_if_fail (priv != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	ms = Unsubscribe (priv->session, conn_id);
-+	if (ms != MAPI_E_SUCCESS)
-+		make_mapi_error (perror, "Unsubscribe", ms);
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static void
-+call_stop_notification (gpointer key,
-+			gpointer value,
-+			gpointer user_data)
-+{
-+	stop_notification (user_data, GPOINTER_TO_UINT (value), NULL, NULL);
-+}
-+
-+static void
-+stop_all_notifications (EMapiConnectionPrivate *priv)
-+{
-+	g_return_if_fail (priv != NULL);
-+
-+	if (!priv->notification_thread)
-+		return;
-+
-+	LOCK_VOID (NULL, NULL);
-+	if (priv->session)
-+		g_hash_table_foreach (priv->known_notifications, call_stop_notification, priv);
-+	g_hash_table_remove_all (priv->known_notifications);
-+	e_flag_set (priv->notification_flag);
-+	UNLOCK ();
-+
-+	g_thread_join (priv->notification_thread);
-+	priv->notification_thread = NULL;
-+}
-+
-+static void
-+release_foreign_stores_cb (gpointer pusername, gpointer pmsg_store, gpointer user_data)
-+{
-+	mapi_object_t *msg_store = pmsg_store;
-+
-+	g_return_if_fail (msg_store != NULL);
-+
-+	mapi_object_release (msg_store);
-+	talloc_free (msg_store);
-+}
-+
-+/* should have session_lock locked already, when calling this function */
-+static void
-+disconnect (EMapiConnectionPrivate *priv,
-+	    gboolean clean)
-+{
-+	g_return_if_fail (priv != NULL);
-+
-+	if (!priv->session)
-+		return;
-+
-+	g_rec_mutex_lock (&priv->folders_lock);
-+	if (priv->folders)
-+		e_mapi_folder_free_list (priv->folders);
-+	priv->folders = NULL;
-+	g_rec_mutex_unlock (&priv->folders_lock);
-+
-+	if (priv->has_public_store)
-+		mapi_object_release (&priv->public_store);
-+
-+	g_hash_table_foreach (priv->foreign_stores, release_foreign_stores_cb, NULL);
-+	g_hash_table_remove_all (priv->foreign_stores); 
-+
-+	if (clean) {
-+		Logoff (&priv->msg_store);
-+		/* it's released by the Logoff() call
-+		mapi_object_release (&priv->msg_store); */
-+	}
-+
-+	if (priv->named_ids)
-+		g_hash_table_remove_all (priv->named_ids);
-+
-+	priv->session = NULL;
-+	priv->has_public_store = FALSE;
-+}
-+
-+/* should have session_lock locked already, when calling this function */
-+static gboolean
-+ensure_public_store (EMapiConnectionPrivate *priv,
-+		     GError **perror)
-+{
-+	e_return_val_mapi_error_if_fail (priv != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	if (!priv->session)
-+		return FALSE;
-+
-+	if (!priv->has_public_store) {
-+		enum MAPISTATUS ms;
-+
-+		mapi_object_init (&priv->public_store);
-+
-+		ms = OpenPublicFolder (priv->session, &priv->public_store);
-+		if (ms == MAPI_E_SUCCESS) {
-+			priv->has_public_store = TRUE;
-+		} else {
-+			make_mapi_error (perror, "OpenPublicFolder", ms);
-+		}
-+	}
-+
-+	return priv->has_public_store;
-+}
-+
-+/* should have session_lock locked already, when calling this function */
-+static gboolean
-+ensure_foreign_store (EMapiConnectionPrivate *priv,
-+		      const gchar *username,
-+		      mapi_object_t **pmsg_store,
-+		      GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	mapi_object_t *msg_store;
-+
-+	e_return_val_mapi_error_if_fail (priv != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (username != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (pmsg_store != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	*pmsg_store = NULL;
-+
-+	if (!priv->session)
-+		return FALSE;
-+
-+	msg_store = g_hash_table_lookup (priv->foreign_stores, username);
-+	if (msg_store) {
-+		*pmsg_store = msg_store;
-+		return TRUE;
-+	}
-+
-+	msg_store = talloc_zero (priv->session, mapi_object_t);
-+	mapi_object_init (msg_store);
-+
-+	ms = OpenUserMailbox (priv->session, username, msg_store);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenUserMailbox", ms);
-+
-+		mapi_object_release (msg_store);
-+		talloc_free (msg_store);
-+
-+		return FALSE;
-+	}
-+
-+	g_hash_table_insert (priv->foreign_stores, g_strdup (username), msg_store);
-+
-+	*pmsg_store = msg_store;
-+
-+	return TRUE;
-+}
-+
-+static void
-+e_mapi_connection_dispose (GObject *object)
-+{
-+	EMapiConnectionPrivate *priv;
-+
-+	unregister_connection (E_MAPI_CONNECTION (object));
-+
-+	priv = E_MAPI_CONNECTION (object)->priv;
-+
-+	if (priv) {
-+		stop_all_notifications (priv);
-+	}
-+
-+	if (G_OBJECT_CLASS (e_mapi_connection_parent_class)->dispose)
-+		G_OBJECT_CLASS (e_mapi_connection_parent_class)->dispose (object);
-+}
-+
-+static void
-+e_mapi_connection_finalize (GObject *object)
-+{
-+	EMapiConnection *conn;
-+	EMapiConnectionPrivate *priv;
-+
-+	conn = E_MAPI_CONNECTION (object);
-+	priv = conn->priv;
-+
-+	if (priv) {
-+		LOCK_VOID (NULL, NULL);
-+		disconnect (priv, TRUE && e_mapi_connection_connected (conn));
-+		g_free (priv->profile);
-+		priv->profile = NULL;
-+
-+		if (priv->named_ids)
-+			g_hash_table_destroy (priv->named_ids);
-+		priv->named_ids = NULL;
-+
-+		if (priv->foreign_stores)
-+			g_hash_table_destroy (priv->foreign_stores);
-+		priv->foreign_stores = NULL;
-+
-+		e_mapi_utils_destroy_mapi_context (priv->mapi_ctx);
-+		priv->mapi_ctx = NULL;
-+
-+		g_hash_table_destroy (priv->known_notifications);
-+		priv->known_notifications = NULL;
-+
-+		e_flag_free (priv->notification_flag);
-+		priv->notification_flag = NULL;
-+
-+		if (priv->registry)
-+			g_object_unref (priv->registry);
-+		priv->registry = NULL;
-+
-+		UNLOCK ();
-+
-+		e_mapi_cancellable_rec_mutex_clear (&priv->session_lock);
-+		g_rec_mutex_clear (&priv->folders_lock);
-+	}
-+
-+	if (G_OBJECT_CLASS (e_mapi_connection_parent_class)->finalize)
-+		G_OBJECT_CLASS (e_mapi_connection_parent_class)->finalize (object);
-+}
-+
-+static void
-+e_mapi_connection_class_init (EMapiConnectionClass *klass)
-+{
-+	GObjectClass *object_class;
-+
-+	g_type_class_add_private (klass, sizeof (EMapiConnectionPrivate));
-+
-+	object_class = G_OBJECT_CLASS (klass);
-+	object_class->dispose = e_mapi_connection_dispose;
-+	object_class->finalize = e_mapi_connection_finalize;
-+
-+	signals[SERVER_NOTIFICATION] = g_signal_new (
-+		"server-notification",
-+		G_OBJECT_CLASS_TYPE (object_class),
-+		G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED | G_SIGNAL_ACTION,
-+		0, NULL, NULL,
-+		g_cclosure_marshal_VOID__UINT_POINTER,
-+		G_TYPE_NONE, 2,
-+		G_TYPE_UINT, G_TYPE_POINTER);
-+}
-+
-+static void
-+e_mapi_connection_init (EMapiConnection *conn)
-+{
-+	conn->priv = G_TYPE_INSTANCE_GET_PRIVATE (conn, E_MAPI_TYPE_CONNECTION, EMapiConnectionPrivate);
-+	g_return_if_fail (conn->priv != NULL);
-+
-+	e_mapi_cancellable_rec_mutex_init (&conn->priv->session_lock);
-+	g_rec_mutex_init (&conn->priv->folders_lock);
-+
-+	conn->priv->session = NULL;
-+	conn->priv->profile = NULL;
-+	conn->priv->has_public_store = FALSE;
-+	conn->priv->folders = NULL;
-+
-+	conn->priv->foreign_stores = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-+	conn->priv->named_ids = g_hash_table_new_full (g_int64_hash, g_int64_equal, g_free, (GDestroyNotify) g_hash_table_destroy);
-+
-+	conn->priv->known_notifications = g_hash_table_new_full (g_int64_hash, g_int64_equal, g_free, NULL);
-+	conn->priv->notification_thread = NULL;
-+	conn->priv->notification_flag = e_flag_new ();
-+	conn->priv->register_notification_result = MAPI_E_RESERVED;
-+	conn->priv->notification_poll_seconds = 60;
-+
-+	if (g_getenv ("MAPI_SERVER_POLL")) {
-+		conn->priv->notification_poll_seconds = atoi (g_getenv ("MAPI_SERVER_POLL"));
-+		if (conn->priv->notification_poll_seconds < 1)
-+			conn->priv->notification_poll_seconds = 60;
-+	}
-+
-+	register_connection (conn);
-+}
-+
-+/* GObject foo - end */
-+
-+/* tracking alive connections - begin  */
-+
-+static GSList *known_connections = NULL;
-+G_LOCK_DEFINE_STATIC (known_connections);
-+
-+static void
-+register_connection (EMapiConnection *conn)
-+{
-+	g_return_if_fail (conn != NULL);
-+	g_return_if_fail (E_MAPI_IS_CONNECTION (conn));
-+
-+	G_LOCK (known_connections);
-+	/* append to prefer older connections when searching with e_mapi_connection_find() */
-+	known_connections = g_slist_append (known_connections, conn);
-+	G_UNLOCK (known_connections);
-+}
-+
-+static void
-+unregister_connection (EMapiConnection *conn)
-+{
-+	g_return_if_fail (conn != NULL);
-+	g_return_if_fail (E_MAPI_IS_CONNECTION (conn));
-+
-+	G_LOCK (known_connections);
-+	if (!g_slist_find (known_connections, conn)) {
-+		G_UNLOCK (known_connections);
-+		return;
-+	}
-+
-+	known_connections = g_slist_remove (known_connections, conn);
-+	G_UNLOCK (known_connections);
-+}
-+
-+/* Tries to find a connection associated with the 'profile'.
-+   If there are more, then the first created is returned.
-+   Note if it doesn't return NULL, then the returned pointer
-+   should be g_object_unref-ed, when done with it.
-+*/
-+EMapiConnection *
-+e_mapi_connection_find (const gchar *profile)
-+{
-+	GSList *l;
-+	EMapiConnection *res = NULL;
-+
-+	g_return_val_if_fail (profile != NULL, NULL);
-+
-+	G_LOCK (known_connections);
-+	for (l = known_connections; l != NULL && res == NULL; l = l->next) {
-+		EMapiConnection *conn = E_MAPI_CONNECTION (l->data);
-+		EMapiConnectionPrivate *priv = conn->priv;
-+
-+		if (priv && priv->profile && g_str_equal (profile, priv->profile) &&
-+		    e_mapi_connection_connected (conn))
-+			res = conn;
-+	}
-+
-+	if (res)
-+		g_object_ref (res);
-+
-+	G_UNLOCK (known_connections);
-+
-+	return res;
-+}
-+
-+/* tracking alive connections - end  */
-+
-+/* Specifies READ/WRITE sizes to be used while handling normal streams */
-+#define STREAM_MAX_READ_SIZE    0x8000
-+#define STREAM_MAX_READ_SIZE_DF 0x1000
-+#define STREAM_MAX_WRITE_SIZE   0x1000
-+
-+#define CHECK_CORRECT_CONN_AND_GET_PRIV(_conn, _val)							\
-+	EMapiConnectionPrivate *priv;									\
-+													\
-+	e_return_val_mapi_error_if_fail (_conn != NULL, MAPI_E_INVALID_PARAMETER, _val);		\
-+	e_return_val_mapi_error_if_fail (E_MAPI_IS_CONNECTION (_conn), MAPI_E_INVALID_PARAMETER, _val);	\
-+													\
-+	priv = (_conn)->priv;										\
-+	e_return_val_mapi_error_if_fail (priv != NULL, MAPI_E_INVALID_PARAMETER, _val);
-+
-+/* Creates a new connection object and connects to a server as defined in 'profile' */
-+EMapiConnection *
-+e_mapi_connection_new (ESourceRegistry *registry,
-+		       const gchar *profile,
-+		       const GString *password,
-+		       GCancellable *cancellable,
-+		       GError **perror)
-+{
-+	EMapiConnection *conn;
-+	EMapiConnectionPrivate *priv;
-+	struct mapi_context *mapi_ctx = NULL;
-+	struct mapi_session *session;
-+	enum MAPISTATUS ms;
-+
-+	e_return_val_mapi_error_if_fail (profile != NULL, MAPI_E_INVALID_PARAMETER, NULL);
-+
-+	if (!e_mapi_utils_create_mapi_context (&mapi_ctx, perror))
-+		return NULL;
-+
-+	session = mapi_profile_load (registry, mapi_ctx, profile, password ? password->str : NULL, cancellable, perror);
-+	if (!session) {
-+		e_mapi_utils_destroy_mapi_context (mapi_ctx);
-+		return NULL;
-+	}
-+
-+	conn = g_object_new (E_MAPI_TYPE_CONNECTION, NULL);
-+	priv = conn->priv;
-+	e_return_val_mapi_error_if_fail (priv != NULL, MAPI_E_INVALID_PARAMETER, conn);
-+
-+	LOCK (cancellable, perror, NULL);
-+	mapi_object_init (&priv->msg_store);
-+	priv->registry = registry ? g_object_ref (registry) : NULL;
-+	priv->mapi_ctx = mapi_ctx;
-+	priv->session = session;
-+
-+	/* Open the message store and keep it opened for all the life-time for this connection */
-+	ms = OpenMsgStore (priv->session, &priv->msg_store);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenMsgStore", ms);
-+
-+		/* how to close and free session without store? */
-+		priv->session = NULL;
-+
-+		UNLOCK ();
-+		g_object_unref (conn);
-+		return NULL;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		UNLOCK ();
-+		g_object_unref (conn);
-+		return NULL;
-+	}
-+
-+	priv->profile = g_strdup (profile);
-+	priv->has_public_store = FALSE;
-+
-+	UNLOCK ();
-+
-+	e_mapi_debug_print ("%s: %s: Connected ", G_STRLOC, G_STRFUNC);
-+
-+	return conn;
-+}
-+
-+gboolean
-+e_mapi_connection_disconnect (EMapiConnection *conn,
-+			      gboolean clean,
-+			      GCancellable *cancellable,
-+			      GError **perror)
-+{
-+	gboolean res = FALSE;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	res = priv->session != NULL;
-+	disconnect (priv, clean && e_mapi_connection_connected (conn));
-+
-+	UNLOCK ();
-+
-+	return res;
-+}
-+
-+gboolean
-+e_mapi_connection_reconnect (EMapiConnection *conn,
-+			     const GString *password,
-+			     GCancellable *cancellable,
-+			     GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+
-+	e_return_val_mapi_error_if_fail (priv->profile != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	if (priv->session)
-+		e_mapi_connection_disconnect (conn, FALSE, cancellable, perror);
-+
-+	priv->session = mapi_profile_load (priv->registry, priv->mapi_ctx, priv->profile, password ? password->str : NULL, cancellable, perror);
-+	if (!priv->session) {
-+		e_mapi_debug_print ("%s: %s: Login failed ", G_STRLOC, G_STRFUNC);
-+		UNLOCK ();
-+		return FALSE;
-+	}
-+
-+	mapi_object_init (&priv->msg_store);
-+
-+	/* Open the message store and keep it opened for all the life-time for this connection */
-+	ms = OpenMsgStore (priv->session, &priv->msg_store);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenMsgStore", ms);
-+
-+		/* how to close and free session without store? */
-+		priv->session = NULL;
-+
-+		UNLOCK ();
-+		return FALSE;
-+	}
-+
-+	priv->has_public_store = FALSE;
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		UNLOCK ();
-+		return FALSE;
-+	}
-+
-+	UNLOCK ();
-+
-+	e_mapi_debug_print ("%s: %s: Connected ", G_STRLOC, G_STRFUNC);
-+
-+	return priv->session != NULL;
-+}
-+
-+static gboolean
-+can_reach_mapi_server (const gchar *server_address,
-+		       GCancellable *cancellable,
-+		       GError **perror)
-+{
-+	GNetworkMonitor *network_monitor;
-+	GSocketConnectable *connectable;
-+	GError *local_error = NULL;
-+	gboolean reachable;
-+
-+	g_return_val_if_fail (server_address != NULL, FALSE);
-+
-+	network_monitor = g_network_monitor_get_default ();
-+	connectable = g_network_address_new (server_address, 135);
-+	reachable = g_network_monitor_can_reach (network_monitor, connectable, cancellable, &local_error);
-+	g_object_unref (connectable);
-+
-+	if (!reachable) {
-+		if (local_error)
-+			g_propagate_error (perror, local_error);
-+		else
-+			g_set_error (perror, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE, _("Server '%s' cannot be reached"), server_address);
-+	}
-+
-+	return reachable;
-+}
-+
-+gboolean
-+e_mapi_connection_connected (EMapiConnection *conn)
-+{
-+	/* to have this used in the below macros */
-+	GError **perror = NULL;
-+	gboolean res;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+
-+	LOCK (NULL, NULL, FALSE);
-+
-+	res = priv->session != NULL;
-+	if (res) {
-+		struct mapi_profile *profile;
-+
-+		profile = talloc_zero (priv->mapi_ctx, struct mapi_profile);
-+		if (MAPI_E_SUCCESS == OpenProfile (priv->mapi_ctx, profile, priv->profile, NULL)) {
-+			res = can_reach_mapi_server (profile->server, NULL, perror);
-+			ShutDown (profile);
-+		}
-+
-+		talloc_free (profile);
-+	}
-+
-+	UNLOCK ();
-+
-+	return res;
-+}
-+
-+static gboolean
-+may_skip_property (uint32_t proptag)
-+{
-+	/* skip all "strange" properties */
-+	gboolean skip = TRUE;
-+
-+	switch (proptag & 0xFFFF) {
-+	case PT_BOOLEAN:
-+	case PT_I2:
-+	case PT_LONG:
-+	case PT_DOUBLE:
-+	case PT_I8:
-+	case PT_STRING8:
-+	case PT_UNICODE:
-+	case PT_SYSTIME:
-+	case PT_BINARY:
-+	case PT_ERROR:
-+	case PT_CLSID:
-+	case PT_SVREID:
-+	case PT_MV_STRING8:
-+	case PT_MV_UNICODE:
-+	case PT_MV_BINARY:
-+	case PT_MV_LONG:
-+		skip = FALSE;
-+		break;
-+	default:
-+		break;
-+	}
-+
-+	return skip;
-+}
-+
-+gboolean
-+e_mapi_connection_test_foreign_folder (EMapiConnection *conn,
-+				       const gchar *username,
-+				       const gchar *folder_name,
-+				       mapi_id_t *fid, /* out */
-+				       GCancellable *cancellable,
-+				       GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	mapi_id_t foreign_fid = 0;
-+	mapi_object_t obj_store, obj_folder;
-+
-+	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 (username != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (folder_name != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (fid != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	mapi_object_init (&obj_store);
-+	mapi_object_init (&obj_folder);
-+
-+	ms = OpenUserMailbox (priv->session, username, &obj_store);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenUserMailbox", ms);
-+		goto cleanup;
-+	}
-+
-+	if (folder_name[0] == '0' && folder_name[1] == 'x' && e_mapi_util_mapi_id_from_string (folder_name + 2, &foreign_fid)) {
-+		ms = OpenFolder (&obj_store, foreign_fid, &obj_folder);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "OpenFolder", ms);
-+			goto cleanup;
-+		}
-+	} else {
-+		uint32_t def_folder_id = 0;
-+
-+		/* intentionally not localized strings */
-+		if (g_ascii_strcasecmp (folder_name, "Inbox") == 0) {
-+			def_folder_id = olFolderInbox;
-+		} else if (g_ascii_strcasecmp (folder_name, "DeletedItems") == 0) {
-+			def_folder_id = olFolderDeletedItems;
-+		} else if (g_ascii_strcasecmp (folder_name, "Outbox") == 0) {
-+			def_folder_id = olFolderOutbox;
-+		} else if (g_ascii_strcasecmp (folder_name, "SentMail") == 0) {
-+			def_folder_id = olFolderSentMail;
-+		} else if (g_ascii_strcasecmp (folder_name, "Calendar") == 0) {
-+			def_folder_id = olFolderCalendar;
-+		} else if (g_ascii_strcasecmp (folder_name, "Contacts") == 0) {
-+			def_folder_id = olFolderContacts;
-+		} else if (g_ascii_strcasecmp (folder_name, "Notes") == 0) {
-+			def_folder_id = olFolderNotes;
-+		} else if (g_ascii_strcasecmp (folder_name, "Tasks") == 0) {
-+			def_folder_id = olFolderTasks;
-+		} else if (g_ascii_strcasecmp (folder_name, "Drafts") == 0) {
-+			def_folder_id = olFolderDrafts;
-+		} else if (g_ascii_strcasecmp (folder_name, "Junk") == 0) {
-+			def_folder_id = olFolderJunk;
-+		} else if (!e_mapi_util_mapi_id_from_string (folder_name, &foreign_fid)) {
-+			ms = MAPI_E_CALL_FAILED;
-+			g_propagate_error (perror, g_error_new (E_MAPI_ERROR, ms, _("Folder name '%s' is not a known default folder name, nor folder ID."), folder_name));
-+			goto cleanup;
-+		}
-+
-+		if (def_folder_id != 0) {
-+			ms = GetDefaultFolder (&obj_store, &foreign_fid, def_folder_id);
-+			if (ms != MAPI_E_SUCCESS) {
-+				make_mapi_error (perror, "GetDefaultFolder", ms);
-+				goto cleanup;
-+			}
-+		}
-+
-+		ms = OpenFolder (&obj_store, foreign_fid, &obj_folder);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "OpenFolder", ms);
-+			goto cleanup;
-+		}
-+	}
-+
-+	*fid = mapi_object_get_id (&obj_folder);
-+
-+ cleanup:
-+	mapi_object_release (&obj_folder);
-+	mapi_object_release (&obj_store);
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_get_public_folder (EMapiConnection *conn,
-+				     mapi_object_t *obj_folder,
-+				     GCancellable *cancellable,
-+				     GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	mapi_object_init (obj_folder);
-+
-+	ms = OpenPublicFolder (priv->session, obj_folder);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenPublicFolder", ms);
-+	}
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_peek_store (EMapiConnection *conn,
-+			      gboolean public_store,
-+			      const gchar *foreign_username,
-+			      mapi_object_t **obj_store, /* out */
-+			      GCancellable *cancellable,
-+			      GError **perror)
-+{
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	if (public_store)
-+		e_return_val_mapi_error_if_fail (foreign_username == NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	if (foreign_username)
-+		e_return_val_mapi_error_if_fail (!public_store, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_store != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	if (public_store) {
-+		if (!ensure_public_store (priv, perror)) {
-+			UNLOCK ();
-+			return FALSE;
-+		}
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			UNLOCK ();
-+			return FALSE;
-+		}
-+
-+		*obj_store = &priv->public_store;
-+
-+		UNLOCK ();
-+
-+		return TRUE;
-+	}
-+
-+	if (foreign_username) {
-+		if (!ensure_foreign_store (priv, foreign_username, obj_store, perror)) {
-+			UNLOCK ();
-+			return FALSE;
-+		}
-+
-+		UNLOCK ();
-+		return TRUE;
-+	}
-+
-+	*obj_store = &priv->msg_store;
-+
-+	UNLOCK ();
-+
-+	return TRUE;
-+}
-+
-+/* sets quotas and current_size to -1 when not available, but still can return TRUE */
-+gboolean
-+e_mapi_connection_get_store_quotas (EMapiConnection *conn,
-+				    mapi_object_t *obj_store, /* can be NULL, for mailbox store */
-+				    uint64_t *current_size, /* out */
-+				    uint64_t *receive_quota, /* out */
-+				    uint64_t *send_quota, /* out */
-+				    GCancellable *cancellable,
-+				    GError **perror)
-+{
-+	enum MAPISTATUS ms = MAPI_E_RESERVED;
-+	TALLOC_CTX *mem_ctx;
-+	struct SPropTagArray *spropTagArray = NULL;
-+	struct SPropValue *lpProps = NULL;
-+	mapi_object_t *use_store;
-+
-+	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 (current_size != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (receive_quota != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (send_quota != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	use_store = obj_store;
-+	if (!use_store)
-+		use_store = &priv->msg_store;
-+
-+	*current_size = -1;
-+	*receive_quota = -1;
-+	*send_quota = -1;
-+
-+	mem_ctx = talloc_new (priv->session);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	spropTagArray = set_SPropTagArray (mem_ctx, 4,
-+		PidTagMessageSize,
-+		PidTagMessageSizeExtended,
-+		PidTagProhibitReceiveQuota,
-+		PidTagProhibitSendQuota);
-+
-+	if (spropTagArray && spropTagArray->cValues) {
-+		uint32_t prop_count = 0;
-+		const uint32_t *pmessage_size, *preceive_quota, *psend_quota;
-+		const uint64_t *pmessage_size_ex;
-+
-+		ms = GetProps (use_store, MAPI_PROPS_SKIP_NAMEDID_CHECK | MAPI_UNICODE, spropTagArray, &lpProps, &prop_count);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "GetProps", ms);
-+			goto cleanup;
-+		} else if (!lpProps) {
-+			ms = MAPI_E_CALL_FAILED;
-+			make_mapi_error (perror, "GetProps", ms);
-+			goto cleanup;
-+		}
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			goto cleanup;
-+		}
-+
-+		pmessage_size = e_mapi_util_find_SPropVal_array_propval (lpProps, PidTagMessageSize);
-+		pmessage_size_ex = e_mapi_util_find_SPropVal_array_propval (lpProps, PidTagMessageSizeExtended);
-+		preceive_quota = e_mapi_util_find_SPropVal_array_propval (lpProps, PidTagProhibitReceiveQuota);
-+		psend_quota = e_mapi_util_find_SPropVal_array_propval (lpProps, PidTagProhibitSendQuota);
-+
-+		if (pmessage_size && *pmessage_size != -1)
-+			*current_size = *pmessage_size;
-+		else if (pmessage_size_ex && *pmessage_size_ex)
-+			*current_size = *pmessage_size_ex;
-+
-+		if (*current_size != -1) {
-+			if (preceive_quota && *preceive_quota != -1) {
-+				*receive_quota = *preceive_quota;
-+				*receive_quota *= 1024;
-+			}
-+
-+			if (psend_quota && *psend_quota != -1) {
-+				*send_quota = *psend_quota;
-+				*send_quota *= 1024;
-+			}
-+		}
-+	} else {
-+		ms = MAPI_E_NOT_ENOUGH_RESOURCES;
-+		make_mapi_error (perror, "set_SPropTagArray", ms);
-+	}
-+
-+ cleanup:
-+	talloc_free (spropTagArray);
-+	talloc_free (lpProps);
-+	talloc_free (mem_ctx);
-+	UNLOCK();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_open_default_folder (EMapiConnection *conn,
-+				       uint32_t olFolderIdentifier,
-+				       mapi_object_t *obj_folder,
-+				       GCancellable *cancellable,
-+				       GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	mapi_id_t fid = 0;
-+	gboolean res;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	mapi_object_init (obj_folder);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	ms = GetDefaultFolder (&priv->msg_store, &fid, olFolderIdentifier);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetDefaultFolder", ms);
-+		UNLOCK ();
-+		return FALSE;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		UNLOCK ();
-+		return FALSE;
-+	}
-+
-+	res = e_mapi_connection_open_personal_folder (conn, fid, obj_folder, cancellable, perror);
-+
-+	UNLOCK ();
-+
-+	return res;
-+}
-+
-+gboolean
-+e_mapi_connection_open_personal_folder (EMapiConnection *conn,
-+					mapi_id_t fid,
-+					mapi_object_t *obj_folder,
-+					GCancellable *cancellable,
-+					GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	mapi_object_init (obj_folder);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	ms = OpenFolder (&priv->msg_store, fid, obj_folder);
-+	if (ms != MAPI_E_SUCCESS)
-+		make_mapi_error (perror, "OpenFolder", ms);
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_open_public_folder (EMapiConnection *conn,
-+				      mapi_id_t fid,
-+				      mapi_object_t *obj_folder,
-+				      GCancellable *cancellable,
-+				      GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	mapi_object_init (obj_folder);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	if (!ensure_public_store (priv, perror)) {
-+		UNLOCK ();
-+		return FALSE;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		UNLOCK ();
-+		return FALSE;
-+	}
-+
-+	ms = OpenFolder (&priv->public_store, fid, obj_folder);
-+	if (ms != MAPI_E_SUCCESS)
-+		make_mapi_error (perror, "OpenFolder", ms);
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_open_foreign_folder (EMapiConnection *conn,
-+				       const gchar *username,
-+				       mapi_id_t fid,
-+				       mapi_object_t *obj_folder, /* out */
-+				       GCancellable *cancellable,
-+				       GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	mapi_object_t *msg_store = NULL;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (username != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	mapi_object_init (obj_folder);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		UNLOCK ();
-+		return FALSE;
-+	}
-+
-+	if (!ensure_foreign_store (conn->priv, username, &msg_store, perror)) {
-+		ms = MAPI_E_CALL_FAILED;
-+		if (perror && !*perror)
-+			g_propagate_error (perror, g_error_new (E_MAPI_ERROR, ms, _("Failed to open store for user '%s'"), username));
-+	} else {
-+		ms = MAPI_E_SUCCESS;
-+	}
-+
-+	if (ms == MAPI_E_SUCCESS) {
-+		ms = OpenFolder (msg_store, fid, obj_folder);
-+		if (ms == MAPI_E_NOT_FOUND)
-+			g_propagate_error (perror, g_error_new (E_MAPI_ERROR, ms, _("Folder of user '%s' not found"), username));
-+		else if (ms != MAPI_E_SUCCESS)
-+			make_mapi_error (perror, "OpenFolder", ms);
-+	}
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_close_folder (EMapiConnection *conn,
-+				mapi_object_t *obj_folder,
-+				GCancellable *cancellable,
-+				GError **perror)
-+{
-+	gboolean was_cancelled = FALSE;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	/* kinda bad thing to do, but nothing better;
-+	   if the open_folder succeeded, then it's always good to free resources,
-+	   even when the operation on the folder was cancelled; and as it's good
-+	   to be cancellable, then this is better than passing NULL to LOCK().
-+	*/
-+	if (cancellable) {
-+		was_cancelled = g_cancellable_is_cancelled (cancellable);
-+		if (was_cancelled)
-+			g_cancellable_reset (cancellable);
-+	}
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	mapi_object_release (obj_folder);
-+
-+	/* this can invoke 'cancelled' again, but no big deal for evo-mapi */
-+	if (was_cancelled)
-+		g_cancellable_cancel (cancellable);
-+
-+	UNLOCK ();
-+
-+	return TRUE;
-+}
-+
-+static void
-+maybe_add_named_id_tag (uint32_t proptag,
-+			EResolveNamedIDsData **named_ids_list,
-+			guint *named_ids_len)
-+{
-+	g_return_if_fail (named_ids_list != NULL);
-+	g_return_if_fail (named_ids_len != NULL);
-+
-+	if (get_namedid_name (proptag)) {
-+		if (!*named_ids_list) {
-+			*named_ids_list = g_new0 (EResolveNamedIDsData, 1);
-+			*named_ids_len = 0;
-+		} else {
-+			*named_ids_list = g_renew (EResolveNamedIDsData, *named_ids_list, *named_ids_len + 1);
-+		}
-+
-+		(*named_ids_list)[*named_ids_len].pidlid_propid = proptag;
-+		(*named_ids_list)[*named_ids_len].propid = MAPI_E_RESERVED;
-+		(*named_ids_len) += 1;
-+	}
-+}
-+
-+/* free returned pointer with g_hash_table_destroy */
-+static GHashTable *
-+prepare_maybe_replace_hash (const EResolveNamedIDsData *named_ids_list,
-+			    guint named_ids_len,
-+			    gboolean to_server_ids)
-+{
-+	GHashTable *res;
-+	gint ii;
-+
-+	if (!named_ids_list || !named_ids_len)
-+		return NULL;
-+
-+	res = g_hash_table_new (g_direct_hash, g_direct_equal);
-+
-+	for (ii = 0; ii < named_ids_len; ii++) {
-+		uint32_t search_tag = named_ids_list[ii].pidlid_propid;
-+		uint32_t replace_with = named_ids_list[ii].propid;
-+
-+		if (!to_server_ids) {
-+			uint32_t ui32;
-+
-+			ui32 = search_tag;
-+			search_tag = replace_with;
-+			replace_with = ui32;
-+		}
-+
-+		g_hash_table_insert (res, GUINT_TO_POINTER (search_tag), GUINT_TO_POINTER (replace_with));
-+
-+		search_tag = (search_tag & ~0xFFFF) | PT_ERROR;
-+		replace_with = (replace_with & ~0xFFFF) | PT_ERROR;
-+
-+		g_hash_table_insert (res, GUINT_TO_POINTER (search_tag), GUINT_TO_POINTER (replace_with));
-+	}
-+
-+	return res;
-+}
-+
-+static void
-+maybe_replace_named_id_tag (uint32_t *pproptag,
-+			    GHashTable *replace_hash)
-+{
-+	gpointer key, value;
-+
-+	g_return_if_fail (pproptag != NULL);
-+
-+	if (!replace_hash)
-+		return;
-+
-+	if (g_hash_table_lookup_extended (replace_hash, GUINT_TO_POINTER (*pproptag), &key, &value))
-+		*pproptag = GPOINTER_TO_UINT (value);
-+}
-+
-+/* deals with named IDs transparently, if not using NULL bpr_cb, thus it's OK to check with PidLid and PidName constants only */
-+gboolean
-+e_mapi_connection_get_folder_properties (EMapiConnection *conn,
-+					 mapi_object_t *obj_folder,
-+					 BuildReadPropsCB brp_cb,
-+					 gpointer brp_cb_user_data,
-+					 GetPropertiesCB cb,
-+					 gpointer cb_user_data,
-+					 GCancellable *cancellable,
-+					 GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	TALLOC_CTX *mem_ctx;
-+	struct SPropTagArray *spropTagArray = NULL;
-+	struct mapi_SPropValue_array *properties = NULL;
-+	struct SPropValue *lpProps = NULL;
-+	gboolean res = FALSE;
-+
-+	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 (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (cb != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	mem_ctx = talloc_new (priv->session);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-+		goto cleanup;
-+
-+	spropTagArray = set_SPropTagArray (mem_ctx, 3, PidTagFolderId, PidTagLastModificationTime, PidTagContentCount);
-+	if (brp_cb) {
-+		if (!brp_cb (conn, mem_ctx, spropTagArray, brp_cb_user_data, cancellable, perror)) {
-+			goto cleanup;
-+		}
-+	} else {
-+		talloc_free (spropTagArray);
-+		spropTagArray = NULL;
-+	}
-+
-+	properties = talloc_zero (mem_ctx, struct mapi_SPropValue_array);
-+	if (spropTagArray && spropTagArray->cValues) {
-+		uint32_t prop_count = 0, k, ll;
-+		EResolveNamedIDsData *named_ids_list = NULL;
-+		guint named_ids_len = 0;
-+		GHashTable *replace_hash = NULL;
-+
-+		for (k = 0; k < spropTagArray->cValues; k++) {
-+			uint32_t proptag = spropTagArray->aulPropTag[k];
-+
-+			if (may_skip_property (proptag)) {
-+				const gchar *name = get_proptag_name (proptag);
-+				if (!name)
-+					name = "";
-+
-+				g_debug ("%s: Cannot fetch property 0x%08x %s", G_STRFUNC, proptag, name);
-+			} else {
-+				maybe_add_named_id_tag (proptag, &named_ids_list, &named_ids_len);
-+			}
-+		}
-+
-+		if (named_ids_list) {
-+			if (!e_mapi_connection_resolve_named_props (conn, obj_folder, named_ids_list, named_ids_len, cancellable, perror)) {
-+				g_free (named_ids_list);
-+				goto cleanup;
-+			}
-+
-+			if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+				g_free (named_ids_list);
-+				goto cleanup;
-+			}
-+
-+			replace_hash = prepare_maybe_replace_hash (named_ids_list, named_ids_len, TRUE);
-+			if (replace_hash) {
-+				for (k = 0; k < spropTagArray->cValues; k++) {
-+					uint32_t proptag = spropTagArray->aulPropTag[k];
-+
-+					maybe_replace_named_id_tag (&proptag, replace_hash);
-+
-+					spropTagArray->aulPropTag[k] = proptag;
-+				}
-+				g_hash_table_destroy (replace_hash);
-+				replace_hash = NULL;
-+			}
-+		}
-+
-+		ms = GetProps (obj_folder, MAPI_PROPS_SKIP_NAMEDID_CHECK | MAPI_UNICODE, spropTagArray, &lpProps, &prop_count);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "GetProps", ms);
-+			g_free (named_ids_list);
-+			goto cleanup;
-+		} else if (!lpProps) {
-+			ms = MAPI_E_CALL_FAILED;
-+			make_mapi_error (perror, "GetProps", ms);
-+			g_free (named_ids_list);
-+			goto cleanup;
-+		}
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			g_free (named_ids_list);
-+			goto cleanup;
-+		}
-+
-+		if (named_ids_list)
-+			replace_hash = prepare_maybe_replace_hash (named_ids_list, named_ids_len, FALSE);
-+
-+		/* Conversion from SPropValue to mapi_SPropValue. (no padding here) */
-+		properties->cValues = prop_count;
-+		properties->lpProps = talloc_zero_array (mem_ctx, struct mapi_SPropValue, prop_count + 1);
-+		for (k = 0, ll = 0; k < prop_count; k++, ll++) {
-+			if (may_skip_property (lpProps[k].ulPropTag)) {
-+				ll--;
-+				properties->cValues--;
-+			} else {
-+				uint32_t proptag = lpProps[k].ulPropTag;
-+
-+				maybe_replace_named_id_tag (&proptag, replace_hash);
-+				lpProps[k].ulPropTag = proptag;
-+
-+				cast_mapi_SPropValue (mem_ctx, &properties->lpProps[ll], &lpProps[k]);
-+			}
-+		}
-+
-+		g_free (named_ids_list);
-+		if (replace_hash)
-+			g_hash_table_destroy (replace_hash);
-+	} else {
-+		ms = GetPropsAll (obj_folder, MAPI_UNICODE, properties);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "GetPropsAll", ms);
-+			goto cleanup;
-+		}
-+
-+		if (properties)
-+			properties->lpProps = talloc_steal (properties, properties->lpProps);
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-+		goto cleanup;
-+
-+	res = cb (conn, mem_ctx, properties, cb_user_data, cancellable, perror);
-+
-+ cleanup:
-+	talloc_free (spropTagArray);
-+	talloc_free (properties);
-+	talloc_free (lpProps);
-+	talloc_free (mem_ctx);
-+	UNLOCK();
-+
-+	return res;
-+}
-+
-+typedef gboolean (*ForeachTableRowCB)	(EMapiConnection *conn,
-+					 TALLOC_CTX *mem_ctx,
-+					 struct SRow *srow,
-+					 guint32 row_index,
-+					 guint32 rows_total,
-+					 gpointer user_data,
-+					 GCancellable *cancellable,
-+					 GError **perror);
-+
-+static enum MAPISTATUS
-+foreach_tablerow (EMapiConnection *conn,
-+		  TALLOC_CTX *mem_ctx,
-+		  mapi_object_t *obj_table,
-+		  ForeachTableRowCB cb,
-+		  gpointer user_data,
-+		  GCancellable *cancellable,
-+		  GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	struct SRowSet SRowSet;
-+	uint32_t count, i, cursor_pos = 0;
-+
-+	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 (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_table != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (cb != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	do {
-+		/* Number of items in the container */
-+		ms = QueryPosition (obj_table, &cursor_pos, &count);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "QueryPosition", ms);
-+			break;
-+		}
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			break;
-+		}
-+
-+		if (!count)
-+			break;
-+
-+		/* 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);
-+			break;
-+		}
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			break;
-+		}
-+
-+		for (i = 0; i < SRowSet.cRows && ms == MAPI_E_SUCCESS; i++) {
-+			if (!cb (conn, mem_ctx, &SRowSet.aRow[i], cursor_pos + i + 1, count, user_data, cancellable, perror))
-+				ms = MAPI_E_RESERVED;
-+			else if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-+				ms = MAPI_E_USER_CANCEL;
-+		}
-+	} while (cursor_pos < count && ms == MAPI_E_SUCCESS);
-+
-+	return ms;
-+}
-+
-+static gboolean
-+gather_folder_permissions_cb (EMapiConnection *conn,
-+			      TALLOC_CTX *mem_ctx,
-+			      struct SRow *srow,
-+			      guint32 row_index,
-+			      guint32 rows_total,
-+			      gpointer user_data,
-+			      GCancellable *cancellable,
-+			      GError **perror)
-+{
-+	GSList **entries = user_data;
-+	const gchar *username;
-+	const struct Binary_r *pentry_id;
-+	const uint64_t *pid;
-+	const uint32_t *prights;
-+
-+	g_return_val_if_fail (srow != NULL, FALSE);
-+	g_return_val_if_fail (entries != NULL, FALSE);
-+
-+	username = e_mapi_util_find_row_propval (srow, PidTagMemberName);
-+	pid = e_mapi_util_find_row_propval (srow, PidTagMemberId);
-+	pentry_id = e_mapi_util_find_row_propval (srow, PidTagEntryId);
-+	prights = e_mapi_util_find_row_propval (srow, PidTagMemberRights);
-+
-+	if (prights && pid) {
-+		EMapiPermissionEntry *pem;
-+		struct SBinary_short entry_id;
-+
-+		entry_id.cb = pentry_id ? pentry_id->cb : 0;
-+		entry_id.lpb = pentry_id ? pentry_id->lpb : NULL;
-+
-+		pem = e_mapi_permission_entry_new (username, pentry_id ? &entry_id : NULL, *pid, *prights);
-+		g_return_val_if_fail (pem != NULL, FALSE);
-+
-+		*entries = g_slist_prepend (*entries, pem);
-+	} else {
-+		g_debug ("%s: Skipping [%d/%d] (%s) No rights or member ID set", G_STRFUNC, row_index, rows_total, username ? username : "no member name");
-+	}
-+
-+	return TRUE;
-+}
-+
-+gboolean
-+e_mapi_connection_get_permissions (EMapiConnection *conn,
-+				   mapi_object_t *obj_folder,
-+				   gboolean with_freebusy,
-+				   GSList **entries, /* EMapiPermissionEntry */
-+				   GCancellable *cancellable,
-+				   GError **perror)
-+{
-+	enum MAPISTATUS ms = MAPI_E_RESERVED;
-+	struct SPropTagArray *propTagArray;
-+	mapi_object_t obj_table;
-+	TALLOC_CTX *mem_ctx;
-+
-+	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 (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (entries != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	mem_ctx = talloc_new (priv->session);
-+	mapi_object_init (&obj_table);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	ms = GetPermissionsTable (obj_folder, with_freebusy ? IncludeFreeBusy : 0, &obj_table);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetPermissionsTable", ms);
-+		goto cleanup;
-+	}
-+
-+	propTagArray = set_SPropTagArray (mem_ctx, 4,
-+					  PidTagMemberId,
-+					  PidTagEntryId,
-+					  PidTagMemberName,
-+					  PidTagMemberRights);
-+
-+	/* Set primary columns to be fetched */
-+	ms = SetColumns (&obj_table, propTagArray);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "SetColumns", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	*entries = NULL;
-+
-+	ms = foreach_tablerow (conn, mem_ctx, &obj_table, gather_folder_permissions_cb, entries, cancellable, perror);
-+	if (ms == MAPI_E_SUCCESS) {
-+		*entries = g_slist_reverse (*entries);
-+	} else {
-+		g_slist_free_full (*entries, (GDestroyNotify) e_mapi_permission_entry_free);
-+		*entries = NULL;
-+	}
-+
-+ cleanup:
-+	mapi_object_release (&obj_table);
-+	talloc_free (mem_ctx);
-+	UNLOCK();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_set_permissions (EMapiConnection *conn,
-+				   mapi_object_t *obj_folder,
-+				   gboolean with_freebusy,
-+				   const GSList *entries, /* EMapiPermissionEntry */
-+				   GCancellable *cancellable,
-+				   GError **perror)
-+{
-+	enum MAPISTATUS ms = MAPI_E_RESERVED;
-+	struct mapi_PermissionsData *rows = NULL;
-+	GSList *current_entries = NULL;
-+	TALLOC_CTX *mem_ctx;
-+
-+	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 (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	mem_ctx = talloc_new (priv->session);
-+
-+	rows = talloc_zero (mem_ctx, struct mapi_PermissionsData);
-+	if (!rows) {
-+		ms = MAPI_E_NOT_ENOUGH_RESOURCES;
-+		make_mapi_error (perror, "talloc_zero", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	if (!e_mapi_connection_get_permissions (conn, obj_folder, with_freebusy, &current_entries, cancellable, perror)) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "e_mapi_connection_get_permissions", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	rows->ModifyCount = g_slist_length ((GSList *) entries) + g_slist_length (current_entries);
-+	if (rows->ModifyCount > 0) {
-+		const GSList *iter, *citer;
-+		GSList *removed_entries = g_slist_copy (current_entries);
-+		gint row_index = 0;
-+
-+		rows->PermissionsData = talloc_array (rows, struct PermissionData, rows->ModifyCount);
-+		if (!rows->PermissionsData) {
-+			ms = MAPI_E_NOT_ENOUGH_RESOURCES;
-+			make_mapi_error (perror, "talloc_zero", ms);
-+			g_slist_free (removed_entries);
-+			goto cleanup;
-+		}
-+
-+		for (iter = entries; iter; iter = iter->next) {
-+			const EMapiPermissionEntry *pem = iter->data, *cpem = NULL;
-+
-+			if (!pem) {
-+				ms = MAPI_E_INVALID_PARAMETER;
-+				make_mapi_error (perror, "entries::data", ms);
-+				g_slist_free (removed_entries);
-+				goto cleanup;
-+			}
-+
-+			for (citer = current_entries; citer; citer = citer->next) {
-+				cpem = citer->data;
-+
-+				if (cpem && ((cpem->entry_id.cb == pem->entry_id.cb && cpem->member_id == pem->member_id) ||
-+				   (cpem->entry_id.cb > 0 && e_mapi_util_recip_entryid_equal (&cpem->entry_id, &pem->entry_id)))) {
-+					removed_entries = g_slist_remove (removed_entries, cpem);
-+					break;
-+				}
-+
-+				cpem = NULL;
-+			}
-+
-+			if (cpem == NULL) {
-+				rows->PermissionsData[row_index].PermissionDataFlags = ROW_ADD;
-+				rows->PermissionsData[row_index].lpProps.cValues = 2;
-+				rows->PermissionsData[row_index].lpProps.lpProps = talloc_zero_array (rows, struct mapi_SPropValue, 3);
-+				if (!rows->PermissionsData[row_index].lpProps.lpProps) {
-+					ms = MAPI_E_NOT_ENOUGH_RESOURCES;
-+					make_mapi_error (perror, "talloc_zero", ms);
-+					g_slist_free (removed_entries);
-+					goto cleanup;
-+				}
-+
-+				rows->PermissionsData[row_index].lpProps.lpProps[0].ulPropTag = PidTagEntryId;
-+				rows->PermissionsData[row_index].lpProps.lpProps[0].value.bin.cb = pem->entry_id.cb;
-+				rows->PermissionsData[row_index].lpProps.lpProps[0].value.bin.lpb = pem->entry_id.lpb;
-+
-+				rows->PermissionsData[row_index].lpProps.lpProps[1].ulPropTag = PidTagMemberRights;
-+				rows->PermissionsData[row_index].lpProps.lpProps[1].value.l = pem->member_rights &
-+					~(with_freebusy ? 0 : (E_MAPI_PERMISSION_BIT_FREE_BUSY_DETAILED | E_MAPI_PERMISSION_BIT_FREE_BUSY_SIMPLE));
-+
-+				row_index++;
-+			} else if (cpem->member_rights != pem->member_rights) {
-+				rows->PermissionsData[row_index].PermissionDataFlags = ROW_MODIFY;
-+				rows->PermissionsData[row_index].lpProps.cValues = 2;
-+				rows->PermissionsData[row_index].lpProps.lpProps = talloc_zero_array (rows, struct mapi_SPropValue, 3);
-+				if (!rows->PermissionsData[row_index].lpProps.lpProps) {
-+					ms = MAPI_E_NOT_ENOUGH_RESOURCES;
-+					make_mapi_error (perror, "talloc_zero", ms);
-+					g_slist_free (removed_entries);
-+					goto cleanup;
-+				}
-+
-+				rows->PermissionsData[row_index].lpProps.lpProps[0].ulPropTag = PidTagMemberId;
-+				rows->PermissionsData[row_index].lpProps.lpProps[0].value.d = pem->member_id;
-+
-+				rows->PermissionsData[row_index].lpProps.lpProps[1].ulPropTag = PidTagMemberRights;
-+				rows->PermissionsData[row_index].lpProps.lpProps[1].value.l = pem->member_rights &
-+					~(with_freebusy ? 0 : (E_MAPI_PERMISSION_BIT_FREE_BUSY_DETAILED | E_MAPI_PERMISSION_BIT_FREE_BUSY_SIMPLE));
-+
-+				row_index++;
-+			}
-+		}
-+
-+		for (citer = removed_entries; citer; citer = citer->next) {
-+			const EMapiPermissionEntry *cpem = citer->data;
-+
-+			if (cpem) {
-+				rows->PermissionsData[row_index].PermissionDataFlags = ROW_REMOVE;
-+				rows->PermissionsData[row_index].lpProps.cValues = 1;
-+				rows->PermissionsData[row_index].lpProps.lpProps = talloc_zero_array (rows, struct mapi_SPropValue, 2);
-+				if (!rows->PermissionsData[row_index].lpProps.lpProps) {
-+					ms = MAPI_E_NOT_ENOUGH_RESOURCES;
-+					make_mapi_error (perror, "talloc_zero", ms);
-+					g_slist_free (removed_entries);
-+					goto cleanup;
-+				}
-+
-+				rows->PermissionsData[row_index].lpProps.lpProps[0].ulPropTag = PidTagMemberId;
-+				rows->PermissionsData[row_index].lpProps.lpProps[0].value.d = cpem->member_id;
-+
-+				row_index++;
-+			}
-+		}
-+
-+		rows->ModifyCount = row_index;
-+
-+		g_slist_free (removed_entries);
-+	}
-+
-+	if (rows->ModifyCount > 0) {
-+		ms = ModifyPermissions (obj_folder, with_freebusy ? ModifyPerms_IncludeFreeBusy : 0, rows);
-+		if (ms == MAPI_E_INVALID_PARAMETER && with_freebusy) {
-+			gint ii;
-+
-+			for (ii = 0; ii < rows->ModifyCount; ii++) {
-+				if (rows->PermissionsData[ii].PermissionDataFlags == ROW_ADD) {
-+					rows->PermissionsData[ii].lpProps.lpProps[1].value.l &=
-+						~(E_MAPI_PERMISSION_BIT_FREE_BUSY_DETAILED | E_MAPI_PERMISSION_BIT_FREE_BUSY_SIMPLE);
-+				} else if (rows->PermissionsData[ii].PermissionDataFlags == ROW_MODIFY) {
-+					rows->PermissionsData[ii].lpProps.lpProps[1].value.l &=
-+						~(E_MAPI_PERMISSION_BIT_FREE_BUSY_DETAILED | E_MAPI_PERMISSION_BIT_FREE_BUSY_SIMPLE);
-+				}
-+			}
-+
-+			/* older servers (up to 8.0.360.0) can have issue setting Free/Busy flags,
-+			   thus try to set permissions without modifying these;
-+			   similar error can be also thrown when setting Free/Busy flags in rights,
-+			   but does not use ModifyPerms_IncludeFreeBusy flag
-+			*/
-+			ms = ModifyPermissions (obj_folder, 0, rows);
-+		}
-+
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "ModifyPermissions", ms);
-+			goto cleanup;
-+		}
-+	}
-+
-+ cleanup:
-+	g_slist_free_full (current_entries, (GDestroyNotify) e_mapi_permission_entry_free);
-+	talloc_free (rows);
-+	talloc_free (mem_ctx);
-+	UNLOCK();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+struct ListObjectsInternalData
-+{
-+	ListObjectsCB cb;
-+	gpointer user_data;
-+};
-+
-+static gboolean
-+list_objects_internal_cb (EMapiConnection *conn,
-+			  TALLOC_CTX *mem_ctx,
-+			  struct SRow *srow,
-+			  guint32 row_index,
-+			  guint32 rows_total,
-+			  gpointer user_data,
-+			  GCancellable *cancellable,
-+			  GError **perror)
-+{
-+	struct ListObjectsInternalData *loi_data = user_data;
-+	ListObjectsData lod = { 0 };
-+	const mapi_id_t	*pmid;
-+	const gchar *msg_class;
-+	const uint32_t *pmsg_flags;
-+	const struct FILETIME *last_modified;
-+
-+	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 (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (srow != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	pmid = e_mapi_util_find_row_propval (srow, PidTagMid);
-+	msg_class = e_mapi_util_find_row_propval (srow, PidTagMessageClass);
-+	pmsg_flags = e_mapi_util_find_row_propval (srow, PidTagMessageFlags);
-+	last_modified = e_mapi_util_find_row_propval (srow, PidTagLastModificationTime);
-+
-+	lod.mid = pmid ? *pmid : 0;
-+	lod.msg_class = msg_class;
-+	lod.msg_flags = pmsg_flags ? *pmsg_flags : 0;
-+	lod.last_modified = last_modified ? e_mapi_util_filetime_to_time_t (last_modified) : 0;
-+
-+	return loi_data->cb (conn, mem_ctx, &lod, row_index, rows_total, loi_data->user_data, cancellable, perror);
-+}
-+
-+static void
-+gather_mapi_SRestriction_named_ids (struct mapi_SRestriction *restriction,
-+				    EResolveNamedIDsData **named_ids_list,
-+				    guint *named_ids_len)
-+{
-+	guint i;
-+
-+	g_return_if_fail (restriction != NULL);
-+	g_return_if_fail (named_ids_list != NULL);
-+	g_return_if_fail (named_ids_len != NULL);
-+
-+	switch (restriction->rt) {
-+	case RES_AND:
-+		for (i = 0; i < restriction->res.resAnd.cRes; i++) {
-+			gather_mapi_SRestriction_named_ids ((struct mapi_SRestriction *) &(restriction->res.resAnd.res[i]), named_ids_list, named_ids_len);
-+		}
-+		break;
-+	case RES_OR:
-+		for (i = 0; i < restriction->res.resOr.cRes; i++) {
-+			gather_mapi_SRestriction_named_ids ((struct mapi_SRestriction *) &(restriction->res.resOr.res[i]), named_ids_list, named_ids_len);
-+		}
-+		break;
-+	#ifdef HAVE_RES_NOT_SUPPORTED
-+	case RES_NOT:
-+		gather_mapi_SRestriction_named_ids ((struct mapi_SRestriction *) restriction->res.resNot.res, named_ids_list, named_ids_len);
-+		break;
-+	#endif
-+	case RES_CONTENT:
-+		maybe_add_named_id_tag (restriction->res.resContent.ulPropTag, named_ids_list, named_ids_len);
-+		maybe_add_named_id_tag (restriction->res.resContent.lpProp.ulPropTag, named_ids_list, named_ids_len);
-+		break;
-+	case RES_PROPERTY:
-+		maybe_add_named_id_tag (restriction->res.resProperty.ulPropTag, named_ids_list, named_ids_len);
-+		maybe_add_named_id_tag (restriction->res.resProperty.lpProp.ulPropTag, named_ids_list, named_ids_len);
-+		break;
-+	case RES_COMPAREPROPS:
-+		maybe_add_named_id_tag (restriction->res.resCompareProps.ulPropTag1, named_ids_list, named_ids_len);
-+		maybe_add_named_id_tag (restriction->res.resCompareProps.ulPropTag2, named_ids_list, named_ids_len);
-+		break;
-+	case RES_BITMASK:
-+		maybe_add_named_id_tag (restriction->res.resBitmask.ulPropTag, named_ids_list, named_ids_len);
-+		break;
-+	case RES_SIZE:
-+		maybe_add_named_id_tag (restriction->res.resSize.ulPropTag, named_ids_list, named_ids_len);
-+		break;
-+	case RES_EXIST:
-+		maybe_add_named_id_tag (restriction->res.resExist.ulPropTag, named_ids_list, named_ids_len);
-+		break;
-+	}
-+}
-+
-+static void
-+replace_mapi_SRestriction_named_ids (struct mapi_SRestriction *restriction,
-+				     GHashTable *replace_hash)
-+{
-+	guint i;
-+	uint32_t proptag;
-+
-+	g_return_if_fail (restriction != NULL);
-+
-+	#define check_proptag(x) {						\
-+			proptag = x;						\
-+			maybe_replace_named_id_tag (&proptag, replace_hash);	\
-+			x = proptag;						\
-+		}
-+
-+	switch (restriction->rt) {
-+	case RES_AND:
-+		for (i = 0; i < restriction->res.resAnd.cRes; i++) {
-+			replace_mapi_SRestriction_named_ids ((struct mapi_SRestriction *) &(restriction->res.resAnd.res[i]), replace_hash);
-+		}
-+		break;
-+	case RES_OR:
-+		for (i = 0; i < restriction->res.resOr.cRes; i++) {
-+			replace_mapi_SRestriction_named_ids ((struct mapi_SRestriction *) &(restriction->res.resOr.res[i]), replace_hash);
-+		}
-+		break;
-+	#ifdef HAVE_RES_NOT_SUPPORTED
-+	case RES_NOT:
-+		replace_mapi_SRestriction_named_ids (restriction->res.resNot.res, replace_hash);
-+		break;
-+	#endif
-+	case RES_CONTENT:
-+		check_proptag (restriction->res.resContent.ulPropTag);
-+		check_proptag (restriction->res.resContent.lpProp.ulPropTag);
-+		break;
-+	case RES_PROPERTY:
-+		check_proptag (restriction->res.resProperty.ulPropTag);
-+		check_proptag (restriction->res.resProperty.lpProp.ulPropTag);
-+		break;
-+	case RES_COMPAREPROPS:
-+		check_proptag (restriction->res.resCompareProps.ulPropTag1);
-+		check_proptag (restriction->res.resCompareProps.ulPropTag2);
-+		break;
-+	case RES_BITMASK:
-+		check_proptag (restriction->res.resBitmask.ulPropTag);
-+		break;
-+	case RES_SIZE:
-+		check_proptag (restriction->res.resSize.ulPropTag);
-+		break;
-+	case RES_EXIST:
-+		check_proptag (restriction->res.resExist.ulPropTag);
-+		break;
-+	}
-+
-+	#undef check_proptag
-+}
-+
-+static void
-+remove_unknown_proptags_mapi_SRestriction_rec (struct mapi_SRestriction *restriction,
-+					       TALLOC_CTX *mem_ctx,
-+					       GSList **new_rests)
-+{
-+	gint ii;
-+	GSList *sub_rests = NULL, *iter;
-+
-+	if (!restriction)
-+		return;
-+
-+	g_return_if_fail (mem_ctx != NULL);
-+
-+	#define proptag_is_ok(x) (((uint32_t) (x)) != 0 && ((uint32_t) (x)) != MAPI_E_RESERVED)
-+
-+	switch (restriction->rt) {
-+	case RES_AND:
-+		for (ii = 0; ii < restriction->res.resAnd.cRes; ii++) {
-+			remove_unknown_proptags_mapi_SRestriction_rec ((struct mapi_SRestriction *) &(restriction->res.resAnd.res[ii]), mem_ctx, &sub_rests);
-+		}
-+
-+		if (sub_rests) {
-+			struct mapi_SRestriction *rest = talloc_zero (mem_ctx, struct mapi_SRestriction);
-+			g_return_if_fail (rest != NULL);
-+
-+			rest->rt = RES_AND;
-+			rest->res.resAnd.cRes = g_slist_length (sub_rests);
-+			rest->res.resAnd.res = talloc_zero_array (mem_ctx, struct mapi_SRestriction_and, rest->res.resAnd.cRes + 1);
-+			g_return_if_fail (rest->res.resAnd.res != NULL);
-+
-+			for (iter = sub_rests, ii = 0; iter; iter = iter->next, ii++) {
-+				struct mapi_SRestriction *subrest = iter->data;
-+
-+				g_return_if_fail (subrest != NULL);
-+
-+				rest->res.resAnd.res[ii].rt = subrest->rt;
-+				rest->res.resAnd.res[ii].res = subrest->res;
-+			}
-+
-+			*new_rests = g_slist_append (*new_rests, rest);
-+		}
-+		break;
-+	case RES_OR:
-+		for (ii = 0; ii < restriction->res.resOr.cRes; ii++) {
-+			remove_unknown_proptags_mapi_SRestriction_rec ((struct mapi_SRestriction *) &(restriction->res.resOr.res[ii]), mem_ctx, &sub_rests);
-+		}
-+
-+		if (sub_rests) {
-+			struct mapi_SRestriction *rest = talloc_zero (mem_ctx, struct mapi_SRestriction);
-+			g_return_if_fail (rest != NULL);
-+
-+			rest->rt = RES_OR;
-+			rest->res.resOr.cRes = g_slist_length (sub_rests);
-+			rest->res.resOr.res = talloc_zero_array (mem_ctx, struct mapi_SRestriction_or, rest->res.resOr.cRes + 1);
-+			g_return_if_fail (rest->res.resOr.res != NULL);
-+
-+			for (iter = sub_rests, ii = 0; iter; iter = iter->next, ii++) {
-+				struct mapi_SRestriction *subrest = iter->data;
-+
-+				g_return_if_fail (subrest != NULL);
-+
-+				rest->res.resOr.res[ii].rt = subrest->rt;
-+				rest->res.resOr.res[ii].res = subrest->res;
-+			}
-+
-+			*new_rests = g_slist_append (*new_rests, rest);
-+		}
-+		break;
-+	#ifdef HAVE_RES_NOT_SUPPORTED
-+	case RES_NOT:
-+		remove_unknown_proptags_mapi_SRestriction_rec (restriction->res.resNot.res, mem_ctx, &sub_rests);
-+		if (sub_rests) {
-+			struct mapi_SRestriction *rest = talloc_zero (esp->mem_ctx, struct mapi_SRestriction);
-+			g_return_if_fail (rest != NULL);
-+
-+			rest->rt = RES_NOT;
-+			res->res.resNot.res = sub_rests->data;
-+		}
-+		break;
-+	#endif
-+	case RES_CONTENT:
-+		if (proptag_is_ok (restriction->res.resContent.ulPropTag) &&
-+		    proptag_is_ok (restriction->res.resContent.lpProp.ulPropTag)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	case RES_PROPERTY:
-+		if (proptag_is_ok (restriction->res.resProperty.ulPropTag) &&
-+		    proptag_is_ok (restriction->res.resProperty.lpProp.ulPropTag)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	case RES_COMPAREPROPS:
-+		if (proptag_is_ok (restriction->res.resCompareProps.ulPropTag1) &&
-+		    proptag_is_ok (restriction->res.resCompareProps.ulPropTag2)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	case RES_BITMASK:
-+		if (proptag_is_ok (restriction->res.resBitmask.ulPropTag)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	case RES_SIZE:
-+		if (proptag_is_ok (restriction->res.resSize.ulPropTag)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	case RES_EXIST:
-+		if (proptag_is_ok (restriction->res.resExist.ulPropTag)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	default:
-+		g_warn_if_reached ();
-+		break;
-+	}
-+
-+	#undef proptag_is_ok
-+
-+	g_slist_free (sub_rests);
-+}
-+
-+static void
-+remove_unknown_proptags_mapi_SRestriction (struct mapi_SRestriction **prestrictions,
-+					   TALLOC_CTX *mem_ctx)
-+{
-+	GSList *new_rests = NULL;
-+
-+	g_return_if_fail (mem_ctx != NULL);
-+
-+	remove_unknown_proptags_mapi_SRestriction_rec (*prestrictions, mem_ctx, &new_rests);
-+
-+	if (new_rests) {
-+		g_return_if_fail (g_slist_length (new_rests) == 1);
-+
-+		*prestrictions = new_rests->data;
-+
-+		g_slist_free (new_rests);
-+	} else {
-+		*prestrictions = NULL;
-+	}
-+}
-+
-+static gboolean
-+change_mapi_SRestriction_named_ids (EMapiConnection *conn,
-+				    mapi_object_t *obj_folder,
-+				    TALLOC_CTX *mem_ctx,
-+				    struct mapi_SRestriction **prestrictions,
-+				    GCancellable *cancellable,
-+				    GError **perror)
-+{
-+	EResolveNamedIDsData *named_ids_list = NULL;
-+	guint named_ids_len = 0;
-+	gboolean res = FALSE;
-+
-+	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 (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (prestrictions != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (*prestrictions != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	gather_mapi_SRestriction_named_ids (*prestrictions, &named_ids_list, &named_ids_len);
-+
-+	if (!named_ids_list)
-+		return TRUE;
-+
-+	res = e_mapi_connection_resolve_named_props (conn, obj_folder, named_ids_list, named_ids_len, cancellable, perror);
-+
-+	if (res) {
-+		GHashTable *replace_hash = prepare_maybe_replace_hash (named_ids_list, named_ids_len, TRUE);
-+
-+		if (replace_hash) {
-+			replace_mapi_SRestriction_named_ids (*prestrictions, replace_hash);
-+			g_hash_table_destroy (replace_hash);
-+		}
-+	}
-+
-+	g_free (named_ids_list);
-+
-+	remove_unknown_proptags_mapi_SRestriction (prestrictions, mem_ctx); 
-+
-+	return res;
-+}
-+
-+/* deals with named IDs transparently, thus it's OK to pass Restrictions with PidLid and PidName constants */
-+gboolean
-+e_mapi_connection_list_objects (EMapiConnection *conn,
-+				mapi_object_t *obj_folder,
-+				BuildRestrictionsCB build_rs_cb,
-+				gpointer build_rs_cb_data,
-+				ListObjectsCB cb,
-+				gpointer user_data,
-+				GCancellable *cancellable,
-+				GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	TALLOC_CTX *mem_ctx;
-+	mapi_object_t obj_table;
-+	struct SPropTagArray *propTagArray;
-+	struct ListObjectsInternalData loi_data;
-+
-+	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 (cancellable, perror, FALSE);
-+	mem_ctx = talloc_new (priv->session);
-+	mapi_object_init (&obj_table);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* Get a handle on the container */
-+	ms = GetContentsTable (obj_folder, &obj_table, TableFlags_UseUnicode, NULL);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetContentsTable", ms);
-+		goto cleanup;
-+	}
-+
-+	propTagArray = set_SPropTagArray (mem_ctx, 4,
-+		PidTagMid,
-+		PidTagMessageClass,
-+		PidTagMessageFlags,
-+		PidTagLastModificationTime);
-+		/* PidTagObjectType doesn't work with Exchange 2010 servers */
-+
-+	/* Set primary columns to be fetched */
-+	ms = SetColumns (&obj_table, propTagArray);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "SetColumns", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	if (build_rs_cb) {
-+		struct mapi_SRestriction *restrictions = NULL;
-+
-+		if (!build_rs_cb (conn, mem_ctx, &restrictions, build_rs_cb_data, cancellable, perror)) {
-+			ms = MAPI_E_CALL_FAILED;
-+			make_mapi_error (perror, "build_restrictions", ms);
-+			goto cleanup;
-+		}
-+
-+		if (restrictions) {
-+			change_mapi_SRestriction_named_ids (conn, obj_folder, mem_ctx, &restrictions, cancellable, perror);
-+
-+			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;
-+				}
-+			}
-+		}
-+	}
-+
-+	loi_data.cb = cb;
-+	loi_data.user_data = user_data;
-+
-+	ms = foreach_tablerow (conn, mem_ctx, &obj_table, list_objects_internal_cb, &loi_data, cancellable, perror);
-+
-+ cleanup:
-+	mapi_object_release (&obj_table);
-+	talloc_free (mem_ctx);
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static gboolean
-+has_embedded_message_without_body (EMapiObject *object)
-+{
-+	EMapiAttachment *attach;
-+
-+	if (!object)
-+		return FALSE;
-+
-+	for (attach = object->attachments; attach; attach = attach->next) {
-+		if (!attach->embedded_object)
-+			continue;
-+
-+		if (!e_mapi_object_contains_prop (attach->embedded_object, PidTagBody))
-+			return TRUE;
-+
-+		if (has_embedded_message_without_body (attach->embedded_object))
-+			return TRUE;
-+	}
-+
-+	return FALSE;
-+}
-+
-+static gboolean
-+get_additional_properties_cb (EMapiConnection *conn,
-+			      TALLOC_CTX *mem_ctx,
-+			      /* const */ EMapiObject *object,
-+			      guint32 obj_index,
-+			      guint32 obj_total,
-+			      gpointer user_data,
-+			      GCancellable *cancellable,
-+			      GError **perror)
-+{
-+	uint32_t ii;
-+	EMapiObject *dest_object = user_data;
-+
-+	g_return_val_if_fail (object != NULL, FALSE);
-+	g_return_val_if_fail (dest_object != NULL, FALSE);
-+
-+	for (ii = 0; ii < object->properties.cValues; ii++) {
-+		uint32_t proptag = object->properties.lpProps[ii].ulPropTag;
-+
-+		if ((proptag & 0xFFFF) == PT_ERROR
-+		    || e_mapi_util_find_array_propval (&dest_object->properties, proptag))
-+			continue;
-+
-+		dest_object->properties.cValues++;
-+		dest_object->properties.lpProps = talloc_realloc (mem_ctx,
-+				    dest_object->properties.lpProps,
-+				    struct mapi_SPropValue,
-+				    dest_object->properties.cValues + 1);
-+		dest_object->properties.lpProps[dest_object->properties.cValues - 1] = object->properties.lpProps[ii];
-+
-+		#define steal_ptr(x) (x) = talloc_steal (dest_object, (x))
-+		switch (proptag & 0xFFFF) {
-+		case PT_BOOLEAN:
-+		case PT_I2:
-+		case PT_LONG:
-+		case PT_DOUBLE:
-+		case PT_I8:
-+		case PT_SYSTIME:
-+			break;
-+		case PT_STRING8:
-+			steal_ptr (dest_object->properties.lpProps[dest_object->properties.cValues - 1].value.lpszA);
-+			break;
-+		case PT_UNICODE:
-+			steal_ptr (dest_object->properties.lpProps[dest_object->properties.cValues - 1].value.lpszW);
-+			break;
-+		default:
-+			g_debug ("%s: Do not know how to steal property type 0x%x, skipping it", G_STRFUNC, proptag & 0xFFFF);
-+			dest_object->properties.cValues--;
-+			break;
-+		}
-+		#undef steal_ptr
-+
-+		dest_object->properties.lpProps[dest_object->properties.cValues].ulPropTag = 0;
-+	}
-+
-+	return TRUE;
-+}
-+
-+static void
-+traverse_attachments_for_body (EMapiConnection *conn,
-+			       TALLOC_CTX *mem_ctx,
-+			       EMapiObject *object,
-+			       mapi_object_t *obj_message,
-+			       GCancellable *cancellable,
-+			       GError **perror)
-+{
-+	EMapiAttachment *attach;
-+
-+	g_return_if_fail (conn != NULL);
-+	g_return_if_fail (mem_ctx != NULL);
-+	g_return_if_fail (obj_message != NULL);
-+
-+	for (attach = object->attachments; attach && !g_cancellable_is_cancelled (cancellable); attach = attach->next) {
-+		if (attach->embedded_object) {
-+			const uint32_t *pattach_num;
-+			mapi_object_t obj_attach;
-+			mapi_object_t obj_embedded;
-+			gboolean have_embedded = FALSE;
-+
-+			pattach_num = e_mapi_util_find_array_propval (&attach->properties, PidTagAttachNumber);
-+			if (!pattach_num)
-+				continue;
-+
-+			mapi_object_init (&obj_attach);
-+			mapi_object_init (&obj_embedded);
-+
-+			if (!e_mapi_object_contains_prop (attach->embedded_object, PidTagBody)) {
-+				struct SPropTagArray *tags;
-+
-+				if (OpenAttach (obj_message, *pattach_num, &obj_attach) != MAPI_E_SUCCESS)
-+					continue;
-+
-+				if (OpenEmbeddedMessage (&obj_attach, &obj_embedded, MAPI_READONLY) != MAPI_E_SUCCESS) {
-+					mapi_object_release (&obj_attach);
-+					continue;
-+				}
-+
-+				have_embedded = TRUE;
-+
-+				tags = set_SPropTagArray (mem_ctx, 1, PidTagBody);
-+
-+				e_mapi_fast_transfer_properties (conn, mem_ctx, &obj_embedded, tags, get_additional_properties_cb, attach->embedded_object, cancellable, perror);
-+
-+				talloc_free (tags);
-+			}
-+
-+			if (has_embedded_message_without_body (attach->embedded_object)) {
-+				if (!have_embedded) {
-+					if (OpenAttach (obj_message, *pattach_num, &obj_attach) != MAPI_E_SUCCESS)
-+						continue;
-+
-+					if (OpenEmbeddedMessage (&obj_attach, &obj_embedded, MAPI_READONLY) != MAPI_E_SUCCESS) {
-+						mapi_object_release (&obj_attach);
-+						continue;
-+					}
-+
-+					have_embedded = TRUE;
-+				}
-+
-+				traverse_attachments_for_body (conn, mem_ctx, attach->embedded_object, &obj_embedded, cancellable, perror);
-+			}
-+
-+			mapi_object_release (&obj_embedded);
-+			mapi_object_release (&obj_attach);
-+		}
-+	}
-+}
-+
-+struct EnsureAdditionalPropertiesData
-+{
-+	TransferObjectCB cb;
-+	gpointer cb_user_data;
-+	mapi_object_t *obj_folder;
-+	guint32 downloaded;
-+	guint32 download_offset;
-+	guint32 download_total;
-+};
-+
-+static gboolean
-+ensure_additional_properties_cb (EMapiConnection *conn,
-+				 TALLOC_CTX *mem_ctx,
-+				 /* const */ EMapiObject *object,
-+				 guint32 obj_index,
-+				 guint32 obj_total,
-+				 gpointer user_data,
-+				 GCancellable *cancellable,
-+				 GError **perror)
-+{
-+	struct ap_data {
-+		uint32_t orig_proptag, use_proptag;
-+	} additional_properties[] = {
-+		{ PidTagBody, MAPI_E_RESERVED },
-+		{ PidNameContentClass, MAPI_E_RESERVED }
-+	};
-+	struct EnsureAdditionalPropertiesData *eap = user_data;
-+	gboolean need_any = FALSE;
-+	uint32_t ii;
-+
-+	g_return_val_if_fail (eap != NULL, FALSE);
-+	g_return_val_if_fail (eap->cb != NULL, FALSE);
-+	g_return_val_if_fail (object != NULL, FALSE);
-+
-+	for (ii = 0; ii < G_N_ELEMENTS (additional_properties); ii++) {
-+		uint32_t prop = additional_properties[ii].orig_proptag;
-+
-+		if (!e_mapi_object_contains_prop (object, prop)) {
-+			if (get_namedid_name (prop)) {
-+				prop = e_mapi_connection_resolve_named_prop (conn, eap->obj_folder, prop, cancellable, NULL);
-+			}
-+		} else {
-+			prop = MAPI_E_RESERVED;
-+		}
-+
-+		additional_properties[ii].use_proptag = prop;
-+		need_any = need_any || prop != MAPI_E_RESERVED;
-+	}
-+
-+	/* Fast-transfer transfers only Html or Body, never both */
-+	if (need_any || has_embedded_message_without_body (object)) {
-+		const mapi_id_t *mid;
-+
-+		mid = e_mapi_util_find_array_propval (&object->properties, PidTagMid);
-+		if (mid && *mid) {
-+			mapi_object_t obj_message;
-+			
-+			mapi_object_init (&obj_message);
-+
-+			if (OpenMessage (eap->obj_folder, mapi_object_get_id (eap->obj_folder), *mid, &obj_message, 0) == MAPI_E_SUCCESS) {
-+				struct SPropTagArray *tags = NULL;
-+
-+				for (ii = 0; ii < G_N_ELEMENTS (additional_properties); ii++) {
-+					uint32_t prop = additional_properties[ii].use_proptag;
-+
-+					if (prop == MAPI_E_RESERVED)
-+						continue;
-+
-+					if (!tags)
-+						tags = set_SPropTagArray (mem_ctx, 1, prop);
-+					else
-+						SPropTagArray_add (mem_ctx, tags, prop);
-+				}
-+
-+				if (tags) {
-+					uint32_t jj = object->properties.cValues;
-+
-+					e_mapi_fast_transfer_properties	(conn, mem_ctx, &obj_message, tags, get_additional_properties_cb, object, cancellable, perror);
-+
-+					while (jj < object->properties.cValues) {
-+						for (ii = 0; ii < G_N_ELEMENTS (additional_properties); ii++) {
-+							uint32_t proptag = object->properties.lpProps[jj].ulPropTag;
-+
-+							if (additional_properties[ii].use_proptag == proptag ||
-+							    (((proptag & 0xFFFF) == PT_STRING8 || (proptag & 0xFFFF) == PT_UNICODE) &&
-+							        (proptag & ~0xFFFF) == (additional_properties[ii].use_proptag & ~0xFFFF))) {
-+								/* string8 and unicode properties are interchangeable in the union, luckily */
-+								object->properties.lpProps[jj].ulPropTag = additional_properties[ii].orig_proptag;
-+								break;
-+							}
-+						}
-+
-+						jj++;
-+					}
-+
-+					talloc_free (tags);
-+				}
-+
-+				traverse_attachments_for_body (conn, mem_ctx, object, &obj_message, cancellable, perror);
-+			}
-+
-+			mapi_object_release (&obj_message);
-+		}
-+	}
-+
-+	eap->downloaded++;
-+
-+	return eap->cb (conn, mem_ctx, object, eap->downloaded + eap->download_offset, eap->download_total, eap->cb_user_data, cancellable, perror);
-+}
-+
-+static enum MAPISTATUS
-+fetch_object_property_as_stream (EMapiConnection *conn,
-+				 TALLOC_CTX *mem_ctx,
-+				 mapi_object_t *obj_message,
-+				 uint32_t proptag,
-+				 uint64_t *pcb,
-+				 uint8_t **plpb,
-+				 GCancellable *cancellable,
-+				 GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	mapi_object_t obj_stream;
-+	uint32_t buf_size, max_read;
-+	uint16_t off_data, cn_read;
-+	uint64_t cb = 0;
-+	uint8_t *lpb = NULL;
-+	gboolean done = FALSE;
-+
-+	g_return_val_if_fail (conn != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (obj_message != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (pcb != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (plpb != NULL, MAPI_E_INVALID_PARAMETER);
-+
-+	mapi_object_init (&obj_stream);
-+
-+	ms = OpenStream (obj_message, proptag, OpenStream_ReadOnly, &obj_stream);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenStream", ms);
-+		goto cleanup;
-+	}
-+
-+	cb = 0;
-+
-+	ms = GetStreamSize (&obj_stream, &buf_size);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetStreamSize", ms);
-+		goto cleanup;
-+	}
-+
-+	cb = buf_size;
-+	lpb = talloc_size (mem_ctx, cb + 1);
-+	if (!lpb || !cb)
-+		goto cleanup;
-+
-+	/* determine max_read first, to read by chunks as long as possible */
-+	off_data = 0;
-+	max_read = buf_size > STREAM_MAX_READ_SIZE ? STREAM_MAX_READ_SIZE : buf_size;
-+	do {
-+		ms = ReadStream (&obj_stream, lpb + off_data, max_read, &cn_read);
-+		if (ms == MAPI_E_SUCCESS) {
-+			if (cn_read == 0) {
-+				done = TRUE;
-+			} else {
-+				off_data += cn_read;
-+				if (off_data >= buf_size)
-+					done = TRUE;
-+			}
-+			break;
-+		}
-+
-+		if (ms == 0x2c80)
-+			max_read = max_read >> 1;
-+		else
-+			max_read = STREAM_MAX_READ_SIZE_DF;
-+
-+		if (max_read < STREAM_MAX_READ_SIZE_DF)
-+			max_read = STREAM_MAX_READ_SIZE_DF;
-+	} while (ms == 0x2c80); /* an error when max_read is too large? */
-+
-+	while (!done) {
-+		ms = ReadStream (&obj_stream, lpb + off_data, max_read, &cn_read);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "ReadStream", ms);
-+			done = TRUE;
-+		} else if (cn_read == 0) {
-+			done = TRUE;
-+		} else {
-+			off_data += cn_read;
-+			if (off_data >= buf_size)
-+				done = TRUE;
-+		}
-+	}
-+
-+ cleanup:
-+	mapi_object_release (&obj_stream);
-+
-+	*pcb = cb;
-+	*plpb = lpb;
-+
-+	return ms;
-+}
-+
-+static enum MAPISTATUS
-+e_mapi_connection_fetch_object_internal (EMapiConnection *conn,
-+					 TALLOC_CTX *mem_ctx,
-+					 mapi_object_t *obj_message,
-+					 struct EnsureAdditionalPropertiesData *eap,
-+					 EMapiObject **out_object,
-+					 GCancellable *cancellable,
-+					 GError **perror);
-+
-+struct FetchObjectAttachmentData
-+{
-+	mapi_object_t *obj_message;
-+	struct EnsureAdditionalPropertiesData *eap;
-+	EMapiObject *object; /* to add attachments to */
-+};
-+
-+static gboolean
-+fetch_object_attachment_cb (EMapiConnection *conn,
-+			    TALLOC_CTX *mem_ctx,
-+			    struct SRow *srow,
-+			    guint32 row_index,
-+			    guint32 rows_total,
-+			    gpointer user_data,
-+			    GCancellable *cancellable,
-+			    GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	struct FetchObjectAttachmentData *foa = user_data;
-+	EMapiAttachment *attachment = NULL;
-+	mapi_object_t obj_attach;
-+	const uint32_t *attach_num, *attach_method;
-+
-+	g_return_val_if_fail (conn != NULL, FALSE);
-+	g_return_val_if_fail (mem_ctx != NULL, FALSE);
-+	g_return_val_if_fail (srow != NULL, FALSE);
-+	g_return_val_if_fail (user_data != NULL, FALSE);
-+	g_return_val_if_fail (foa->obj_message != NULL, FALSE);
-+	g_return_val_if_fail (foa->object != NULL, FALSE);
-+
-+	mapi_object_init (&obj_attach);
-+
-+	attach_num = e_mapi_util_find_row_propval (srow, PidTagAttachNumber);
-+	if (!attach_num)
-+		return FALSE;
-+
-+	ms = OpenAttach (foa->obj_message, *attach_num, &obj_attach);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenAttach", ms);
-+		goto cleanup;
-+	}
-+
-+	attachment = e_mapi_attachment_new (foa->object);
-+
-+	ms = GetPropsAll (&obj_attach, MAPI_UNICODE, &attachment->properties);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "Attachment::GetPropsAll", ms);
-+		goto cleanup;
-+	}
-+
-+	if (attachment->properties.lpProps)
-+		attachment->properties.lpProps = talloc_steal (attachment, attachment->properties.lpProps);
-+
-+	attach_method = e_mapi_util_find_row_propval (srow, PidTagAttachMethod);
-+	if (attach_method && *attach_method == ATTACH_BY_VALUE) {
-+		if (!e_mapi_attachment_contains_prop (attachment, PidTagAttachDataBinary)) {
-+			uint64_t cb = 0;
-+			uint8_t *lpb = NULL;
-+
-+			ms = fetch_object_property_as_stream (conn, mem_ctx, &obj_attach, PidTagAttachDataBinary, &cb, &lpb, cancellable, perror);
-+			if (ms != MAPI_E_SUCCESS) {
-+				make_mapi_error (perror, "Attachment::fetch PidTagAttachDataBinary", ms);
-+				goto cleanup;
-+			}
-+
-+			e_mapi_attachment_add_streamed (attachment, PidTagAttachDataBinary, cb, lpb);
-+		}
-+	} else if (attach_method && *attach_method == ATTACH_EMBEDDED_MSG) {
-+		mapi_object_t obj_emb_msg;
-+
-+		mapi_object_init (&obj_emb_msg);
-+
-+		if (OpenEmbeddedMessage (&obj_attach, &obj_emb_msg, MAPI_READONLY) == MAPI_E_SUCCESS) {
-+			e_mapi_connection_fetch_object_internal (conn, mem_ctx, &obj_emb_msg, foa->eap, &attachment->embedded_object, cancellable, perror);
-+		}
-+
-+		mapi_object_release (&obj_emb_msg);
-+	}
-+
-+ cleanup:
-+	mapi_object_release (&obj_attach);
-+
-+	if (ms == MAPI_E_SUCCESS) {
-+		if (!foa->object->attachments) {
-+			foa->object->attachments = attachment;
-+		} else {
-+			EMapiAttachment *attach = foa->object->attachments;
-+			while (attach->next)
-+				attach = attach->next;
-+			attach->next = attachment;
-+		}
-+	} else {
-+		e_mapi_attachment_free (attachment);
-+	}
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static enum MAPISTATUS
-+e_mapi_connection_fetch_object_internal (EMapiConnection *conn,
-+					 TALLOC_CTX *mem_ctx,
-+					 mapi_object_t *obj_message,
-+					 struct EnsureAdditionalPropertiesData *eap,
-+					 EMapiObject **out_object,
-+					 GCancellable *cancellable,
-+					 GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	EMapiObject *object;
-+	uint16_t ui16, uj16, np_count = 0, *np_propID = NULL;
-+	uint32_t ui32;
-+	struct MAPINAMEID *np_nameid = NULL;
-+	const uint8_t *has_attachments;
-+	struct SPropTagArray recipient_proptags;
-+	struct SRowSet recipient_rows;
-+	mapi_object_t attach_table;
-+
-+	g_return_val_if_fail (conn != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (obj_message != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (eap != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (out_object != NULL, MAPI_E_INVALID_PARAMETER);
-+
-+	mapi_object_init (&attach_table);
-+
-+	object = e_mapi_object_new (mem_ctx);
-+
-+	ms = GetPropsAll (obj_message, MAPI_UNICODE, &object->properties);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetPropsAll", ms);
-+		goto cleanup;
-+	}
-+
-+	if (object->properties.lpProps)
-+		object->properties.lpProps = talloc_steal (object, object->properties.lpProps);
-+
-+	/* to transform named ids to their PidLid or PidName tags, like the fast-transfer does */
-+	ms = QueryNamedProperties (obj_message, 0, NULL, &np_count, &np_propID, &np_nameid);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "QueryNamedProperties", ms);
-+		goto cleanup;
-+	}
-+
-+	if (np_count && np_propID && np_nameid) {
-+		for (ui16 = 0; ui16 < np_count; ui16++) {
-+			uint32_t proptag = np_propID[ui16];
-+
-+			for (uj16 = 0; uj16 < object->properties.cValues; uj16++) {
-+				if (object->properties.lpProps[uj16].ulPropTag == proptag) {
-+					uint32_t lid = MAPI_E_RESERVED;
-+					char *guid;
-+
-+					guid = GUID_string (mem_ctx, &(np_nameid[ui16].lpguid));
-+
-+					if (np_nameid[ui16].ulKind == MNID_ID) {
-+						if (mapi_nameid_lid_lookup_canonical (np_nameid[ui16].kind.lid, guid, &lid) != MAPI_E_SUCCESS)
-+							lid = MAPI_E_RESERVED;
-+					} else if (np_nameid[ui16].ulKind == MNID_STRING) {
-+						if (mapi_nameid_string_lookup_canonical (np_nameid[ui16].kind.lpwstr.Name, guid, &lid) != MAPI_E_SUCCESS)
-+							lid = MAPI_E_RESERVED;
-+					}
-+
-+					talloc_free (guid);
-+
-+					if (lid != MAPI_E_RESERVED && (lid & 0xFFFF) == (proptag & 0xFFFF)) {
-+						object->properties.lpProps[uj16].ulPropTag = lid;
-+					}
-+
-+					break;
-+				}
-+			}
-+		}
-+	}
-+
-+	talloc_free (np_propID);
-+	talloc_free (np_nameid);
-+
-+	/* ensure certain properties */
-+	if (!e_mapi_object_contains_prop (object, PidTagHtml)) {
-+		uint8_t best_body = 0;
-+
-+		if (GetBestBody (obj_message, &best_body) == MAPI_E_SUCCESS && best_body == olEditorHTML) {
-+			uint64_t cb = 0;
-+			uint8_t *lpb = NULL;
-+
-+			ms = fetch_object_property_as_stream (conn, mem_ctx, obj_message, PidTagHtml, &cb, &lpb, cancellable, perror);
-+			if (ms != MAPI_E_SUCCESS) {
-+				make_mapi_error (perror, "Object::fetch PidTagHtml", ms);
-+				goto cleanup;
-+			}
-+
-+			e_mapi_object_add_streamed (object, PidTagHtml, cb, lpb);
-+		}
-+	}
-+
-+	if (!e_mapi_object_contains_prop (object, PidTagBody)) {
-+		uint64_t cb = 0;
-+		uint8_t *lpb = NULL;
-+
-+		if (fetch_object_property_as_stream (conn, mem_ctx, obj_message, PidTagBody, &cb, &lpb, cancellable, NULL) == MAPI_E_SUCCESS) {
-+			object->properties.cValues++;
-+			object->properties.lpProps = talloc_realloc (mem_ctx,
-+								     object->properties.lpProps,
-+								     struct mapi_SPropValue,
-+								     object->properties.cValues + 1);
-+			object->properties.lpProps[object->properties.cValues - 1].ulPropTag = PidTagBody;
-+			if (cb > 0 && lpb[cb - 1] == 0)
-+				object->properties.lpProps[object->properties.cValues - 1].value.lpszW = (const char *) talloc_steal (object, lpb);
-+			else
-+				object->properties.lpProps[object->properties.cValues - 1].value.lpszW = talloc_strndup (object, (char *) lpb, cb);
-+			object->properties.lpProps[object->properties.cValues].ulPropTag = 0;
-+		}
-+	}
-+
-+	if (!e_mapi_util_find_array_propval (&object->properties, PidNameContentClass)) {
-+		uint32_t prop = PidNameContentClass;
-+
-+		prop = e_mapi_connection_resolve_named_prop (conn, eap->obj_folder, prop, cancellable, NULL);
-+		if (prop != MAPI_E_RESERVED) {
-+			struct SPropTagArray *tags;
-+			struct SPropValue *lpProps = NULL;
-+			uint32_t prop_count = 0;
-+
-+			tags = set_SPropTagArray (mem_ctx, 1, prop);
-+
-+			if (GetProps (obj_message, MAPI_PROPS_SKIP_NAMEDID_CHECK | MAPI_UNICODE, tags, &lpProps, &prop_count) == MAPI_E_SUCCESS && lpProps) {
-+				if (lpProps[0].ulPropTag == prop) {
-+					object->properties.cValues++;
-+					object->properties.lpProps = talloc_realloc (mem_ctx,
-+										     object->properties.lpProps,
-+										     struct mapi_SPropValue,
-+										     object->properties.cValues + 1);
-+					object->properties.lpProps[object->properties.cValues - 1].ulPropTag = PidNameContentClass;
-+					object->properties.lpProps[object->properties.cValues - 1].value.lpszW = talloc_strdup (object, lpProps[0].value.lpszW);
-+					object->properties.lpProps[object->properties.cValues].ulPropTag = 0;
-+				}
-+			}
-+
-+			talloc_free (tags);
-+			talloc_free (lpProps);
-+		}
-+	}
-+
-+	/* fetch attachments */
-+	has_attachments = e_mapi_util_find_array_propval (&object->properties, PidTagHasAttachments);
-+	if (has_attachments && *has_attachments) {
-+		struct SPropTagArray *attach_columns;
-+		struct FetchObjectAttachmentData foa;
-+
-+		ms = GetAttachmentTable (obj_message, &attach_table);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "GetAttachmentTable", ms);
-+			goto cleanup;
-+		}
-+
-+		attach_columns = set_SPropTagArray (mem_ctx, 1, PidTagAttachNumber);
-+		ms = SetColumns (&attach_table, attach_columns);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "AttachTable::SetColumns", ms);
-+			talloc_free (attach_columns);
-+			goto cleanup;
-+		}
-+		talloc_free (attach_columns);
-+
-+		foa.obj_message = obj_message;
-+		foa.eap = eap;
-+		foa.object = object;
-+
-+		ms = foreach_tablerow (conn, mem_ctx, &attach_table, fetch_object_attachment_cb, &foa, cancellable, perror);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "AttachTable::foreach_tablerow", ms);
-+			goto cleanup;
-+		}
-+	}
-+
-+	/* get recipients */
-+	ms = GetRecipientTable (obj_message, &recipient_rows, &recipient_proptags);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetRecipientTable", ms);
-+		goto cleanup;
-+	}
-+
-+	if (recipient_rows.cRows > 0) {
-+		uint32_t uj32, uk32;
-+		EMapiRecipient *first_recipient = NULL;
-+
-+		for (ui32 = 0; ui32 < recipient_rows.cRows; ui32++) {
-+			struct SRow *row = &recipient_rows.aRow[ui32];
-+			EMapiRecipient *recipient;
-+
-+			recipient = e_mapi_recipient_new (object);
-+			recipient->properties.cValues = row->cValues;
-+			recipient->properties.lpProps = talloc_zero_array (recipient, struct mapi_SPropValue, recipient->properties.cValues + 1);
-+
-+			for (uj32 = 0, uk32 = 0; uj32 < row->cValues; uj32++, uk32++) {
-+				if (may_skip_property (row->lpProps[uj32].ulPropTag) ||
-+				    !e_mapi_utils_copy_to_mapi_SPropValue (recipient, &recipient->properties.lpProps[uk32], &row->lpProps[uj32])) {
-+					uk32--;
-+					recipient->properties.cValues--;
-+					recipient->properties.lpProps[recipient->properties.cValues].ulPropTag = 0;
-+				}
-+			}
-+
-+			recipient->properties.lpProps[recipient->properties.cValues].ulPropTag = 0;
-+		}
-+
-+		object->recipients = first_recipient;
-+	}
-+
-+ cleanup:
-+	mapi_object_release (&attach_table);
-+
-+	if (ms == MAPI_E_SUCCESS) {
-+		*out_object = object;
-+	} else {
-+		*out_object = NULL;
-+		e_mapi_object_free (object);
-+	}
-+
-+	return ms;
-+}
-+
-+static enum MAPISTATUS
-+e_mapi_connection_fetch_objects_internal (EMapiConnection *conn,
-+					  TALLOC_CTX *mem_ctx,
-+					  mapi_id_array_t *ids,
-+					  struct EnsureAdditionalPropertiesData *eap,
-+					  GCancellable *cancellable,
-+					  GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	guint32 idx;
-+	mapi_container_list_t *element;
-+
-+	g_return_val_if_fail (conn != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (ids != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (eap != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (eap->obj_folder != NULL, MAPI_E_INVALID_PARAMETER);
-+	g_return_val_if_fail (eap->downloaded < ids->count, MAPI_E_INVALID_PARAMETER);
-+
-+	for (idx = 0, element = ids->lpContainerList; idx < ids->count && idx < eap->downloaded && element; idx++) {
-+		element = element->next;
-+	}
-+
-+	g_return_val_if_fail (idx < ids->count, MAPI_E_INVALID_PARAMETER);
-+
-+	ms = MAPI_E_SUCCESS;
-+	while (element && ms == MAPI_E_SUCCESS) {
-+		mapi_object_t obj_message;
-+		EMapiObject *object = NULL;
-+		GError *local_error = NULL;
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			break;
-+		}
-+
-+		mapi_object_init (&obj_message);
-+
-+		ms = OpenMessage (eap->obj_folder, mapi_object_get_id (eap->obj_folder), element->id, &obj_message, 0 /* read-only */);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "OpenMessage", ms);
-+			mapi_object_release (&obj_message);
-+			break;
-+		}
-+
-+		/* silently skip broken objects */
-+		ms = e_mapi_connection_fetch_object_internal (conn, mem_ctx, &obj_message, eap, &object, cancellable, &local_error);
-+		if (ms == MAPI_E_SUCCESS) {
-+			if (!eap->cb (conn, mem_ctx, object, eap->downloaded + eap->download_offset, eap->download_total, eap->cb_user_data, cancellable, perror)) {
-+				ms = MAPI_E_USER_CANCEL;
-+				make_mapi_error (perror, "Object processing", ms);
-+			}
-+		} else {
-+			e_mapi_debug_print ("%s: Failed to fetch object %016" G_GINT64_MODIFIER "X: %s",
-+				G_STRFUNC, element->id, local_error ? local_error->message : mapi_get_errstr (ms));
-+		}
-+
-+		e_mapi_object_free (object);
-+		mapi_object_release (&obj_message);
-+
-+		eap->downloaded++;
-+
-+		element = element->next;
-+	}
-+
-+	return ms;
-+}
-+
-+/* deals with named IDs transparently, thus it's OK to check with PidLid and PidName constants only */
-+gboolean
-+e_mapi_connection_transfer_objects (EMapiConnection *conn,
-+				    mapi_object_t *obj_folder,
-+				    const GSList *mids,
-+				    TransferObjectCB cb,
-+				    gpointer cb_user_data,
-+				    GCancellable *cancellable,
-+				    GError **perror)
-+{
-+	enum MAPISTATUS ms = MAPI_E_CALL_FAILED;
-+	TALLOC_CTX *mem_ctx;
-+	const GSList *iter;
-+	struct EnsureAdditionalPropertiesData eap;
-+
-+	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 (cancellable, perror, FALSE);
-+	mem_ctx = talloc_new (priv->session);
-+
-+	eap.download_offset = 0;
-+	eap.download_total = g_slist_length ((GSList *) mids);
-+
-+	iter = mids;
-+	while (iter) {
-+		mapi_id_array_t ids;
-+
-+		ms = mapi_id_array_init (mem_ctx, &ids);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "mapi_id_array_init", ms);
-+			goto cleanup;
-+		}
-+
-+		/* run this in chunks of 100 IDs */
-+		for (; iter && ids.count < 100; iter = iter->next) {
-+			mapi_id_t *pmid = iter->data;
-+
-+			if (pmid)
-+				mapi_id_array_add_id (&ids, *pmid);
-+		}
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			mapi_id_array_release (&ids);
-+			goto cleanup;
-+		}
-+
-+		eap.cb = cb;
-+		eap.cb_user_data = cb_user_data;
-+		eap.obj_folder = obj_folder;
-+		eap.downloaded = 0;
-+
-+		ms = e_mapi_fast_transfer_objects (conn, mem_ctx, obj_folder, &ids, ensure_additional_properties_cb, &eap, cancellable, perror);
-+		if (ms == MAPI_E_CALL_FAILED) {
-+			/* err, fallback to slow transfer, probably FXGetBuffer failed;
-+			   see http://tracker.openchange.org/issues/378
-+			*/
-+
-+			g_clear_error (perror);
-+
-+			e_mapi_debug_print ("%s: Failed to fast-transfer, fallback to slow fetch from %d of %d objects\n", G_STRFUNC, eap.downloaded, ids.count);
-+
-+			ms = e_mapi_connection_fetch_objects_internal (conn, mem_ctx, &ids, &eap, cancellable, perror);
-+		}
-+
-+		eap.download_offset += ids.count;
-+
-+		mapi_id_array_release (&ids);
-+	}
-+
-+ cleanup:
-+	talloc_free (mem_ctx);
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_transfer_object (EMapiConnection *conn,
-+				   mapi_object_t *obj_folder,
-+				   mapi_id_t message_id,
-+				   TransferObjectCB cb,
-+				   gpointer cb_user_data,
-+				   GCancellable *cancellable,
-+				   GError **perror)
-+{
-+	GSList *mids;
-+	gboolean res;
-+
-+	mids = g_slist_append (NULL, &message_id);
-+	res = e_mapi_connection_transfer_objects (conn, obj_folder, mids, cb, cb_user_data, cancellable, perror);
-+	g_slist_free (mids);
-+
-+	return res;
-+}
-+
-+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_object_contains_prop (object, 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 PidTagTransportMessageHeaders 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 (cancellable, perror, FALSE);
-+	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, 9,
-+				PidTagFolderId,
-+				PidTagMid,
-+				PidTagMessageFlags,
-+				PidTagMessageSize,
-+				PidTagMessageClass,
-+				PidTagLastModificationTime,
-+				PidTagTransportMessageHeaders,
-+				PidTagIconIndex,
-+				PidTagReadReceiptRequested);
-+
-+			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, PidTagTransportMessageHeaders);
-+
-+					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);
-+							talloc_free (lpProps);
-+							talloc_free (tags);
-+							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);
-+					talloc_free (lpProps);
-+					talloc_free (tags);
-+					goto cleanup;
-+				}
-+			}
-+
-+			mapi_object_release (&obj_message);
-+			talloc_free (lpProps);
-+			talloc_free (tags);
-+		}
-+
-+		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;
-+}
-+
-+static gboolean
-+convert_mapi_props_to_props (EMapiConnection *conn,
-+			     mapi_object_t *obj_folder,
-+			     const struct mapi_SPropValue_array *mapi_props,
-+			     const EMapiStreamedProp *known_streams,
-+			     guint known_streams_count,
-+			     struct SPropValue **props,
-+			     uint32_t *propslen,
-+			     EMapiStreamedProp **streams, /* can be NULL for no streaming */
-+			     guint *streamslen, /* can be NULL only if streams is NULL; is ignored if streams is NULL */
-+			     TALLOC_CTX *mem_ctx,
-+			     GCancellable *cancellable,
-+			     GError **perror)
-+{
-+	uint16_t ii;
-+	EResolveNamedIDsData *named_ids_list = NULL;
-+	guint named_ids_len = 0;
-+	gboolean res = TRUE;
-+
-+	e_return_val_mapi_error_if_fail (conn != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (mapi_props != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (props != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (propslen != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	if (streams) {
-+		e_return_val_mapi_error_if_fail (streamslen != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	} else {
-+		e_return_val_mapi_error_if_fail (known_streams == NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	}
-+
-+	#define addstream() {										\
-+			if (!*streams) {								\
-+				*streams = g_new0 (EMapiStreamedProp, 1);				\
-+				*streamslen = 0;							\
-+			} else {									\
-+				*streams = g_renew (EMapiStreamedProp, *streams, *streamslen + 1);	\
-+			}										\
-+													\
-+			(*streams)[*streamslen].proptag = proptag;					\
-+			(*streams)[*streamslen].cb = 0;							\
-+			(*streams)[*streamslen].lpb = NULL;						\
-+			(*streams)[*streamslen].orig_value = NULL;					\
-+			(*streamslen) += 1;								\
-+		}
-+
-+	for (ii = 0; ii < mapi_props->cValues; ii++) {
-+		gboolean processed = FALSE;
-+		uint32_t proptag = mapi_props->lpProps[ii].ulPropTag;
-+		gconstpointer propdata = get_mapi_SPropValue_data (&mapi_props->lpProps[ii]);
-+
-+		maybe_add_named_id_tag (proptag, &named_ids_list, &named_ids_len);
-+
-+		if (streams && propdata) {
-+			/* copy anything longer than 1KB as streams; this doesn't count total packet size needed,
-+			   but because this is usually useful only for PidTagBody, PidTagHtml, which are there
-+			   only once, then no big deal
-+			*/
-+
-+			uint32_t sz;
-+			const gchar *str;
-+			const struct SBinary_short *bin;
-+
-+			switch (proptag & 0xFFFF) {
-+			case PT_BINARY:
-+				bin = propdata;
-+				if (bin->cb > MAX_PROPERTY_WRITE_SIZE) {
-+					addstream ();
-+					(*streams)[(*streamslen) - 1].cb = bin->cb;
-+					(*streams)[(*streamslen) - 1].lpb = bin->lpb;
-+					(*streams)[(*streamslen) - 1].orig_value = propdata;
-+					processed = TRUE;
-+				}
-+				break;
-+			case PT_STRING8:
-+				str = propdata;
-+				sz = get_mapi_property_size (&mapi_props->lpProps[ii]);
-+				if (sz > MAX_PROPERTY_WRITE_SIZE) {
-+					addstream ();
-+					(*streams)[(*streamslen) - 1].cb = sz;
-+					(*streams)[(*streamslen) - 1].lpb = (uint8_t *) str;
-+					(*streams)[(*streamslen) - 1].orig_value = propdata;
-+					processed = TRUE;
-+				}
-+				break;
-+			case PT_UNICODE:
-+				str = propdata;
-+				sz = get_mapi_property_size (&mapi_props->lpProps[ii]);
-+				if (sz > MAX_PROPERTY_WRITE_SIZE) {
-+					gchar *in_unicode;
-+					gsize written = 0;
-+
-+					addstream ();
-+					(*streams)[(*streamslen) - 1].orig_value = propdata;
-+
-+					in_unicode = g_convert (str, strlen (str), "UTF-16", "UTF-8", NULL, &written, NULL);
-+					if (in_unicode && written > 0) {
-+						uint8_t *bytes = talloc_zero_size (mem_ctx, written + 2);
-+
-+						/* skip Unicode marker, if there */
-+						if (written >= 2 && (const guchar) in_unicode[0] == 0xFF && (const guchar) in_unicode[1] == 0xFE) {
-+							memcpy (bytes, in_unicode + 2, written - 2);
-+							written -= 2;
-+						} else
-+							memcpy (bytes, in_unicode, written);
-+
-+						/* null-terminated unicode string */
-+						(*streams)[(*streamslen) - 1].lpb = bytes;
-+						(*streams)[(*streamslen) - 1].cb = written + 2;
-+					}
-+					g_free (in_unicode);
-+					processed = TRUE;
-+				}
-+				break;
-+			}
-+		}
-+
-+		if (!processed)
-+			e_mapi_utils_add_spropvalue (mem_ctx, props, propslen, proptag, propdata);
-+	}
-+
-+	if (known_streams && known_streams_count > 0 && streams) {
-+		for (ii = 0; ii < known_streams_count; ii++) {
-+			uint32_t proptag = known_streams[ii].proptag;
-+
-+			maybe_add_named_id_tag (proptag, &named_ids_list, &named_ids_len);
-+
-+			addstream ();
-+			(*streams)[(*streamslen) - 1].cb = known_streams[ii].cb;
-+			(*streams)[(*streamslen) - 1].lpb = known_streams[ii].lpb;
-+			(*streams)[(*streamslen) - 1].orig_value = NULL;
-+		}
-+	}
-+	#undef addstream
-+
-+	if (named_ids_list) {
-+		GHashTable *replace_hash = NULL;
-+
-+		res = e_mapi_connection_resolve_named_props (conn, obj_folder, named_ids_list, named_ids_len, cancellable, perror);
-+
-+		if (res)
-+			replace_hash = prepare_maybe_replace_hash (named_ids_list, named_ids_len, TRUE);
-+
-+		if (replace_hash && *props) {
-+			for (ii = 0; ii < *propslen; ii++) {
-+				uint32_t proptag = (*props)[ii].ulPropTag;
-+
-+				maybe_replace_named_id_tag (&proptag, replace_hash);
-+
-+				(*props)[ii].ulPropTag = proptag;
-+			}
-+		}
-+
-+		if (replace_hash && streams) {
-+			for (ii = 0; ii < *streamslen; ii++) {
-+				maybe_replace_named_id_tag (&((*streams)[ii].proptag), replace_hash);
-+			}
-+		}
-+
-+		if (replace_hash)
-+			g_hash_table_destroy (replace_hash);
-+	}
-+
-+	g_free (named_ids_list);
-+
-+	return res;
-+}
-+
-+static gboolean
-+write_streamed_prop (EMapiConnection *conn,
-+		     mapi_object_t *obj_object,
-+		     const EMapiStreamedProp *stream,
-+		     TALLOC_CTX *mem_ctx,
-+		     GCancellable *cancellable,
-+		     GError **perror)
-+{
-+	enum MAPISTATUS	ms;
-+	uint64_t total_written;
-+	gboolean done = FALSE;
-+	mapi_object_t obj_stream;
-+
-+	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 (obj_object != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (stream != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	mapi_object_init (&obj_stream);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* OpenStream on required proptag */
-+	ms = OpenStream (obj_object, stream->proptag, OpenStream_Create, &obj_stream);
-+	if (ms != MAPI_E_SUCCESS) {
-+		if (ms == MAPI_E_NO_ACCESS && stream->orig_value) {
-+			/* write property with SetProps, because this one cannot be written as stream */
-+			struct SPropValue *props = NULL;
-+			uint32_t propslen = 0;
-+
-+			e_mapi_utils_add_spropvalue (mem_ctx, &props, &propslen, stream->proptag, stream->orig_value);
-+
-+			ms = SetProps (obj_object, MAPI_PROPS_SKIP_NAMEDID_CHECK, props, propslen);
-+
-+			talloc_free (props);
-+
-+			if (ms != MAPI_E_SUCCESS)
-+				make_mapi_error (perror, "SetProps", ms);
-+		} else {
-+			make_mapi_error (perror, "OpenStream", ms);
-+		}
-+		goto cleanup;
-+	}
-+
-+	/* Set the stream size */
-+	ms = SetStreamSize (&obj_stream, stream->cb);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "SetStreamSize", ms);
-+		goto cleanup;
-+	}
-+
-+	total_written = 0;
-+	/* Write stream */
-+	while (!done) {
-+		uint16_t cn_written = 0;
-+		DATA_BLOB blob;
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			goto cleanup;
-+		}
-+
-+		blob.length = (stream->cb - total_written) < STREAM_MAX_WRITE_SIZE ?
-+			      (stream->cb - total_written) : STREAM_MAX_WRITE_SIZE;
-+		blob.data = (uint8_t *) (stream->lpb + total_written);
-+
-+		ms = WriteStream (&obj_stream, &blob, &cn_written);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "WriteStream", ms);
-+			done = TRUE;
-+		} else if (cn_written == 0) {
-+			done = TRUE;
-+		} else {
-+			total_written += cn_written;
-+			if (total_written >= stream->cb)
-+				done = TRUE;
-+		}
-+	}
-+
-+	if (ms == MAPI_E_SUCCESS) {
-+		/* Commit the stream */
-+		ms = CommitStream (&obj_stream);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "CommitStream", ms);
-+			goto cleanup;
-+		}
-+	}
-+
-+ cleanup:
-+	mapi_object_release (&obj_stream);
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static gboolean
-+update_props_on_object (EMapiConnection *conn,
-+			mapi_object_t *obj_folder,
-+			mapi_object_t *obj_object,
-+			const struct mapi_SPropValue_array *properties,
-+			const EMapiStreamedProp *known_streams,
-+			guint known_streams_count,
-+			TALLOC_CTX *mem_ctx,
-+			GCancellable *cancellable,
-+			GError **perror)
-+{
-+	enum MAPISTATUS	ms = MAPI_E_RESERVED;
-+	struct SPropValue *props = NULL;
-+	uint32_t propslen = 0;
-+	EMapiStreamedProp *streams = NULL;
-+	guint streamslen = 0;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	if (!convert_mapi_props_to_props (conn, obj_folder, properties, known_streams, known_streams_count, &props, &propslen, &streams, &streamslen, mem_ctx, cancellable, perror)) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "convert_mapi_props_to_props", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	if (props) {
-+		/* set properties for the item */
-+		ms = SetProps (obj_object, MAPI_PROPS_SKIP_NAMEDID_CHECK, props, propslen);
-+
-+		talloc_free (props);
-+
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "SetProps", ms);
-+			goto cleanup;
-+		}
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	if (streams) {
-+		guint ii;
-+
-+		for (ii = 0; ii < streamslen; ii++) {
-+			if (!write_streamed_prop (conn, obj_object, &streams[ii], mem_ctx, cancellable, perror)) {
-+				ms = MAPI_E_CALL_FAILED;
-+				make_mapi_error (perror, "write_streamed_prop", ms);
-+				break;
-+			}
-+
-+			if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+				ms = MAPI_E_USER_CANCEL;
-+				break;
-+			}
-+		}
-+
-+		g_free (streams);
-+	}
-+ cleanup:
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static gboolean
-+update_recipient_properties (EMapiConnection *conn,
-+			     mapi_object_t *obj_folder,
-+			     struct SRow *aRow,
-+			     EMapiRecipient *recipient,
-+			     gboolean is_resolved,
-+			     TALLOC_CTX *mem_ctx,
-+			     GCancellable *cancellable,
-+			     GError **perror)
-+{
-+	struct SPropValue *props = NULL;
-+	uint32_t propslen = 0, ii;
-+
-+	g_return_val_if_fail (recipient != NULL, FALSE);
-+
-+	if (!convert_mapi_props_to_props (conn, obj_folder, &recipient->properties, NULL, 0, &props, &propslen, NULL, NULL, mem_ctx, cancellable, perror))
-+		return FALSE;
-+
-+	for (ii = 0; ii < propslen; ii++) {
-+		/* do not overwrite all properties, if recipient was resolved properly */
-+		if (!is_resolved
-+		    || props[ii].ulPropTag == PidTagRecipientType
-+		    || props[ii].ulPropTag == PidTagSendInternetEncoding
-+		    || props[ii].ulPropTag == PidTagRecipientFlags
-+		    || props[ii].ulPropTag == PidTagRecipientTrackStatus)
-+			SRow_addprop (aRow, props[ii]);
-+	}
-+
-+	return TRUE;
-+}
-+
-+static gboolean
-+delete_object_recipients (EMapiConnection *conn,
-+			  mapi_object_t *obj_folder,
-+			  mapi_object_t *obj_object,
-+			  TALLOC_CTX *mem_ctx,
-+			  GCancellable *cancellable,
-+			  GError **perror)
-+{
-+	enum MAPISTATUS	ms;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	ms = RemoveAllRecipients (obj_object);
-+	if (ms != MAPI_E_SUCCESS)
-+		make_mapi_error (perror, "RemoveAllRecipients", ms);
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static gboolean
-+add_object_recipients (EMapiConnection *conn,
-+		       mapi_object_t *obj_folder,
-+		       mapi_object_t *obj_message,
-+		       EMapiRecipient *recipients,
-+		       TALLOC_CTX *mem_ctx,
-+		       GCancellable *cancellable,
-+		       GError **perror)
-+{
-+	const uint32_t required_tags[] = {PidTagEntryId,
-+					  PidTagDisplayName,
-+					  PidTagObjectType,
-+					  PidTagDisplayType,
-+					  PidTagTransmittableDisplayName,
-+					  PidTagEmailAddress,
-+					  PidTagAddressType,
-+					  PidTagSendRichInfo};
-+	enum MAPISTATUS	ms;
-+	struct SPropTagArray *tags;
-+	struct SRowSet *rows = NULL;
-+	struct PropertyRowSet_r *prop_rows = NULL;
-+	struct PropertyTagArray_r *flagList = NULL;
-+	EResolveNamedIDsData *named_ids_list = NULL;
-+	guint named_ids_len = 0;
-+	const gchar **users = NULL;
-+	EMapiRecipient *recipient;
-+	EMapiRecipient **recips;
-+	uint32_t ii, jj, count = 0;
-+	GHashTable *all_proptags;
-+	GHashTableIter iter;
-+	gpointer key, value;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	count = 0;
-+	for (recipient = recipients, ii = 0; recipient; recipient = recipient->next, ii++) {
-+		if (!e_mapi_util_find_array_propval (&recipient->properties, PidTagPrimarySmtpAddress)
-+		    && !e_mapi_util_find_array_propval (&recipient->properties, PidTagDisplayName))
-+			g_debug ("%s: Cannot get email or display name for a recipient %d, skipping it", G_STRFUNC, ii);
-+		else
-+			count++;
-+	}
-+
-+	if (!count)
-+		return TRUE;
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	all_proptags = g_hash_table_new (g_direct_hash, g_direct_equal);
-+	users = g_new0 (const gchar *, count + 1);
-+	recips = g_new0 (EMapiRecipient *, count + 1);
-+
-+	for (ii = 0; ii < G_N_ELEMENTS (required_tags); ii++) {
-+		g_hash_table_insert (all_proptags, GUINT_TO_POINTER (required_tags[ii]), GUINT_TO_POINTER (1));
-+	}
-+
-+	for (ii = 0, jj = 0, recipient = recipients; ii < count && recipient != NULL; ii++, recipient = recipient->next) {
-+		users[ii] = e_mapi_util_find_array_propval (&recipient->properties, PidTagPrimarySmtpAddress);
-+		if (!users[ii])
-+			users[ii] = e_mapi_util_find_array_propval (&recipient->properties, PidTagDisplayName);
-+		if (!users[ii]) {
-+			ii--;
-+		} else {
-+			uint32_t kk;
-+
-+			recips[jj] = recipient;
-+			jj++;
-+
-+			for (kk = 0; kk < recipient->properties.cValues; kk++) {
-+				g_hash_table_insert (all_proptags, GUINT_TO_POINTER (recipient->properties.lpProps[kk].ulPropTag), GUINT_TO_POINTER (1));
-+			}
-+		}
-+	}
-+
-+	/* Attempt to resolve names from the server */
-+	tags = NULL;
-+	g_hash_table_iter_init (&iter, all_proptags);
-+	while (g_hash_table_iter_next (&iter, &key, &value)) {
-+		uint32_t proptag = GPOINTER_TO_UINT (key);
-+
-+		maybe_add_named_id_tag (proptag, &named_ids_list, &named_ids_len);
-+
-+		if (!tags)
-+			tags = set_SPropTagArray (mem_ctx, 1, proptag);
-+		else
-+			SPropTagArray_add (mem_ctx, tags, proptag);
-+	}
-+
-+	if (named_ids_list) {
-+		GHashTable *replace_hash;
-+
-+		if (!e_mapi_connection_resolve_named_props (conn, obj_folder, named_ids_list, named_ids_len, cancellable, perror)) {
-+			ms = MAPI_E_CALL_FAILED;
-+			make_mapi_error (perror, "e_mapi_connection_resolve_named_props", ms);
-+			goto cleanup;
-+		}
-+
-+		replace_hash = prepare_maybe_replace_hash (named_ids_list, named_ids_len, TRUE);
-+
-+		for (ii = 0; ii < tags->cValues && replace_hash; ii++) {
-+			uint32_t proptag = tags->aulPropTag[ii];
-+
-+			maybe_replace_named_id_tag (&proptag, replace_hash);
-+
-+			tags->aulPropTag[ii] = proptag;
-+		}
-+
-+		if (replace_hash)
-+			g_hash_table_destroy (replace_hash);
-+	}
-+
-+	ms = ResolveNames (priv->session, users, tags, &prop_rows, &flagList, MAPI_UNICODE);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "ResolveNames", ms);
-+		goto cleanup;
-+	}
-+
-+	g_assert (count == flagList->cValues);
-+
-+	rows = talloc_zero (mem_ctx, struct SRowSet);
-+
-+	/* 'prop_rows == NULL' happens when there are none resolved recipients */
-+	if (prop_rows)
-+		cast_PropertyRowSet_to_SRowSet (mem_ctx, prop_rows, rows);
-+
-+	for (ii = 0, jj = 0; ii < count; ii++) {
-+		recipient = recips[ii];
-+
-+		if (flagList->aulPropTag[ii] == MAPI_AMBIGUOUS) {
-+			/* We should never get an ambiguous resolution as we use the email-id for resolving.
-+			 * However, if we do still get an ambiguous entry, we can't handle it :-( */
-+			ms = MAPI_E_AMBIGUOUS_RECIP;
-+			/* Translators: %s is replaced with an email address which was found ambiguous on a remote server */
-+			g_set_error (perror, E_MAPI_ERROR, ms, _("Recipient '%s' is ambiguous"), users[ii]);
-+			goto cleanup;
-+		} else if (flagList->aulPropTag[ii] == MAPI_UNRESOLVED) {
-+			uint32_t last;
-+
-+			/* If the recipient is unresolved, consider it is a SMTP one */
-+			rows->aRow = talloc_realloc (mem_ctx, rows->aRow, struct SRow, rows->cRows + 1);
-+			last = rows->cRows;
-+			rows->aRow[last].cValues = 0;
-+			rows->aRow[last].lpProps = talloc_zero (mem_ctx, struct SPropValue);
-+			if (!update_recipient_properties (conn, obj_folder, &rows->aRow[last], recipient, FALSE, mem_ctx, cancellable, perror)) {
-+				ms = MAPI_E_CALL_FAILED;
-+				goto cleanup;
-+			}
-+			rows->cRows += 1;
-+		} else if (flagList->aulPropTag[ii] == MAPI_RESOLVED) {
-+			if (!update_recipient_properties (conn, obj_folder, &rows->aRow[jj], recipient, TRUE, mem_ctx, cancellable, perror)) {
-+				ms = MAPI_E_CALL_FAILED;
-+				goto cleanup;
-+			}
-+			jj += 1;
-+		}
-+	}
-+
-+	/* Modify the recipient table */
-+	ms = ModifyRecipients (obj_message, rows);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "ModifyRecipients", ms);
-+		goto cleanup;
-+	}
-+
-+ cleanup:
-+	talloc_free (rows);
-+	talloc_free (prop_rows);
-+	talloc_free (flagList);
-+
-+	UNLOCK ();
-+
-+	g_free (users);
-+	g_free (recips);
-+	g_free (named_ids_list);
-+	g_hash_table_destroy (all_proptags);
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static gboolean
-+delete_attachment_cb (EMapiConnection *conn,
-+		      TALLOC_CTX *mem_ctx,
-+		      struct SRow *srow,
-+		      guint32 row_index,
-+		      guint32 rows_total,
-+		      gpointer user_data,
-+		      GCancellable *cancellable,
-+		      GError **perror)
-+{
-+	const uint32_t *attach_num;
-+	mapi_object_t *obj_object = user_data;
-+	enum MAPISTATUS ms;
-+
-+	g_return_val_if_fail (obj_object != NULL, FALSE);
-+
-+	attach_num = e_mapi_util_find_row_propval (srow, PidTagAttachNumber);
-+	g_return_val_if_fail (attach_num != NULL, FALSE);
-+
-+	ms = DeleteAttach (obj_object, *attach_num);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "DeleteAttach", ms);
-+	}
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static gboolean
-+delete_object_attachments (EMapiConnection *conn,
-+			   mapi_object_t *obj_folder,
-+			   mapi_object_t *obj_object,
-+			   TALLOC_CTX *mem_ctx,
-+			   GCancellable *cancellable,
-+			   GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	mapi_object_t obj_table;
-+	struct SPropTagArray *proptags;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	mapi_object_init (&obj_table);
-+
-+	/* open attachment table */
-+	ms = GetAttachmentTable (obj_object, &obj_table);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetAttachmentTable", ms);
-+		goto cleanup;
-+	}
-+
-+	proptags = set_SPropTagArray (mem_ctx, 1, PidTagAttachNumber);
-+
-+	ms = SetColumns (&obj_table, proptags);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "SetColumns", ms);
-+		goto cleanup;
-+	}
-+
-+	ms = foreach_tablerow (conn, mem_ctx, &obj_table, delete_attachment_cb, obj_object, cancellable, perror);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "foreach_tablerow", ms);
-+	}
-+
-+ cleanup:
-+	mapi_object_release (&obj_table);
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static gboolean update_message_with_object (EMapiConnection *conn,
-+					    mapi_object_t *obj_folder,
-+					    mapi_object_t *obj_message,
-+					    EMapiObject *object,
-+					    TALLOC_CTX *mem_ctx,
-+					    GCancellable *cancellable,
-+					    GError **perror);
-+
-+static gboolean
-+add_object_attachments (EMapiConnection *conn,
-+			mapi_object_t *obj_folder,
-+			mapi_object_t *obj_message,
-+			EMapiAttachment *attachments,
-+			TALLOC_CTX *mem_ctx,
-+			GCancellable *cancellable,
-+			GError **perror)
-+{
-+	enum MAPISTATUS ms = MAPI_E_SUCCESS;
-+	EMapiAttachment *attachment;
-+
-+	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 (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_message != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	for (attachment = attachments; attachment && ms == MAPI_E_SUCCESS; attachment = attachment->next) {
-+		mapi_object_t obj_attach;
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			break;
-+		}
-+
-+		mapi_object_init (&obj_attach);
-+
-+		ms = CreateAttach (obj_message, &obj_attach);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "CreateAttach", ms);
-+			goto cleanup;
-+		}
-+
-+		if (!update_props_on_object (conn, obj_folder, &obj_attach,
-+			&attachment->properties,
-+			attachment->streamed_properties, attachment->streamed_properties_count,
-+			mem_ctx, cancellable, perror)) {
-+			ms = MAPI_E_CALL_FAILED;
-+			make_mapi_error (perror, "update_props_on_object", ms);
-+			goto cleanup;
-+		}
-+
-+		if (attachment->embedded_object) {
-+			mapi_object_t obj_emb_msg;
-+
-+			mapi_object_init (&obj_emb_msg);
-+
-+			ms = OpenEmbeddedMessage (&obj_attach, &obj_emb_msg, MAPI_CREATE);
-+			if (ms != MAPI_E_SUCCESS) {
-+				make_mapi_error (perror, "OpenEmbeddedMessage", ms);
-+				goto cleanup;
-+			}
-+
-+			if (!update_message_with_object (conn, obj_folder, &obj_emb_msg, attachment->embedded_object, mem_ctx, cancellable, perror)) {
-+				ms = MAPI_E_CALL_FAILED;
-+				make_mapi_error (perror, "SaveChangesMessage", ms);
-+				mapi_object_release (&obj_emb_msg);
-+				goto cleanup;
-+			}
-+
-+			ms = SaveChangesMessage (&obj_attach, &obj_emb_msg, KeepOpenReadOnly);
-+			if (ms != MAPI_E_SUCCESS) {
-+				make_mapi_error (perror, "SaveChangesMessage", ms);
-+				mapi_object_release (&obj_emb_msg);
-+				goto cleanup;
-+			}
-+
-+			mapi_object_release (&obj_emb_msg);
-+		}
-+
-+		ms = SaveChangesAttachment (obj_message, &obj_attach, KeepOpenReadWrite);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "SaveChangesAttachment", ms);
-+			goto cleanup;
-+		}
-+
-+	 cleanup:
-+		mapi_object_release (&obj_attach);
-+	}
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static gboolean
-+update_message_with_object (EMapiConnection *conn,
-+			    mapi_object_t *obj_folder,
-+			    mapi_object_t *obj_message,
-+			    EMapiObject *object,
-+			    TALLOC_CTX *mem_ctx,
-+			    GCancellable *cancellable,
-+			    GError **perror)
-+{
-+	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 (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_message != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (object != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	if (!update_props_on_object (conn, obj_folder, obj_message,
-+		&object->properties,
-+		object->streamed_properties, object->streamed_properties_count,
-+		mem_ctx, cancellable, perror))
-+		return FALSE;
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-+		return FALSE;
-+
-+	/* do not touch recipients if not set */
-+	if (object->recipients) {
-+		/* remove current recipients... */
-+		if (!delete_object_recipients (conn, obj_folder, obj_message, mem_ctx, cancellable, perror))
-+			return FALSE;
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-+			return FALSE;
-+
-+		/* ... and add new */
-+		if (!add_object_recipients (conn, obj_folder, obj_message, object->recipients, mem_ctx, cancellable, perror))
-+			return FALSE;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-+		return FALSE;
-+
-+	/* remove current attachments... */
-+	if (!delete_object_attachments (conn, obj_folder, obj_message, mem_ctx, cancellable, perror))
-+		return FALSE;
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-+		return FALSE;
-+
-+	/* ... and add new */
-+	if (object->attachments && !add_object_attachments (conn, obj_folder, obj_message, object->attachments, mem_ctx, cancellable, perror))
-+		return FALSE;
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-+		return FALSE;
-+
-+	return TRUE;
-+}
-+
-+gboolean
-+e_mapi_connection_create_object (EMapiConnection *conn,
-+				 mapi_object_t *obj_folder,
-+				 uint32_t flags, /* bit-or of EMapiCreateFlags */
-+				 WriteObjectCB write_object_cb,
-+				 gpointer woc_data,
-+				 mapi_id_t *out_mid,
-+				 GCancellable *cancellable,
-+				 GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	TALLOC_CTX *mem_ctx;
-+	EMapiObject *object = NULL;
-+	mapi_object_t obj_message;
-+
-+	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 (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (write_object_cb != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (out_mid != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	*out_mid = 0;
-+
-+	mem_ctx = talloc_new (priv->session);
-+	mapi_object_init (&obj_message);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	if (!write_object_cb (conn, mem_ctx, &object, woc_data, cancellable, perror) || !object) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "write_object_cb", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	ms = CreateMessage (obj_folder, &obj_message);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "CreateMessage", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	if (!update_message_with_object (conn, obj_folder, &obj_message, object, mem_ctx, cancellable, perror)) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "update_message_with_object", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	ms = SaveChangesMessage (obj_folder, &obj_message, KeepOpenReadWrite);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "SaveChangesMessage", ms);
-+		goto cleanup;
-+	}
-+
-+	if ((flags & E_MAPI_CREATE_FLAG_SUBMIT) != 0) {
-+		/* Mark message as ready to be sent */
-+		ms = SubmitMessage (&obj_message);
-+		if (ms != MAPI_E_SUCCESS) {
-+			mapi_id_t mid;
-+			make_mapi_error (perror, "SubmitMessage", ms);
-+
-+			/*
-+			The code is storing message right to Sent items instead of Outbox,
-+			because fetching PR_ENTRYID or PR_IPM_SENTMAIL_ENTRYID didn't seem
-+			to work in time of doing this change.
-+
-+			For more information and other possible (correct) approaches see:
-+			https://bugzilla.gnome.org/show_bug.cgi?id=561794
-+			*/
-+			mid = mapi_object_get_id (&obj_message);
-+
-+			mapi_object_release (&obj_message);
-+			/* to not release a message object twice */
-+			mapi_object_init (&obj_message);
-+
-+			ms = DeleteMessage (obj_folder, &mid, 1);
-+			if (ms != MAPI_E_SUCCESS) {
-+				make_mapi_error (perror, "DeleteMessage", ms);
-+			}
-+
-+			goto cleanup;
-+		}
-+	}
-+
-+	*out_mid = mapi_object_get_id (&obj_message);
-+
-+ cleanup:
-+	e_mapi_object_free (object);
-+	mapi_object_release (&obj_message);
-+	talloc_free (mem_ctx);
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_modify_object (EMapiConnection *conn,
-+				 mapi_object_t *obj_folder,
-+				 mapi_id_t mid,
-+				 WriteObjectCB write_object_cb,
-+				 gpointer woc_data,
-+				 GCancellable *cancellable,
-+				 GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	TALLOC_CTX *mem_ctx;
-+	EMapiObject *object = NULL;
-+	mapi_object_t obj_message;
-+
-+	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 (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (write_object_cb != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (mid != 0, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	mem_ctx = talloc_new (priv->session);
-+	mapi_object_init (&obj_message);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	if (!write_object_cb (conn, mem_ctx, &object, woc_data, cancellable, perror)) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "write_object_cb", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	ms = OpenMessage (obj_folder, mapi_object_get_id (obj_folder), mid, &obj_message, MAPI_MODIFY);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenMessage", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	if (!update_message_with_object (conn, obj_folder, &obj_message, object, mem_ctx, cancellable, perror)) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "update_message_with_object", ms);
-+		goto cleanup;
-+	}
-+
-+	ms = SaveChangesMessage (obj_folder, &obj_message, KeepOpenReadOnly);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "SaveChangesMessage", ms);
-+		goto cleanup;
-+	}
-+
-+ cleanup:
-+	e_mapi_object_free (object);
-+	mapi_object_release (&obj_message);
-+	talloc_free (mem_ctx);
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static void
-+e_mapi_cast_SPropValue_to_PropertyValue (struct SPropValue *spropvalue,
-+					 struct PropertyValue_r *propvalue)
-+{
-+	propvalue->ulPropTag = spropvalue->ulPropTag;
-+
-+	switch (spropvalue->ulPropTag & 0xFFFF) {
-+	case PT_BOOLEAN:
-+		propvalue->value.b = spropvalue->value.b;
-+		break;
-+	case PT_I2:
-+		propvalue->value.i = spropvalue->value.i;
-+		break;
-+	case PT_LONG:
-+		propvalue->value.l = spropvalue->value.l;
-+		break;
-+	case PT_STRING8:
-+		propvalue->value.lpszA = spropvalue->value.lpszA;
-+		break;
-+	case PT_UNICODE:
-+		propvalue->value.lpszW = spropvalue->value.lpszW;
-+		break;
-+	case PT_SYSTIME:
-+		propvalue->value.ft = spropvalue->value.ft;
-+		break;
-+	case PT_CLSID:
-+		propvalue->value.lpguid = spropvalue->value.lpguid;
-+		break;
-+	case PT_SVREID:
-+	case PT_BINARY:
-+		propvalue->value.bin = spropvalue->value.bin;
-+		break;
-+        case PT_ERROR:
-+                propvalue->value.err = spropvalue->value.err;
-+		break;
-+	case PT_MV_LONG:
-+		propvalue->value.MVl = spropvalue->value.MVl;
-+		break;
-+	case PT_MV_STRING8:
-+		propvalue->value.MVszA = spropvalue->value.MVszA;
-+		break;
-+        case PT_MV_UNICODE:
-+		propvalue->value.MVszW = spropvalue->value.MVszW;
-+		break;
-+	case PT_MV_CLSID:
-+		propvalue->value.MVguid = spropvalue->value.MVguid;
-+		break;
-+	case PT_MV_BINARY:
-+		propvalue->value.MVbin = spropvalue->value.MVbin;
-+		break;
-+        default:
-+                g_warning ("%s: unhandled conversion case: 0x%x", G_STRFUNC, (spropvalue->ulPropTag & 0xFFFF));
-+		break;
-+	}
-+}
-+
-+static void
-+convert_mapi_SRestriction_to_Restriction_r (struct mapi_SRestriction *restriction,
-+					    struct Restriction_r *rr,
-+					    TALLOC_CTX *mem_ctx,
-+					    GHashTable *replace_hash)
-+{
-+	guint i;
-+	uint32_t proptag;
-+
-+	g_return_if_fail (restriction != NULL);
-+	g_return_if_fail (rr != NULL);
-+	g_return_if_fail (mem_ctx != NULL);
-+
-+	#define copy(x, y) rr->res.x = restriction->res.y
-+	#define copy_prop(pprop, mprop)	{							\
-+			struct SPropValue *helper = talloc_zero (mem_ctx, struct SPropValue);	\
-+			rr->res.pprop = talloc_zero (mem_ctx, struct PropertyValue_r);		\
-+			g_return_if_fail (rr->res.pprop != NULL);				\
-+			rr->res.pprop->ulPropTag = restriction->res.mprop.ulPropTag;		\
-+			rr->res.pprop->dwAlignPad = 0;						\
-+			cast_SPropValue (mem_ctx, &(restriction->res.mprop), helper);		\
-+			e_mapi_cast_SPropValue_to_PropertyValue (helper, rr->res.pprop);	\
-+		}
-+	#define check_proptag(x) {								\
-+			proptag = x;								\
-+			maybe_replace_named_id_tag (&proptag, replace_hash);			\
-+			/* workaround for unresolved properties */				\
-+			if (proptag == MAPI_E_RESERVED)						\
-+				proptag = PidTagDisplayName;					\
-+			x = proptag;								\
-+		}
-+
-+	rr->rt = restriction->rt;
-+
-+	switch (restriction->rt) {
-+	case RES_AND:
-+		rr->res.resAnd.lpRes = talloc_zero_array (mem_ctx, struct Restriction_r, restriction->res.resAnd.cRes);
-+		g_return_if_fail (rr->res.resAnd.lpRes != NULL);
-+
-+		copy (resAnd.cRes, resAnd.cRes);
-+		for (i = 0; i < restriction->res.resAnd.cRes; i++) {
-+			convert_mapi_SRestriction_to_Restriction_r (
-+				(struct mapi_SRestriction *) &(restriction->res.resAnd.res[i]),
-+				&(rr->res.resAnd.lpRes[i]),
-+				mem_ctx, replace_hash);
-+		}
-+		break;
-+	case RES_OR:
-+		rr->res.resOr.lpRes = talloc_zero_array (mem_ctx, struct Restriction_r, restriction->res.resOr.cRes);
-+		g_return_if_fail (rr->res.resOr.lpRes != NULL);
-+
-+		copy (resOr.cRes, resOr.cRes);
-+		for (i = 0; i < restriction->res.resOr.cRes; i++) {
-+			convert_mapi_SRestriction_to_Restriction_r (
-+				(struct mapi_SRestriction *) &(restriction->res.resOr.res[i]),
-+				&(rr->res.resOr.lpRes[i]),
-+				mem_ctx, replace_hash);
-+		}
-+		break;
-+	#ifdef HAVE_RES_NOT_SUPPORTED
-+	case RES_NOT:
-+		rr->res.resNot.lpRes = talloc_zero (mem_ctx, struct Restriction_r);
-+		g_return_if_fail (rr->res.resNot.lpRes != NULL);
-+
-+		convert_mapi_SRestriction_to_Restriction_r (
-+			restriction->res.resNot.res,
-+			rr->res.resNot.lpRes,
-+			mem_ctx, replace_hash);
-+		break;
-+	#endif
-+	case RES_CONTENT:
-+		copy (resContent.ulFuzzyLevel, resContent.fuzzy);
-+		copy (resContent.ulPropTag, resContent.ulPropTag);
-+		copy_prop (resContent.lpProp, resContent.lpProp);
-+
-+		check_proptag (rr->res.resContent.ulPropTag);
-+		check_proptag (rr->res.resContent.lpProp->ulPropTag);
-+		break;
-+	case RES_PROPERTY:
-+		copy (resProperty.relop, resProperty.relop);
-+		copy (resProperty.ulPropTag, resProperty.ulPropTag);
-+		copy_prop (resProperty.lpProp, resProperty.lpProp);
-+
-+
-+		check_proptag (rr->res.resProperty.ulPropTag);
-+		check_proptag (rr->res.resProperty.lpProp->ulPropTag);
-+		break;
-+	case RES_COMPAREPROPS:
-+		copy (resCompareProps.relop, resCompareProps.relop);
-+		copy (resCompareProps.ulPropTag1, resCompareProps.ulPropTag1);
-+		copy (resCompareProps.ulPropTag2, resCompareProps.ulPropTag2);
-+
-+		check_proptag (rr->res.resCompareProps.ulPropTag1);
-+		check_proptag (rr->res.resCompareProps.ulPropTag2);
-+		break;
-+	case RES_BITMASK:
-+		copy (resBitMask.relMBR, resBitmask.relMBR);
-+		copy (resBitMask.ulPropTag, resBitmask.ulPropTag);
-+		copy (resBitMask.ulMask, resBitmask.ulMask);
-+
-+		check_proptag (rr->res.resBitMask.ulPropTag);
-+		break;
-+	case RES_SIZE:
-+		copy (resSize.relop, resSize.relop);
-+		copy (resSize.ulPropTag, resSize.ulPropTag);
-+		copy (resSize.cb, resSize.size);
-+
-+		check_proptag (rr->res.resSize.ulPropTag);
-+		break;
-+	case RES_EXIST:
-+		rr->res.resExist.ulReserved1 = 0;
-+		rr->res.resExist.ulReserved2 = 0;
-+		copy (resExist.ulPropTag, resExist.ulPropTag);
-+
-+		check_proptag (rr->res.resExist.ulPropTag);
-+		break;
-+	}
-+
-+	#undef check_proptag
-+	#undef copy_prop
-+	#undef copy
-+}
-+
-+static void
-+remove_unknown_proptags_Restriction_r_rec (struct Restriction_r *restriction,
-+					   TALLOC_CTX *mem_ctx,
-+					   GSList **new_rests)
-+{
-+	gint ii;
-+	GSList *sub_rests = NULL, *iter;
-+
-+	if (!restriction)
-+		return;
-+
-+	g_return_if_fail (mem_ctx != NULL);
-+
-+	#define proptag_is_ok(x) (((uint32_t) (x)) != 0 && ((uint32_t) (x)) != MAPI_E_RESERVED)
-+
-+	switch (restriction->rt) {
-+	case RES_AND:
-+		for (ii = 0; ii < restriction->res.resAnd.cRes; ii++) {
-+			remove_unknown_proptags_Restriction_r_rec (&(restriction->res.resAnd.lpRes[ii]), mem_ctx, &sub_rests);
-+		}
-+
-+		if (sub_rests) {
-+			struct Restriction_r *rest = talloc_zero (mem_ctx, struct Restriction_r);
-+			g_return_if_fail (rest != NULL);
-+
-+			rest->rt = RES_AND;
-+			rest->res.resAnd.cRes = g_slist_length (sub_rests);
-+			rest->res.resAnd.lpRes = talloc_zero_array (mem_ctx, struct Restriction_r, rest->res.resAnd.cRes + 1);
-+			g_return_if_fail (rest->res.resAnd.lpRes != NULL);
-+
-+			for (iter = sub_rests, ii = 0; iter; iter = iter->next, ii++) {
-+				struct Restriction_r *subrest = iter->data;
-+
-+				g_return_if_fail (subrest != NULL);
-+
-+				rest->res.resAnd.lpRes[ii].rt = subrest->rt;
-+				rest->res.resAnd.lpRes[ii].res = subrest->res;
-+			}
-+
-+			*new_rests = g_slist_append (*new_rests, rest);
-+		}
-+		break;
-+	case RES_OR:
-+		for (ii = 0; ii < restriction->res.resOr.cRes; ii++) {
-+			remove_unknown_proptags_Restriction_r_rec (&(restriction->res.resOr.lpRes[ii]), mem_ctx, &sub_rests);
-+		}
-+
-+		if (sub_rests) {
-+			struct Restriction_r *rest = talloc_zero (mem_ctx, struct Restriction_r);
-+			g_return_if_fail (rest != NULL);
-+
-+			rest->rt = RES_OR;
-+			rest->res.resOr.cRes = g_slist_length (sub_rests);
-+			rest->res.resOr.lpRes = talloc_zero_array (mem_ctx, struct Restriction_r, rest->res.resOr.cRes + 1);
-+			g_return_if_fail (rest->res.resOr.lpRes != NULL);
-+
-+			for (iter = sub_rests, ii = 0; iter; iter = iter->next, ii++) {
-+				struct Restriction_r *subrest = iter->data;
-+
-+				g_return_if_fail (subrest != NULL);
-+
-+				rest->res.resOr.lpRes[ii].rt = subrest->rt;
-+				rest->res.resOr.lpRes[ii].res = subrest->res;
-+			}
-+
-+			*new_rests = g_slist_append (*new_rests, rest);
-+		}
-+		break;
-+	#ifdef HAVE_RES_NOT_SUPPORTED
-+	case RES_NOT:
-+		remove_unknown_proptags_Restriction_r_rec (restriction->res.resNot.lpRes, mem_ctx, &sub_rests);
-+		if (sub_rests) {
-+			struct Restriction_r *rest = talloc_zero (esp->mem_ctx, struct Restriction_r);
-+			g_return_if_fail (rest != NULL);
-+
-+			rest->rt = RES_NOT;
-+			res->res.resNot.lpRes = sub_rests->data;
-+		}
-+		break;
-+	#endif
-+	case RES_CONTENT:
-+		if (proptag_is_ok (restriction->res.resContent.ulPropTag) &&
-+		    proptag_is_ok (restriction->res.resContent.lpProp->ulPropTag)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	case RES_PROPERTY:
-+		if (proptag_is_ok (restriction->res.resProperty.ulPropTag) &&
-+		    proptag_is_ok (restriction->res.resProperty.lpProp->ulPropTag)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	case RES_COMPAREPROPS:
-+		if (proptag_is_ok (restriction->res.resCompareProps.ulPropTag1) &&
-+		    proptag_is_ok (restriction->res.resCompareProps.ulPropTag2)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	case RES_BITMASK:
-+		if (proptag_is_ok (restriction->res.resBitMask.ulPropTag)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	case RES_SIZE:
-+		if (proptag_is_ok (restriction->res.resSize.ulPropTag)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	case RES_EXIST:
-+		if (proptag_is_ok (restriction->res.resExist.ulPropTag)) {
-+			*new_rests = g_slist_append (*new_rests, restriction);
-+		}
-+		break;
-+	default:
-+		g_warn_if_reached ();
-+		break;
-+	}
-+
-+	#undef proptag_is_ok
-+
-+	g_slist_free (sub_rests);
-+}
-+
-+static void
-+remove_unknown_proptags_Restriction_r (struct Restriction_r **prestrictions,
-+				       TALLOC_CTX *mem_ctx)
-+{
-+	GSList *new_rests = NULL;
-+
-+	g_return_if_fail (mem_ctx != NULL);
-+
-+	remove_unknown_proptags_Restriction_r_rec (*prestrictions, mem_ctx, &new_rests);
-+
-+	if (new_rests) {
-+		g_return_if_fail (g_slist_length (new_rests) == 1);
-+
-+		*prestrictions = new_rests->data;
-+
-+		g_slist_free (new_rests);
-+	} else {
-+		*prestrictions = NULL;
-+	}
-+}
-+
-+static enum MAPISTATUS
-+process_gal_rows_chunk (EMapiConnection *conn,
-+			TALLOC_CTX *mem_ctx,
-+			uint32_t rows_offset,
-+			uint32_t rows_total,
-+			struct PropertyRowSet_r *rows,
-+			struct PropertyTagArray_r *mids,
-+			ForeachTableRowCB cb,
-+			gpointer user_data,
-+			GCancellable *cancellable,
-+			GError **perror)
-+{
-+	enum MAPISTATUS ms = MAPI_E_SUCCESS;
-+	uint32_t ii;
-+
-+	e_return_val_mapi_error_if_fail (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER, MAPI_E_INVALID_PARAMETER);
-+	e_return_val_mapi_error_if_fail (rows != NULL, MAPI_E_INVALID_PARAMETER, MAPI_E_INVALID_PARAMETER);
-+	e_return_val_mapi_error_if_fail (mids != NULL, MAPI_E_INVALID_PARAMETER, MAPI_E_INVALID_PARAMETER);
-+	e_return_val_mapi_error_if_fail (cb != NULL, MAPI_E_INVALID_PARAMETER, MAPI_E_INVALID_PARAMETER);
-+	e_return_val_mapi_error_if_fail (rows->cRows <= mids->cValues, MAPI_E_INVALID_PARAMETER, MAPI_E_INVALID_PARAMETER);
-+
-+	for (ii = 0; ii < rows->cRows; ii++) {
-+		struct SRow *row;
-+		int64_t mid = mids->aulPropTag[ii];
-+
-+		row = talloc_zero (mem_ctx, struct SRow);
-+		cast_PropertyRow_to_SRow (mem_ctx, &rows->aRow[ii], row);
-+
-+		/* add the temporary mid as a PidTagMid */
-+		if (!e_mapi_utils_add_spropvalue (mem_ctx, &row->lpProps, &row->cValues, PidTagMid, &mid)) {
-+			ms = MAPI_E_CALL_FAILED;
-+			make_mapi_error (perror, "e_mapi_utils_add_spropvalue", ms);
-+			talloc_free (row);
-+			break;
-+		}
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			talloc_free (row);
-+			break;
-+		}
-+
-+		if (!cb (conn, mem_ctx, row, rows_offset + ii + 1, rows_total, user_data, cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			talloc_free (row);
-+			break;
-+		}
-+
-+		talloc_free (row);
-+	}
-+
-+	return ms;
-+}
-+
-+static enum MAPISTATUS
-+foreach_gal_tablerow (EMapiConnection *conn,
-+		      TALLOC_CTX *mem_ctx,
-+		      struct PropertyRowSet_r *first_rows,
-+		      struct PropertyTagArray_r *all_mids,
-+		      struct SPropTagArray *propTagArray,
-+		      ForeachTableRowCB cb,
-+		      gpointer user_data,
-+		      GCancellable *cancellable,
-+		      GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	struct PropertyRowSet_r *rows = NULL;
-+	struct PropertyTagArray_r *to_query = NULL;
-+	uint32_t  midspos;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, MAPI_E_INVALID_PARAMETER);
-+	e_return_val_mapi_error_if_fail (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER, MAPI_E_INVALID_PARAMETER);
-+	e_return_val_mapi_error_if_fail (first_rows != NULL, MAPI_E_INVALID_PARAMETER, MAPI_E_INVALID_PARAMETER);
-+	e_return_val_mapi_error_if_fail (all_mids != NULL, MAPI_E_INVALID_PARAMETER, MAPI_E_INVALID_PARAMETER);
-+	e_return_val_mapi_error_if_fail (cb != NULL, MAPI_E_INVALID_PARAMETER, MAPI_E_INVALID_PARAMETER);
-+	e_return_val_mapi_error_if_fail (first_rows->cRows <= all_mids->cValues, MAPI_E_INVALID_PARAMETER, MAPI_E_INVALID_PARAMETER);
-+
-+	midspos = 0;
-+	ms = process_gal_rows_chunk (conn, mem_ctx, midspos, all_mids->cValues, first_rows, all_mids, cb, user_data, cancellable, perror);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "process_gal_rows_chunk", ms);
-+		goto cleanup;
-+	}
-+
-+	midspos = first_rows->cRows;
-+	to_query = talloc_zero (mem_ctx, struct PropertyTagArray_r);
-+	to_query->aulPropTag = talloc_zero_array (mem_ctx, uint32_t, MAX_GAL_CHUNK);
-+
-+	while (midspos < all_mids->cValues) {
-+		uint32_t ii;
-+
-+		to_query->cValues = 0;
-+		for (ii = midspos; to_query->cValues < MAX_GAL_CHUNK && ii < all_mids->cValues; to_query->cValues++, ii++) {
-+			to_query->aulPropTag[to_query->cValues] = all_mids->aulPropTag[ii];
-+		}
-+
-+		if (!to_query->cValues)
-+			break;
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			break;
-+		}
-+
-+		ms = nspi_QueryRows (priv->session->nspi->ctx, mem_ctx, propTagArray, to_query, to_query->cValues, &rows);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "nspi_QueryRows", ms);
-+			goto cleanup;
-+		}
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			break;
-+		}
-+
-+		if (!rows || rows->cRows <= 0) {
-+			/* success or finished, probably */
-+			break;
-+		}
-+
-+		ms = process_gal_rows_chunk (conn, mem_ctx, midspos, all_mids->cValues, rows, to_query, cb, user_data, cancellable, perror);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "process_gal_rows_chunk", ms);
-+			goto cleanup;
-+		}
-+
-+		midspos += rows->cRows;
-+		talloc_free (rows);
-+		rows = NULL;
-+	}
-+
-+ cleanup:
-+	talloc_free (to_query);
-+	talloc_free (rows);
-+
-+	return ms;
-+}
-+
-+gboolean
-+e_mapi_connection_count_gal_objects (EMapiConnection *conn,
-+				     guint32 *obj_total,
-+				     GCancellable *cancellable,
-+				     GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	uint32_t count = 0;
-+
-+	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 (priv->session->nspi != NULL, MAPI_E_UNCONFIGURED, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session->nspi->ctx != NULL, MAPI_E_UNCONFIGURED, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_total != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	*obj_total = 0;
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+	} else {
-+		ms = GetGALTableCount (priv->session, &count);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "GetGALTableCount", ms);
-+		} else {
-+			*obj_total = count;
-+		}
-+	}
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_list_gal_objects (EMapiConnection *conn,
-+				    BuildRestrictionsCB build_rs_cb,
-+				    gpointer build_rs_cb_data,
-+				    ListObjectsCB cb,
-+				    gpointer user_data,
-+				    GCancellable *cancellable,
-+				    GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	TALLOC_CTX *mem_ctx;
-+	struct SPropTagArray *propTagArray = NULL;
-+	struct Restriction_r *use_restriction = NULL;
-+	struct PropertyRowSet_r *rows = NULL;
-+	struct PropertyTagArray_r *pMIds = NULL;
-+	struct ListObjectsInternalData loi_data;
-+
-+	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 (priv->session->nspi != NULL, MAPI_E_UNCONFIGURED, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session->nspi->ctx != NULL, MAPI_E_UNCONFIGURED, FALSE);
-+	e_return_val_mapi_error_if_fail (cb != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	mem_ctx = talloc_new (priv->session);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* other listing tags not found/used by GAL */
-+	propTagArray = set_SPropTagArray (mem_ctx, 1, PidTagLastModificationTime);
-+
-+	if (build_rs_cb) {
-+		struct mapi_SRestriction *restrictions = NULL;
-+
-+		if (!build_rs_cb (conn, mem_ctx, &restrictions, build_rs_cb_data, cancellable, perror)) {
-+			ms = MAPI_E_CALL_FAILED;
-+			make_mapi_error (perror, "build_restrictions", ms);
-+			goto cleanup;
-+		}
-+
-+		if (restrictions) {
-+			EResolveNamedIDsData *named_ids_list = NULL;
-+			guint named_ids_len = 0;
-+			gboolean res = FALSE;
-+
-+			gather_mapi_SRestriction_named_ids (restrictions, &named_ids_list, &named_ids_len);
-+
-+			if (named_ids_list) {
-+				/* use NULL for GAL as a folder ID parameter */
-+				res = e_mapi_connection_resolve_named_props (conn, NULL, named_ids_list, named_ids_len, cancellable, perror);
-+
-+				if (res) {
-+					GHashTable *replace_hash = prepare_maybe_replace_hash (named_ids_list, named_ids_len, TRUE);
-+
-+					use_restriction = talloc_zero (mem_ctx, struct Restriction_r);
-+					convert_mapi_SRestriction_to_Restriction_r (restrictions, use_restriction, mem_ctx, replace_hash);
-+
-+					if (replace_hash)
-+						g_hash_table_destroy (replace_hash);
-+				} else {
-+					ms = MAPI_E_CALL_FAILED;
-+					goto cleanup;
-+				}
-+
-+				g_free (named_ids_list);
-+			} else {
-+				use_restriction = talloc_zero (mem_ctx, struct Restriction_r);
-+				convert_mapi_SRestriction_to_Restriction_r (restrictions, use_restriction, mem_ctx, NULL);
-+			}
-+
-+			remove_unknown_proptags_Restriction_r (&use_restriction, mem_ctx);
-+
-+			if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+				ms = MAPI_E_USER_CANCEL;
-+				goto cleanup;
-+			}
-+		}
-+	}
-+
-+	loi_data.cb = cb;
-+	loi_data.user_data = user_data;
-+
-+	ms = nspi_GetMatches (priv->session->nspi->ctx, mem_ctx, propTagArray, use_restriction, (uint32_t) -1, &rows, &pMIds);
-+	if (ms == MAPI_E_TOO_COMPLEX && use_restriction && use_restriction->rt == RES_OR) {
-+		/* case lazy MS servers which do not want to search sertain properties in OR-s */
-+		gint ii;
-+		gboolean any_good = FALSE;
-+
-+		for (ii = 0; ii < use_restriction->res.resOr.cRes; ii++) {
-+			talloc_free (pMIds);
-+			talloc_free (rows);
-+			pMIds = NULL;
-+			rows = NULL;
-+
-+			ms = nspi_GetMatches (priv->session->nspi->ctx, mem_ctx, propTagArray,
-+				&use_restriction->res.resOr.lpRes[ii],
-+				(uint32_t) -1, &rows, &pMIds);
-+
-+			if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+				ms = MAPI_E_USER_CANCEL;
-+				goto cleanup;
-+			}
-+
-+			if (ms == MAPI_E_SUCCESS) {
-+				if (!rows)
-+					continue;
-+
-+				ms = foreach_gal_tablerow (conn, mem_ctx, rows, pMIds, propTagArray, list_objects_internal_cb, &loi_data, cancellable, perror);
-+				if (ms != MAPI_E_SUCCESS) {
-+					make_mapi_error (perror, "foreach_gal_tablerow", ms);
-+					goto cleanup;
-+				}
-+
-+				any_good = TRUE;
-+			} else if (ms != MAPI_E_NOT_FOUND && ms != MAPI_E_TOO_COMPLEX && ms != MAPI_E_TABLE_TOO_BIG) {
-+				break;
-+			}
-+		}
-+
-+		/* in case the last check fails, update based on the overall result */
-+		if (any_good) {
-+			ms = MAPI_E_SUCCESS;
-+			goto cleanup;
-+		} else {
-+			ms = MAPI_E_TOO_COMPLEX;
-+		}
-+	}
-+
-+	if (ms != MAPI_E_SUCCESS || !rows) {
-+		if (ms == MAPI_E_NOT_FOUND || (!rows && ms == MAPI_E_SUCCESS))
-+			ms = MAPI_E_SUCCESS;
-+		else if (ms == MAPI_E_TABLE_TOO_BIG)
-+			g_set_error (perror, E_MAPI_ERROR, MAPI_E_TABLE_TOO_BIG, _("Search result exceeded allowed size limit. Use more specific search term, please"));
-+		else if (ms != MAPI_E_SUCCESS)
-+			make_mapi_error (perror, "nspi_GetMatches", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	ms = foreach_gal_tablerow (conn, mem_ctx, rows, pMIds, propTagArray, list_objects_internal_cb, &loi_data, cancellable, perror);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "foreach_gal_tablerow", ms);
-+		goto cleanup;
-+	}
-+
-+ cleanup:
-+	talloc_free (pMIds);
-+	talloc_free (rows);
-+	talloc_free (propTagArray);
-+	talloc_free (mem_ctx);
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+struct TransferGALObjectData
-+{
-+	GHashTable *reverse_replace_hash;
-+	TransferObjectCB cb;
-+	gpointer cb_user_data;
-+};
-+
-+static gboolean
-+e_mapi_transfer_gal_objects_cb (EMapiConnection *conn,
-+				TALLOC_CTX *mem_ctx,
-+				struct SRow *srow,
-+				guint32 row_index,
-+				guint32 rows_total,
-+				gpointer user_data,
-+				GCancellable *cancellable,
-+				GError **perror)
-+{
-+	struct TransferGALObjectData *tgo = user_data;
-+	EMapiObject *object;
-+	uint32_t ii;
-+	gboolean res;
-+
-+	g_return_val_if_fail (conn != NULL, FALSE);
-+	g_return_val_if_fail (mem_ctx != NULL, FALSE);
-+	g_return_val_if_fail (srow != NULL, FALSE);
-+	g_return_val_if_fail (tgo != NULL, FALSE);
-+	g_return_val_if_fail (tgo->cb != NULL, FALSE);
-+
-+	object = e_mapi_object_new (mem_ctx);
-+
-+	res = TRUE;
-+
-+	for (ii = 0; ii < srow->cValues; ii++) {
-+		uint32_t proptag = srow->lpProps[ii].ulPropTag;
-+		gconstpointer propdata = get_SPropValue_data (&srow->lpProps[ii]);
-+
-+		if (!propdata || may_skip_property (srow->lpProps[ii].ulPropTag))
-+			continue;
-+
-+		/* reverse_replace_hash has them stored in opposite,
-+		   the key is the name-id-proptag as stored on the server,
-+		   the value is a pidlid/pidname proptag */
-+		maybe_replace_named_id_tag (&proptag, tgo->reverse_replace_hash);
-+
-+		if (!e_mapi_utils_add_property (&object->properties, proptag, propdata, object)) {
-+			res = FALSE;
-+			make_mapi_error (perror, "e_mapi_utils_add_property", MAPI_E_CALL_FAILED);
-+			break;
-+		}
-+	}
-+
-+	if (res)
-+		res = tgo->cb (conn, mem_ctx, object, row_index, rows_total, tgo->cb_user_data, cancellable, perror);
-+
-+	e_mapi_object_free (object);
-+
-+	return res;
-+}
-+
-+static void
-+fill_reverse_replace_hash (gpointer key,
-+			   gpointer value,
-+			   gpointer user_data)
-+{
-+	GHashTable *reverse_replace_hash = user_data;
-+
-+	g_return_if_fail (reverse_replace_hash != NULL);
-+
-+	g_hash_table_insert (reverse_replace_hash, value, key);
-+}
-+
-+gboolean
-+e_mapi_connection_transfer_gal_objects (EMapiConnection *conn,
-+					const GSList *mids,
-+					BuildReadPropsCB brp_cb,
-+					gpointer brp_cb_user_data,
-+					TransferObjectCB cb,
-+					gpointer cb_user_data,
-+					GCancellable *cancellable,
-+					GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	TALLOC_CTX *mem_ctx;
-+	struct PropertyTagArray_r *ids = NULL;
-+	struct SPropTagArray *propTagArray = NULL;
-+	struct PropertyRowSet_r rows;
-+	struct TransferGALObjectData tgo;
-+	GHashTable *reverse_replace_hash = NULL;
-+	EResolveNamedIDsData *named_ids_list = NULL;
-+	guint named_ids_len = 0, ii;
-+	const GSList *iter;
-+
-+	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 (priv->session->nspi != NULL, MAPI_E_UNCONFIGURED, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session->nspi->ctx != NULL, MAPI_E_UNCONFIGURED, FALSE);
-+	e_return_val_mapi_error_if_fail (cb != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	mem_ctx = talloc_new (priv->session);
-+
-+	for (iter = mids; iter; iter = iter->next) {
-+		mapi_id_t *pmid = iter->data;
-+
-+		if (pmid) {
-+			if (!ids) {
-+				ids = talloc_zero (mem_ctx, struct PropertyTagArray_r);
-+			}
-+			ids->cValues++;
-+			ids->aulPropTag = talloc_realloc (mem_ctx,
-+				ids->aulPropTag,
-+				uint32_t,
-+				ids->cValues + 1);
-+			ids->aulPropTag[ids->cValues - 1] = (uint32_t) (*pmid);
-+			ids->aulPropTag[ids->cValues] = 0;
-+		}
-+	}
-+
-+	if (!ids) {
-+		ms = MAPI_E_INVALID_PARAMETER;
-+		make_mapi_error (perror, "gather valid mids", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	if (brp_cb) {
-+		propTagArray = set_SPropTagArray (mem_ctx, 1, PidTagObjectType);
-+		if (!brp_cb (conn, mem_ctx, propTagArray, brp_cb_user_data, cancellable, perror)) {
-+			ms = MAPI_E_CALL_FAILED;
-+			make_mapi_error (perror, "brp_cb", ms);
-+			goto cleanup;
-+		}
-+	} else {
-+		if (!e_mapi_book_utils_get_supported_mapi_proptags (mem_ctx, &propTagArray) || !propTagArray) {
-+			ms = MAPI_E_CALL_FAILED;
-+			make_mapi_error (perror, "e_mapi_book_utils_get_supported_mapi_proptags", ms);
-+			goto cleanup;
-+		}
-+	}
-+
-+	for (ii = 0; ii < propTagArray->cValues; ii++) {
-+		maybe_add_named_id_tag (propTagArray->aulPropTag[ii], &named_ids_list, &named_ids_len);
-+	}
-+
-+	if (named_ids_list) {
-+		GHashTable *replace_hash;
-+
-+		/* use NULL for GAL as a folder ID parameter */
-+		if (!e_mapi_connection_resolve_named_props (conn, NULL, named_ids_list, named_ids_len, cancellable, perror)) {
-+			ms = MAPI_E_CALL_FAILED;
-+			make_mapi_error (perror, "e_mapi_connection_resolve_named_props", ms);
-+			goto cleanup;
-+		}
-+
-+		replace_hash = prepare_maybe_replace_hash (named_ids_list, named_ids_len, TRUE);
-+
-+		if (replace_hash) {
-+			guint prop_count = propTagArray->cValues, jj;
-+
-+			for (ii = 0, jj = 0; ii < prop_count; ii++) {
-+				uint32_t proptag = propTagArray->aulPropTag[ii];
-+
-+				maybe_replace_named_id_tag (&proptag, replace_hash);
-+
-+				propTagArray->aulPropTag[jj] = proptag;
-+
-+				if (proptag == MAPI_E_RESERVED || proptag == 0)
-+					propTagArray->cValues--;
-+				else
-+					jj++;
-+			}
-+
-+			if (jj < ii)
-+				propTagArray->aulPropTag[jj] = 0;
-+
-+			reverse_replace_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
-+
-+			g_hash_table_foreach (replace_hash, fill_reverse_replace_hash, reverse_replace_hash);
-+			g_hash_table_destroy (replace_hash);
-+		}
-+	}
-+
-+	/* fake rows, to start reading from the first mid */
-+	rows.cRows = 0;
-+	rows.aRow = NULL;
-+
-+	tgo.cb = cb;
-+	tgo.cb_user_data = cb_user_data;
-+	tgo.reverse_replace_hash = reverse_replace_hash;
-+
-+	ms = foreach_gal_tablerow (conn, mem_ctx, &rows, ids, propTagArray, e_mapi_transfer_gal_objects_cb, &tgo, cancellable, perror);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "foreach_gal_tablerow", ms);
-+		goto cleanup;
-+	}
-+
-+ cleanup:
-+	if (reverse_replace_hash)
-+		g_hash_table_destroy (reverse_replace_hash);
-+	talloc_free (propTagArray);
-+	talloc_free (ids);
-+	talloc_free (mem_ctx);
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_transfer_gal_object (EMapiConnection *conn,
-+				       mapi_id_t message_id,
-+				       TransferObjectCB cb,
-+				       gpointer cb_user_data,
-+				       GCancellable *cancellable,
-+				       GError **perror)
-+{
-+	GSList *mids;
-+	gboolean res;
-+
-+	mids = g_slist_append (NULL, &message_id);
-+	res = e_mapi_connection_transfer_gal_objects (conn, mids, NULL, NULL, cb, cb_user_data, cancellable, perror);
-+	g_slist_free (mids);
-+
-+	return res;
-+}
-+
-+gboolean
-+e_mapi_connection_create_folder (EMapiConnection *conn,
-+				 mapi_object_t *obj_parent_folder, /* in */
-+				 const gchar *name,
-+				 const gchar *new_folder_type, /* usually IPF_NOTE and similar */
-+				 mapi_id_t *new_fid, /* out */
-+				 GCancellable *cancellable,
-+				 GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	mapi_object_t obj_folder;
-+	struct SPropValue vals[1];
-+	mapi_id_t fid = 0;
-+
-+	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 (obj_parent_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (name != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (new_folder_type != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (new_fid != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	mapi_object_init (&obj_folder);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* Attempt to create the folder */
-+	ms = CreateFolder (obj_parent_folder, FOLDER_GENERIC, name, "Created using Evolution/LibMAPI", OPEN_IF_EXISTS | MAPI_UNICODE, &obj_folder);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "CreateFolder", ms);
-+		goto cleanup;
-+	}
-+
-+	vals[0].value.lpszW = new_folder_type;
-+	vals[0].ulPropTag = PidTagContainerClass;
-+
-+	ms = SetProps (&obj_folder, MAPI_PROPS_SKIP_NAMEDID_CHECK, vals, 1);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "SetProps", ms);
-+		goto cleanup;
-+	}
-+
-+	fid = mapi_object_get_id (&obj_folder);
-+	if (fid == 0) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "mapi_object_get_id", ms);
-+	} else {
-+		*new_fid = fid;
-+	}
-+
-+ cleanup:
-+	mapi_object_release (&obj_folder);
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_empty_folder (EMapiConnection *conn,
-+				mapi_object_t *obj_folder,
-+				GCancellable *cancellable,
-+				GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+
-+	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 (obj_folder, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* Empty the contents of the folder */
-+	ms = EmptyFolder (obj_folder);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "EmptyFolder", ms);
-+		goto cleanup;
-+	}
-+
-+ cleanup:
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static gboolean
-+add_parent_fid_prop_cb (EMapiConnection *conn,
-+			TALLOC_CTX *mem_ctx,
-+			struct SPropTagArray *props,
-+			gpointer data,
-+			GCancellable *cancellable,
-+			GError **perror)
-+{
-+	g_return_val_if_fail (mem_ctx != NULL, FALSE);
-+	g_return_val_if_fail (props != NULL, FALSE);
-+
-+	SPropTagArray_add (mem_ctx, props, PidTagParentFolderId);
-+
-+	return TRUE;
-+}
-+
-+static gboolean
-+read_parent_fid_prop_cb (EMapiConnection *conn,
-+			 TALLOC_CTX *mem_ctx,
-+			 /* const */ struct mapi_SPropValue_array *properties,
-+			 gpointer user_data,
-+			 GCancellable *cancellable,
-+			 GError **perror)
-+{
-+	mapi_id_t *pmid = user_data;
-+	const mapi_id_t *cmid;
-+
-+	g_return_val_if_fail (properties != NULL, FALSE);
-+	g_return_val_if_fail (pmid != NULL, FALSE);
-+
-+	cmid = e_mapi_util_find_array_propval (properties, PidTagParentFolderId);
-+	g_return_val_if_fail (cmid != NULL, FALSE);
-+
-+	*pmid = *cmid;
-+
-+	return TRUE;
-+}
-+
-+static gboolean
-+emc_open_folders (EMapiConnection *conn,
-+		  mapi_object_t *obj_store, /* in */
-+		  mapi_id_t child_fid,
-+		  mapi_object_t *obj_child_folder, /* out */
-+		  mapi_object_t *obj_parent_folder, /* out */
-+		  GCancellable *cancellable,
-+		  GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	mapi_id_t parent_fid = 0;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_store != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_child_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (obj_parent_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	mapi_object_init (obj_child_folder);
-+	mapi_object_init (obj_parent_folder);
-+
-+	ms = OpenFolder (obj_store, child_fid, obj_child_folder);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenFolder-1", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		mapi_object_release (obj_child_folder);
-+		mapi_object_init (obj_child_folder);
-+		goto cleanup;
-+	}
-+
-+	if (!e_mapi_connection_get_folder_properties (conn, obj_child_folder, add_parent_fid_prop_cb, NULL, read_parent_fid_prop_cb, &parent_fid, cancellable, perror) ||
-+	    parent_fid == 0) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "GetFolderProperties", ms);
-+		mapi_object_release (obj_child_folder);
-+		mapi_object_init (obj_child_folder);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		mapi_object_release (obj_child_folder);
-+		mapi_object_init (obj_child_folder);
-+		goto cleanup;
-+	}
-+
-+	ms = OpenFolder (obj_store, parent_fid, obj_parent_folder);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenFolder-2", ms);
-+		mapi_object_release (obj_child_folder);
-+		mapi_object_init (obj_child_folder);
-+		goto cleanup;
-+	}
-+
-+ cleanup:
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_remove_folder (EMapiConnection *conn,
-+				 mapi_object_t *obj_store, /* in, store, to which folder belongs */
-+				 mapi_id_t fid_to_remove,
-+				 GCancellable *cancellable,
-+				 GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	mapi_object_t obj_parent;
-+	mapi_object_t obj_folder;
-+	EMapiFolder *folder;
-+	GSList *l;
-+
-+	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 (obj_store != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (fid_to_remove != 0, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	e_mapi_debug_print("%s: Entering %s ", G_STRLOC, G_STRFUNC);
-+
-+	folder = NULL;
-+	for (l = e_mapi_connection_peek_folders_list (conn); l; l = l->next) {
-+		folder = l->data;
-+		if (folder && folder->folder_id == fid_to_remove)
-+			break;
-+		else
-+			folder = NULL;
-+	}
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	mapi_object_init (&obj_folder);
-+	mapi_object_init (&obj_parent);
-+
-+	if (!emc_open_folders (conn, obj_store, fid_to_remove, &obj_folder, &obj_parent, cancellable, perror)) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "emc_open_folders", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* Empty the contents of the folder */
-+	ms = EmptyFolder (&obj_folder);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "EmptyFolder", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* Call DeleteFolder on the folder to be removed */
-+	ms = DeleteFolder (&obj_parent, fid_to_remove, DEL_FOLDERS, NULL);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "DeleteFolder", ms);
-+		goto cleanup;
-+	}
-+
-+ cleanup:
-+	mapi_object_release (&obj_folder);
-+	mapi_object_release (&obj_parent);
-+
-+	if (folder) {
-+		g_rec_mutex_lock (&priv->folders_lock);
-+		priv->folders = g_slist_remove (priv->folders, folder);
-+		e_mapi_folder_free (folder);
-+		g_rec_mutex_unlock (&priv->folders_lock);
-+	}
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_rename_folder (EMapiConnection *conn,
-+				 mapi_object_t *obj_folder,
-+				 const gchar *new_name,
-+				 GCancellable *cancellable,
-+				 GError **perror)
-+{
-+	enum MAPISTATUS ms = MAPI_E_RESERVED;
-+	struct SPropValue *props = NULL;
-+	TALLOC_CTX *mem_ctx;
-+
-+	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 (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (new_name != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	e_mapi_debug_print ("%s: Entering %s ", G_STRLOC, G_STRFUNC);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	mem_ctx = talloc_new (priv->session);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	props = talloc_zero(mem_ctx, struct SPropValue);
-+	set_SPropValue_proptag (props, PidTagDisplayName, new_name);
-+
-+	ms = SetProps (obj_folder, MAPI_PROPS_SKIP_NAMEDID_CHECK, props, 1);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "SetProps", ms);
-+		goto cleanup;
-+	}
-+
-+ cleanup:
-+	talloc_free (mem_ctx);
-+	UNLOCK ();
-+
-+	e_mapi_debug_print ("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+/* moves folder 'src_fid' to folder 'des_fid' under name 'new_name' (no path in a new_name),
-+   'src_parent_fid' is folder ID of a parent of the src_fid */
-+gboolean
-+e_mapi_connection_move_folder  (EMapiConnection *conn,
-+				mapi_object_t *src_obj_folder,
-+				mapi_object_t *src_parent_obj_folder,
-+				mapi_object_t *des_obj_folder,
-+				const gchar *new_name,
-+				GCancellable *cancellable,
-+				GError **perror)
-+{
-+	enum MAPISTATUS ms = MAPI_E_RESERVED;
-+
-+	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 (src_obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (src_parent_obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (des_obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (new_name != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (strchr (new_name, '/') == NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+	} else {
-+		ms = MoveFolder (src_obj_folder, src_parent_obj_folder, des_obj_folder, (gchar *) new_name, TRUE);
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "MoveFolder", ms);
-+		}
-+	}
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+/* named_ids_list contains pointers to EResolveNamedIDsData structure;
-+   obj_folder NULL is reserved for lookup in GAL */
-+gboolean
-+e_mapi_connection_resolve_named_props  (EMapiConnection *conn,
-+					mapi_object_t *obj_folder,
-+					EResolveNamedIDsData *named_ids_list,
-+					guint named_ids_n_elems,
-+					GCancellable *cancellable,
-+					GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	TALLOC_CTX *mem_ctx;
-+	mapi_id_t fid;
-+	struct mapi_nameid *nameid;
-+	struct SPropTagArray *SPropTagArray;
-+	guint i, j;
-+	GPtrArray *todo = NULL;
-+	gboolean res = FALSE;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (named_ids_list != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (named_ids_n_elems > 0, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	e_mapi_debug_print ("%s: Entering %s ", G_STRLOC, G_STRFUNC);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	fid = 0;
-+	if (obj_folder)
-+		fid = mapi_object_get_id (obj_folder);
-+
-+	if (priv->named_ids) {
-+		gint64 i64 = fid;
-+		GHashTable *ids = g_hash_table_lookup (priv->named_ids, &i64);
-+
-+		if (ids) {
-+			for (i = 0; i < named_ids_n_elems; i++) {
-+				EResolveNamedIDsData *data = &named_ids_list[i];
-+				uint32_t propid;
-+
-+				propid = GPOINTER_TO_UINT (g_hash_table_lookup (ids, GUINT_TO_POINTER (data->pidlid_propid)));
-+				if (propid) {
-+					data->propid = propid;
-+				} else {
-+					if (!todo)
-+						todo = g_ptr_array_new ();
-+					g_ptr_array_add (todo, data);
-+				}
-+			}
-+
-+			if (!todo) {
-+				UNLOCK ();
-+				e_mapi_debug_print ("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
-+				return TRUE;
-+			}
-+		}
-+	}
-+
-+	mem_ctx = talloc_new (priv->session);
-+
-+	nameid = mapi_nameid_new (mem_ctx);
-+	SPropTagArray = talloc_zero (mem_ctx, struct SPropTagArray);
-+
-+	if (!obj_folder) {
-+		if (!priv->session->nspi || !priv->session->nspi->ctx) {
-+			ms = MAPI_E_UNCONFIGURED;
-+			goto cleanup;
-+		}
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	if (!todo) {
-+		todo = g_ptr_array_new ();
-+		for (i = 0; i < named_ids_n_elems; i++) {
-+			g_ptr_array_add (todo, &named_ids_list[i]);
-+		}
-+	}
-+
-+	for (i = 0; i < todo->len; i++) {
-+		EResolveNamedIDsData *data = todo->pdata[i];
-+
-+		if (mapi_nameid_canonical_add (nameid, data->pidlid_propid) != MAPI_E_SUCCESS)
-+			data->propid = MAPI_E_RESERVED;
-+		else
-+			data->propid = 0;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	if (obj_folder) {
-+		ms = mapi_nameid_GetIDsFromNames (nameid, obj_folder, SPropTagArray);
-+	} else {
-+		/* lookup in GAL */
-+		struct SPropTagArray *gal_tags;
-+		uint32_t prop_count = nameid->count;
-+		struct PropertyName_r *names = talloc_zero_array (mem_ctx, struct PropertyName_r, prop_count + 1);
-+
-+		g_assert (names != NULL);
-+
-+		SPropTagArray = talloc_zero (mem_ctx, struct SPropTagArray);
-+		g_assert (SPropTagArray != NULL);
-+
-+		SPropTagArray->cValues = nameid->count;
-+		SPropTagArray->aulPropTag = talloc_zero_array (mem_ctx, enum MAPITAGS, SPropTagArray->cValues + 1);
-+		g_assert (SPropTagArray->aulPropTag != NULL);
-+
-+		j = 0;
-+		for (i = 0; i < nameid->count; i++) {
-+			guint ab[16];
-+
-+			SPropTagArray->aulPropTag[i] = nameid->entries[i].proptag;
-+
-+			if (nameid->entries[i].ulKind == MNID_ID &&
-+			    16 == sscanf (nameid->entries[i].OLEGUID,
-+					"%02x%02x%02x%02x-"
-+					"%02x%02x-"
-+					"%02x%02x-"
-+					"%02x%02x-"
-+					"%02x%02x%02x%02x%02x%02x",
-+					&ab[0], &ab[1], &ab[2], &ab[3],
-+					&ab[4], &ab[5],
-+					&ab[6], &ab[7],
-+					&ab[8], &ab[9],
-+					&ab[10], &ab[11], &ab[12], &ab[13], &ab[14], &ab[15])) {
-+				gint k;
-+
-+				names[j].ulReserved = 0;
-+				names[j].lID = nameid->entries[i].lid;
-+				names[j].lpguid = talloc_zero (mem_ctx, struct FlatUID_r);
-+
-+				for (k = 0; k < 16; k++) {
-+					names[j].lpguid->ab[k] = (ab[k] & 0xFF);
-+				}
-+
-+				j++;
-+			} else {
-+				SPropTagArray->aulPropTag[i] = (SPropTagArray->aulPropTag[i] & (~0xFFFF)) | PT_ERROR;
-+				prop_count--;
-+			}
-+		}
-+
-+		if (prop_count > 0) {
-+			ms = nspi_GetIDsFromNames (priv->session->nspi->ctx, mem_ctx, 0, prop_count, names, &gal_tags);
-+			if (ms == MAPI_E_SUCCESS && gal_tags) {
-+				if (gal_tags->cValues != prop_count)
-+					g_warning ("%s: Requested (%d) and returned (%d) property names don't match", G_STRFUNC, prop_count, gal_tags->cValues);
-+
-+				j = 0;
-+				for (i = 0; i < gal_tags->cValues; i++) {
-+					while (j < SPropTagArray->cValues && (SPropTagArray->aulPropTag[j] & 0xFFFF) == PT_ERROR) {
-+						j++;
-+					}
-+
-+					if (j >= SPropTagArray->cValues)
-+						break;
-+
-+					SPropTagArray->aulPropTag[j] = gal_tags->aulPropTag[i];
-+				}
-+
-+				while (j < SPropTagArray->cValues) {
-+					SPropTagArray->aulPropTag[j] = (SPropTagArray->aulPropTag[j] & (~0xFFFF)) | PT_ERROR;
-+					j++;
-+				}
-+			}
-+
-+			/* 2010 server can return call_failed or no_support when didn't find any properties */
-+			if (ms == MAPI_E_CALL_FAILED || ms == MAPI_E_NO_SUPPORT)
-+				ms = MAPI_E_NOT_FOUND;
-+
-+			if (ms == MAPI_E_NOT_FOUND || ms == MAPI_E_SUCCESS) {
-+				for (j = 0; j < SPropTagArray->cValues; j++) {
-+					/* if not found then 0 is returned in the array */
-+					if (SPropTagArray->aulPropTag[j] != 0 &&
-+					    (SPropTagArray->aulPropTag[j] & 0xFFFF) != PT_ERROR)
-+						break;
-+				}
-+
-+				/* all of them failed to read, try the Contacts folder in hope
-+				   the named properties has the same numbers there as in GAL */
-+				if (j == SPropTagArray->cValues) {
-+					mapi_object_t obj_contacts;
-+
-+					if (e_mapi_connection_open_default_folder (conn, olFolderContacts, &obj_contacts, cancellable, NULL)) {
-+						/* always keep MAPI_E_NOT_FOUND, thus the later processing on the storing of saved items is skipped */
-+						e_mapi_connection_resolve_named_props (conn, &obj_contacts, named_ids_list, named_ids_n_elems, cancellable, NULL);
-+						e_mapi_connection_close_folder (conn, &obj_contacts, cancellable, NULL);
-+					}
-+				}
-+			}
-+		} else {
-+			ms = MAPI_E_NOT_FOUND;
-+		}
-+
-+		talloc_free (names);
-+	}
-+
-+	if (ms == MAPI_E_NOT_FOUND) {
-+		res = TRUE;
-+		goto cleanup;
-+	}
-+
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "mapi_nameid_GetIDsFromNames", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	for (i = 0, j = 0; i < SPropTagArray->cValues && j < todo->len; i++) {
-+		while (j < todo->len) {
-+			EResolveNamedIDsData *data = todo->pdata[j];
-+			if (data && data->propid == 0) {
-+				if ((SPropTagArray->aulPropTag[i] & 0xFFFF) == PT_ERROR)
-+					data->propid = MAPI_E_RESERVED;
-+				else
-+					data->propid = SPropTagArray->aulPropTag[i];
-+				break;
-+			}
-+
-+			j++;
-+		}
-+	}
-+
-+	if (priv->named_ids) {
-+		gint64 i64 = fid;
-+		GHashTable *ids = g_hash_table_lookup (priv->named_ids, &i64);
-+
-+		if (!ids) {
-+			gint64 *i64ptr = g_malloc (sizeof (gint64));
-+
-+			*i64ptr = fid;
-+			ids = g_hash_table_new (g_direct_hash, g_direct_equal);
-+
-+			g_hash_table_insert (priv->named_ids, i64ptr, ids);
-+		}
-+
-+		for (i = 0; i < todo->len; i++) {
-+			EResolveNamedIDsData *data = todo->pdata[i];
-+
-+			g_hash_table_insert (ids, GUINT_TO_POINTER (data->pidlid_propid), GUINT_TO_POINTER (data->propid));
-+		}
-+	}
-+
-+	res = TRUE;
-+
-+ cleanup:
-+	if (todo)
-+		g_ptr_array_free (todo, TRUE);
-+	talloc_free (mem_ctx);
-+
-+	UNLOCK ();
-+
-+	e_mapi_debug_print ("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
-+
-+	return res;
-+}
-+
-+/* returns MAPI_E_RESERVED on any error */
-+uint32_t
-+e_mapi_connection_resolve_named_prop (EMapiConnection *conn,
-+				      mapi_object_t *obj_folder,
-+				      uint32_t pidlid_propid,
-+				      GCancellable *cancellable,
-+				      GError **perror)
-+{
-+	EResolveNamedIDsData named_ids_list[1];
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, MAPI_E_RESERVED);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, MAPI_E_RESERVED);
-+
-+	named_ids_list[0].pidlid_propid = pidlid_propid;
-+	named_ids_list[0].propid = MAPI_E_RESERVED;
-+
-+	if (!e_mapi_connection_resolve_named_props (conn, obj_folder, named_ids_list, 1, cancellable, perror))
-+		return MAPI_E_RESERVED;
-+
-+	return named_ids_list[0].propid;
-+}
-+
-+/* returns named id, aka PidLid/PidName for a given proptag, which might be previously
-+   obtained as a result of e_mapi_connection_resolve_named_prop/s.
-+   Returns MAPI_E_RESERVED when not found.
-+*/
-+uint32_t
-+e_mapi_connection_unresolve_proptag_to_nameid (EMapiConnection *conn, mapi_id_t fid, uint32_t proptag)
-+{
-+	uint32_t res = MAPI_E_RESERVED;
-+	/* to have this used in the below macros */
-+	GError **perror = NULL;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, res);
-+
-+	if (priv->named_ids) {
-+		gint64 i64 = fid;
-+		GHashTable *ids = g_hash_table_lookup (priv->named_ids, &i64);
-+
-+		if (ids) {
-+			GHashTableIter iter;
-+			gpointer stored_pidlid, stored_proptag, lookup_proptag = GUINT_TO_POINTER (proptag);
-+			gboolean is_error = PT_ERROR == (proptag & 0xFFFF);
-+
-+			g_hash_table_iter_init (&iter, ids);
-+			while (g_hash_table_iter_next (&iter, &stored_pidlid, &stored_proptag)) {
-+				if (stored_proptag == lookup_proptag || (is_error && (GPOINTER_TO_UINT (stored_proptag) & ~0xFFFF) == (proptag & ~0xFFFF))) {
-+					res = GPOINTER_TO_UINT (stored_pidlid);
-+					break;
-+				}
-+			}
-+		}
-+	}
-+
-+	return res;
-+}
-+
-+mapi_id_t
-+e_mapi_connection_get_default_folder_id (EMapiConnection *conn,
-+					 uint32_t olFolder,
-+					 GCancellable *cancellable,
-+					 GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	mapi_id_t fid = 0;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, 0);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, 0);
-+
-+	e_mapi_debug_print("%s: Entering %s ", G_STRLOC, G_STRFUNC);
-+
-+	LOCK (cancellable, perror, 0);
-+
-+	ms = GetDefaultFolder (&priv->msg_store, &fid, olFolder);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetDefaultFolder", ms);
-+		goto cleanup;
-+	}
-+
-+ cleanup:
-+	UNLOCK ();
-+
-+	e_mapi_debug_print("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
-+
-+	return (ms == MAPI_E_SUCCESS ? fid : 0);
-+}
-+
-+gboolean
-+e_mapi_connection_set_flags (EMapiConnection *conn,
-+			     mapi_object_t *obj_folder,
-+			     GSList *mids,
-+			     uint32_t flag,
-+			     GCancellable *cancellable,
-+			     GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	TALLOC_CTX *mem_ctx;
-+	uint32_t i;
-+	mapi_id_t *id_messages;
-+	GSList *tmp = mids;
-+	gboolean result = FALSE;
-+
-+	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 (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	e_mapi_debug_print("%s: Entering %s ", G_STRLOC, G_STRFUNC);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	mem_ctx = talloc_new (priv->session);
-+
-+	id_messages = talloc_array (mem_ctx, mapi_id_t, g_slist_length (mids));
-+	for (i = 0; tmp; tmp = tmp->next, i++)
-+		id_messages[i] = *((mapi_id_t *)tmp->data);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	ms = SetReadFlags (obj_folder, flag, i, id_messages);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "SetReadFlags", ms);
-+		goto cleanup;
-+	}
-+
-+	result = TRUE;
-+
-+ cleanup:
-+	talloc_free (mem_ctx);
-+
-+	UNLOCK ();
-+
-+	e_mapi_debug_print("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
-+
-+	return result;
-+}
-+
-+gboolean
-+e_mapi_connection_copymove_items (EMapiConnection *conn,
-+				  mapi_object_t *src_obj_folder,
-+				  mapi_object_t *des_obj_folder,
-+				  gboolean do_copy,
-+				  GSList *mid_list,
-+				  GCancellable *cancellable,
-+				  GError **perror)
-+{
-+	enum MAPISTATUS	ms = MAPI_E_RESERVED;
-+	TALLOC_CTX *mem_ctx;
-+	GSList *l;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, MAPI_E_INVALID_PARAMETER);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, MAPI_E_INVALID_PARAMETER);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	mem_ctx = talloc_new (priv->session);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	while (mid_list) {
-+		mapi_id_array_t msg_id_array;
-+		gint count = 0;
-+
-+		mapi_id_array_init (mem_ctx, &msg_id_array);
-+
-+		for (l = mid_list; l != NULL && count < 500; l = g_slist_next (l), count++)
-+			mapi_id_array_add_id (&msg_id_array, *((mapi_id_t *)l->data));
-+
-+		mid_list = l;
-+
-+		ms = MoveCopyMessages (src_obj_folder, des_obj_folder, &msg_id_array, do_copy);
-+		mapi_id_array_release (&msg_id_array);
-+
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "MoveCopyMessages", ms);
-+			break;
-+		}
-+
-+		if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+			ms = MAPI_E_USER_CANCEL;
-+			break;
-+		}
-+	}
-+
-+ cleanup:
-+	talloc_free (mem_ctx);
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_remove_items (EMapiConnection *conn,
-+				mapi_object_t *obj_folder,
-+				const GSList *mids,
-+				GCancellable *cancellable,
-+				GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	TALLOC_CTX *mem_ctx;
-+	uint32_t i;
-+	mapi_id_t *id_messages;
-+	const GSList *tmp = mids;
-+	gboolean result = FALSE;
-+
-+	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 (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	e_mapi_debug_print("%s: Entering %s ", G_STRLOC, G_STRFUNC);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	mem_ctx = talloc_new (priv->session);
-+
-+	id_messages = talloc_array (mem_ctx, mapi_id_t, g_slist_length ((GSList *) mids));
-+	for (i = 0; tmp; tmp = tmp->next, i++) {
-+		mapi_id_t *data = tmp->data;
-+		id_messages[i] = *data;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* Delete the messages from the folder */
-+	ms = DeleteMessage (obj_folder, id_messages, i);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "DeleteMessage", ms);
-+		goto cleanup;
-+	}
-+
-+	result = TRUE;
-+
-+ cleanup:
-+	talloc_free(mem_ctx);
-+
-+	UNLOCK ();
-+
-+	e_mapi_debug_print("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
-+
-+	return result;
-+}
-+
-+struct GetFolderHierarchyCBData
-+{
-+	EMapiFolderCategory folder_hier;
-+	mapi_id_t folder_id;
-+	GSList **mapi_folders;
-+	ProgressNotifyCB cb;
-+	gpointer cb_user_data;
-+};
-+
-+static gboolean
-+get_folder_hierarchy_cb (EMapiConnection *conn,
-+			 TALLOC_CTX *mem_ctx,
-+			 struct SRow *srow,
-+			 guint32 row_index,
-+			 guint32 rows_total,
-+			 gpointer user_data,
-+			 GCancellable *cancellable,
-+			 GError **perror)
-+{
-+	struct GetFolderHierarchyCBData *gfh = user_data;
-+
-+	g_return_val_if_fail (gfh != NULL, FALSE);
-+
-+	if (srow) {
-+		EMapiFolder *folder = NULL;
-+		const mapi_id_t *fid = e_mapi_util_find_row_propval (srow, PR_FID);
-+		const mapi_id_t *pid = e_mapi_util_find_row_propval (srow, PR_PARENT_FID);
-+		const gchar *klass = e_mapi_util_find_row_propval (srow, PR_CONTAINER_CLASS);
-+		const gchar *name = e_mapi_util_find_row_propval (srow, PR_DISPLAY_NAME_UNICODE);
-+		const uint32_t *unread = e_mapi_util_find_row_propval (srow, PR_CONTENT_UNREAD);
-+		const uint32_t *total = e_mapi_util_find_row_propval (srow, PR_CONTENT_COUNT);
-+		const uint32_t *child = e_mapi_util_find_row_propval (srow, PR_FOLDER_CHILD_COUNT);
-+		const uint32_t *folder_size = e_mapi_util_find_row_propval (srow, PR_MESSAGE_SIZE);
-+
-+		if (!klass)
-+			klass = IPF_NOTE;
-+
-+		e_mapi_debug_print("|---+ %-15s : (Container class: %s %016" G_GINT64_MODIFIER "X) UnRead : %d Total : %d size : %d",
-+			name, klass, *fid, unread ? *unread : 0, total ? *total : 0, folder_size ? *folder_size : 0);
-+
-+		folder = e_mapi_folder_new (name, klass, gfh->folder_hier, *fid, pid ? *pid : gfh->folder_id,
-+						   child ? *child : 0, unread ? *unread : 0, total ? *total : 0);
-+
-+		folder->size = folder_size ? *folder_size : 0;
-+
-+		*gfh->mapi_folders = g_slist_prepend (*gfh->mapi_folders, folder);
-+	}
-+
-+	if (gfh->cb)
-+		return gfh->cb (conn, row_index, rows_total, gfh->cb_user_data, cancellable, perror);
-+
-+	return TRUE;
-+}
-+
-+static gboolean
-+get_child_folders (EMapiConnection *conn,
-+		   TALLOC_CTX *mem_ctx,
-+		   EMapiFolderCategory folder_hier,
-+		   mapi_object_t *parent,
-+		   mapi_id_t folder_id,
-+		   GSList **mapi_folders,
-+		   ProgressNotifyCB cb,
-+		   gpointer cb_user_data,
-+		   GCancellable *cancellable,
-+		   GError **perror)
-+{
-+	enum MAPISTATUS		ms;
-+	mapi_object_t		obj_folder;
-+	mapi_object_t		obj_table;
-+	struct SPropTagArray	*spropTagArray = NULL;
-+	uint32_t row_count = 0;
-+	struct GetFolderHierarchyCBData gfh;
-+
-+	/* sanity check */
-+	e_return_val_mapi_error_if_fail (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (parent != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	mapi_object_init (&obj_folder);
-+	mapi_object_init (&obj_table);
-+
-+	/* Attempt to open the folder */
-+	ms = OpenFolder (parent, folder_id, &obj_folder);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenFolder", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* Get the hierarchy table */
-+	ms = GetHierarchyTable (&obj_folder, &obj_table, TableFlags_Depth | TableFlags_NoNotifications, &row_count);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetHierarchyTable", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror) || !row_count) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	spropTagArray = set_SPropTagArray (mem_ctx, 8,
-+					   PR_FID,
-+					   PR_PARENT_FID,
-+					   PR_CONTAINER_CLASS,
-+					   PR_DISPLAY_NAME_UNICODE,
-+					   PR_CONTENT_UNREAD,
-+					   PR_CONTENT_COUNT,
-+					   PR_MESSAGE_SIZE,
-+					   PR_FOLDER_CHILD_COUNT);
-+
-+	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)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	gfh.folder_hier = folder_hier;
-+	gfh.folder_id = folder_id;
-+	gfh.mapi_folders = mapi_folders;
-+	gfh.cb = cb;
-+	gfh.cb_user_data = cb_user_data;
-+
-+	ms = foreach_tablerow (conn, mem_ctx, &obj_table, get_folder_hierarchy_cb, &gfh, cancellable, perror);
-+
-+ cleanup:
-+	talloc_free (spropTagArray);
-+	mapi_object_release (&obj_folder);
-+	mapi_object_release (&obj_table);
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+/* TODO : Find a right place for this.
-+ * The following are only defined in openchange fairly recently, so
-+ * we will conditionally define them here otherwise
-+ */
-+#ifndef PR_ADDITIONAL_REN_ENTRYIDS
-+	#define PR_ADDITIONAL_REN_ENTRYIDS    PROP_TAG(PT_MV_BINARY, 0x36D8)
-+#endif
-+#ifndef PidTagMailboxOwnerName
-+	#define PidTagMailboxOwnerName PR_USER_NAME_UNICODE
-+#endif
-+
-+/*NOTE : This should be called when you hold the connection lock*/
-+/*NOTE : IsMailboxFolder doesn't support this yet. */
-+/* Ticket : http://trac.openchange.org/ticket/134  */
-+static gboolean
-+mapi_get_ren_additional_fids (TALLOC_CTX *mem_ctx,
-+			      mapi_object_t *obj_store,
-+			      GHashTable **folder_list,
-+			      GCancellable *cancellable,
-+			      GError **perror)
-+{
-+	mapi_id_t inbox_id, fid;
-+	mapi_object_t obj_folder_inbox;
-+	struct SPropTagArray *SPropTagArray;
-+	struct SPropValue *lpProps = NULL;
-+	struct SRow aRow;
-+	const struct BinaryArray_r *entryids;
-+	struct Binary_r entryid;
-+	enum MAPISTATUS ms;
-+
-+	guint32 count, *folder_type;
-+	guint i = 0;
-+
-+	/*Note : Do not change the order.*/
-+	const guint32 olfolder_defaults[] = {
-+		olFolderConflicts,
-+		olFolderSyncIssues,
-+		olFolderLocalFailures,
-+		olFolderServerFailures,
-+		olFolderJunk
-+	};
-+
-+	mapi_object_init (&obj_folder_inbox);
-+
-+	/* Get Inbox FID using GetDefaultFolder. */
-+	ms = GetDefaultFolder (obj_store, &inbox_id, olFolderInbox);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetDefaultFolder", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* Open InboxFolder. */
-+	ms = OpenFolder (obj_store, inbox_id, &obj_folder_inbox);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "OpenFolder", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* GetProps on Inbox for PR_ADDITIONAL_REN_ENTRYIDS */
-+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_ADDITIONAL_REN_ENTRYIDS);
-+
-+	ms = GetProps (&obj_folder_inbox, MAPI_PROPS_SKIP_NAMEDID_CHECK | MAPI_UNICODE, SPropTagArray, &lpProps, &count);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetProps", ms);
-+		goto cleanup;
-+	} else if (!lpProps) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "GetProps", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* Build a SRow structure */
-+	aRow.ulAdrEntryPad = 0;
-+	aRow.cValues = count;
-+	aRow.lpProps = lpProps;
-+
-+	entryids = (const struct BinaryArray_r *) e_mapi_util_find_row_propval (&aRow, PR_ADDITIONAL_REN_ENTRYIDS);
-+
-+	/* Iterate through MV_BINARY */
-+	if (entryids) {
-+		for (i = 0; i < G_N_ELEMENTS (olfolder_defaults); i++) {
-+			fid = 0;
-+			entryid = entryids->lpbin [i];
-+			ms = GetFIDFromEntryID(entryid.cb, entryid.lpb, inbox_id, &fid);
-+
-+			if (ms == MAPI_E_SUCCESS && fid) {
-+				folder_type = g_new0 (guint32, 1);
-+				*folder_type = olfolder_defaults[i];
-+
-+				g_hash_table_insert (*folder_list,
-+						     e_mapi_util_mapi_id_to_string (fid),
-+						     folder_type);
-+			}
-+		}
-+	}
-+
-+ cleanup:
-+	mapi_object_release (&obj_folder_inbox);
-+	talloc_free (lpProps);
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static gboolean
-+set_default_folders (TALLOC_CTX *mem_ctx,
-+		     mapi_object_t *obj_store,
-+		     GSList **mapi_folders,
-+		     GCancellable *cancellable,
-+		     GError **perror)
-+{
-+	GSList *folder_list = *mapi_folders;
-+
-+	GHashTable *default_folders = g_hash_table_new_full (g_str_hash, g_str_equal,
-+							     g_free, g_free);
-+
-+	if (!mapi_get_ren_additional_fids (mem_ctx, obj_store, &default_folders, cancellable, perror)) {
-+		g_hash_table_destroy (default_folders);
-+		return FALSE;
-+	}
-+
-+	while (folder_list != NULL) {
-+		EMapiFolder *folder = NULL;
-+		guint32 default_type = 0;
-+		gchar *key_fid = NULL;
-+		gpointer value = NULL;
-+
-+		folder = folder_list->data;
-+		key_fid = e_mapi_util_mapi_id_to_string (folder->folder_id);
-+
-+		if ((value = g_hash_table_lookup (default_folders, key_fid)) != NULL)
-+			default_type = *(guint32 *)value;
-+		g_free (key_fid);
-+
-+		if (default_type != 0 || IsMailboxFolder (obj_store,folder->folder_id, &default_type)) {
-+			folder->is_default = TRUE; /* TODO : Clean up. Redundant.*/
-+			folder->default_type = default_type;
-+		}
-+
-+		folder_list = g_slist_next (folder_list);
-+	}
-+
-+	g_hash_table_destroy (default_folders);
-+
-+	return TRUE;
-+}
-+
-+static void
-+set_owner_name (gpointer data, gpointer user_data)
-+{
-+	EMapiFolder *folder = (EMapiFolder *)(data);
-+	folder->owner_name = g_strdup (user_data);
-+}
-+
-+static void
-+set_user_name (gpointer data, gpointer user_data)
-+{
-+	EMapiFolder *folder = (EMapiFolder *)(data);
-+	folder->user_name = g_strdup (user_data);
-+}
-+
-+gboolean
-+e_mapi_connection_get_folders_list (EMapiConnection *conn,
-+				    GSList **mapi_folders,
-+				    ProgressNotifyCB cb,
-+				    gpointer cb_user_data,
-+				    GCancellable *cancellable,
-+				    GError **perror)
-+{
-+	enum MAPISTATUS	ms;
-+	TALLOC_CTX		*mem_ctx;
-+	struct SPropTagArray	*SPropTagArray = NULL;
-+	struct SPropValue	*lpProps = NULL;
-+	struct SRow		aRow;
-+	gboolean		result = FALSE;
-+	mapi_id_t		mailbox_id;
-+	EMapiFolder	*folder;
-+	uint32_t		count = 0;
-+	const gchar		*mailbox_name = NULL;
-+	const gchar		*mailbox_owner_name = NULL;
-+	const gchar		*mailbox_user_name = NULL;
-+	const uint32_t          *mailbox_size = NULL;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	e_mapi_debug_print("%s: Entering %s ", G_STRLOC, G_STRFUNC);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	mem_ctx = talloc_new (priv->session);
-+
-+	/* Build the array of Mailbox properties we want to fetch */
-+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x4,
-+					  PR_DISPLAY_NAME_UNICODE,
-+					  PR_MAILBOX_OWNER_NAME_UNICODE,
-+					  PR_MESSAGE_SIZE,
-+					  PidTagMailboxOwnerName);
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	ms = GetProps (&priv->msg_store, MAPI_PROPS_SKIP_NAMEDID_CHECK | MAPI_UNICODE, SPropTagArray, &lpProps, &count);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetProps", ms);
-+		goto cleanup;
-+	} else if (!lpProps) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "GetProps", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* Build a SRow structure */
-+	aRow.ulAdrEntryPad = 0;
-+	aRow.cValues = count;
-+	aRow.lpProps = lpProps;
-+
-+	/* betting that these will never fail */
-+	mailbox_name = (const gchar *) e_mapi_util_find_row_propval (&aRow, PR_DISPLAY_NAME_UNICODE);
-+	mailbox_owner_name = (const gchar *) e_mapi_util_find_row_propval (&aRow, PR_MAILBOX_OWNER_NAME_UNICODE);
-+	mailbox_user_name = (const gchar *) e_mapi_util_find_row_propval (&aRow, PidTagMailboxOwnerName);
-+	mailbox_size = (const uint32_t *)e_mapi_util_find_row_propval  (&aRow, PR_MESSAGE_SIZE);
-+
-+	/* Prepare the directory listing */
-+	ms = GetDefaultFolder (&priv->msg_store, &mailbox_id, olFolderTopInformationStore);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetDefaultFolder", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	/* FIXME: May have to get the child folders count? Do we need/use it? */
-+	folder = e_mapi_folder_new (mailbox_name, IPF_NOTE,
-+					   E_MAPI_FOLDER_CATEGORY_PERSONAL, mailbox_id, 0, 0, 0 ,0);
-+	folder->is_default = TRUE;
-+	folder->default_type = olFolderTopInformationStore; /*Is this correct ?*/
-+	folder->size = mailbox_size ? *mailbox_size : 0;
-+
-+	*mapi_folders = g_slist_prepend (*mapi_folders, folder);
-+
-+	/* FIXME: check status of get_child_folders */
-+	result = get_child_folders (conn, mem_ctx, E_MAPI_FOLDER_CATEGORY_PERSONAL, &priv->msg_store, mailbox_id, mapi_folders, cb, cb_user_data, cancellable, perror);
-+
-+	*mapi_folders = g_slist_reverse (*mapi_folders);
-+
-+	if (result && !set_default_folders (mem_ctx, &priv->msg_store, mapi_folders, cancellable, perror)) {
-+		goto cleanup;
-+	}
-+
-+	g_slist_foreach (*mapi_folders, (GFunc) set_owner_name, (gpointer) mailbox_owner_name);
-+	g_slist_foreach (*mapi_folders, (GFunc) set_user_name, (gpointer) mailbox_user_name);
-+
-+ cleanup:
-+	talloc_free (SPropTagArray);
-+	talloc_free (lpProps);
-+	talloc_free (mem_ctx);
-+
-+	UNLOCK ();
-+
-+	e_mapi_debug_print("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
-+
-+	return result;
-+}
-+
-+gboolean
-+e_mapi_connection_get_pf_folders_list (EMapiConnection *conn,
-+				       GSList **mapi_folders,
-+				       ProgressNotifyCB cb,
-+				       gpointer cb_user_data,
-+				       GCancellable *cancellable,
-+				       GError **perror)
-+{
-+	enum MAPISTATUS		ms;
-+	TALLOC_CTX		*mem_ctx;
-+	gboolean		result = FALSE;
-+	mapi_id_t		mailbox_id;
-+	EMapiFolder	*folder;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	e_mapi_debug_print("%s: Entering %s ", G_STRLOC, G_STRFUNC);
-+
-+	LOCK (cancellable, perror, FALSE);
-+	mem_ctx = talloc_new (priv->session);
-+
-+	if (!ensure_public_store (priv, perror))
-+		goto cleanup;
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	ms = GetDefaultPublicFolder (&priv->public_store, &mailbox_id, olFolderPublicIPMSubtree);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "GetDefaultPublicFolder", ms);
-+		goto cleanup;
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+		goto cleanup;
-+	}
-+
-+	folder = e_mapi_folder_new (_("All Public Folders"), IPF_NOTE, 0, mailbox_id, 0, 0, 0, 0);
-+	folder->is_default = TRUE;
-+	folder->default_type = olPublicFoldersAllPublicFolders;
-+	*mapi_folders = g_slist_prepend (*mapi_folders, folder);
-+	result = get_child_folders (conn, mem_ctx, E_MAPI_FOLDER_CATEGORY_PUBLIC, &priv->public_store, mailbox_id, mapi_folders, cb, cb_user_data, cancellable, perror);
-+	*mapi_folders = g_slist_reverse (*mapi_folders);
-+
-+ cleanup:
-+	talloc_free (mem_ctx);
-+
-+	UNLOCK ();
-+
-+	e_mapi_debug_print("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
-+
-+	return result;
-+}
-+
-+GSList *
-+e_mapi_connection_peek_folders_list (EMapiConnection *conn)
-+{
-+	/* to have this used in the below macros */
-+	GError **perror = NULL;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, NULL);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, NULL);
-+
-+	g_rec_mutex_lock (&priv->folders_lock);
-+
-+	if (!priv->folders) {
-+		LOCK (NULL, NULL, NULL);
-+		e_mapi_connection_get_folders_list (conn, &priv->folders, NULL, NULL, NULL, perror);
-+		UNLOCK ();
-+	}
-+
-+	g_rec_mutex_unlock (&priv->folders_lock);
-+
-+	return priv->folders;
-+}
-+
-+/* free returned pointer with g_free() */
-+gchar *
-+e_mapi_connection_ex_to_smtp (EMapiConnection *conn,
-+			      const gchar *ex_address,
-+			      gchar **display_name,
-+			      GCancellable *cancellable,
-+			      GError **perror)
-+{
-+	enum MAPISTATUS	ms;
-+	TALLOC_CTX		*mem_ctx;
-+	struct SPropTagArray	*SPropTagArray;
-+	struct PropertyRowSet_r *rowSet = NULL;
-+	struct PropertyTagArray_r *flaglist = NULL;
-+	const gchar		*str_array[2];
-+	gchar			*smtp_addr = 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_return_val_mapi_error_if_fail (ex_address != NULL, MAPI_E_INVALID_PARAMETER, NULL);
-+
-+	str_array[0] = ex_address;
-+	str_array[1] = NULL;
-+
-+	LOCK (cancellable, perror, NULL);
-+
-+	mem_ctx = talloc_new (priv->session);
-+
-+	SPropTagArray = set_SPropTagArray (mem_ctx, 0x2,
-+					  PR_DISPLAY_NAME_UNICODE,
-+					  PR_SMTP_ADDRESS_UNICODE);
-+
-+	ms = ResolveNames (priv->session, (const gchar **) str_array, SPropTagArray, &rowSet, &flaglist, MAPI_UNICODE);
-+	if (ms != MAPI_E_SUCCESS) {
-+		talloc_free (rowSet);
-+		talloc_free (flaglist);
-+
-+		rowSet = NULL;
-+		flaglist = NULL;
-+
-+		ms = ResolveNames (priv->session, (const gchar **)str_array, SPropTagArray, &rowSet, &flaglist, 0);
-+	}
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+		ms = MAPI_E_USER_CANCEL;
-+	}
-+
-+	if (ms == MAPI_E_SUCCESS && rowSet && rowSet->cRows == 1) {
-+		smtp_addr = g_strdup (e_mapi_util_find_propertyrow_propval (rowSet->aRow, PR_SMTP_ADDRESS_UNICODE));
-+		if (display_name)
-+			*display_name = g_strdup (e_mapi_util_find_propertyrow_propval (rowSet->aRow, PR_DISPLAY_NAME_UNICODE));
-+	}
-+
-+	talloc_free (rowSet);
-+	talloc_free (flaglist);
-+	talloc_free (mem_ctx);
-+
-+	UNLOCK ();
-+
-+	if (ms != MAPI_E_SUCCESS)
-+		make_mapi_error (perror, "ResolveNames", ms);
-+
-+	return smtp_addr;
-+}
-+
-+gboolean
-+e_mapi_connection_resolve_username (EMapiConnection *conn,
-+				    const gchar *to_resolve,
-+				    BuildReadPropsCB brp_cb,
-+				    gpointer brp_cb_user_data,
-+				    GetPropertiesCB cb,
-+				    gpointer cb_user_data,
-+				    GCancellable *cancellable,
-+				    GError **perror)
-+{
-+	enum MAPISTATUS ms;
-+	TALLOC_CTX *mem_ctx;
-+	struct SPropTagArray *tag_array;
-+	struct PropertyRowSet_r *rows = NULL;
-+	struct PropertyTagArray_r *flaglist = NULL;
-+	const gchar *str_array[2];
-+	EResolveNamedIDsData *named_ids_list = NULL;
-+	guint named_ids_len = 0, ii, jj, qq;
-+
-+	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 (to_resolve != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+	e_return_val_mapi_error_if_fail (cb != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	str_array[0] = to_resolve;
-+	str_array[1] = NULL;
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	mem_ctx = talloc_new (priv->session);
-+
-+	tag_array = set_SPropTagArray (mem_ctx, 3,
-+		PidTagEntryId,
-+		PidTagDisplayName,
-+		PidTagSmtpAddress);
-+
-+	ms = MAPI_E_SUCCESS;
-+	if (brp_cb != NULL && !brp_cb (conn, mem_ctx, tag_array, brp_cb_user_data, cancellable, perror)) {
-+		ms = MAPI_E_CALL_FAILED;
-+		make_mapi_error (perror, "build_read_props_callback", ms);
-+	}
-+
-+	if (ms == MAPI_E_SUCCESS) {
-+		for (ii = 0; ii < tag_array->cValues; ii++) {
-+			uint32_t proptag = tag_array->aulPropTag[ii];
-+
-+			if (may_skip_property (proptag)) {
-+				const gchar *name = get_proptag_name (proptag);
-+				if (!name)
-+					name = "";
-+
-+				g_debug ("%s: Cannot fetch property 0x%08x %s", G_STRFUNC, proptag, name);
-+			} else {
-+				maybe_add_named_id_tag (proptag, &named_ids_list, &named_ids_len);
-+			}
-+		}
-+
-+		if (named_ids_list) {
-+			GHashTable *replace_hash;
-+
-+			if (!e_mapi_connection_resolve_named_props (conn, NULL, named_ids_list, named_ids_len, cancellable, perror)) {
-+				goto cleanup;
-+			}
-+
-+			if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+				goto cleanup;
-+			}
-+
-+			replace_hash = prepare_maybe_replace_hash (named_ids_list, named_ids_len, TRUE);
-+			if (replace_hash) {
-+				for (ii = 0; ii < tag_array->cValues; ii++) {
-+					uint32_t proptag = tag_array->aulPropTag[ii];
-+
-+					maybe_replace_named_id_tag (&proptag, replace_hash);
-+
-+					tag_array->aulPropTag[ii] = proptag;
-+				}
-+
-+				g_hash_table_destroy (replace_hash);
-+				replace_hash = NULL;
-+			}
-+		}
-+
-+		ms = ResolveNames (priv->session, str_array, tag_array, &rows, &flaglist, MAPI_UNICODE);
-+		if (ms != MAPI_E_SUCCESS && ms != MAPI_E_USER_CANCEL) {
-+			if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
-+				ms = MAPI_E_USER_CANCEL;
-+			} else {
-+				talloc_free (rows);
-+				talloc_free (flaglist);
-+
-+				rows = NULL;
-+				flaglist = NULL;
-+
-+				ms = ResolveNames (priv->session, str_array, tag_array, &rows, &flaglist, 0);
-+			}
-+		}
-+
-+		if (ms != MAPI_E_SUCCESS) {
-+			make_mapi_error (perror, "ResolveNames", ms);
-+			goto cleanup;
-+		}
-+	}
-+
-+	if (ms == MAPI_E_SUCCESS && rows) {
-+		GHashTable *replace_hash = NULL;
-+
-+		if (named_ids_list)
-+			replace_hash = prepare_maybe_replace_hash (named_ids_list, named_ids_len, FALSE);
-+
-+		for (qq = 0; qq < rows->cRows; qq++) {
-+			struct mapi_SPropValue_array *properties;
-+			struct SRow *row;
-+
-+			row = talloc_zero (mem_ctx, struct SRow);
-+			if (!row) {
-+				UNLOCK();
-+				e_return_val_mapi_error_if_fail (properties != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+			}
-+
-+			cast_PropertyRow_to_SRow (mem_ctx, &rows->aRow[qq], row);
-+
-+			properties = talloc_zero (mem_ctx, struct mapi_SPropValue_array);
-+			if (!properties) {
-+				UNLOCK();
-+				talloc_free (row);
-+				e_return_val_mapi_error_if_fail (properties != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+			}
-+
-+			/* Conversion from SPropValue to mapi_SPropValue. (no padding here) */
-+			properties->cValues = row->cValues;
-+			properties->lpProps = talloc_zero_array (mem_ctx, struct mapi_SPropValue, properties->cValues + 1);
-+			for (ii = 0, jj = 0; ii < row->cValues; ii++, jj++) {
-+				if (may_skip_property (row->lpProps[ii].ulPropTag)) {
-+					jj--;
-+					properties->cValues--;
-+				} else {
-+					uint32_t proptag = row->lpProps[ii].ulPropTag;
-+
-+					maybe_replace_named_id_tag (&proptag, replace_hash);
-+					row->lpProps[ii].ulPropTag = proptag;
-+
-+					cast_mapi_SPropValue (mem_ctx, &properties->lpProps[jj], &row->lpProps[ii]);
-+				}
-+			}
-+
-+			if (!cb (conn, mem_ctx, properties, cb_user_data, cancellable, perror)) {
-+				ms = MAPI_E_CALL_FAILED;
-+				make_mapi_error (perror, "callback", ms);
-+				talloc_free (properties);
-+				talloc_free (row);
-+				break;
-+			}
-+
-+			talloc_free (properties);
-+			talloc_free (row);
-+		}
-+
-+		if (replace_hash)
-+			g_hash_table_destroy (replace_hash);
-+	} else if (ms == MAPI_E_SUCCESS) {
-+		if (flaglist && flaglist->aulPropTag[0] == MAPI_AMBIGUOUS) {
-+			ms = MAPI_E_AMBIGUOUS_RECIP;
-+			g_set_error (perror, E_MAPI_ERROR, ms, _("User name '%s' is ambiguous"), to_resolve);
-+		} else {
-+			ms = MAPI_E_NOT_FOUND;
-+			g_set_error (perror, E_MAPI_ERROR, ms, _("User name '%s' not found"), to_resolve);
-+		}
-+	}
-+
-+ cleanup:
-+	g_free (named_ids_list);
-+	talloc_free (rows);
-+	talloc_free (flaglist);
-+	talloc_free (mem_ctx);
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+static gint
-+emit_server_notification_signal (uint16_t event_type, gpointer event_data, gpointer user_data)
-+{
-+	EMapiConnection *conn = user_data;
-+	guint uint_event_type = event_type;
-+
-+	g_signal_emit (conn, signals[SERVER_NOTIFICATION], 0, uint_event_type, event_data);
-+
-+	return MAPI_E_SUCCESS;
-+}
-+
-+static gpointer
-+e_mapi_connection_notification_thread (gpointer user_data)
-+{
-+	EMapiConnection *conn = user_data;
-+	EMapiConnectionPrivate *priv;
-+
-+	g_return_val_if_fail (conn != NULL, NULL);
-+	g_return_val_if_fail (conn->priv != NULL, NULL);
-+	g_return_val_if_fail (conn->priv->session != NULL, NULL);
-+
-+	priv = conn->priv;
-+
-+	while (g_hash_table_size (priv->known_notifications) > 0) {
-+		gint64 end_time;
-+
-+		LOCK (NULL, NULL, NULL);
-+		/* this returns MAPI_E_INVALID_PARAMETER when there
-+		   is no pending notification
-+		*/
-+		DispatchNotifications (priv->session);
-+		UNLOCK ();
-+
-+		/* poll not so often */
-+		end_time = g_get_monotonic_time () + (G_TIME_SPAN_SECOND * priv->notification_poll_seconds);
-+
-+		e_flag_clear (priv->notification_flag);
-+		e_flag_wait_until (priv->notification_flag, end_time);
-+	}
-+
-+	return NULL;
-+}
-+
-+/* enables server notifications on a folder, or on a whole store, if obj_folder is NULL.
-+   the event_mask can be 0 to obtain all notifications;
-+   Pair function for this is e_mapi_connection_disable_notifications().
-+   The notification is received to the caller with the "server-notification" signal.
-+   Note that the signal is used for each notification, without distinction on the enable
-+   object.
-+*/
-+gboolean
-+e_mapi_connection_enable_notifications (EMapiConnection *conn,
-+					mapi_object_t *obj_folder,
-+					uint32_t event_mask,
-+					GCancellable *cancellable,
-+					GError **perror)
-+{
-+	enum MAPISTATUS	ms;
-+	mapi_id_t fid = 0;
-+	uint32_t conn_id;
-+	gint64 i64;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	if (event_mask == 0)
-+		event_mask = fnevNewMail |
-+			     fnevObjectCreated |
-+			     fnevObjectDeleted |
-+			     fnevObjectModified |
-+			     fnevObjectMoved;
-+
-+	if (obj_folder)
-+		fid = mapi_object_get_id (obj_folder);
-+
-+	i64 = (gint64) fid;
-+	conn_id = GPOINTER_TO_UINT (g_hash_table_lookup (priv->known_notifications, &i64));
-+	if (conn_id) {
-+		stop_notification (priv, conn_id, cancellable, perror);
-+		g_hash_table_remove (priv->known_notifications, &i64);
-+	}
-+
-+	if (priv->register_notification_result == MAPI_E_RESERVED)
-+		priv->register_notification_result = RegisterNotification (priv->session);
-+
-+	if (priv->register_notification_result != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "RegisterNotification", priv->register_notification_result);
-+		UNLOCK ();
-+
-+		return FALSE;
-+	}
-+
-+	conn_id = 0;
-+	ms = Subscribe (obj_folder ? obj_folder : &priv->msg_store, &conn_id, event_mask, obj_folder == NULL, emit_server_notification_signal, conn);
-+	if (ms == MAPI_E_SUCCESS) {
-+		gint64 *pi64;
-+
-+		pi64 = g_new0 (gint64, 1);
-+		*pi64 = i64;
-+
-+		g_hash_table_insert (priv->known_notifications, pi64, GUINT_TO_POINTER (conn_id));
-+
-+		if (priv->notification_thread) {
-+			e_flag_set (priv->notification_flag);
-+		} else {
-+			priv->notification_thread = g_thread_new (NULL, e_mapi_connection_notification_thread, conn);
-+		}
-+	} else {
-+		make_mapi_error (perror, "Subscribe", ms);
-+	}
-+
-+	UNLOCK ();
-+
-+	return ms == MAPI_E_SUCCESS;
-+}
-+
-+gboolean
-+e_mapi_connection_disable_notifications	(EMapiConnection *conn,
-+					 mapi_object_t *obj_folder,
-+					 GCancellable *cancellable,
-+					 GError **perror)
-+{
-+	mapi_id_t fid = 0;
-+	uint32_t conn_id;
-+	gint64 i64;
-+
-+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
-+	e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	LOCK (cancellable, perror, FALSE);
-+
-+	if (!priv->notification_thread) {
-+		/* no notifications started, just return */
-+		UNLOCK ();
-+
-+		return TRUE;
-+	}
-+
-+	if (priv->register_notification_result != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "RegisterNotification", priv->register_notification_result);
-+		UNLOCK ();
-+
-+		return FALSE;
-+	}
-+
-+	if (obj_folder)
-+		fid = mapi_object_get_id (obj_folder);
-+
-+	i64 = (gint64) fid;
-+	conn_id = GPOINTER_TO_UINT (g_hash_table_lookup (priv->known_notifications, &i64));
-+	if (conn_id) {
-+		gboolean stopped = stop_notification (priv, conn_id, cancellable, perror);
-+		g_hash_table_remove (priv->known_notifications, &i64);
-+
-+		if (!stopped) {
-+			UNLOCK ();
-+			return FALSE;
-+		}
-+	} else {
-+		make_mapi_error (perror, "e_mapi_connection_disable_notifications", MAPI_E_NOT_FOUND);
-+		UNLOCK ();
-+
-+		return FALSE;
-+	}
-+
-+	if (g_hash_table_size (priv->known_notifications) == 0) {
-+		stop_all_notifications (priv);
-+	}
-+
-+	UNLOCK ();
-+
-+	return TRUE;
-+}
-+
-+/* profile related functions - begin */
-+
-+struct tcp_data
-+{
-+	ESourceRegistry *registry;
-+	struct mapi_context *mapi_ctx;
-+	const gchar *profname;
-+	const gchar *password;
-+	GCancellable *cancellable;
-+	GError **perror;
-+
-+	EFlag *eflag;
-+	gboolean has_profile;
-+};
-+
-+static gboolean
-+try_create_profile_main_thread_cb (struct tcp_data *data)
-+{
-+	EMapiProfileData empd = { 0 };
-+	GList *all_sources;
-+	ESource *source;
-+
-+	g_return_val_if_fail (data != NULL, FALSE);
-+	if (!data->registry) {
-+		e_flag_set (data->eflag);
-+		return FALSE;
-+	}
-+
-+	all_sources = e_source_registry_list_sources (data->registry, NULL);
-+	source = e_mapi_utils_get_master_source (all_sources, data->profname);
-+
-+	if (source) {
-+		ESourceCamel *extension;
-+		CamelSettings *settings;
-+		const gchar *extension_name;
-+		CamelNetworkSettings *network_settings;
-+
-+		extension_name = e_source_camel_get_extension_name ("mapi");
-+		extension = e_source_get_extension (source, extension_name);
-+		settings = e_source_camel_get_settings (extension);
-+
-+		network_settings = CAMEL_NETWORK_SETTINGS (settings);
-+
-+		empd.server = camel_network_settings_get_host (network_settings);
-+		empd.username = camel_network_settings_get_user (network_settings);
-+		e_mapi_util_profiledata_from_settings (&empd, CAMEL_MAPI_SETTINGS (settings));
-+
-+		if (data->password)
-+			empd.password = g_string_new (data->password);
-+		else
-+			data->password = NULL;
-+
-+		if (COMPLETE_PROFILEDATA (&empd)) {
-+			gchar *profname = e_mapi_util_profile_name (data->mapi_ctx, &empd, FALSE);
-+
-+			if (profname && g_str_equal (profname, data->profname)) {
-+				/* do not use locking here, because when this is called then other thread is holding the lock */
-+				data->has_profile = mapi_profile_create (data->mapi_ctx, &empd, NULL, NULL, NULL, data->perror, FALSE);
-+			}
-+
-+			g_free (profname);
-+		}
-+
-+		if (empd.password) {
-+			if (empd.password->len)
-+				memset (empd.password->str, 0, empd.password->len);
-+			g_string_free (empd.password, TRUE);
-+		}
-+	}
-+
-+	g_list_free_full (all_sources, g_object_unref);
-+
-+	e_flag_set (data->eflag);
-+
-+	return FALSE;
-+}
-+
-+static gboolean
-+try_create_profile (ESourceRegistry *registry,
-+		    struct mapi_context *mapi_ctx,
-+		    const gchar *profname,
-+		    const gchar *password,
-+		    GCancellable *cancellable,
-+		    GError **perror)
-+{
-+	struct tcp_data data;
-+
-+	g_return_val_if_fail (mapi_ctx != NULL, FALSE);
-+	g_return_val_if_fail (profname != NULL, FALSE);
-+	g_return_val_if_fail (*profname != 0, FALSE);
-+
-+	data.registry = registry;
-+	data.mapi_ctx = mapi_ctx;
-+	data.profname = profname;
-+	data.password = password;
-+	data.eflag = e_flag_new ();
-+	data.has_profile = FALSE;
-+	data.cancellable = cancellable;
-+	data.perror = perror;
-+
-+	if (!g_main_context_is_owner (g_main_context_default ())) {
-+		/* function called from other than main thread */
-+		g_timeout_add (10, (GSourceFunc) try_create_profile_main_thread_cb, &data);
-+		e_flag_wait (data.eflag);
-+	} else {
-+		try_create_profile_main_thread_cb (&data);
-+	}
-+
-+	e_flag_free (data.eflag);
-+
-+	return data.has_profile;
-+}
-+
-+static struct mapi_session *
-+mapi_profile_load (ESourceRegistry *registry,
-+		   struct mapi_context *mapi_ctx,
-+		   const gchar *profname,
-+		   const gchar *password,
-+		   GCancellable *cancellable,
-+		   GError **perror)
-+{
-+	enum MAPISTATUS	ms = MAPI_E_SUCCESS;
-+	struct mapi_session *session = NULL;
-+	struct mapi_profile *profile;
-+
-+	e_return_val_mapi_error_if_fail (mapi_ctx != NULL, MAPI_E_INVALID_PARAMETER, NULL);
-+	e_return_val_mapi_error_if_fail (profname != NULL, MAPI_E_INVALID_PARAMETER, NULL);
-+
-+	if (!e_mapi_utils_global_lock (cancellable, perror))
-+		return NULL;
-+
-+	e_mapi_debug_print("%s: Entering %s ", G_STRLOC, G_STRFUNC);
-+
-+	profile = talloc_zero (mapi_ctx, struct mapi_profile);
-+	if (MAPI_E_SUCCESS == OpenProfile (mapi_ctx, profile, profname, NULL)) {
-+		if (!can_reach_mapi_server (profile->server, cancellable, perror)) {
-+			ShutDown (profile);
-+			goto cleanup;
-+		}
-+
-+		ShutDown (profile);
-+	}
-+
-+	e_mapi_debug_print("Loading profile %s ", profname);
-+
-+	ms = MapiLogonEx (mapi_ctx, &session, profname, password);
-+	if (ms == MAPI_E_NOT_FOUND && try_create_profile (registry, mapi_ctx, profname, password, cancellable, perror))
-+		ms = MapiLogonEx (mapi_ctx, &session, profname, password);
-+
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "MapiLogonEx", ms);
-+		goto cleanup;
-+	}
-+
-+ cleanup:
-+	talloc_free (profile);
-+	e_mapi_utils_global_unlock ();
-+	e_mapi_debug_print ("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
-+
-+	return session;
-+}
-+
-+static int
-+create_profile_fallback_callback (struct PropertyRowSet_r *rowset,
-+				  gconstpointer data)
-+{
-+	guint32	ii;
-+	const gchar *username = (const gchar *) data;
-+
-+	/* If we can find the exact username, then find & return its index. */
-+	for (ii = 0; ii < rowset->cRows; ii++) {
-+		const gchar *account_name;
-+
-+		account_name = e_mapi_util_find_propertyrow_propval (&(rowset->aRow[ii]), PR_ACCOUNT_UNICODE);
-+
-+		if (account_name && g_strcmp0 (username, account_name) == 0)
-+			return ii;
-+	}
-+
-+	/* cancel it, do authenticate again */
-+	return rowset->cRows + 1;
-+}
-+
-+static gboolean
-+mapi_profile_create (struct mapi_context *mapi_ctx,
-+		     const EMapiProfileData *empd,
-+		     mapi_profile_callback_t callback, gconstpointer data,
-+		     GCancellable *cancellable,
-+		     GError **perror,
-+		     gboolean use_locking)
-+{
-+	enum MAPISTATUS	ms;
-+	gboolean result = FALSE;
-+	const gchar *workstation = "localhost";
-+	gchar *profname = NULL;
-+	struct mapi_session *session = NULL;
-+
-+	e_return_val_mapi_error_if_fail (mapi_ctx != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	if (!callback) {
-+		callback = create_profile_fallback_callback;
-+		data = (gpointer) empd->username;
-+	}
-+
-+	/*We need all the params before proceeding.*/
-+	e_return_val_mapi_error_if_fail (COMPLETE_PROFILEDATA (empd) && (empd->krb_sso || (empd->password && empd->password->len)),
-+					 MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	if (!can_reach_mapi_server (empd->server, cancellable, perror))
-+		return FALSE;
-+
-+	if (use_locking) {
-+		if (!e_mapi_utils_global_lock (cancellable, perror))
-+			return FALSE;
-+	}
-+
-+	e_mapi_debug_print ("Create profile with %s %s %s\n", empd->username,
-+		 empd->domain, empd->server);
-+
-+	profname = e_mapi_util_profile_name (mapi_ctx, empd, TRUE);
-+
-+	/* Delete any existing profiles with the same profilename */
-+	ms = DeleteProfile (mapi_ctx, profname);
-+	/* don't bother to check error - it would be valid if we got an error */
-+
-+	ms = CreateProfile (mapi_ctx, profname, empd->username,
-+			    empd->krb_sso ? NULL : empd->password->str, OC_PROFILE_NOPASSWORD);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "CreateProfile", ms);
-+		goto cleanup;
-+	}
-+
-+	#define add_string_attr(_prof,_aname,_val)				\
-+		mapi_profile_add_string_attr (mapi_ctx, _prof, _aname, _val)
-+
-+	add_string_attr (profname, "binding", empd->server);
-+	add_string_attr (profname, "workstation", workstation);
-+	add_string_attr (profname, "kerberos", empd->krb_sso ? "yes" : "no");
-+
-+	/* note: domain and realm are intentially not added to
-+	 *       the libmapi profile in the case of SSO enabled,
-+	 *       as it changes the behavior, and breaks SSO support. */
-+	if (!empd->krb_sso) {
-+		add_string_attr (profname, "domain", empd->domain);
-+	}
-+
-+	if (empd->use_ssl)
-+		add_string_attr (profname, "seal", "true");
-+
-+	/* This is only convenient here and should be replaced at some point */
-+	add_string_attr (profname, "codepage", "1252");
-+	add_string_attr (profname, "language", "1033");
-+	add_string_attr (profname, "method", "1033");
-+
-+	#undef add_string_attr
-+
-+	/* Login now */
-+	e_mapi_debug_print("Logging into the server... ");
-+	ms = MapiLogonProvider (mapi_ctx, &session, profname, empd->krb_sso ? NULL : empd->password->str,
-+				PROVIDER_ID_NSPI);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "MapiLogonProvider", ms);
-+		e_mapi_debug_print ("Deleting profile %s ", profname);
-+		DeleteProfile (mapi_ctx, profname);
-+		goto cleanup;
-+	}
-+	e_mapi_debug_print("MapiLogonProvider : succeeded \n");
-+
-+	if (g_cancellable_set_error_if_cancelled (cancellable, perror))
-+		goto cleanup;
-+
-+	ms = ProcessNetworkProfile (session, empd->username, callback, data);
-+	if (ms != MAPI_E_SUCCESS) {
-+		make_mapi_error (perror, "ProcessNetworkProfile", ms);
-+		e_mapi_debug_print ("Deleting profile %s ", profname);
-+		DeleteProfile (mapi_ctx, profname);
-+		goto cleanup;
-+	}
-+	e_mapi_debug_print("ProcessNetworkProfile : succeeded \n");
-+
-+	result = TRUE;
-+
-+ cleanup:
-+	g_free (profname);
-+
-+	/* this is causing segfault in openchange */
-+	/*if (session && result) {
-+		mapi_object_t msg_store;
-+
-+		mapi_object_init (&msg_store);
-+
-+		ms = OpenMsgStore (session, &msg_store);
-+		if (ms == MAPI_E_SUCCESS) {
-+			Logoff (&msg_store);
-+		} else {
-+			/ * how to close and free session without store? * /
-+			make_mapi_error (perror, "OpenMsgStore", ms);
-+		}
-+
-+		mapi_object_release (&msg_store);
-+	}*/
-+
-+	if (use_locking)
-+		e_mapi_utils_global_unlock ();
-+
-+	return result;
-+}
-+
-+gboolean
-+e_mapi_create_profile (struct mapi_context *mapi_ctx,
-+		       EMapiProfileData *empd,
-+		       mapi_profile_callback_t callback,
-+		       gconstpointer data,
-+		       GCancellable *cancellable,
-+		       GError **perror)
-+{
-+	return mapi_profile_create (mapi_ctx, empd, callback, data, cancellable, perror, TRUE);
-+}
-+
-+gboolean
-+e_mapi_delete_profile (struct mapi_context *mapi_ctx,
-+		       const gchar *profile,
-+		       GError **perror)
-+{
-+	gboolean result = FALSE;
-+	enum MAPISTATUS ms;
-+
-+	e_return_val_mapi_error_if_fail (mapi_ctx != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
-+
-+	if (!e_mapi_utils_global_lock (NULL, perror))
-+		return FALSE;
-+
-+	e_mapi_debug_print ("Deleting profile %s ", profile);
-+
-+	ms = DeleteProfile (mapi_ctx, profile);
-+	if (ms == MAPI_E_SUCCESS || ms == MAPI_E_NOT_FOUND) {
-+		result = TRUE;
-+	} else {
-+		make_mapi_error (perror, "DeleteProfile", ms);
-+	}
-+
-+	e_mapi_utils_global_unlock ();
-+
-+	return result;
-+}
-+
-+void
-+e_mapi_rename_profile (struct mapi_context *mapi_ctx,
-+		       const gchar *old_name,
-+		       const gchar *new_name,
-+		       GError **perror)
-+{
-+	g_return_if_fail (mapi_ctx != NULL);
-+	g_return_if_fail (old_name != NULL);
-+	g_return_if_fail (new_name != NULL);
-+
-+	/* do not use locking here, it's called with a lock held already */
-+	/* if (!e_mapi_utils_global_lock (NULL, perror))
-+		return; */
-+
-+	RenameProfile (mapi_ctx, old_name, new_name);
-+
-+	/* e_mapi_utils_global_unlock (); */
-+}
-+
-+/* profile related functions - end */
-+
-+EMapiRecipient *
-+e_mapi_recipient_new (TALLOC_CTX *mem_ctx)
-+{
-+	EMapiRecipient *recipient;
-+
-+	recipient = talloc_zero (mem_ctx, EMapiRecipient);
-+	g_assert (recipient != NULL);
-+
-+	recipient->properties.cValues = 0;
-+	recipient->properties.lpProps = talloc_zero_array (mem_ctx, struct mapi_SPropValue, 1);
-+	recipient->next = NULL;
-+
-+	g_assert (recipient->properties.lpProps != NULL);
-+
-+	return recipient;
-+}
-+
-+void
-+e_mapi_recipient_free (EMapiRecipient *recipient)
-+{
-+	if (!recipient)
-+		return;
-+
-+	talloc_free (recipient->properties.lpProps);
-+	talloc_free (recipient);
-+}
-+
-+EMapiAttachment *
-+e_mapi_attachment_new (TALLOC_CTX *mem_ctx)
-+{
-+	EMapiAttachment *attachment;
-+
-+	attachment = talloc_zero (mem_ctx, EMapiAttachment);
-+	g_assert (attachment != NULL);
-+
-+	attachment->properties.cValues = 0;
-+	attachment->properties.lpProps = talloc_zero_array (mem_ctx, struct mapi_SPropValue, 1);
-+	attachment->streamed_properties = NULL;
-+	attachment->streamed_properties_count = 0;
-+	attachment->embedded_object = NULL;
-+	attachment->next = NULL;
-+
-+	g_assert (attachment->properties.lpProps != NULL);
-+
-+	return attachment;
-+}
-+
-+void
-+e_mapi_attachment_free (EMapiAttachment *attachment)
-+{
-+	if (!attachment)
-+		return;
-+
-+	e_mapi_object_free (attachment->embedded_object);
-+	talloc_free (attachment->properties.lpProps);
-+	talloc_free (attachment->streamed_properties);
-+	talloc_free (attachment);
-+}
-+
-+void
-+e_mapi_attachment_add_streamed (EMapiAttachment *attachment,
-+				uint32_t proptag,
-+				uint64_t cb,
-+				const uint8_t *lpb)
-+{
-+	guint32 index;
-+
-+	g_return_if_fail (attachment != NULL);
-+	g_return_if_fail (proptag != 0);
-+	g_return_if_fail (e_mapi_attachment_get_streamed (attachment, proptag) == NULL);
-+
-+	attachment->streamed_properties = talloc_realloc (attachment,
-+		attachment->streamed_properties,
-+		EMapiStreamedProp,
-+		attachment->streamed_properties_count + 1);
-+	g_return_if_fail (attachment->streamed_properties != NULL);
-+
-+	index = attachment->streamed_properties_count;
-+	attachment->streamed_properties_count++;
-+	attachment->streamed_properties[index].proptag = proptag;
-+	attachment->streamed_properties[index].cb = cb;
-+	attachment->streamed_properties[index].lpb = lpb;
-+	attachment->streamed_properties[index].orig_value = lpb;
-+}
-+
-+EMapiStreamedProp *
-+e_mapi_attachment_get_streamed (EMapiAttachment *attachment,
-+				uint32_t proptag)
-+{
-+	guint32 ii;
-+
-+	g_return_val_if_fail (attachment != NULL, NULL);
-+
-+	if (!attachment->streamed_properties_count || !attachment->streamed_properties)
-+		return NULL;
-+
-+	for (ii = 0; ii < attachment->streamed_properties_count; ii++) {
-+		if (attachment->streamed_properties[ii].proptag == proptag)
-+			return &attachment->streamed_properties[ii];
-+	}
-+
-+	return NULL;
-+}
-+
-+gboolean
-+e_mapi_attachment_get_bin_prop (EMapiAttachment *attachment,
-+				uint32_t proptag,
-+				uint64_t *cb,
-+				const uint8_t **lpb)
-+{
-+	EMapiStreamedProp *streamed;
-+	const struct SBinary_short *bin;
-+
-+	g_return_val_if_fail (attachment != NULL, FALSE);
-+	g_return_val_if_fail (cb != NULL, FALSE);
-+	g_return_val_if_fail (lpb != NULL, FALSE);
-+
-+	*cb = 0;
-+	*lpb = NULL;
-+
-+	streamed = e_mapi_attachment_get_streamed (attachment, proptag);
-+	if (streamed) {
-+		*cb = streamed->cb;
-+		*lpb = streamed->lpb;
-+
-+		return TRUE;
-+	}
-+
-+	bin = e_mapi_util_find_array_propval (&attachment->properties, proptag);
-+	if (bin) {
-+		*cb = bin->cb;
-+		*lpb = bin->lpb;
-+
-+		return TRUE;
-+	}
-+
-+	return FALSE;
-+}
-+
-+gboolean
-+e_mapi_attachment_contains_prop (EMapiAttachment *attachment,
-+				 uint32_t proptag)
-+{
-+	g_return_val_if_fail (attachment != NULL, FALSE);
-+
-+	return e_mapi_attachment_get_streamed (attachment, proptag) != NULL ||
-+	       e_mapi_util_find_array_propval (&attachment->properties, proptag) != NULL;
-+}
-+
-+EMapiObject *
-+e_mapi_object_new (TALLOC_CTX *mem_ctx)
-+{
-+	EMapiObject *object;
-+
-+	object = talloc_zero (mem_ctx, EMapiObject);
-+	g_assert (object != NULL);
-+
-+	object->properties.cValues = 0;
-+	object->properties.lpProps = talloc_zero_array (mem_ctx, struct mapi_SPropValue, 1);
-+	object->streamed_properties = NULL;
-+	object->streamed_properties_count = 0;
-+	object->recipients = NULL;
-+	object->attachments = NULL;
-+	object->parent = NULL;
-+
-+	g_assert (object->properties.lpProps != NULL);
-+
-+	return object;
-+}
-+
-+void
-+e_mapi_object_free (EMapiObject *object)
-+{
-+	EMapiRecipient *recipient;
-+	EMapiAttachment *attachment;
-+
-+	if (!object)
-+		return;
-+
-+	recipient = object->recipients;
-+	while (recipient) {
-+		EMapiRecipient *r = recipient;
-+
-+		recipient = recipient->next;
-+		e_mapi_recipient_free (r);
-+	}
-+
-+	attachment = object->attachments;
-+	while (attachment) {
-+		EMapiAttachment *a = attachment;
-+
-+		attachment = attachment->next;
-+		e_mapi_attachment_free (a);
-+	}
-+
-+	talloc_free (object->streamed_properties);
-+	talloc_free (object->properties.lpProps);
-+	talloc_free (object);
-+}
-+
-+void
-+e_mapi_object_add_recipient (EMapiObject *object,
-+			     EMapiRecipient *recipient)
-+{
-+	g_return_if_fail (object != NULL);
-+	g_return_if_fail (recipient != NULL);
-+	g_return_if_fail (recipient->next == NULL);
-+
-+	if (!object->recipients) {
-+		object->recipients = recipient;
-+	} else {
-+		EMapiRecipient *recip = object->recipients;
-+
-+		while (recip->next) {
-+			recip = recip->next;
-+		}
-+
-+		recip->next = recipient;
-+	}
-+}
-+
-+void
-+e_mapi_object_add_attachment (EMapiObject *object,
-+			      EMapiAttachment *attachment)
-+{
-+	g_return_if_fail (object != NULL);
-+	g_return_if_fail (attachment != NULL);
-+	g_return_if_fail (attachment->next == NULL);
-+
-+	if (!object->attachments) {
-+		object->attachments = attachment;
-+	} else {
-+		EMapiAttachment *attach = object->attachments;
-+
-+		while (attach->next) {
-+			attach = attach->next;
-+		}
-+
-+		attach->next = attachment;
-+	}
-+}
-+
-+void
-+e_mapi_object_add_streamed (EMapiObject *object,
-+			    uint32_t proptag,
-+			    uint64_t cb,
-+			    const uint8_t *lpb)
-+{
-+	guint32 index;
-+
-+	g_return_if_fail (object != NULL);
-+	g_return_if_fail (proptag != 0);
-+	g_return_if_fail (e_mapi_object_get_streamed (object, proptag) == NULL);
-+
-+	object->streamed_properties = talloc_realloc (object,
-+		object->streamed_properties,
-+		EMapiStreamedProp,
-+		object->streamed_properties_count + 1);
-+	g_return_if_fail (object->streamed_properties != NULL);
-+
-+	index = object->streamed_properties_count;
-+	object->streamed_properties_count++;
-+	object->streamed_properties[index].proptag = proptag;
-+	object->streamed_properties[index].cb = cb;
-+	object->streamed_properties[index].lpb = lpb;
-+	object->streamed_properties[index].orig_value = lpb;
-+}
-+
-+EMapiStreamedProp *
-+e_mapi_object_get_streamed (EMapiObject *object,
-+			    uint32_t proptag)
-+{
-+	guint32 ii;
-+
-+	g_return_val_if_fail (object != NULL, NULL);
-+
-+	if (!object->streamed_properties_count || !object->streamed_properties)
-+		return NULL;
-+
-+	for (ii = 0; ii < object->streamed_properties_count; ii++) {
-+		if (object->streamed_properties[ii].proptag == proptag)
-+			return &object->streamed_properties[ii];
-+	}
-+
-+	return NULL;
-+}
-+
-+gboolean
-+e_mapi_object_get_bin_prop (EMapiObject *object,
-+			    uint32_t proptag,
-+			    uint64_t *cb,
-+			    const uint8_t **lpb)
-+{
-+	EMapiStreamedProp *streamed;
-+	gconstpointer value;
-+
-+	g_return_val_if_fail (object != NULL, FALSE);
-+	g_return_val_if_fail (cb != NULL, FALSE);
-+	g_return_val_if_fail (lpb != NULL, FALSE);
-+
-+	*cb = 0;
-+	*lpb = NULL;
-+
-+	streamed = e_mapi_object_get_streamed (object, proptag);
-+	if (streamed) {
-+		*cb = streamed->cb;
-+		*lpb = streamed->lpb;
-+
-+		return TRUE;
-+	}
-+
-+	value = e_mapi_util_find_array_propval (&object->properties, proptag);
-+	if (value) {
-+		if ((proptag & 0xFFFF) == PT_BINARY) {
-+			const struct SBinary_short *bin = value;
-+
-+			*cb = bin->cb;
-+			*lpb = bin->lpb;
-+
-+			return TRUE;
-+		}
-+
-+		if ((proptag & 0xFFFF) == PT_STRING8 ||
-+		    (proptag & 0xFFFF) == PT_UNICODE) {
-+			*cb = strlen (value);
-+			*lpb = value;
-+
-+			return TRUE;
-+		}
-+	}
-+
-+	return FALSE;
-+}
-+
-+gboolean
-+e_mapi_object_contains_prop (EMapiObject *object,
-+			     uint32_t proptag)
-+{
-+	g_return_val_if_fail (object != NULL, FALSE);
-+
-+	return e_mapi_object_get_streamed (object, proptag) != NULL ||
-+	       e_mapi_util_find_array_propval (&object->properties, proptag) != NULL;
-+}
-+
-+EMapiPermissionEntry *
-+e_mapi_permission_entry_new (const gchar *username,
-+			     const struct SBinary_short *entry_id,
-+			     uint64_t member_id,
-+			     uint32_t member_rights)
-+{
-+	EMapiPermissionEntry *entry;
-+
-+	entry = g_new0 (EMapiPermissionEntry, 1);
-+	entry->username = g_strdup (username);
-+
-+	if (entry_id && entry_id->lpb) {
-+		entry->entry_id.cb = entry_id->cb;
-+		entry->entry_id.lpb = g_memdup (entry_id->lpb, entry_id->cb);
-+	} else {
-+		entry->entry_id.cb = 0;
-+		entry->entry_id.lpb = NULL;
-+	}
-+
-+	entry->member_id = member_id;
-+	entry->member_rights = member_rights;
-+
-+	return entry;
-+}
-+
-+void
-+e_mapi_permission_entry_free (EMapiPermissionEntry *entry)
-+{
-+	if (!entry)
-+		return;
-+
-+	g_free (entry->username);
-+	g_free (entry->entry_id.lpb);
-+	g_free (entry);
-+}
 Index: evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-defs.h
 ===================================================================
---- evolution-mapi-3.8.5.orig/src/libexchangemapi/e-mapi-defs.h	2013-09-08 02:06:59.026196227 +0200
-+++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-defs.h	2013-09-08 02:06:59.022196179 +0200
+--- evolution-mapi-3.8.5.orig/src/libexchangemapi/e-mapi-defs.h	2013-09-08 02:35:40.223726352 +0200
++++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-defs.h	2013-09-08 02:35:40.219726301 +0200
 @@ -76,6 +76,43 @@
      MeetInfoUpdate = 0x0409
  } IconIndex;
@@ -8222,8 +479,8 @@
  #define IPM_APPOINTMENT				"IPM.Appointment"
 Index: evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-utils.c
 ===================================================================
---- evolution-mapi-3.8.5.orig/src/libexchangemapi/e-mapi-utils.c	2013-09-08 02:06:59.026196227 +0200
-+++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-utils.c	2013-09-08 02:06:59.022196179 +0200
+--- evolution-mapi-3.8.5.orig/src/libexchangemapi/e-mapi-utils.c	2013-09-08 02:35:40.223726352 +0200
++++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-utils.c	2013-09-08 02:35:40.219726301 +0200
 @@ -269,30 +269,6 @@
  	return (find_SPropValue_data(aRow, proptag));
  }
@@ -8257,8 +514,8 @@
   *
 Index: evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-utils.h
 ===================================================================
---- evolution-mapi-3.8.5.orig/src/libexchangemapi/e-mapi-utils.h	2013-09-08 02:06:59.026196227 +0200
-+++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-utils.h	2013-09-08 02:06:59.022196179 +0200
+--- evolution-mapi-3.8.5.orig/src/libexchangemapi/e-mapi-utils.h	2013-09-08 02:35:40.223726352 +0200
++++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-utils.h	2013-09-08 02:35:40.219726301 +0200
 @@ -53,8 +53,6 @@
  gconstpointer	e_mapi_util_find_SPropVal_array_propval	(struct SPropValue *values, uint32_t proptag);
  gconstpointer	e_mapi_util_find_row_propval		(struct SRow *aRow,




More information about the pkg-evolution-commits mailing list