[evolution-mapi] Use EMapiObject API for writing in book and calendar



commit ea303b4f6a5878115b24b9cac5c88085cb2c0253
Author: Milan Crha <mcrha redhat com>
Date:   Tue Dec 13 19:19:07 2011 +0100

    Use EMapiObject API for writing in book and calendar

 src/addressbook/e-book-backend-mapi-contacts.c |  233 +++----
 src/calendar/e-cal-backend-mapi.c              |  177 ++----
 src/libexchangemapi/e-mapi-cal-recur-utils.c   |   25 +-
 src/libexchangemapi/e-mapi-cal-recur-utils.h   |   12 +-
 src/libexchangemapi/e-mapi-cal-tz-utils.c      |   10 +-
 src/libexchangemapi/e-mapi-cal-tz-utils.h      |    4 +-
 src/libexchangemapi/e-mapi-cal-utils.c         |  932 +++++++++++++++++++++++-
 src/libexchangemapi/e-mapi-cal-utils.h         |    8 +-
 src/libexchangemapi/e-mapi-connection.c        |   13 +-
 src/libexchangemapi/e-mapi-connection.h        |    2 +-
 src/libexchangemapi/e-mapi-mail-utils.c        |   81 +--
 src/libexchangemapi/e-mapi-utils.c             |    5 +
 12 files changed, 1180 insertions(+), 322 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-mapi-contacts.c b/src/addressbook/e-book-backend-mapi-contacts.c
index 8017276..a757a32 100644
--- a/src/addressbook/e-book-backend-mapi-contacts.c
+++ b/src/addressbook/e-book-backend-mapi-contacts.c
@@ -130,59 +130,27 @@ cmp_member_id (gconstpointer a, gconstpointer b, gpointer ht)
 typedef struct {
 	EContact *contact;
 	EBookBackendSqliteDB *db;
-} MapiCreateitemData;
+} EMapiCreateitemData;
 
 static gboolean
-mapi_book_write_props (EMapiConnection *conn,
-		       mapi_id_t fid,
-		       TALLOC_CTX *mem_ctx,
-		       struct SPropValue **values,
-		       uint32_t *n_values,
-		       gpointer data,
-		       GCancellable *cancellable,
-		       GError **perror)
+ebbm_contact_to_object (EMapiConnection *conn,
+			TALLOC_CTX *mem_ctx,
+			EMapiObject **pobject, /* out */
+			gpointer user_data,
+			GCancellable *cancellable,
+			GError **perror)
 {
-	/* Do not make this array static, below function modifies it.
-	   The array is used to just ensure named ids are known later. */
-	ResolveNamedIDsData nids[] = {
-		{ PidLidDistributionListName, 0 },
-		{ PidLidDistributionListOneOffMembers, 0 },
-		{ PidLidDistributionListMembers, 0 },
-		{ PidLidDistributionListChecksum, 0 },
-		{ PidLidFileUnder, 0 },
-		{ PidLidFileUnderId, 0 },
-		{ PidLidEmail1OriginalDisplayName, 0 },
-		{ PidLidEmail1EmailAddress, 0 },
-		{ PidLidEmail2EmailAddress, 0 },
-		{ PidLidEmail3EmailAddress, 0 },
-		{ PidLidHtml, 0 },
-		{ PidLidInstantMessagingAddress, 0 },
-		{ PidLidHomeAddress, 0 },
-		{ PidLidWorkAddress, 0 },
-		{ PidLidEmail2OriginalDisplayName, 0 },
-		{ PidLidEmail3OriginalDisplayName, 0 }
-	};
-
-	MapiCreateitemData *mcd = data;
-
-	#define set_str_value(hex, val) G_STMT_START { \
-		if (!e_mapi_utils_add_spropvalue (mem_ctx, values, n_values, hex, val ? val : "")) \
-			return FALSE;	\
-		} G_STMT_END
+	EMapiCreateitemData *mcd = user_data;
+	EMapiObject *object;
 
-	#define set_str_named_value(named_id, val) G_STMT_START { \
-		if (!e_mapi_utils_add_spropvalue_namedid (conn, fid, mem_ctx, values, n_values, named_id, val ? val : "", cancellable, perror)) \
+	#define set_value(hex, val) G_STMT_START { \
+		if (!e_mapi_utils_add_property (&object->properties, hex, val, object)) \
 			return FALSE;	\
 		} G_STMT_END
 
-	#define set_str_con_value(hex, field_id) G_STMT_START { \
-		if (e_contact_get (mcd->contact, field_id)) { \
-			set_str_value (hex, e_contact_get (mcd->contact, field_id)); \
-		} } G_STMT_END
-
-	#define set_str_named_con_value(named_id, field_id) G_STMT_START { \
+	#define set_con_value(hex, field_id) G_STMT_START { \
 		if (e_contact_get (mcd->contact, field_id)) { \
-			set_str_named_value (named_id, e_contact_get (mcd->contact, field_id)); \
+			set_value (hex, e_contact_get (mcd->contact, field_id)); \
 		} } G_STMT_END
 
 	g_return_val_if_fail (mcd != NULL, FALSE);
@@ -190,18 +158,17 @@ mapi_book_write_props (EMapiConnection *conn,
 	g_return_val_if_fail (mcd->db != NULL, FALSE);
 	g_return_val_if_fail (conn != NULL, FALSE);
 	g_return_val_if_fail (mem_ctx != NULL, FALSE);
-	g_return_val_if_fail (values != NULL, FALSE);
-	g_return_val_if_fail (n_values != NULL, FALSE);
+	g_return_val_if_fail (pobject != NULL, FALSE);
 
-	if (!e_mapi_connection_resolve_named_props (conn, fid, nids, G_N_ELEMENTS (nids), cancellable, perror))
-		return FALSE;
+	object = e_mapi_object_new (mem_ctx);
+	*pobject = object;
 
 	if (GPOINTER_TO_INT (e_contact_get (mcd->contact, E_CONTACT_IS_LIST))) {
 		const gchar *uid = NULL;
 		EContact *old_contact = NULL;
 		GList *local, *l;
 		struct BinaryArray_r *members, *oneoff_members;
-		uint32_t list_size = 0, u32, crc32 = 0;
+		uint32_t u32, crc32 = 0;
 		GHashTable *member_values = NULL, *member_ids = NULL;
 		GError *error = NULL;
 
@@ -240,14 +207,13 @@ mapi_book_write_props (EMapiConnection *conn,
 		if (error)
 			g_error_free (error);
 
-		set_str_value (PR_MESSAGE_CLASS, IPM_DISTLIST);
+		set_value (PidTagMessageClass, IPM_DISTLIST);
 		u32 = 0xFFFFFFFF;
-		if (!e_mapi_utils_add_spropvalue_namedid (conn, fid, mem_ctx, values, n_values, PidLidFileUnderId, &u32, cancellable, perror))
-			return FALSE;
-		set_str_named_con_value (PidLidFileUnder, E_CONTACT_FILE_AS);
-		set_str_named_con_value (PidLidDistributionListName, E_CONTACT_FILE_AS);
-		set_str_con_value (PR_DISPLAY_NAME_UNICODE, E_CONTACT_FILE_AS);
-		set_str_con_value (PR_NORMALIZED_SUBJECT_UNICODE, E_CONTACT_FILE_AS);
+		set_value (PidLidFileUnderId, &u32);
+		set_con_value (PidLidFileUnder, E_CONTACT_FILE_AS);
+		set_con_value (PidLidDistributionListName, E_CONTACT_FILE_AS);
+		set_con_value (PidTagDisplayName, E_CONTACT_FILE_AS);
+		set_con_value (PidTagNormalizedSubject, E_CONTACT_FILE_AS);
 
 		local = e_contact_get_attributes (mcd->contact, E_CONTACT_EMAIL);
 		if (member_ids)
@@ -292,7 +258,6 @@ mapi_book_write_props (EMapiConnection *conn,
 					e_mapi_util_recip_entryid_generate_smtp (mem_ctx, &oneoff_members->lpbin[oneoff_members->cValues], nm ? nm : "", eml);
 					oneoff_members->cValues++;
 
-					list_size += MAX (oneoff_members->lpbin[oneoff_members->cValues - 1].cb, members->lpbin[members->cValues - 1].cb);
 					crc32 = e_mapi_utils_push_crc32 (crc32, members->lpbin[members->cValues - 1].lpb, members->lpbin[members->cValues - 1].cb);
 				}
 			}
@@ -308,63 +273,51 @@ mapi_book_write_props (EMapiConnection *conn,
 		g_list_foreach (local, (GFunc)e_vcard_attribute_free, NULL);
 		g_list_free (local);
 
-		if (!e_mapi_utils_add_spropvalue_namedid (conn, fid, mem_ctx, values, n_values,
-			PidLidDistributionListOneOffMembers, oneoff_members, cancellable, perror))
-			return FALSE;
-
-		if (!e_mapi_utils_add_spropvalue_namedid (conn, fid, mem_ctx, values, n_values,
-			PidLidDistributionListMembers, members, cancellable, perror))
-			return FALSE;
-
-		if (!e_mapi_utils_add_spropvalue_namedid (conn, fid, mem_ctx, values, n_values,
-			PidLidDistributionListChecksum, &crc32, cancellable, perror))
-			return FALSE;
-
-		/* list_size shouldn't exceed 15000 bytes, is so, use a stream instead of those properties above, but for now... */
-		if (list_size > 15000)
-			return FALSE;
+		set_value (PidLidDistributionListOneOffMembers, oneoff_members);
+		set_value (PidLidDistributionListMembers, members);
+		set_value (PidLidDistributionListChecksum, &crc32);
 
 		return TRUE;
 	}
 
-	set_str_value (PR_MESSAGE_CLASS, IPM_CONTACT);
-	set_str_named_con_value (PidLidFileUnder, E_CONTACT_FILE_AS);
+	set_value (PidTagMessageClass, IPM_CONTACT);
+	set_con_value (PidLidFileUnder, E_CONTACT_FILE_AS);
 
-	set_str_con_value (PR_DISPLAY_NAME_UNICODE, E_CONTACT_FULL_NAME);
-	set_str_con_value (PR_NORMALIZED_SUBJECT_UNICODE, E_CONTACT_FILE_AS);
-	set_str_named_con_value (PidLidEmail1OriginalDisplayName, E_CONTACT_EMAIL_1);
-	/*set_str_named_con_value (PidLidEmail1EmailAddress, E_CONTACT_EMAIL_1);*/
+	set_con_value (PidTagDisplayName, E_CONTACT_FULL_NAME);
+	set_con_value (PidTagNormalizedSubject, E_CONTACT_FILE_AS);
+	set_con_value (PidLidEmail1OriginalDisplayName, E_CONTACT_EMAIL_1);
+	/*set_con_value (PidLidEmail1EmailAddress, E_CONTACT_EMAIL_1);*/
 
-	/*set_str_con_value (0x8083001e, E_CONTACT_EMAIL_1);*/
-	set_str_named_con_value (PidLidEmail2EmailAddress, E_CONTACT_EMAIL_2);
+	/*set_con_value (0x8083001e, E_CONTACT_EMAIL_1);*/
+	set_con_value (PidLidEmail2EmailAddress, E_CONTACT_EMAIL_2);
 
-	set_str_named_con_value (PidLidEmail3EmailAddress, E_CONTACT_EMAIL_3);
-	/*set_str_named_con_value (PidLidEmail3OriginalDisplayName, E_CONTACT_EMAIL_3);*/
+	set_con_value (PidLidEmail3EmailAddress, E_CONTACT_EMAIL_3);
+	/*set_con_value (PidLidEmail3OriginalDisplayName, E_CONTACT_EMAIL_3);*/
 
-	set_str_named_con_value (PidLidHtml, E_CONTACT_HOMEPAGE_URL);
-	set_str_named_con_value (PidLidFreeBusyLocation, E_CONTACT_FREEBUSY_URL);
+	set_con_value (PidLidHtml, E_CONTACT_HOMEPAGE_URL);
+	set_con_value (PidLidFreeBusyLocation, E_CONTACT_FREEBUSY_URL);
 
-	set_str_con_value (PR_OFFICE_TELEPHONE_NUMBER_UNICODE, E_CONTACT_PHONE_BUSINESS);
-	set_str_con_value (PR_HOME_TELEPHONE_NUMBER_UNICODE, E_CONTACT_PHONE_HOME);
-	set_str_con_value (PR_MOBILE_TELEPHONE_NUMBER_UNICODE, E_CONTACT_PHONE_MOBILE);
-	set_str_con_value (PR_HOME_FAX_NUMBER_UNICODE, E_CONTACT_PHONE_HOME_FAX);
-	set_str_con_value (PR_BUSINESS_FAX_NUMBER_UNICODE, E_CONTACT_PHONE_BUSINESS_FAX);
-	set_str_con_value (PR_PAGER_TELEPHONE_NUMBER_UNICODE, E_CONTACT_PHONE_PAGER);
-	set_str_con_value (PR_ASSISTANT_TELEPHONE_NUMBER_UNICODE, E_CONTACT_PHONE_ASSISTANT);
-	set_str_con_value (PR_COMPANY_MAIN_PHONE_NUMBER_UNICODE, E_CONTACT_PHONE_COMPANY);
+	set_con_value (PidTagBusinessTelephoneNumber, E_CONTACT_PHONE_BUSINESS);
+	set_con_value (PidTagHomeTelephoneNumber, E_CONTACT_PHONE_HOME);
+	set_con_value (PidTagMobileTelephoneNumber, E_CONTACT_PHONE_MOBILE);
+	set_con_value (PidTagHomeFaxNumber, E_CONTACT_PHONE_HOME_FAX);
+	set_con_value (PidTagBusinessFaxNumber, E_CONTACT_PHONE_BUSINESS_FAX);
+	set_con_value (PidTagPagerTelephoneNumber, E_CONTACT_PHONE_PAGER);
+	set_con_value (PidTagAssistantTelephoneNumber, E_CONTACT_PHONE_ASSISTANT);
+	set_con_value (PidTagCompanyMainTelephoneNumber, E_CONTACT_PHONE_COMPANY);
 
-	set_str_con_value (PR_MANAGER_NAME_UNICODE, E_CONTACT_MANAGER);
-	set_str_con_value (PR_ASSISTANT_UNICODE, E_CONTACT_ASSISTANT);
-	set_str_con_value (PR_COMPANY_NAME_UNICODE, E_CONTACT_ORG);
-	set_str_con_value (PR_DEPARTMENT_NAME_UNICODE, E_CONTACT_ORG_UNIT);
-	set_str_con_value (PR_PROFESSION_UNICODE, E_CONTACT_ROLE);
-	set_str_con_value (PR_TITLE_UNICODE, E_CONTACT_TITLE);
+	set_con_value (PidTagManagerName, E_CONTACT_MANAGER);
+	set_con_value (PidTagAssistant, E_CONTACT_ASSISTANT);
+	set_con_value (PidTagCompanyName, E_CONTACT_ORG);
+	set_con_value (PidTagDepartmentName, E_CONTACT_ORG_UNIT);
+	set_con_value (PidTagProfession, E_CONTACT_ROLE);
+	set_con_value (PidTagTitle, E_CONTACT_TITLE);
 
-	set_str_con_value (PR_OFFICE_LOCATION_UNICODE, E_CONTACT_OFFICE);
-	set_str_con_value (PR_SPOUSE_NAME_UNICODE, E_CONTACT_SPOUSE);
+	set_con_value (PidTagOfficeLocation, E_CONTACT_OFFICE);
+	set_con_value (PidTagSpouseName, E_CONTACT_SPOUSE);
 
-	set_str_con_value (PR_BODY_UNICODE, E_CONTACT_NOTE);
-	set_str_con_value (PR_NICKNAME_UNICODE, E_CONTACT_NICKNAME);
+	set_con_value (PidTagBody, E_CONTACT_NOTE);
+	set_con_value (PidTagNickname, E_CONTACT_NICKNAME);
 
 	/* BDAY AND ANNV */
 	if (e_contact_get (mcd->contact, E_CONTACT_BIRTH_DATE)) {
@@ -378,8 +331,7 @@ mapi_book_write_props (EMapiConnection *conn,
 
 		e_mapi_util_time_t_to_filetime (mktime (&tmtime) + (24 * 60 * 60), &t);
 
-		if (!e_mapi_utils_add_spropvalue (mem_ctx, values, n_values, PR_BIRTHDAY, &t))
-			return FALSE;
+		set_value (PidTagBirthday, &t);
 	}
 
 	if (e_contact_get (mcd->contact, E_CONTACT_ANNIVERSARY)) {
@@ -393,38 +345,39 @@ mapi_book_write_props (EMapiConnection *conn,
 
 		e_mapi_util_time_t_to_filetime (mktime (&tmtime) + (24 * 60 * 60), &t);
 
-		if (!e_mapi_utils_add_spropvalue (mem_ctx, values, n_values, PR_WEDDING_ANNIVERSARY, &t))
-			return FALSE;
+		set_value (PidTagWeddingAnniversary, &t);
 	}
 
 	/* Home and Office address */
 	if (e_contact_get (mcd->contact, E_CONTACT_ADDRESS_HOME)) {
 		EContactAddress *contact_addr = e_contact_get (mcd->contact, E_CONTACT_ADDRESS_HOME);
 
-		set_str_named_value (PidLidHomeAddress, contact_addr->street);
-		set_str_value (PR_HOME_ADDRESS_POST_OFFICE_BOX_UNICODE, contact_addr->ext);
-		set_str_value (PR_HOME_ADDRESS_CITY_UNICODE, contact_addr->locality);
-		set_str_value (PR_HOME_ADDRESS_STATE_OR_PROVINCE_UNICODE, contact_addr->region);
-		set_str_value (PR_HOME_ADDRESS_POSTAL_CODE_UNICODE, contact_addr->code);
-		set_str_value (PR_HOME_ADDRESS_COUNTRY_UNICODE, contact_addr->country);
+		set_value (PidLidHomeAddress, contact_addr->street);
+		set_value (PidTagHomeAddressPostOfficeBox, contact_addr->ext);
+		set_value (PidTagHomeAddressCity, contact_addr->locality);
+		set_value (PidTagHomeAddressStateOrProvince, contact_addr->region);
+		set_value (PidTagHomeAddressPostalCode, contact_addr->code);
+		set_value (PidTagHomeAddressCountry, contact_addr->country);
 	}
 
 	if (e_contact_get (mcd->contact, E_CONTACT_ADDRESS_WORK)) {
 		EContactAddress *contact_addr = e_contact_get (mcd->contact, E_CONTACT_ADDRESS_WORK);
 
-		set_str_named_value (PidLidWorkAddress, contact_addr->street);
-		set_str_value (PR_POST_OFFICE_BOX_UNICODE, contact_addr->ext);
-		set_str_value (PR_LOCALITY_UNICODE, contact_addr->locality);
-		set_str_value (PR_STATE_OR_PROVINCE_UNICODE, contact_addr->region);
-		set_str_value (PR_POSTAL_CODE_UNICODE, contact_addr->code);
-		set_str_value (PR_COUNTRY_UNICODE, contact_addr->country);
+		set_value (PidLidWorkAddress, contact_addr->street);
+		set_value (PidTagPostOfficeBox, contact_addr->ext);
+		set_value (PidTagLocality, contact_addr->locality);
+		set_value (PidTagStateOrProvince, contact_addr->region);
+		set_value (PidTagPostalCode, contact_addr->code);
+		set_value (PidTagCountry, contact_addr->country);
 	}
 
 	if (e_contact_get (mcd->contact, E_CONTACT_IM_AIM)) {
 		GList *l = e_contact_get (mcd->contact, E_CONTACT_IM_AIM);
-		set_str_named_value (PidLidInstantMessagingAddress, l->data);
+		set_value (PidLidInstantMessagingAddress, l->data);
 	}
 
+	#undef set_value
+
 	return TRUE;
 }
 
@@ -769,9 +722,11 @@ ebbm_contacts_create_contacts (EBookBackendMAPI *ebma, GCancellable *cancellable
 	EBookBackendMAPIContacts *ebmac;
 	EBookBackendMAPIContactsPrivate *priv;
 	EMapiConnection *conn;
-	MapiCreateitemData mcd;
+	EMapiCreateitemData mcd;
 	GError *mapi_error = NULL;
-	mapi_id_t mid;
+	mapi_id_t mid = 0;
+	mapi_object_t obj_folder;
+	gboolean status;
 	gchar *id;
 	EContact *contact;
 
@@ -810,9 +765,17 @@ ebbm_contacts_create_contacts (EBookBackendMAPI *ebma, GCancellable *cancellable
 	e_book_backend_mapi_get_db (ebma, &mcd.db);
 	mcd.contact = contact;
 
-	mid = e_mapi_connection_create_item (conn, olFolderContacts, priv->fid,
-		mapi_book_write_props, &mcd,
-		NULL, NULL, NULL, MAPI_OPTIONS_DONT_SUBMIT | (priv->is_public_folder ? MAPI_OPTIONS_USE_PFSTORE : 0), cancellable, &mapi_error);
+	if (priv->is_public_folder)
+		status = e_mapi_connection_open_public_folder (conn, priv->fid, &obj_folder, cancellable, &mapi_error);
+	else
+		status = e_mapi_connection_open_personal_folder (conn, priv->fid, &obj_folder, cancellable, &mapi_error);
+
+	if (status) {
+		e_mapi_connection_create_object (conn, &obj_folder, E_MAPI_CREATE_FLAG_NONE,
+						 ebbm_contact_to_object, &mcd,
+						 &mid, cancellable, &mapi_error);
+		e_mapi_connection_close_folder (conn, &obj_folder, cancellable, &mapi_error);
+	}
 
 	e_book_backend_mapi_unlock_connection (ebma);
 
@@ -907,7 +870,7 @@ ebbm_contacts_modify_contacts (EBookBackendMAPI *ebma, GCancellable *cancellable
 	EBookBackendMAPIContacts *ebmac;
 	EBookBackendMAPIContactsPrivate *priv;
 	EMapiConnection *conn;
-	MapiCreateitemData mcd;
+	EMapiCreateitemData mcd;
 	EContact *contact;
 	GError *mapi_error = NULL;
 	mapi_id_t mid;
@@ -948,9 +911,23 @@ ebbm_contacts_modify_contacts (EBookBackendMAPI *ebma, GCancellable *cancellable
 	mcd.contact = contact;
 
 	if (e_mapi_util_mapi_id_from_string (e_contact_get_const (contact, E_CONTACT_UID), &mid)) {
-		if (!e_mapi_connection_modify_item (conn, olFolderContacts, priv->fid, mid,
-			mapi_book_write_props, &mcd, NULL, NULL, NULL, priv->is_public_folder ? MAPI_OPTIONS_USE_PFSTORE : 0, cancellable, &mapi_error)) {
+		mapi_object_t obj_folder;
+		gboolean status;
 
+		if (priv->is_public_folder)
+			status = e_mapi_connection_open_public_folder (conn, priv->fid, &obj_folder, cancellable, &mapi_error);
+		else
+			status = e_mapi_connection_open_personal_folder (conn, priv->fid, &obj_folder, cancellable, &mapi_error);
+
+		if (status) {
+			status = e_mapi_connection_modify_object (conn, &obj_folder, mid,
+								  ebbm_contact_to_object, &mcd,
+								  cancellable, &mapi_error);
+
+			e_mapi_connection_close_folder (conn, &obj_folder, cancellable, &mapi_error);
+		}
+
+		if (!status) {
 			mapi_error_to_edb_error (error, mapi_error, E_DATA_BOOK_STATUS_OTHER_ERROR, _("Failed to modify item on a server"));
 			if (mapi_error)
 				g_error_free (mapi_error);
diff --git a/src/calendar/e-cal-backend-mapi.c b/src/calendar/e-cal-backend-mapi.c
index f7c903f..36ec3a3 100644
--- a/src/calendar/e-cal-backend-mapi.c
+++ b/src/calendar/e-cal-backend-mapi.c
@@ -1504,19 +1504,14 @@ ecbm_create_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 	ECalComponent *comp;
 	mapi_id_t mid = 0;
 	gchar *tmp = NULL;
-	GSList *recipients = NULL;
-	GSList *attachments = NULL;
-	GSList *streams = NULL;
 	struct cal_cbdata cbdata = { 0 };
 	struct icaltimetype current;
-	const gchar *cache_dir;
 	GError *mapi_error = NULL;
 
 	cbmapi = E_CAL_BACKEND_MAPI (backend);
 	priv = cbmapi->priv;
 
 	kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
-	cache_dir = e_cal_backend_get_cache_dir (E_CAL_BACKEND (backend));
 
 	e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), InvalidArg);
 	e_return_data_cal_error_if_fail (calobj != NULL, InvalidArg);
@@ -1547,25 +1542,6 @@ ecbm_create_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 	e_cal_component_set_created (comp, &current);
 	e_cal_component_set_last_modified (comp, &current);
 
-	/* FIXME: [WIP] Add support for recurrences */
-	if (e_cal_component_has_recurrences (comp)) {
-		GByteArray *ba = e_mapi_cal_util_rrule_to_bin (comp, NULL);
-		if (ba) {
-			ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
-			stream->value = ba;
-			stream->proptag = e_mapi_connection_resolve_named_prop (priv->conn, priv->fid, PidLidAppointmentRecur, cancellable, NULL);
-			if (stream->proptag != MAPI_E_RESERVED)
-				streams = g_slist_append (streams, stream);
-		}
-	}
-
-	/* FIXME: [WIP] Add support for meetings/assigned tasks */
-	if (e_cal_component_has_attendees (comp))
-		e_mapi_cal_util_fetch_recipients (comp, &recipients);
-
-	if (e_cal_component_has_attachments (comp))
-		e_mapi_cal_util_fetch_attachments (comp, &attachments, cache_dir);
-
 	cbdata.kind = kind;
 	cbdata.username = (gchar *) ecbm_get_user_name (cbmapi);
 	cbdata.useridtype = (gchar *) "SMTP";
@@ -1578,26 +1554,37 @@ ecbm_create_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 
 	/* Check if object exists */
 	if (e_backend_get_online (E_BACKEND (backend))) {
+		gboolean status;
+		mapi_object_t obj_folder;
+		gboolean has_attendees = e_cal_component_has_attendees (comp);
+
 		/* Create an appointment */
 		cbdata.comp = comp;
 		cbdata.is_modify = FALSE;
 		cbdata.msgflags = MSGFLAG_READ;
-		cbdata.meeting_type = (recipients != NULL) ? MEETING_OBJECT : NOT_A_MEETING;
-		cbdata.resp = (recipients != NULL) ? olResponseOrganized : olResponseNone;
+		cbdata.meeting_type = has_attendees ? MEETING_OBJECT : NOT_A_MEETING;
+		cbdata.resp = has_attendees ? olResponseOrganized : olResponseNone;
 		cbdata.appt_id = e_mapi_cal_util_get_new_appt_id (priv->conn, priv->fid);
 		cbdata.appt_seq = 0;
 		cbdata.globalid = NULL;
 		cbdata.cleanglobalid = NULL;
 
-		mid = e_mapi_connection_create_item (priv->conn, priv->olFolder, priv->fid,
-						e_mapi_cal_utils_write_props_cb, &cbdata,
-						recipients, attachments, streams, MAPI_OPTIONS_DONT_SUBMIT, cancellable, &mapi_error);
-		g_free (cbdata.props);
+		if (priv->is_public_folder) {
+			status = e_mapi_connection_open_public_folder (priv->conn, priv->fid, &obj_folder, cancellable, &mapi_error);
+		} else {
+			status = e_mapi_connection_open_personal_folder (priv->conn, priv->fid, &obj_folder, cancellable, &mapi_error);
+		}
+
+		if (status) {
+			e_mapi_connection_create_object (priv->conn, &obj_folder, E_MAPI_CREATE_FLAG_NONE,
+							 e_mapi_cal_utils_comp_to_object, &cbdata,
+							 &mid, cancellable, &mapi_error);
+
+			e_mapi_connection_close_folder (priv->conn, &obj_folder, cancellable, &mapi_error);
+		}
+
 		if (!mid) {
 			g_object_unref (comp);
-			e_mapi_util_free_recipient_list (&recipients);
-			e_mapi_util_free_stream_list (&streams);
-			e_mapi_util_free_attachment_list (&attachments);
 			mapi_error_to_edc_error (error, mapi_error, OtherError, _("Failed to create item on a server"));
 			if (mapi_error)
 				g_error_free (mapi_error);
@@ -1616,19 +1603,14 @@ ecbm_create_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 		*new_ecalcomp = e_cal_component_clone (comp);
 		e_cal_backend_notify_component_created (E_CAL_BACKEND (cbmapi), *new_ecalcomp);
 	} else {
-		e_mapi_util_free_recipient_list (&recipients);
-		e_mapi_util_free_stream_list (&streams);
-		e_mapi_util_free_attachment_list (&attachments);
 		g_propagate_error (error, EDC_ERROR (UnsupportedMethod));
+		g_object_unref (comp);
 		return;
 	}
 
 	run_delta_thread (cbmapi);
 
 	g_object_unref (comp);
-	e_mapi_util_free_recipient_list (&recipients);
-	e_mapi_util_free_stream_list (&streams);
-	e_mapi_util_free_attachment_list (&attachments);
 }
 
 static gboolean
@@ -1696,14 +1678,10 @@ ecbm_modify_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 	gboolean status;
 	mapi_id_t mid;
 	const gchar *uid = NULL, *rid = NULL;
-	GSList *recipients = NULL;
-	GSList *streams = NULL;
-	GSList *attachments = NULL;
 	struct cal_cbdata cbdata = { 0 };
 	gboolean no_increment = FALSE;
 	icalproperty *prop;
 	struct icaltimetype current;
-	const gchar *cache_dir;
 	GError *mapi_error = NULL;
 
 	*old_ecalcomp = *new_ecalcomp = NULL;
@@ -1711,7 +1689,6 @@ ecbm_modify_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 	priv = cbmapi->priv;
 
 	kind = e_cal_backend_get_kind (backend);
-	cache_dir = e_cal_backend_get_cache_dir (backend);
 
 	e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), InvalidArg);
 	e_return_data_cal_error_if_fail (calobj != NULL, InvalidArg);
@@ -1749,24 +1726,6 @@ ecbm_modify_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 	current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
 	e_cal_component_set_last_modified (comp, &current);
 
-	/* FIXME: [WIP] Add support for recurrences */
-	if (e_cal_component_has_recurrences (comp)) {
-		GByteArray *ba = e_mapi_cal_util_rrule_to_bin (comp, NULL);
-		if (ba) {
-			ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
-			stream->value = ba;
-			stream->proptag = e_mapi_connection_resolve_named_prop (priv->conn, priv->fid, PidLidAppointmentRecur, cancellable, NULL);
-			if (stream->proptag != MAPI_E_RESERVED)
-				streams = g_slist_append (streams, stream);
-		}
-	}
-
-	if (e_cal_component_has_attendees (comp))
-		e_mapi_cal_util_fetch_recipients (comp, &recipients);
-
-	if (e_cal_component_has_attachments (comp))
-		e_mapi_cal_util_fetch_attachments (comp, &attachments, cache_dir);
-
 	e_cal_component_get_uid (comp, &uid);
 	/* rid = e_cal_component_get_recurid_as_string (comp); */
 
@@ -1775,6 +1734,9 @@ ecbm_modify_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 	cbdata.get_tz_data = cbmapi;
 
 	if (e_backend_get_online (E_BACKEND (backend))) {
+		gboolean has_attendees = e_cal_component_has_attendees (comp);
+		mapi_object_t obj_folder;
+
 		/* when online, send the item to the server */
 		/* check if the object exists */
 		cache_comp = e_cal_backend_store_get_component (priv->store, uid, rid);
@@ -1786,9 +1748,6 @@ ecbm_modify_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 		if (!cache_comp) {
 			g_message ("CRITICAL : Could not find the object in cache");
 			g_object_unref (comp);
-			e_mapi_util_free_recipient_list (&recipients);
-			e_mapi_util_free_stream_list (&streams);
-			e_mapi_util_free_attachment_list (&attachments);
 			g_propagate_error (error, EDC_ERROR (ObjectNotFound));
 			return;
 		}
@@ -1801,8 +1760,8 @@ ecbm_modify_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 
 		get_server_data (cbmapi, comp, &cbdata, cancellable);
 		if (modifier_is_organizer(cbmapi, comp)) {
-			cbdata.meeting_type = (recipients != NULL) ? MEETING_OBJECT : NOT_A_MEETING;
-			cbdata.resp = (recipients != NULL) ? olResponseOrganized : olResponseNone;
+			cbdata.meeting_type = has_attendees ? MEETING_OBJECT : NOT_A_MEETING;
+			cbdata.resp = has_attendees ? olResponseOrganized : olResponseNone;
 			if (!no_increment)
 				cbdata.appt_seq += 1;
 			free_and_dupe_str (cbdata.username, ecbm_get_user_name (cbmapi));
@@ -1812,21 +1771,28 @@ ecbm_modify_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 			free_and_dupe_str (cbdata.owneridtype, "SMTP");
 			free_and_dupe_str (cbdata.ownerid, ecbm_get_owner_email (cbmapi));
 		} else {
-			cbdata.resp = (recipients != NULL) ? find_my_response(cbmapi, comp) : olResponseNone;
-			cbdata.meeting_type = (recipients != NULL) ? MEETING_OBJECT_RCVD : NOT_A_MEETING;
+			cbdata.resp = has_attendees ? find_my_response(cbmapi, comp) : olResponseNone;
+			cbdata.meeting_type = has_attendees ? MEETING_OBJECT_RCVD : NOT_A_MEETING;
+		}
+
+		if (priv->is_public_folder) {
+			status = e_mapi_connection_open_public_folder (priv->conn, priv->fid, &obj_folder, cancellable, &mapi_error);
+		} else {
+			status = e_mapi_connection_open_personal_folder (priv->conn, priv->fid, &obj_folder, cancellable, &mapi_error);
+		}
+
+		if (status) {
+			status = e_mapi_connection_modify_object (priv->conn, &obj_folder, mid, 
+								  e_mapi_cal_utils_comp_to_object, &cbdata,
+								  cancellable, &mapi_error);
+
+			status = e_mapi_connection_close_folder (priv->conn, &obj_folder, cancellable, &mapi_error) && status;
 		}
 
-		status = e_mapi_connection_modify_item (priv->conn, priv->olFolder, priv->fid, mid,
-						e_mapi_cal_utils_write_props_cb, &cbdata,
-						recipients, attachments, streams, MAPI_OPTIONS_DONT_SUBMIT, cancellable, &mapi_error);
-		g_free (cbdata.props);
 		free_server_data (&cbdata);
 		if (!status) {
 			g_object_unref (comp);
 			g_object_unref (cache_comp);
-			e_mapi_util_free_recipient_list (&recipients);
-			e_mapi_util_free_stream_list (&streams);
-			e_mapi_util_free_attachment_list (&attachments);
 
 			mapi_error_to_edc_error (error, mapi_error, OtherError, _("Failed to modify item on a server"));
 			if (mapi_error)
@@ -1836,9 +1802,6 @@ ecbm_modify_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 	} else {
 		g_object_unref (comp);
 		g_object_unref (cache_comp);
-		e_mapi_util_free_recipient_list (&recipients);
-		e_mapi_util_free_stream_list (&streams);
-		e_mapi_util_free_attachment_list (&attachments);
 		g_propagate_error (error, EDC_ERROR (UnsupportedMethod));
 		return;
 	}
@@ -1851,9 +1814,6 @@ ecbm_modify_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 
 	g_object_unref (comp);
 	g_object_unref (cache_comp);
-	e_mapi_util_free_recipient_list (&recipients);
-	e_mapi_util_free_stream_list (&streams);
-	e_mapi_util_free_attachment_list (&attachments);
 }
 
 static void
@@ -1960,14 +1920,12 @@ ecbm_send_objects (ECalBackend *backend, EDataCal *cal, GCancellable *cancellabl
 	ECalBackendMAPIPrivate *priv;
 	icalcomponent_kind kind;
 	icalcomponent *icalcomp;
-	const gchar *cache_dir;
 	GError *mapi_error = NULL;
 
 	cbmapi = E_CAL_BACKEND_MAPI (backend);
 	priv = cbmapi->priv;
 
 	kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
-	cache_dir = e_cal_backend_get_cache_dir (E_CAL_BACKEND (backend));
 
 	e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), InvalidArg);
 	e_return_data_cal_error_if_fail (calobj != NULL, InvalidArg);
@@ -1994,33 +1952,16 @@ ecbm_send_objects (ECalBackend *backend, EDataCal *cal, GCancellable *cancellabl
 			ECalComponent *comp = e_cal_component_new ();
 			struct cal_cbdata cbdata = { 0 };
 			mapi_id_t mid = 0;
-			GSList *recipients = NULL;
-			GSList *attachments = NULL;
-			GSList *streams = NULL;
 			const gchar *compuid;
 			gchar *propval;
 			struct Binary_r globalid = { 0 }, cleanglobalid = { 0 };
 			struct timeval *exception_repleace_time = NULL, ex_rep_time = { 0 };
 			struct FILETIME creation_time = { 0 };
 			struct icaltimetype ical_creation_time = { 0 };
+			mapi_object_t obj_folder;
 
 			e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (subcomp));
 
-			/* FIXME: Add support for recurrences */
-			if (e_cal_component_has_recurrences (comp)) {
-				GByteArray *ba = e_mapi_cal_util_rrule_to_bin (comp, NULL);
-				if (ba) {
-					ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
-					stream->value = ba;
-					stream->proptag = e_mapi_connection_resolve_named_prop (priv->conn, priv->fid, PidLidAppointmentRecur, cancellable, NULL);
-					if (stream->proptag != MAPI_E_RESERVED)
-						streams = g_slist_append (streams, stream);
-				}
-			}
-
-			if (e_cal_component_has_attachments (comp))
-				e_mapi_cal_util_fetch_attachments (comp, &attachments, cache_dir);
-
 			cbdata.kind = kind;
 			cbdata.comp = comp;
 			cbdata.is_modify = TRUE;
@@ -2030,27 +1971,19 @@ ecbm_send_objects (ECalBackend *backend, EDataCal *cal, GCancellable *cancellabl
 			case ICAL_METHOD_REQUEST :
 				cbdata.meeting_type = MEETING_REQUEST;
 				cbdata.resp = olResponseNotResponded;
-				if (e_cal_component_has_attendees (comp))
-					e_mapi_cal_util_fetch_recipients (comp, &recipients);
 				break;
 			case ICAL_METHOD_CANCEL :
 				cbdata.meeting_type = MEETING_CANCEL;
 				cbdata.resp = olResponseNotResponded;
-				if (e_cal_component_has_attendees (comp))
-					e_mapi_cal_util_fetch_recipients (comp, &recipients);
 				break;
 			case ICAL_METHOD_REPLY:
 			case ICAL_METHOD_RESPONSE :
 				cbdata.meeting_type = MEETING_RESPONSE;
 				cbdata.resp = find_my_response (cbmapi, comp);
-				if (e_cal_component_has_organizer (comp))
-					e_mapi_cal_util_fetch_organizer (comp, &recipients);
 				break;
 			default :
 				cbdata.meeting_type = NOT_A_MEETING;
 				cbdata.resp = olResponseNone;
-				if (e_cal_component_has_attendees (comp))
-					e_mapi_cal_util_fetch_organizer (comp, &recipients);
 				break;
 			}
 
@@ -2118,20 +2051,23 @@ ecbm_send_objects (ECalBackend *backend, EDataCal *cal, GCancellable *cancellabl
 			cbdata.globalid = &globalid;
 			cbdata.cleanglobalid = &cleanglobalid;
 
-			mid = e_mapi_connection_create_item (priv->conn, olFolderSentMail, 0,
-							e_mapi_cal_utils_write_props_cb, &cbdata,
-							recipients, attachments, streams, MAPI_OPTIONS_DELETE_ON_SUBMIT_FAILURE, cancellable, &mapi_error);
+			mid = 0;
+			if (e_mapi_connection_open_default_folder (priv->conn, olFolderSentMail, &obj_folder, cancellable, &mapi_error)) {
+				e_mapi_connection_create_object (priv->conn, &obj_folder, E_MAPI_CREATE_FLAG_SUBMIT,
+								 e_mapi_cal_utils_comp_to_object, &cbdata,
+								 &mid, cancellable, &mapi_error);
+
+				e_mapi_connection_close_folder (priv->conn, &obj_folder, cancellable, &mapi_error);
+			}
+
 			cbdata.globalid = NULL;
 			cbdata.cleanglobalid = NULL;
 			free_server_data (&cbdata);
-			g_free (cbdata.props);
 			g_free (globalid.lpb);
 			g_free (cleanglobalid.lpb);
 
 			if (!mid) {
 				g_object_unref (comp);
-				e_mapi_util_free_recipient_list (&recipients);
-				e_mapi_util_free_attachment_list (&attachments);
 				mapi_error_to_edc_error (error, mapi_error, OtherError, _("Failed to create item on a server"));
 				if (mapi_error)
 					g_error_free (mapi_error);
@@ -2139,8 +2075,6 @@ ecbm_send_objects (ECalBackend *backend, EDataCal *cal, GCancellable *cancellabl
 			}
 
 			g_object_unref (comp);
-			e_mapi_util_free_recipient_list (&recipients);
-			e_mapi_util_free_attachment_list (&attachments);
 
 			subcomp = icalcomponent_get_next_component (icalcomp,
 								    e_cal_backend_get_kind (E_CAL_BACKEND (backend)));
@@ -2358,11 +2292,8 @@ ecbm_add_timezone (ECalBackend *backend, EDataCal *cal, GCancellable *cancellabl
 		zone = icaltimezone_new ();
 		icaltimezone_set_component (zone, tz_comp);
 
-		if (e_cal_backend_store_put_timezone (priv->store, zone) == FALSE) {
-			icaltimezone_free (zone, 1);
-			g_propagate_error (error, EDC_ERROR_EX (OtherError, "Cannot push timezone to cache"));
-			return;
-		}
+		e_cal_backend_store_put_timezone (priv->store, zone);
+
 		icaltimezone_free (zone, 1);
 	}
 }
diff --git a/src/libexchangemapi/e-mapi-cal-recur-utils.c b/src/libexchangemapi/e-mapi-cal-recur-utils.c
index d9580fc..404afca 100644
--- a/src/libexchangemapi/e-mapi-cal-recur-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-recur-utils.c
@@ -1118,8 +1118,10 @@ compare_guint32 (gconstpointer a, gconstpointer b, gpointer user_data)
 	return (*((guint32 *) a) - *((guint32 *) b));
 }
 
-GByteArray *
-e_mapi_cal_util_rrule_to_bin (ECalComponent *comp, GSList *modified_comps)
+gboolean
+e_mapi_cal_util_rrule_to_bin (ECalComponent *comp,
+			      struct SBinary_short *bin,
+			      TALLOC_CTX *mem_ctx)
 {
 	struct icalrecurrencetype *rt;
 	gint i;
@@ -1128,8 +1130,12 @@ e_mapi_cal_util_rrule_to_bin (ECalComponent *comp, GSList *modified_comps)
 	struct ema_AppointmentRecurrencePattern arp;
 	struct ema_RecurrencePattern *rp; /* Convenience ptr */
 
+	g_return_val_if_fail (comp != NULL, FALSE);
+	g_return_val_if_fail (bin != NULL, FALSE);
+	g_return_val_if_fail (mem_ctx != NULL, FALSE);
+
 	if (!e_cal_component_has_recurrences (comp))
-		return NULL;
+		return FALSE;
 
 	e_cal_component_get_rrule_list (comp, &rrule_list);
 	e_cal_component_get_exdate_list (comp, &exdate_list);
@@ -1357,16 +1363,21 @@ e_mapi_cal_util_rrule_to_bin (ECalComponent *comp, GSList *modified_comps)
 	/* Reserved Block 2 Size */
 	arp_to_gba(&arp, ba);
 
-cleanup:
+ cleanup:
 	free_arp_contents(&arp);
 	e_cal_component_free_exdate_list (exdate_list);
 	e_cal_component_free_recur_list (rrule_list);
 
-	g_print ("\n== ICAL to MAPI == The recurrence blob data is as follows:\n");
+	/*g_print ("\n== ICAL to MAPI == The recurrence blob data is as follows:\n");
 	for (i = 0; i < ba->len; ++i)
 		g_print ("0x%02X ", ba->data[i]);
-	g_print("\n== End of stream ==\n");
+	g_print("\n== End of stream ==\n");*/
 
-	return ba;
+	bin->cb = ba->len;
+	bin->lpb = talloc_memdup (mem_ctx, ba->data, ba->len);
+
+	g_byte_array_free (ba, TRUE);
+
+	return TRUE;
 }
 
diff --git a/src/libexchangemapi/e-mapi-cal-recur-utils.h b/src/libexchangemapi/e-mapi-cal-recur-utils.h
index 0c2dfff..dd6cf1a 100644
--- a/src/libexchangemapi/e-mapi-cal-recur-utils.h
+++ b/src/libexchangemapi/e-mapi-cal-recur-utils.h
@@ -30,9 +30,15 @@
 
 G_BEGIN_DECLS
 
-gboolean	e_mapi_cal_util_bin_to_rrule (const guint8 *lpb, guint32 cb, ECalComponent *comp, GSList **extra_detached, icaltimezone *recur_zone);
-
-GByteArray *	e_mapi_cal_util_rrule_to_bin (ECalComponent *comp, GSList *modified_comps);
+gboolean	e_mapi_cal_util_bin_to_rrule	(const guint8 *lpb,
+						 guint32 cb,
+						 ECalComponent *comp,
+						 GSList **extra_detached,
+						 icaltimezone *recur_zone);
+
+gboolean	e_mapi_cal_util_rrule_to_bin	(ECalComponent *comp,
+						 struct SBinary_short *bin,
+						 TALLOC_CTX *mem_ctx);
 
 G_END_DECLS
 
diff --git a/src/libexchangemapi/e-mapi-cal-tz-utils.c b/src/libexchangemapi/e-mapi-cal-tz-utils.c
index 7cf3513..23addbc 100644
--- a/src/libexchangemapi/e-mapi-cal-tz-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-tz-utils.c
@@ -293,7 +293,9 @@ e_mapi_cal_tz_util_dump (void)
 #define TZ_BIN_VERSION_MINOR  0x01 
 
 void
-e_mapi_cal_util_mapi_tz_to_bin (const gchar *mapi_tzid, struct Binary_r *sb)
+e_mapi_cal_util_mapi_tz_to_bin (const gchar *mapi_tzid,
+				struct SBinary_short *bin,
+				TALLOC_CTX *mem_ctx)
 {
 	GByteArray *ba;
 	guint8 flag8;
@@ -333,14 +335,14 @@ e_mapi_cal_util_mapi_tz_to_bin (const gchar *mapi_tzid, struct Binary_r *sb)
 
 	/* Rules may now be appended here */
 
-	sb->lpb = ba->data;
-	sb->cb = ba->len;
+	bin->cb = ba->len;
+	bin->lpb = talloc_memdup (mem_ctx, ba->data, ba->len);
 
 	d(g_message ("New timezone stream.. Length: %d bytes.. Hex-data follows:", ba->len));
 	d(for (i = 0; i < ba->len; i++)
 		g_print("0x%.2X ", ba->data[i]));
 
-	g_byte_array_free (ba, FALSE);
+	g_byte_array_free (ba, TRUE);
 }
 
 gchar *
diff --git a/src/libexchangemapi/e-mapi-cal-tz-utils.h b/src/libexchangemapi/e-mapi-cal-tz-utils.h
index 0e097bf..9db6596 100644
--- a/src/libexchangemapi/e-mapi-cal-tz-utils.h
+++ b/src/libexchangemapi/e-mapi-cal-tz-utils.h
@@ -35,7 +35,9 @@ const gchar *	e_mapi_cal_tz_util_get_ical_equivalent	(const gchar *mapi_tz_locat
 gboolean	e_mapi_cal_tz_util_populate		(void);
 void		e_mapi_cal_tz_util_destroy		(void);
 void		e_mapi_cal_tz_util_dump			(void);
-void		e_mapi_cal_util_mapi_tz_to_bin		(const gchar *mapi_tzid, struct Binary_r *sb);
+void		e_mapi_cal_util_mapi_tz_to_bin		(const gchar *mapi_tzid,
+							 struct SBinary_short *bin,
+							 TALLOC_CTX *mem_ctx);
 int		e_mapi_cal_util_mapi_tz_pidlidtimezone	(icaltimezone *ictz);
 gchar *		e_mapi_cal_util_bin_to_mapi_tz		(const guint8 *lpb, guint32 cb);
 
diff --git a/src/libexchangemapi/e-mapi-cal-utils.c b/src/libexchangemapi/e-mapi-cal-utils.c
index bb9cf6d..ddaba75 100644
--- a/src/libexchangemapi/e-mapi-cal-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-utils.c
@@ -1635,7 +1635,7 @@ e_mapi_cal_utils_write_props_cb (EMapiConnection *conn,
 
 	if (kind == ICAL_VEVENT_COMPONENT) {
 		const gchar *mapi_tzid;
-		struct Binary_r start_tz, end_tz;
+		struct SBinary_short start_tz, end_tz;
 
 		set_named_value (PidLidAppointmentMessageClass, IPM_APPOINTMENT);
 
@@ -1681,7 +1681,7 @@ e_mapi_cal_utils_write_props_cb (EMapiConnection *conn,
 		/* Start TZ */
 		mapi_tzid = e_mapi_cal_tz_util_get_mapi_equivalent ((dtstart_tz_location && *dtstart_tz_location) ? dtstart_tz_location : "UTC");
 		if (mapi_tzid && *mapi_tzid) {
-			e_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &start_tz);
+			e_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &start_tz, mem_ctx);
 			set_named_value (PidLidAppointmentTimeZoneDefinitionStartDisplay, &start_tz);
 		}
 		set_named_value (PidLidTimeZoneDescription, mapi_tzid ? mapi_tzid : "");
@@ -1695,7 +1695,7 @@ e_mapi_cal_utils_write_props_cb (EMapiConnection *conn,
 		/* End TZ */
 		mapi_tzid = e_mapi_cal_tz_util_get_mapi_equivalent ((dtend_tz_location && *dtend_tz_location) ? dtend_tz_location : "UTC");
 		if (mapi_tzid && *mapi_tzid) {
-			e_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &end_tz);
+			e_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &end_tz, mem_ctx);
 			set_named_value (PidLidAppointmentTimeZoneDefinitionEndDisplay, &end_tz);
 		}
 
@@ -2027,6 +2027,11 @@ e_mapi_cal_utils_write_props_cb (EMapiConnection *conn,
 		set_named_value (PidLidNoteHeight, &flag32);
 	}
 
+	#undef set_value
+	#undef set_named_value
+	#undef set_datetime_value
+	#undef set_named_datetime_value
+
 	return TRUE;
 }
 
@@ -2087,7 +2092,7 @@ uint32_t
 e_mapi_cal_util_get_new_appt_id (EMapiConnection *conn, mapi_id_t fid)
 {
 	uint32_t id;
-	gboolean unused = TRUE;
+	gboolean unused = FALSE;
 	mapi_object_t obj_folder;
 
 	if (!e_mapi_connection_open_personal_folder (conn, fid, &obj_folder, NULL, NULL))
@@ -2520,7 +2525,10 @@ populate_ical_attendees (EMapiConnection *conn,
 }
 
 static void
-set_attachments_to_comp (EMapiConnection *conn, EMapiAttachment *attachments, ECalComponent *comp, const gchar *local_store_path)
+set_attachments_to_comp (EMapiConnection *conn,
+			 EMapiAttachment *attachments,
+			 ECalComponent *comp,
+			 const gchar *local_store_path)
 {
 	GSList *comp_attach_list = NULL;
 	EMapiAttachment *attach;
@@ -3018,3 +3026,917 @@ e_mapi_cal_util_object_to_comp (EMapiConnection *conn,
 
 	return comp;
 }
+
+static void
+e_mapi_cal_utils_add_organizer (EMapiObject *object,
+				ECalComponent *comp)
+{
+	icalcomponent *icalcomp;
+	icalproperty *org_prop = NULL;
+	const gchar *org = NULL;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (comp != NULL);
+
+	icalcomp = e_cal_component_get_icalcomponent (comp);
+	org_prop = icalcomponent_get_first_property (icalcomp, ICAL_ORGANIZER_PROPERTY);
+	org = icalproperty_get_organizer (org_prop);
+	if (org && *org) {
+		EMapiRecipient *recipient;
+		uint32_t ui32 = 0;
+		const gchar *str = NULL, *email;
+		icalparameter *param;
+
+		recipient = e_mapi_recipient_new (object);
+		e_mapi_object_add_recipient (object, recipient);
+
+		#define set_value(pt,vl) {								\
+			if (!e_mapi_utils_add_property (&recipient->properties, pt, vl, recipient)) {	\
+				g_warning ("%s: Failed to set property 0x%x", G_STRFUNC, pt);		\
+													\
+				return;									\
+			}										\
+		}
+
+		if (g_ascii_strncasecmp (org, "mailto:";, 7) == 0)
+			email = org + 7;
+		else
+			email = org;
+
+		set_value (PidTagAddressType, "SMTP");
+		set_value (PidTagEmailAddress, email);
+
+		set_value (PidTagSmtpAddress, email);
+		set_value (PidTagPrimarySmtpAddress, email);
+
+		ui32 = 0;
+		set_value (PidTagSendInternetEncoding, &ui32);
+
+		ui32 = RECIP_SENDABLE | RECIP_ORGANIZER;
+		set_value (PidTagRecipientFlags, &ui32);
+
+		ui32 = olResponseNone;
+		set_value (PidTagRecipientTrackStatus, &ui32);
+
+		ui32 = olTo;
+		set_value (PidTagRecipientType, &ui32);
+
+		param = icalproperty_get_first_parameter (org_prop, ICAL_CN_PARAMETER);
+		str = icalparameter_get_cn (param);
+		str = (str && *str) ? str : email;
+		set_value (PidTagRecipientDisplayName, str);
+		set_value (PidTagDisplayName, str);
+
+		ui32 = DT_MAILUSER;
+		set_value (PidTagDisplayType, &ui32);
+
+		ui32 = MAPI_MAILUSER;
+		set_value (PidTagObjectType, &ui32);
+
+		#undef set_value
+	}
+}
+
+static void
+e_mapi_cal_utils_add_recipients (EMapiObject *object,
+				 ECalComponent *comp)
+{
+	icalcomponent *icalcomp;
+	icalproperty *org_prop = NULL, *att_prop = NULL;
+	const gchar *org = NULL;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (comp != NULL);
+
+	if (!e_cal_component_has_attendees (comp))
+		return;
+
+	icalcomp = e_cal_component_get_icalcomponent (comp);
+	org_prop = icalcomponent_get_first_property (icalcomp, ICAL_ORGANIZER_PROPERTY);
+	org = icalproperty_get_organizer (org_prop);
+	if (!org)
+		org = "";
+
+	att_prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+	while (att_prop) {
+		EMapiRecipient *recipient;
+		uint32_t ui32 = 0;
+		const gchar *str = NULL, *email;
+		icalparameter *param;
+
+		str = icalproperty_get_attendee (att_prop);
+		if (!str || g_ascii_strcasecmp (str, org) == 0) {
+			att_prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+			continue;
+		}
+
+		recipient = e_mapi_recipient_new (object);
+		e_mapi_object_add_recipient (object, recipient);
+
+		#define set_value(pt,vl) {								\
+			if (!e_mapi_utils_add_property (&recipient->properties, pt, vl, recipient)) {	\
+				g_warning ("%s: Failed to set property 0x%x", G_STRFUNC, pt);		\
+													\
+				return;									\
+			}										\
+		}
+
+		if (g_ascii_strncasecmp (str, "mailto:";, 7) == 0)
+			email = str + 7;
+		else
+			email = str;
+
+		set_value (PidTagAddressType, "SMTP");
+		set_value (PidTagEmailAddress, email);
+
+		set_value (PidTagSmtpAddress, email);
+		set_value (PidTagPrimarySmtpAddress, email);
+
+		ui32 = 0;
+		set_value (PidTagSendInternetEncoding, &ui32);
+
+		ui32 = RECIP_SENDABLE | (g_ascii_strcasecmp (str, org) == 0 ? RECIP_ORGANIZER : 0);
+		set_value (PidTagRecipientFlags, &ui32);
+
+		param = icalproperty_get_first_parameter (att_prop, ICAL_PARTSTAT_PARAMETER);
+		ui32 = get_trackstatus_from_partstat (icalparameter_get_partstat (param));
+		set_value (PidTagRecipientTrackStatus, &ui32);
+
+		param = icalproperty_get_first_parameter (att_prop, ICAL_ROLE_PARAMETER);
+		ui32 = get_type_from_role (icalparameter_get_role (param));
+		set_value (PidTagRecipientType, &ui32);
+
+		param = icalproperty_get_first_parameter (att_prop, ICAL_CN_PARAMETER);
+		str = icalparameter_get_cn (param);
+		str = (str && *str) ? str : email;
+		set_value (PidTagRecipientDisplayName, str);
+		set_value (PidTagDisplayName, str);
+
+		ui32 = DT_MAILUSER;
+		set_value (PidTagDisplayType, &ui32);
+
+		ui32 = MAPI_MAILUSER;
+		set_value (PidTagObjectType, &ui32);
+
+		#undef set_value
+
+		att_prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+	}
+}
+
+static void
+e_mapi_cal_utils_add_attachments (EMapiObject *object,
+				  ECalComponent *comp)
+{
+	GSList *comp_attach_list = NULL;
+	GSList *l;
+	const gchar *uid;
+	gchar *safeuid;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (comp != NULL);
+
+	if (!e_cal_component_has_attachments (comp))
+		return;
+
+	e_cal_component_get_attachment_list (comp, &comp_attach_list);
+	e_cal_component_get_uid (comp, &uid);
+
+	safeuid = g_strdup (uid);
+	e_filename_make_safe (safeuid);
+	g_return_if_fail (safeuid != NULL);
+
+	for (l = comp_attach_list; l; l = l->next) {
+		gchar *sfname_uri = (gchar *) l->data;
+		gchar *sfname = NULL, *filename = NULL;
+		GMappedFile *mapped_file;
+		GError *error = NULL;
+
+		sfname = g_filename_from_uri (sfname_uri, NULL, NULL);
+		mapped_file = g_mapped_file_new (sfname, FALSE, &error);
+		filename = g_path_get_basename (sfname);
+
+		if (mapped_file) {
+			EMapiAttachment *attachment;
+			guint8 *attach = (guint8 *) g_mapped_file_get_contents (mapped_file);
+			guint filelength = g_mapped_file_get_length (mapped_file);
+			const gchar *split_name;
+			uint32_t ui32;
+			struct SBinary_short bin;
+
+			if (g_str_has_prefix (filename, safeuid)) {
+				split_name = (filename + strlen (safeuid) + strlen ("-"));
+			} else {
+				split_name = filename;
+			}
+
+			attachment = e_mapi_attachment_new (object);
+			e_mapi_object_add_attachment (object, attachment);
+
+			#define set_value(pt,vl) {								\
+				if (!e_mapi_utils_add_property (&attachment->properties, pt, vl, attachment)) {	\
+					g_warning ("%s: Failed to set property 0x%x", G_STRFUNC, pt);		\
+														\
+					return;									\
+				}										\
+			}
+
+			ui32 = ATTACH_BY_VALUE;
+			set_value (PidTagAttachMethod, &ui32);
+
+			/* MSDN Documentation: When the supplied offset is -1 (0xFFFFFFFF), the
+			 * attachment is not rendered using the PR_RENDERING_POSITION property.
+			 * All values other than -1 indicate the position within PR_BODY at which
+			 * the attachment is to be rendered.
+			 */
+			ui32 = -1;
+			set_value (PidTagRenderingPosition, &ui32);
+
+			set_value (PidTagAttachFilename, split_name);
+			set_value (PidTagAttachLongFilename, split_name);
+
+			bin.cb = filelength;
+			bin.lpb = talloc_memdup (attachment, attach, bin.cb);
+			set_value (PidTagAttachDataBinary, &bin);
+
+			#undef set_value
+
+#if GLIB_CHECK_VERSION(2,21,3)
+			g_mapped_file_unref (mapped_file);
+#else
+			g_mapped_file_free (mapped_file);
+#endif
+		} else if (error) {
+			e_mapi_debug_print ("Could not map %s: %s \n", sfname_uri, error->message);
+			g_error_free (error);
+		}
+
+		g_free (filename);
+	}
+
+	g_free (safeuid);
+}
+
+gboolean
+e_mapi_cal_utils_comp_to_object (EMapiConnection *conn,
+				 TALLOC_CTX *mem_ctx,
+				 EMapiObject **pobject, /* out */
+				 gpointer user_data,
+				 GCancellable *cancellable,
+				 GError **perror)
+{
+	struct cal_cbdata *cbdata = (struct cal_cbdata *) user_data;
+	ECalComponent *comp;
+	icalcomponent *ical_comp;
+	icalcomponent_kind kind;
+	uint32_t flag32;
+	bool b;
+	icalproperty *prop;
+	struct icaltimetype dtstart, dtend, utc_dtstart, utc_dtend, all_day_dtstart = {0}, all_day_dtend = {0};
+	const icaltimezone *utc_zone;
+	const gchar *dtstart_tz_location, *dtend_tz_location, *text = NULL;
+	time_t tt;
+	gboolean is_all_day;
+	GSList *categories = NULL;
+	EMapiObject *object;
+
+	g_return_val_if_fail (conn != NULL, FALSE);
+	g_return_val_if_fail (mem_ctx != NULL, FALSE);
+	g_return_val_if_fail (cbdata != NULL, FALSE);
+	g_return_val_if_fail (pobject != NULL, FALSE);
+
+	switch (cbdata->kind) {
+		case ICAL_VEVENT_COMPONENT:
+		case ICAL_VTODO_COMPONENT:
+		case ICAL_VJOURNAL_COMPONENT:
+			break;
+		default:
+			return FALSE;
+	}
+
+	comp = cbdata->comp;
+	ical_comp = e_cal_component_get_icalcomponent (comp);
+	kind = icalcomponent_isa (ical_comp);
+	g_return_val_if_fail (kind == cbdata->kind, FALSE);
+
+	object = e_mapi_object_new (mem_ctx);
+	*pobject = object;
+
+	#define set_value(hex, val) G_STMT_START { \
+		if (!e_mapi_utils_add_property (&object->properties, hex, val, object)) \
+			return FALSE;	\
+		} G_STMT_END
+
+	#define set_timet_value(hex, dtval) G_STMT_START {		\
+		struct FILETIME	filetime;				\
+									\
+		e_mapi_util_time_t_to_filetime (dtval, &filetime); 	\
+		set_value (hex, &filetime); 				\
+		} G_STMT_END
+
+	utc_zone = icaltimezone_get_utc_timezone ();
+
+	dtstart = icalcomponent_get_dtstart (ical_comp);
+
+	/* For VEVENTs */
+	if (icalcomponent_get_first_property (ical_comp, ICAL_DTEND_PROPERTY) != 0)
+		dtend = icalcomponent_get_dtend (ical_comp);
+	/* For VTODOs */
+	else if (icalcomponent_get_first_property (ical_comp, ICAL_DUE_PROPERTY) != 0)
+		dtend = icalcomponent_get_due (ical_comp);
+	else
+		dtend = icalcomponent_get_dtstart (ical_comp);
+
+	dtstart_tz_location = get_tzid_location (icaltime_get_tzid (dtstart), cbdata);
+	dtend_tz_location = get_tzid_location (icaltime_get_tzid (dtend), cbdata);
+
+	is_all_day = kind == ICAL_VEVENT_COMPONENT && icaltime_is_date (dtstart) && icaltime_is_date (dtend);
+	if (is_all_day) {
+		const gchar *def_location;
+		icaltimezone *use_zone = NULL;
+
+		/* all-day events expect times not in UTC but in local time;
+		   if this differs from the server timezone, then the event
+		   is shown spread among (two) days */
+		def_location = get_tzid_location ("*default-zone*", cbdata);
+		if (def_location && *def_location)
+			use_zone = icaltimezone_get_builtin_timezone (def_location);
+
+		if (!use_zone)
+			use_zone = (icaltimezone *) utc_zone;
+
+		dtstart.is_date = 0;
+		dtstart.hour = 0;
+		dtstart.minute = 0;
+		dtstart.second = 0;
+		all_day_dtstart = icaltime_convert_to_zone (dtstart, use_zone);
+		dtstart.is_date = 1;
+		all_day_dtstart = icaltime_convert_to_zone (all_day_dtstart, (icaltimezone *) utc_zone);
+
+		dtend.is_date = 0;
+		dtend.hour = 0;
+		dtend.minute = 0;
+		dtend.second = 0;
+		all_day_dtend = icaltime_convert_to_zone (dtend, use_zone);
+		dtend.is_date = 1;
+		all_day_dtend = icaltime_convert_to_zone (all_day_dtend, (icaltimezone *) utc_zone);
+	}
+
+	utc_dtstart = icaltime_convert_to_zone (dtstart, (icaltimezone *)utc_zone);
+	utc_dtend = icaltime_convert_to_zone (dtend, (icaltimezone *)utc_zone);
+
+	text = icalcomponent_get_summary (ical_comp);
+	if (!(text && *text))
+		text = "";
+	set_value (PidTagSubject, text);
+	set_value (PidTagNormalizedSubject, text);
+	if (cbdata->appt_seq == 0)
+		set_value (PidTagConversationTopic, text);
+	text = NULL;
+
+	/* we don't support HTML event/task/memo editor */
+	flag32 = olEditorText;
+	set_value (PidTagMessageEditorFormat, &flag32);
+
+	/* it'd be better to convert, then set it in unicode */
+	text = icalcomponent_get_description (ical_comp);
+	if (!(text && *text) || !g_utf8_validate (text, -1, NULL))
+		text = "";
+	set_value (PidTagBody, text);
+	text = NULL;
+
+	e_cal_component_get_categories_list (comp, &categories);
+	if (categories) {
+		gint ii;
+		GSList *c;
+		struct StringArrayW_r categories_array;
+
+		categories_array.cValues = g_slist_length (categories);
+		categories_array.lppszW = (const char **) talloc_zero_array (mem_ctx, gchar *, categories_array.cValues);
+
+		for (c = categories, ii = 0; c; c = c->next, ii++) {
+			const gchar *category = c->data;
+
+			if (!category || !*category) {
+				ii--;
+				categories_array.cValues--;
+				continue;
+			}
+
+			categories_array.lppszW[ii] = talloc_strdup (mem_ctx, category);
+		}
+
+		set_value (PidNameKeywords, &categories_array);
+
+		e_cal_component_free_categories_list (categories);
+	}
+
+	/* Priority and Importance */
+	prop = icalcomponent_get_first_property (ical_comp, ICAL_PRIORITY_PROPERTY);
+	flag32 = prop ? get_prio_prop_from_priority (icalproperty_get_priority (prop)) : PRIORITY_NORMAL;
+	set_value (PidTagPriority, &flag32);
+	flag32 = prop ? get_imp_prop_from_priority (icalproperty_get_priority (prop)) : IMPORTANCE_NORMAL;
+	set_value (PidTagImportance, &flag32);
+
+	if (cbdata->ownername && cbdata->owneridtype && cbdata->ownerid) {
+		set_value (PidTagSentRepresentingName, cbdata->ownername);
+		set_value (PidTagSentRepresentingAddressType, cbdata->owneridtype);
+		set_value (PidTagSentRepresentingEmailAddress, cbdata->ownerid);
+	}
+
+	if (cbdata->username && cbdata->useridtype && cbdata->userid) {
+		set_value (PidTagSenderName, cbdata->username);
+		set_value (PidTagSenderAddressType, cbdata->useridtype);
+		set_value (PidTagSenderEmailAddress, cbdata->userid);
+	}
+
+	flag32 = cbdata->msgflags;
+	set_value (PidTagMessageFlags, &flag32);
+
+	flag32 = 0x0;
+	b = e_cal_component_has_alarms (comp);
+	if (b) {
+		/* We know there would be only a single alarm of type:DISPLAY [static properties of the backend] */
+		GList *alarm_uids = e_cal_component_get_alarm_uids (comp);
+		ECalComponentAlarm *alarm = e_cal_component_get_alarm (comp, (const gchar *)(alarm_uids->data));
+		ECalComponentAlarmAction action;
+		e_cal_component_alarm_get_action (alarm, &action);
+		if (action == E_CAL_COMPONENT_ALARM_DISPLAY) {
+			ECalComponentAlarmTrigger trigger;
+			gint dur_int = 0;
+			e_cal_component_alarm_get_trigger (alarm, &trigger);
+			switch (trigger.type) {
+			case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START :
+				dur_int = (icaldurationtype_as_int (trigger.u.rel_duration)) / SECS_IN_MINUTE;
+			/* we cannot set an alarm to popup after the start of an appointment on Exchange */
+				flag32 = (dur_int < 0) ? -(dur_int) : 0;
+				break;
+			default :
+				break;
+			}
+		}
+		e_cal_component_alarm_free (alarm);
+		cal_obj_uid_list_free (alarm_uids);
+	}
+	if (!flag32)
+		switch (kind) {
+			case ICAL_VEVENT_COMPONENT:
+				flag32 = DEFAULT_APPT_REMINDER_MINS;
+				break;
+			case ICAL_VTODO_COMPONENT:
+				flag32 = DEFAULT_TASK_REMINDER_MINS;
+				break;
+			default:
+				break;
+		}
+	set_value (PidLidReminderSet, &b);
+	set_value (PidLidReminderDelta, &flag32);
+	tt = icaltime_as_timet (utc_dtstart);
+	set_timet_value (PidLidReminderTime, tt);
+	tt = icaltime_as_timet (utc_dtstart) - (flag32 * SECS_IN_MINUTE);
+	/* ReminderNextTime: FIXME for recurrence */
+	set_timet_value (PidLidReminderSignalTime, tt);
+
+	/* Sensitivity, Private */
+	flag32 = olNormal;	/* default */
+	b = 0;			/* default */
+	prop = icalcomponent_get_first_property (ical_comp, ICAL_CLASS_PROPERTY);
+	if (prop)
+		flag32 = get_prop_from_class (icalproperty_get_class (prop));
+	if (flag32 == olPrivate || flag32 == olConfidential)
+		b = 1;
+	set_value (PidTagSensitivity, &flag32);
+	set_value (PidLidPrivate, &b);
+
+	tt = icaltime_as_timet (is_all_day ? all_day_dtstart : utc_dtstart);
+	set_timet_value (PidLidCommonStart, tt);
+	set_timet_value (PidTagStartDate, tt);
+
+	tt = icaltime_as_timet (is_all_day ? all_day_dtend : utc_dtend);
+	set_timet_value (PidLidCommonEnd, tt);
+	set_timet_value (PidTagEndDate, tt);
+
+	b = 1;
+	set_value (PidTagResponseRequested, &b);
+
+	/* PR_OWNER_APPT_ID needs to be set in certain cases only */
+	/* PR_ICON_INDEX needs to be set appropriately */
+
+	b = 0;
+	set_value (PidTagRtfInSync, &b);
+
+	if (kind == ICAL_VEVENT_COMPONENT) {
+		const gchar *mapi_tzid;
+		struct SBinary_short start_tz, end_tz;
+
+		set_value (PidLidAppointmentMessageClass, IPM_APPOINTMENT);
+
+		/* Busy Status */
+		flag32 = olBusy;
+		prop = icalcomponent_get_first_property (ical_comp, ICAL_TRANSP_PROPERTY);
+		if (prop)
+			flag32 = get_prop_from_transp (icalproperty_get_transp (prop));
+		if (cbdata->meeting_type == MEETING_CANCEL)
+			flag32 = olFree;
+		set_value (PidLidIntendedBusyStatus, &flag32);
+
+		if (cbdata->meeting_type == MEETING_REQUEST || cbdata->meeting_type == MEETING_REQUEST_RCVD) {
+			flag32 = olTentative;
+			set_value (PidLidBusyStatus, &flag32);
+		} else if (cbdata->meeting_type == MEETING_CANCEL) {
+			flag32 = olFree;
+			set_value (PidLidBusyStatus, &flag32);
+		} else
+			set_value (PidLidBusyStatus, &flag32);
+
+		/* Location */
+		text = icalcomponent_get_location (ical_comp);
+		if (!(text && *text))
+			text = "";
+		set_value (PidLidLocation, text);
+		set_value (PidLidWhere, text);
+		text = NULL;
+		/* Auto-Location is always FALSE - Evolution doesn't work that way */
+		b = 0;
+		set_value (PidLidAutoFillLocation, &b);
+
+		/* All-day event */
+		b = is_all_day ? 1 : 0;
+		set_value (PidLidAppointmentSubType, &b);
+
+		/* Start */
+		tt = icaltime_as_timet (is_all_day ? all_day_dtstart : utc_dtstart);
+		set_timet_value (PidLidAppointmentStartWhole, tt);
+		/* FIXME: for recurrence */
+		set_timet_value (PidLidClipStart, tt);
+
+		/* Start TZ */
+		mapi_tzid = e_mapi_cal_tz_util_get_mapi_equivalent ((dtstart_tz_location && *dtstart_tz_location) ? dtstart_tz_location : "UTC");
+		if (mapi_tzid && *mapi_tzid) {
+			e_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &start_tz, object);
+			set_value (PidLidAppointmentTimeZoneDefinitionStartDisplay, &start_tz);
+		}
+		set_value (PidLidTimeZoneDescription, mapi_tzid ? mapi_tzid : "");
+
+		/* End */
+		tt = icaltime_as_timet (is_all_day ? all_day_dtend : utc_dtend);
+		set_timet_value (PidLidAppointmentEndWhole, tt);
+		/* FIXME: for recurrence */
+		set_timet_value (PidLidClipEnd, tt);
+
+		/* End TZ */
+		mapi_tzid = e_mapi_cal_tz_util_get_mapi_equivalent ((dtend_tz_location && *dtend_tz_location) ? dtend_tz_location : "UTC");
+		if (mapi_tzid && *mapi_tzid) {
+			e_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &end_tz, object);
+			set_value (PidLidAppointmentTimeZoneDefinitionEndDisplay, &end_tz);
+		}
+
+		/* Recurrences also need to have this rather arbitrary index set
+		   to properly determine SDT/DST and appear in OWA (Bug #629057). */
+		if (e_cal_component_has_recurrences (comp)) {
+			uint64_t pltz;
+			icaltimezone *ictz;
+			const gchar *zone_location = dtstart_tz_location;
+
+			if (!zone_location)
+				zone_location = get_tzid_location ("*default-zone*", cbdata);
+
+			ictz = icaltimezone_get_builtin_timezone (zone_location);
+			pltz = e_mapi_cal_util_mapi_tz_pidlidtimezone (ictz);
+			set_value (PidLidTimeZone, &pltz);
+		}
+
+		/* Duration */
+		flag32 = icaldurationtype_as_int (icaltime_subtract (dtend, dtstart));
+		flag32 /= MINUTES_IN_HOUR;
+		set_value (PidLidAppointmentDuration, &flag32);
+
+		if (e_cal_component_has_recurrences (comp)) {
+			GSList *rrule_list = NULL;
+			struct icalrecurrencetype *rt = NULL;
+
+			e_cal_component_get_rrule_list (comp, &rrule_list);
+			rt = (struct icalrecurrencetype *)(rrule_list->data);
+
+			if (rt->freq == ICAL_DAILY_RECURRENCE)
+				flag32 = rectypeDaily;
+			else if (rt->freq == ICAL_WEEKLY_RECURRENCE)
+				flag32 = rectypeWeekly;
+			else if (rt->freq == ICAL_MONTHLY_RECURRENCE)
+				flag32 = rectypeMonthly;
+			else if (rt->freq == ICAL_YEARLY_RECURRENCE)
+				flag32 = rectypeYearly;
+			else
+				flag32 = rectypeNone;
+
+			e_cal_component_free_recur_list (rrule_list);
+		} else
+			flag32 = rectypeNone;
+		set_value (PidLidRecurrenceType, &flag32);
+
+		flag32 = cbdata->appt_id;
+		if (!flag32) {
+			gchar *propval;
+
+			propval = e_mapi_cal_utils_get_icomp_x_prop (e_cal_component_get_icalcomponent (comp), "X-EVOLUTION-MAPI-OWNER-APPT-ID");
+			if (propval && *propval) {
+				mapi_id_t as_id = 0;
+
+				if (e_mapi_util_mapi_id_from_string (propval, &as_id))
+					flag32 = (uint32_t) as_id;
+			}
+
+			g_free (propval);
+		}
+		set_value (PidTagOwnerAppointmentId, &flag32);
+
+		flag32 = cbdata->appt_seq;
+		set_value (PidLidAppointmentSequence, &flag32);
+
+		if (cbdata->cleanglobalid) {
+			set_value (PidLidCleanGlobalObjectId, cbdata->cleanglobalid);
+		}
+
+		if (cbdata->globalid) {
+			set_value (PidLidGlobalObjectId, cbdata->globalid);
+		}
+
+		flag32 = cbdata->resp;
+		set_value (PidLidResponseStatus, &flag32);
+
+		switch (cbdata->meeting_type) {
+		case MEETING_OBJECT :
+			set_value (PidTagMessageClass, IPM_APPOINTMENT);
+
+			flag32 = e_cal_component_has_recurrences (comp) ? RecurMeet : SingleMeet;
+			set_value (PidTagIconIndex, &flag32);
+
+			flag32 = 0x0171;
+			set_value (PidLidSideEffects, &flag32);
+
+			flag32 = asfMeeting;
+			set_value (PidLidAppointmentStateFlags, &flag32);
+
+			flag32 = mtgRequest;
+			set_value (PidLidMeetingType, &flag32);
+
+			b = 1;
+			set_value (PidLidFInvited, &b);
+
+			break;
+		case MEETING_OBJECT_RCVD :
+			set_value (PidTagMessageClass, IPM_APPOINTMENT);
+
+			flag32 = e_cal_component_has_recurrences (comp) ? RecurMeet : SingleMeet;
+			set_value (PidTagIconIndex, (gconstpointer ) &flag32);
+
+			flag32 = 0x0171;
+			set_value (PidLidSideEffects, &flag32);
+
+			flag32 = asfMeeting | asfReceived;
+			set_value (PidLidAppointmentStateFlags, &flag32);
+
+			flag32 = mtgRequest;
+			set_value (PidLidMeetingType, &flag32);
+
+			b = 1;
+			set_value (PidLidFInvited, &b);
+
+			break;
+		case MEETING_REQUEST :
+			set_value (PidTagMessageClass, IPM_SCHEDULE_MEETING_REQUEST);
+
+			flag32 = 0xFFFFFFFF;  /* no idea why this has to be -1, but that's what the docs say */
+			set_value (PidTagIconIndex, &flag32);
+
+			flag32 = 0x1C61;
+			set_value (PidLidSideEffects, &flag32);
+
+			flag32 = asfMeeting | asfReceived;
+			set_value (PidLidAppointmentStateFlags, &flag32);
+
+			flag32 = (cbdata->appt_seq == 0) ? mtgRequest : mtgFull;
+			set_value (PidLidMeetingType, &flag32);
+
+			b = 1;
+			set_value (PidLidFInvited, &b);
+
+			break;
+		case MEETING_REQUEST_RCVD :
+			set_value (PidTagMessageClass, IPM_APPOINTMENT);
+
+			flag32 = e_cal_component_has_recurrences (comp) ? RecurMeet : SingleMeet;
+			set_value (PidTagIconIndex, &flag32);
+
+			flag32 = 0x0171;
+			set_value (PidLidSideEffects, &flag32);
+
+			flag32 = asfMeeting | asfReceived;
+			set_value (PidLidAppointmentStateFlags, &flag32);
+
+			flag32 = mtgRequest;
+			set_value (PidLidMeetingType, &flag32);
+
+			b = 1;
+			set_value (PidLidFInvited, &b);
+
+			break;
+		case MEETING_CANCEL :
+			set_value (PidTagMessageClass, IPM_SCHEDULE_MEETING_CANCELED);
+
+			flag32 = 0xFFFFFFFF;  /* no idea why this has to be -1, but that's what the docs say */
+			set_value (PidTagIconIndex, &flag32);
+
+			flag32 = 0x1C61;
+			set_value (PidLidSideEffects, &flag32);
+
+			flag32 = asfMeeting | asfReceived | asfCanceled;
+			set_value (PidLidAppointmentStateFlags, &flag32);
+
+			flag32 = mtgEmpty;
+			set_value (PidLidMeetingType, &flag32);
+
+			b = 1;
+			set_value (PidLidFInvited, &b);
+
+			break;
+		case MEETING_RESPONSE :
+			#define prefix_subject(prefix) {					\
+				const gchar *summary;						\
+												\
+				summary = icalcomponent_get_summary (ical_comp);		\
+				if (!(summary && *summary))					\
+					summary = "";						\
+												\
+				summary = talloc_asprintf (mem_ctx, "%s %s", prefix, summary);	\
+												\
+				set_value (PidTagSubject, summary);				\
+				set_value (PidTagNormalizedSubject, summary);			\
+				if (cbdata->appt_seq == 0)					\
+					set_value (PidTagConversationTopic, summary);		\
+			}
+			if (cbdata->resp == olResponseAccepted) {
+				/* Translators: This is a meeting response prefix which will be shown in a message Subject */
+				prefix_subject (C_("MeetingResp", "Accepted:"));
+				text = IPM_SCHEDULE_MEETING_RESP_POS;
+			} else if (cbdata->resp == olResponseTentative) {
+				/* Translators: This is a meeting response prefix which will be shown in a message Subject */
+				prefix_subject (C_("MeetingResp", "Tentative:"));
+				text = IPM_SCHEDULE_MEETING_RESP_TENT;
+			} else if (cbdata->resp == olResponseDeclined) {
+				/* Translators: This is a meeting response prefix which will be shown in a message Subject */
+				prefix_subject (C_("MeetingResp", "Declined:"));
+				text = IPM_SCHEDULE_MEETING_RESP_NEG;
+			} else {
+				text = "";
+			}
+			#undef prefix_subject
+			set_value (PidTagMessageClass, text);
+			text = NULL;
+
+			flag32 = 0xFFFFFFFF;  /* no idea why this has to be -1, but that's what the docs say */
+			set_value (PidTagIconIndex, &flag32);
+
+			flag32 = 0x1C61;
+			set_value (PidLidSideEffects, &flag32);
+
+			flag32 = asfNone;
+			set_value (PidLidAppointmentStateFlags, &flag32);
+
+			flag32 = mtgEmpty;
+			set_value (PidLidMeetingType, &flag32);
+
+			break;
+		case NOT_A_MEETING :
+		default :
+			set_value (PidTagMessageClass, IPM_APPOINTMENT);
+
+			flag32 = e_cal_component_has_recurrences (comp) ? RecurAppt : SingleAppt;
+			set_value (PidTagIconIndex, &flag32);
+
+			flag32 = 0x0171;
+			set_value (PidLidSideEffects, &flag32);
+
+			flag32 = 0;
+			set_value (PidLidAppointmentStateFlags, &flag32);
+
+			b = 0;
+			set_value (PidLidFInvited, &b);
+
+			break;
+		}
+
+		b = e_cal_component_has_recurrences (comp);
+		set_value (PidLidRecurring, &b);
+		set_value (PidLidIsRecurring, &b);
+
+		if (b) {
+			struct SBinary_short bin;
+
+			if (e_mapi_cal_util_rrule_to_bin (comp, &bin, object)) {
+				set_value (PidLidAppointmentRecur, &bin);
+			}
+		}
+
+		/* FIXME: Modified exceptions */
+		b = e_cal_component_has_exceptions (comp) && FALSE; b = 0;
+		set_value (PidLidIsException, &b);
+
+		/* Counter Proposal for appointments : not supported */
+		b = 1;
+		set_value (PidLidAppointmentNotAllowPropose, &b);
+		b = 0;
+		set_value (PidLidAppointmentCounterProposal, &b);
+
+	} else if (kind == ICAL_VTODO_COMPONENT) {
+		gdouble d;
+
+		set_value (PidTagMessageClass, IPM_TASK);
+
+		/* Context menu flags */ /* FIXME: for assigned tasks */
+		flag32 = 0x0110;
+		set_value (PidLidSideEffects, &flag32);
+
+		/* Status, Percent complete, IsComplete */
+		flag32 = olTaskNotStarted;	/* default */
+		b = 0;				/* default */
+		d = 0.0;
+		prop = icalcomponent_get_first_property (ical_comp, ICAL_PERCENTCOMPLETE_PROPERTY);
+		if (prop)
+			d = 0.01 * icalproperty_get_percentcomplete (prop);
+
+		flag32 = get_prop_from_taskstatus (icalcomponent_get_status (ical_comp));
+		if (flag32 == olTaskComplete) {
+			b = 1;
+			d = 1.0;
+		}
+
+		set_value (PidLidTaskStatus, &flag32);
+		set_value (PidLidPercentComplete, &d);
+		set_value (PidLidTaskComplete, &b);
+
+		/* Date completed */
+		if (b) {
+			struct icaltimetype completed;
+			prop = icalcomponent_get_first_property (ical_comp, ICAL_COMPLETED_PROPERTY);
+			completed = icalproperty_get_completed (prop);
+
+			completed.hour = completed.minute = completed.second = 0; completed.is_date = completed.is_utc = 1;
+			tt = icaltime_as_timet (completed);
+			set_timet_value (PidLidTaskDateCompleted, tt);
+		}
+
+		/* Start */
+		dtstart.hour = dtstart.minute = dtstart.second = 0; dtstart.is_date = dtstart.is_utc = 1;
+		tt = icaltime_as_timet (dtstart);
+		if (!icaltime_is_null_time (dtstart)) {
+			set_timet_value (PidLidTaskStartDate, tt);
+		}
+
+		/* Due */
+		dtend.hour = dtend.minute = dtend.second = 0; dtend.is_date = dtend.is_utc = 1;
+		tt = icaltime_as_timet (dtend);
+		if (!icaltime_is_null_time (dtend)) {
+			set_timet_value (PidLidTaskDueDate, tt);
+		}
+
+		/* FIXME: Evolution does not support recurring tasks */
+		b = 0;
+		set_value (PidLidTaskFRecurring, &b);
+
+	} else if (kind == ICAL_VJOURNAL_COMPONENT) {
+		uint32_t color = olYellow;
+
+		set_value (PidTagMessageClass, IPM_STICKYNOTE);
+
+		/* Context menu flags */
+		flag32 = 0x0110;
+		set_value (PidLidSideEffects, &flag32);
+
+		flag32 = 0x0300 + color;
+		set_value (PidTagIconIndex, &flag32);
+
+		flag32 = color;
+		set_value (PidLidNoteColor, &flag32);
+
+		/* some random value */
+		flag32 = 0x00FF;
+		set_value (PidLidNoteWidth, &flag32);
+
+		/* some random value */
+		flag32 = 0x00FF;
+		set_value (PidLidNoteHeight, &flag32);
+	}
+
+	#undef set_value
+	#undef set_timet_value
+
+	if (cbdata->meeting_type == MEETING_RESPONSE || cbdata->meeting_type == NOT_A_MEETING)
+		e_mapi_cal_utils_add_organizer (object, comp);
+	else
+		e_mapi_cal_utils_add_recipients (object, comp);
+
+	e_mapi_cal_utils_add_attachments (object, comp);
+
+	return TRUE;
+}
diff --git a/src/libexchangemapi/e-mapi-cal-utils.h b/src/libexchangemapi/e-mapi-cal-utils.h
index b512bdb..38a5142 100644
--- a/src/libexchangemapi/e-mapi-cal-utils.h
+++ b/src/libexchangemapi/e-mapi-cal-utils.h
@@ -51,7 +51,6 @@ typedef enum {
 struct cal_cbdata {
 	gint kind;
 	ECalComponent *comp;
-	struct SPropValue *props;
 	gboolean is_modify;
 
 	/* These are appt specific data */
@@ -136,6 +135,13 @@ ECalComponent *	e_mapi_cal_util_object_to_comp			(EMapiConnection *conn,
 								 const gchar *use_uid,
 								 GSList **detached_components);
 
+gboolean	e_mapi_cal_utils_comp_to_object			(EMapiConnection *conn,
+								 TALLOC_CTX *mem_ctx,
+								 EMapiObject **pobject, /* out */
+								 gpointer user_data,
+								 GCancellable *cancellable,
+								 GError **perror);
+
 gchar *	e_mapi_cal_utils_get_icomp_x_prop (icalcomponent *comp, const gchar *key);
 
 G_END_DECLS
diff --git a/src/libexchangemapi/e-mapi-connection.c b/src/libexchangemapi/e-mapi-connection.c
index a607a59..ae94799 100644
--- a/src/libexchangemapi/e-mapi-connection.c
+++ b/src/libexchangemapi/e-mapi-connection.c
@@ -2131,10 +2131,10 @@ maybe_replace_named_id_tag (uint32_t *pproptag,
 		return;
 
 	for (i = 0; i < named_ids_len; i++) {
-		if ((*pproptag) == named_ids_list[i].propid ||
+		if ((*pproptag) == named_ids_list[i].pidlid_propid ||
 		    ((((*pproptag) & 0xFFFF) == PT_ERROR) &&
-			((*pproptag) & ~0xFFFF) == (named_ids_list[i].propid & ~0xFFFF))) {
-			(*pproptag) = ((*pproptag) & 0xFFFF) | (named_ids_list[i].pidlid_propid & ~0xFFFF);
+			((*pproptag) & ~0xFFFF) == (named_ids_list[i].pidlid_propid & ~0xFFFF))) {
+			(*pproptag) = ((*pproptag) & 0xFFFF) | (named_ids_list[i].propid & ~0xFFFF);
 			break;
 		}
 	}
@@ -3670,7 +3670,9 @@ update_recipient_properties (EMapiConnection *conn,
 		/* do not overwrite all properties, if recipient was resolved properly */
 		if (!is_resolved
 		    || props[ii].ulPropTag == PidTagRecipientType
-		    || props[ii].ulPropTag == PidTagSendInternetEncoding)
+		    || props[ii].ulPropTag == PidTagSendInternetEncoding
+		    || props[ii].ulPropTag == PidTagRecipientFlags
+		    || props[ii].ulPropTag == PidTagRecipientTrackStatus)
 			SRow_addprop (aRow, props[ii]);
 	}
 
@@ -3718,8 +3720,7 @@ add_object_recipients (EMapiConnection *conn,
 					  PidTagEmailAddress,
 					  PidTagAddressType,
 					  PidTagSendRichInfo,
-					  PidTag7BitDisplayName/*,
-					  PidTagPrimarySmtpAddress*/};
+					  PidTag7BitDisplayName};
 	enum MAPISTATUS	ms;
 	struct SPropTagArray *tags;
 	struct SRowSet *rows = NULL;
diff --git a/src/libexchangemapi/e-mapi-connection.h b/src/libexchangemapi/e-mapi-connection.h
index 83a9a78..5b05942 100644
--- a/src/libexchangemapi/e-mapi-connection.h
+++ b/src/libexchangemapi/e-mapi-connection.h
@@ -251,7 +251,7 @@ typedef gboolean (*TransferObjectCB)		(EMapiConnection *conn,
 						 GError **perror);
 typedef gboolean (*WriteObjectCB)		(EMapiConnection *conn,
 						 TALLOC_CTX *mem_ctx,
-						 EMapiObject **object, /* out */
+						 EMapiObject **pobject, /* out */
 						 gpointer user_data,
 						 GCancellable *cancellable,
 						 GError **perror);
diff --git a/src/libexchangemapi/e-mapi-mail-utils.c b/src/libexchangemapi/e-mapi-mail-utils.c
index 66912cf..a4e5333 100644
--- a/src/libexchangemapi/e-mapi-mail-utils.c
+++ b/src/libexchangemapi/e-mapi-mail-utils.c
@@ -1775,14 +1775,12 @@ e_mapi_mail_add_recipients (EMapiObject *object,
 
 		#define set_value(pt,vl) {								\
 			if (!e_mapi_utils_add_property (&recipient->properties, pt, vl, recipient)) {	\
-				g_warning ("%s: Faield to set property 0x%x", G_STRFUNC, pt);		\
+				g_warning ("%s: Failed to set property 0x%x", G_STRFUNC, pt);		\
 													\
 				return;									\
 			}										\
 		}
 
-		#define set_str_value(pt,st) set_value (pt, talloc_strdup (recipient, st))
-
 		ui32 = recip_type;
 		set_value (PidTagRecipientType, &ui32);
 
@@ -1790,15 +1788,15 @@ e_mapi_mail_add_recipients (EMapiObject *object,
 			name = email;
 
 		if (name && *name) {
-			set_str_value (PidTagDisplayName, name);
-			set_str_value (PidTagRecipientDisplayName, name);
+			set_value (PidTagDisplayName, name);
+			set_value (PidTagRecipientDisplayName, name);
 		}
 		if (email && *email) {
-			set_str_value (PidTagAddressType, "SMTP");
-			set_str_value (PidTagEmailAddress, email);
+			set_value (PidTagAddressType, "SMTP");
+			set_value (PidTagEmailAddress, email);
 
-			set_str_value (PidTagSmtpAddress, email);
-			set_str_value (PidTagPrimarySmtpAddress, email);
+			set_value (PidTagSmtpAddress, email);
+			set_value (PidTagPrimarySmtpAddress, email);
 		}
 
 		ui32 = 0;
@@ -1814,7 +1812,6 @@ e_mapi_mail_add_recipients (EMapiObject *object,
 		set_value (PidTagSendRichInfo, &bl);
 
 		#undef set_value
-		#undef set_str_value
 
 		name = NULL;
 		email = NULL;
@@ -1934,8 +1931,6 @@ e_mapi_mail_content_stream_to_bin (CamelStream *content_stream,
 	}									\
 }
 
-#define set_attach_str_value(pt,st) set_attach_value (pt, talloc_strdup (attach, st))
-
 static gboolean
 e_mapi_mail_add_attach (EMapiObject *object,
 			CamelMimePart *part,
@@ -1963,19 +1958,19 @@ e_mapi_mail_add_attach (EMapiObject *object,
 
 	filename = camel_mime_part_get_filename (part);
 	if (filename) {
-		set_attach_str_value (PidTagAttachFilename, filename);
-		set_attach_str_value (PidTagAttachLongFilename, filename);
+		set_attach_value (PidTagAttachFilename, filename);
+		set_attach_value (PidTagAttachLongFilename, filename);
 	}
 
 	content_id = camel_mime_part_get_content_id (part);
 	if (content_id)
-		set_attach_str_value (PidTagAttachContentId, content_id);
+		set_attach_value (PidTagAttachContentId, content_id);
 
 	content_type  = camel_mime_part_get_content_type (part);
 	if (content_type) {
 		gchar *ct = camel_content_type_simple (content_type);
 		if (ct)
-			set_attach_str_value (PidTagAttachMimeTag, ct);
+			set_attach_value (PidTagAttachMimeTag, ct);
 		g_free (ct);
 	}
 
@@ -2005,10 +2000,14 @@ e_mapi_mail_add_body (EMapiObject *object,
 
 		return e_mapi_utils_add_property (&object->properties, proptag, &bin, object);
 	} else if (str) {
-		if (!e_mapi_utils_add_property (&object->properties, proptag, str, object))
+		if (!e_mapi_utils_add_property (&object->properties, proptag, str, object)) {
+			talloc_free (str);
 			return FALSE;
+		}
+
+		talloc_free (str);
 	} else {
-		return e_mapi_utils_add_property (&object->properties, proptag, talloc_strdup (object, ""), object);
+		return e_mapi_utils_add_property (&object->properties, proptag, "", object);
 	}
 
 	return TRUE;
@@ -2054,10 +2053,10 @@ e_mapi_mail_do_smime_encrypted (EMapiObject *object,
 	set_attach_value (PidTagAttachMethod, &ui32);
 	ui32 = -1;
 	set_attach_value (PidTagRenderingPosition, &ui32);
-	set_attach_str_value (PidTagAttachMimeTag, content_type_str);
-	set_attach_str_value (PidTagAttachFilename, "SMIME.txt");
-	set_attach_str_value (PidTagAttachLongFilename, "SMIME.txt");
-	set_attach_str_value (PidTagDisplayName, "SMIME.txt");
+	set_attach_value (PidTagAttachMimeTag, content_type_str);
+	set_attach_value (PidTagAttachFilename, "SMIME.txt");
+	set_attach_value (PidTagAttachLongFilename, "SMIME.txt");
+	set_attach_value (PidTagDisplayName, "SMIME.txt");
 
 	e_mapi_mail_content_stream_to_bin (content_stream, &bin, attach, cancellable);
 	set_attach_value (PidTagAttachDataBinary, &bin);
@@ -2127,10 +2126,10 @@ e_mapi_mail_do_smime_signed (EMapiObject *object,
 	set_attach_value (PidTagAttachMethod, &ui32);
 	ui32 = -1;
 	set_attach_value (PidTagRenderingPosition, &ui32);
-	set_attach_str_value (PidTagAttachMimeTag, "multipart/signed");
-	set_attach_str_value (PidTagAttachFilename, "SMIME.txt");
-	set_attach_str_value (PidTagAttachLongFilename, "SMIME.txt");
-	set_attach_str_value (PidTagDisplayName, "SMIME.txt");
+	set_attach_value (PidTagAttachMimeTag, "multipart/signed");
+	set_attach_value (PidTagAttachFilename, "SMIME.txt");
+	set_attach_value (PidTagAttachLongFilename, "SMIME.txt");
+	set_attach_value (PidTagDisplayName, "SMIME.txt");
 
 	e_mapi_mail_content_stream_to_bin (content_stream, &bin, attach, cancellable);
 	set_attach_value (PidTagAttachDataBinary, &bin);
@@ -2188,11 +2187,11 @@ e_mapi_mail_do_multipart (EMapiObject *object,
 				set_attach_value (PidTagAttachMethod, &ui32);
 				ui32 = 0;
 				set_attach_value (PidTagRenderingPosition, &ui32);
-				set_attach_str_value (PidTagAttachMimeTag, "message/rfc822");
+				set_attach_value (PidTagAttachMimeTag, "message/rfc822");
 
 				str = camel_mime_message_get_subject (message);
 				if (str)
-					set_attach_str_value (PidTagAttachFilename, str);
+					set_attach_value (PidTagAttachFilename, str);
 				continue;
 			} else {
 				e_mapi_attachment_free (attach);
@@ -2219,7 +2218,6 @@ e_mapi_mail_do_multipart (EMapiObject *object,
 }
 
 #undef set_attach_value
-#undef set_attach_str_value
 
 gboolean
 e_mapi_mail_utils_message_to_object (struct _CamelMimeMessage *message,
@@ -2265,14 +2263,12 @@ e_mapi_mail_utils_message_to_object (struct _CamelMimeMessage *message,
 			g_free (msg_class);						\
 			g_free (pid_name_content_type);					\
 											\
-			g_warning ("%s: Faield to set property 0x%x", G_STRFUNC, pt);	\
+			g_warning ("%s: Failed to set property 0x%x", G_STRFUNC, pt);	\
 											\
 			return FALSE;							\
 		}									\
 	}
 
-	#define set_str_value(pt,st) set_value (pt, talloc_strdup (object, st))
-
 	ui32 = 65001; /* UTF8 - also used with PR_HTML */
 	set_value (PidTagInternetCodepage, &ui32);
 
@@ -2294,7 +2290,7 @@ e_mapi_mail_utils_message_to_object (struct _CamelMimeMessage *message,
 	   are computed from PidTagSubject by a server */
 	str = camel_mime_message_get_subject (message);
 	if (str)
-		set_str_value (PidTagSubject, str);
+		set_value (PidTagSubject, str);
 
 	/* some properties may not be set when submitting a message */
 	if ((create_flags & E_MAPI_CREATE_FLAG_SUBMIT) == 0) {
@@ -2303,11 +2299,11 @@ e_mapi_mail_utils_message_to_object (struct _CamelMimeMessage *message,
 		GArray *headers;
 
 		if (namep && *namep)
-			set_str_value (PidTagSentRepresentingName, namep);
+			set_value (PidTagSentRepresentingName, namep);
 
 		if (addressp && *addressp) {
-			set_str_value (PidTagSentRepresentingAddressType, "SMTP");
-			set_str_value (PidTagSentRepresentingEmailAddress, addressp);
+			set_value (PidTagSentRepresentingAddressType, "SMTP");
+			set_value (PidTagSentRepresentingEmailAddress, addressp);
 		}
 
 		msg_time = camel_mime_message_get_date (message, &msg_time_offset);
@@ -2337,7 +2333,7 @@ e_mapi_mail_utils_message_to_object (struct _CamelMimeMessage *message,
 			camel_medium_free_headers (CAMEL_MEDIUM (message), headers);
 
 			if (hstr->len && hstr->str)
-				set_str_value (PidTagTransportMessageHeaders, hstr->str);
+				set_value (PidTagTransportMessageHeaders, hstr->str);
 
 			g_string_free (hstr, TRUE);
 		}
@@ -2345,15 +2341,15 @@ e_mapi_mail_utils_message_to_object (struct _CamelMimeMessage *message,
 
 	str = camel_medium_get_header ((CamelMedium *) message, "References");
 	if (str)
-		set_str_value (PidTagInternetReferences, str);
+		set_value (PidTagInternetReferences, str);
 
 	str = camel_medium_get_header ((CamelMedium *) message, "In-Reply-To");
 	if (str)
-		set_str_value (PidTagInReplyToId, str);
+		set_value (PidTagInReplyToId, str);
 
 	str = camel_medium_get_header ((CamelMedium *) message, "Message-ID");
 	if (str)
-		set_str_value (PidTagInternetMessageId, str);
+		set_value (PidTagInternetMessageId, str);
 
 	addresses = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_TO);
 	e_mapi_mail_add_recipients (object, addresses, olTo);
@@ -2405,10 +2401,10 @@ e_mapi_mail_utils_message_to_object (struct _CamelMimeMessage *message,
 	}
 
 	if (msg_class)
-		set_str_value (PidTagMessageClass, msg_class);
+		set_value (PidTagMessageClass, msg_class);
 
 	if (pid_name_content_type)
-		set_str_value (PidNameContentType, pid_name_content_type);
+		set_value (PidNameContentType, pid_name_content_type);
 
 	g_free (msg_class);
 	g_free (pid_name_content_type);
@@ -2416,7 +2412,6 @@ e_mapi_mail_utils_message_to_object (struct _CamelMimeMessage *message,
 	*pobject = object;
 
 	#undef set_value
-	#undef set_str_value
 
 	return TRUE;
 }
diff --git a/src/libexchangemapi/e-mapi-utils.c b/src/libexchangemapi/e-mapi-utils.c
index be5a598..2a25502 100644
--- a/src/libexchangemapi/e-mapi-utils.c
+++ b/src/libexchangemapi/e-mapi-utils.c
@@ -1072,6 +1072,11 @@ e_mapi_utils_add_property (struct mapi_SPropValue_array *properties,
 	g_return_val_if_fail (propvalue != NULL, FALSE);
 	g_return_val_if_fail (mem_ctx != NULL, FALSE);
 
+	/* make copy of string properties */
+	if ((proptag & 0xFFFF) == PT_STRING8 ||
+	    (proptag & 0xFFFF) == PT_UNICODE)
+		propvalue = talloc_strdup (mem_ctx, (const gchar *) propvalue);
+
 	sprop.ulPropTag = proptag;
 	g_return_val_if_fail (set_SPropValue (&sprop, propvalue), FALSE);
 



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