evolution-data-server r9483 - in branches/EXCHANGE_MAPI_BRANCH: addressbook addressbook/backends/mapi addressbook/libedata-book calendar/backends/mapi camel/providers/mapi servers/mapi



Author: msuman
Date: Fri Sep  5 05:54:08 2008
New Revision: 9483
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9483&view=rev

Log:
MAPI - Support for recurring appointments. Create/Modify all/Delete operations are supported. Modify single instance is not implemented.

Modified:
   branches/EXCHANGE_MAPI_BRANCH/addressbook/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c
   branches/EXCHANGE_MAPI_BRANCH/addressbook/libedata-book/e-book-backend-db-cache.h
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c
   branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h

Modified: branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c	Fri Sep  5 05:54:08 2008
@@ -641,7 +641,7 @@
 		exchange_mapi_util_mapi_ids_from_uid (tmp, &fid, &mid);		
 		printf("modify id %s\n", tmp);
 		
-		status = exchange_mapi_modify_item (olFolderContacts, priv->fid, mid, mapi_book_build_name_id, contact, mapi_book_build_props, contact, NULL, NULL, 0);
+		status = exchange_mapi_modify_item (olFolderContacts, priv->fid, mid, mapi_book_build_name_id, contact, mapi_book_build_props, contact, NULL, NULL, NULL, 0);
 		printf("getting %016llX\n", status);
 		if (!status) {
 			e_data_book_respond_modify(book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);

Modified: branches/EXCHANGE_MAPI_BRANCH/addressbook/libedata-book/e-book-backend-db-cache.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/addressbook/libedata-book/e-book-backend-db-cache.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/addressbook/libedata-book/e-book-backend-db-cache.h	Fri Sep  5 05:54:08 2008
@@ -25,6 +25,8 @@
 #include <libebook/e-contact.h>
 #include "db.h"
 
+G_BEGIN_DECLS
+
 EContact* e_book_backend_db_cache_get_contact (DB *db, const char *uid);
 void string_to_dbt(const char *str, DBT *dbt);
 char *e_book_backend_db_cache_get_filename(DB *db);
@@ -39,9 +41,8 @@
 void     e_book_backend_db_cache_set_populated (DB *db);
 gboolean e_book_backend_db_cache_is_populated (DB *db);
 GPtrArray* e_book_backend_db_cache_search (DB *db, const char *query);
-
-
-
+void e_book_backend_db_cache_set_time(DB *db, const char *t);
+char * e_book_backend_db_cache_get_time (DB *db); 
 
 G_END_DECLS
 

Modified: branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c	Fri Sep  5 05:54:08 2008
@@ -365,17 +365,6 @@
 //	exchange_mapi_debug_property_dump (array);
 
 	recurring = NULL;
-	/* FIXME: Provide backend support for recurrence for appointments/meetings */
-	recurring = (const bool *)find_mapi_SPropValue_data(array, PROP_TAG(PT_BOOLEAN, 0x8223));
-	if (recurring && *recurring) {
-		g_warning ("Encountered a recurring event.");
-		exchange_mapi_util_free_stream_list (&streams);
-		exchange_mapi_util_free_recipient_list (&recipients);
-		exchange_mapi_util_free_attachment_list (&attachments);
-		return TRUE;
-	}
-
-	recurring = NULL;
 	/* FIXME: Evolution does not support recurring tasks */
 	recurring = (const bool *)find_mapi_SPropValue_data(array, PROP_TAG(PT_BOOLEAN, 0x8126));
 	if (recurring && *recurring) {
@@ -846,17 +835,6 @@
 //	exchange_mapi_debug_property_dump (properties);
 
 	switch (kind) {
-		case ICAL_VEVENT_COMPONENT:
-			/* FIXME: Provide backend support for recurrence */
-			recurring = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8223));
-			if (recurring && *recurring) {
-				g_warning ("Encountered a recurring event.");
-				exchange_mapi_util_free_stream_list (&streams);
-				exchange_mapi_util_free_recipient_list (&recipients);
-				exchange_mapi_util_free_attachment_list (&attachments);
-				return TRUE;
-			}
-			break;
 		case ICAL_VTODO_COMPONENT:
 			/* FIXME: Evolution does not support recurring tasks */
 			recurring = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8126));
@@ -868,6 +846,7 @@
 				return TRUE;
 			}
 			break;
+		case ICAL_VEVENT_COMPONENT  :
 		case ICAL_VJOURNAL_COMPONENT:
 			break;
 		default:
@@ -1263,6 +1242,7 @@
 	gchar *tmp = NULL;
 	GSList *recipients = NULL;
 	GSList *attachments = NULL;
+	GSList *streams = NULL;
 	struct cbdata cbdata;
 	struct SBinary globalid;
 
@@ -1289,10 +1269,19 @@
 	comp = e_cal_component_new ();
 	e_cal_component_set_icalcomponent (comp, icalcomp);
 
-	/* FIXME: Add support for recurrences */
+	/* FIXME: [WIP] Add support for recurrences */
 	if (e_cal_component_has_recurrences (comp)) {
-		g_object_unref (comp);
-		return GNOME_Evolution_Calendar_OtherError;
+		GByteArray *ba = exchange_mapi_cal_util_rrule_to_bin (comp, NULL); 
+		if (ba) {
+			struct SPropTagArray *tag_array; 
+			ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1); 
+			stream->value = ba; 
+			tag_array = exchange_mapi_util_resolve_named_prop (priv->olFolder, priv->fid, 0x8216, PSETID_Appointment); 
+			if (tag_array) {
+				stream->proptag = tag_array->aulPropTag[0];
+				streams = g_slist_append (streams, stream); 
+			}
+		}
 	}
 
 	/* FIXME: [WIP] Add support for meetings/assigned tasks */
@@ -1329,12 +1318,13 @@
 			mid = exchange_mapi_create_item (priv->olFolder, priv->fid, 
 							exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind), 
 							exchange_mapi_cal_util_build_props, &cbdata, 
-							recipients, attachments, NULL, MAPI_OPTIONS_DONT_SUBMIT);
+							recipients, attachments, streams, MAPI_OPTIONS_DONT_SUBMIT);
 			g_free (cbdata.props);
 //			g_free (globalid.lpb);
 			if (!mid) {
 				g_object_unref (comp);
 				exchange_mapi_util_free_recipient_list (&recipients);
+				exchange_mapi_util_free_stream_list (&streams);
 				exchange_mapi_util_free_attachment_list (&attachments);
 				return GNOME_Evolution_Calendar_OtherError;
 			}
@@ -1350,6 +1340,7 @@
 			break;
 		default:
 			exchange_mapi_util_free_recipient_list (&recipients);
+			exchange_mapi_util_free_stream_list (&streams);
 			exchange_mapi_util_free_attachment_list (&attachments);
 			return GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED;
 	}
@@ -1360,6 +1351,7 @@
 
 	g_object_unref (comp);
 	exchange_mapi_util_free_recipient_list (&recipients);
+	exchange_mapi_util_free_stream_list (&streams);
 	exchange_mapi_util_free_attachment_list (&attachments);
 
 	return GNOME_Evolution_Calendar_Success;
@@ -1432,6 +1424,7 @@
 	mapi_id_t mid;
 	const char *uid = NULL, *rid = NULL;
 	GSList *recipients = NULL;
+	GSList *streams = NULL;
 	GSList *attachments = NULL;
 	struct cbdata cbdata;
 	gboolean no_increment = FALSE;
@@ -1448,6 +1441,11 @@
 	if (priv->mode == CAL_MODE_LOCAL)
 		return GNOME_Evolution_Calendar_RepositoryOffline;
 
+	if (mod != CALOBJ_MOD_ALL) {
+		e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Support for modifying single instances of a recurring appointment is not yet implemented. No change was made to the appointment on the server.")); 
+		return GNOME_Evolution_Calendar_Success;
+	}
+
 	/* check the component for validity */
 	icalcomp = icalparser_parse_string (calobj);
 	if (!icalcomp)
@@ -1466,10 +1464,19 @@
 	comp = e_cal_component_new ();
 	e_cal_component_set_icalcomponent (comp, icalcomp);
 
-	/* FIXME: Add support for recurrences */
+	/* FIXME: [WIP] Add support for recurrences */
 	if (e_cal_component_has_recurrences (comp)) {
-		g_object_unref (comp);
-		return GNOME_Evolution_Calendar_OtherError;
+		GByteArray *ba = exchange_mapi_cal_util_rrule_to_bin (comp, NULL); 
+		if (ba) {
+			struct SPropTagArray *tag_array; 
+			ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1); 
+			stream->value = ba; 
+			tag_array = exchange_mapi_util_resolve_named_prop (priv->olFolder, priv->fid, 0x8216, PSETID_Appointment); 
+			if (tag_array) {
+				stream->proptag = tag_array->aulPropTag[0];
+				streams = g_slist_append (streams, stream); 
+			}
+		}
 	}
 
 	if (e_cal_component_has_attendees (comp)) 
@@ -1479,7 +1486,7 @@
 		exchange_mapi_cal_util_fetch_attachments (comp, &attachments, priv->local_attachments_store);
 
 	e_cal_component_get_uid (comp, &uid);
-	rid = e_cal_component_get_recurid_as_string (comp);
+//	rid = e_cal_component_get_recurid_as_string (comp);
 
 	switch (priv->mode) {
 	case CAL_MODE_ANY :
@@ -1495,6 +1502,7 @@
 			g_message ("CRITICAL : Could not find the object in cache");
 			g_object_unref (comp);
 			exchange_mapi_util_free_recipient_list (&recipients);
+			exchange_mapi_util_free_stream_list (&streams);
 			exchange_mapi_util_free_attachment_list (&attachments);
 			return GNOME_Evolution_Calendar_ObjectNotFound;
 		}
@@ -1524,12 +1532,13 @@
 		status = exchange_mapi_modify_item (priv->olFolder, priv->fid, mid, 
 						exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind), 
 						exchange_mapi_cal_util_build_props, &cbdata, 
-						recipients, attachments, MAPI_OPTIONS_DONT_SUBMIT);
+						recipients, attachments, streams, MAPI_OPTIONS_DONT_SUBMIT);
 		g_free (cbdata.props);
 		if (!status) {
 			g_object_unref (comp);
 			g_object_unref (cache_comp);
 			exchange_mapi_util_free_recipient_list (&recipients);
+			exchange_mapi_util_free_stream_list (&streams);
 			exchange_mapi_util_free_attachment_list (&attachments);
 			return GNOME_Evolution_Calendar_OtherError;
 		}
@@ -1538,6 +1547,7 @@
 		g_object_unref (comp);
 		g_object_unref (cache_comp);
 		exchange_mapi_util_free_recipient_list (&recipients);
+		exchange_mapi_util_free_stream_list (&streams);
 		exchange_mapi_util_free_attachment_list (&attachments);
 		return GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED;
 	}
@@ -1548,6 +1558,7 @@
 	g_object_unref (comp);
 	g_object_unref (cache_comp);
 	exchange_mapi_util_free_recipient_list (&recipients);
+	exchange_mapi_util_free_stream_list (&streams);
 	exchange_mapi_util_free_attachment_list (&attachments);
 
 	return GNOME_Evolution_Calendar_Success;
@@ -1578,7 +1589,8 @@
 	case CAL_MODE_ANY :
 	case CAL_MODE_REMOTE : 	/* when online, modify/delete the item from the server */
 		/* check if the object exists */
-		status = e_cal_backend_mapi_get_object (backend, cal, uid, rid, &calobj);
+		/* FIXME: we may have detached instances which need to be removed */
+		status = e_cal_backend_mapi_get_object (backend, cal, uid, NULL, &calobj);
 		if (status != GNOME_Evolution_Calendar_Success)
 			return status;
 
@@ -1599,7 +1611,7 @@
 			time_rid = icaltime_from_string (rid);
 			e_cal_util_remove_instances (icalcomp, time_rid, mod);
 			new_calobj  = (char *) icalcomponent_as_ical_string (icalcomp);
-			status = e_cal_backend_mapi_modify_object (backend, cal, new_calobj, mod, &obj, &new_object);
+			status = e_cal_backend_mapi_modify_object (backend, cal, new_calobj, CALOBJ_MOD_ALL, &obj, &new_object);
 			if (status == GNOME_Evolution_Calendar_Success) {
 				*old_object = obj;
 				*object = new_object;
@@ -1637,10 +1649,13 @@
 			g_slist_free (comp_list);
 		} 
 		g_free (calobj);
-		return status;
+		break; 
 	default :
-		return GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED;
+		status = GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED;
+		break; 
 	}
+
+	return status;
 }
 
 static ECalBackendSyncStatus 

Modified: branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c	Fri Sep  5 05:54:08 2008
@@ -597,8 +597,6 @@
 
 	PR_BODY, 
 	PR_BODY_UNICODE, 
-	PR_BODY_HTML, 
-	PR_BODY_HTML_UNICODE, 
 
 	PR_DISPLAY_TO, 
 	PR_DISPLAY_TO_UNICODE, 

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am	Fri Sep  5 05:54:08 2008
@@ -29,7 +29,10 @@
 	exchange-mapi-cal-utils.c		\
 	exchange-mapi-cal-utils.h		\
 	exchange-mapi-cal-tz-utils.c		\
-	exchange-mapi-cal-tz-utils.h
+	exchange-mapi-cal-tz-utils.h		\
+	exchange-mapi-cal-recur-utils.c		\
+	exchange-mapi-cal-recur-utils.h
+
 
 libexchangemapi_1_0_la_LIBADD =			\
 	$(E_DATA_SERVER_LIBS)			\
@@ -44,7 +47,8 @@
 	exchange-mapi-connection.h		\
 	exchange-mapi-utils.h			\
 	exchange-mapi-cal-utils.h		\
-	exchange-mapi-cal-tz-utils.h
+	exchange-mapi-cal-tz-utils.h		\
+	exchange-mapi-cal-recur-utils.h
 
 %-1.0.pc: %.pc
 	 cp $< $@

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c	Fri Sep  5 05:54:08 2008
@@ -25,47 +25,207 @@
 
 #include "exchange-mapi-cal-recur-utils.h"
 
-#define ZERO_BYTE 	0x00
+/* Reader/Writer versions */
+#define READER_VERSION 	0x3004
+#define WRITER_VERSION 	0x3004
+#define READER_VERSION2 0x3006
+#define WRITER_VERSION2 0x3009
+
+#if 0
+struct ChangeHighlight {
+	uint32_t Size; 
+	uint32_t Value; 
+	uint32_t Reserved; 
+};
+
+struct ExtendedException {
+	struct ChangeHighlight ch; 
+	uint32_t ReservedEE1Size;
+	uint32_t ReservedEE1;
+	uint32_t StartDateTime; 
+	uint32_t EndDateTime; 
+	uint32_t OrigStartDate; 
+	uint16_t WideCharSubjectLength; 
+	gchar *WideCharSubject; 
+	uint16_t WideCharLocationLength; 
+	gchar *WideCharLocation; 
+	uint32_t ReservedEE2Size;
+	uint32_t ReservedEE2;
+};
+
+struct ExceptionInfo {
+	uint32_t StartDateTime; 
+	uint32_t EndDateTime; 
+	uint32_t OrigStartDate; 
+	uint16_t OverrideFlags; 
+	uint16_t SubjectLength; 
+	uint16_t SubjectLength2; 
+	gchar *Subject; 
+	uint32_t MeetingType; 
+	uint32_t ReminderDelta; 
+	uint32_t ReminderSet; 
+	uint16_t LocationLength; 
+	uint16_t LocationLength2; 
+	gchar *Location; 
+	uint32_t BusyStatus; 
+	uint32_t Attachment; 
+	uint32_t SubType; 
+	uint32_t AppointmentColor; 
+};
+#endif
 
-/* preamble */
-#define PREAMBLE 0x30043004
+static icalrecurrencetype_weekday 
+get_ical_weekstart (uint32_t fdow) 
+{
+	switch (fdow) {
+		case FirstDOW_Sunday 	: return ICAL_SUNDAY_WEEKDAY;
+		case FirstDOW_Monday 	: return ICAL_MONDAY_WEEKDAY;
+		case FirstDOW_Tuesday 	: return ICAL_TUESDAY_WEEKDAY;
+		case FirstDOW_Wednesday : return ICAL_WEDNESDAY_WEEKDAY;
+		case FirstDOW_Thursday 	: return ICAL_THURSDAY_WEEKDAY;
+		case FirstDOW_Friday 	: return ICAL_FRIDAY_WEEKDAY;
+		case FirstDOW_Saturday 	: return ICAL_SATURDAY_WEEKDAY;
+		default 		: return ICAL_SUNDAY_WEEKDAY;
+	}
+}
 
-/** Pattern termination **/
-#define REPEAT_UNTIL 	0x00002021
-#define REPEAT_FOR_N 	0x00002022
-#define REPEAT_FOREVER 	0x00002023
+static uint32_t 
+get_mapi_weekstart (icalrecurrencetype_weekday weekstart) 
+{
+	switch (weekstart) {
+		case ICAL_SUNDAY_WEEKDAY   : return FirstDOW_Sunday;
+		case ICAL_MONDAY_WEEKDAY   : return FirstDOW_Monday;
+		case ICAL_TUESDAY_WEEKDAY  : return FirstDOW_Tuesday;
+		case ICAL_WEDNESDAY_WEEKDAY: return FirstDOW_Wednesday;
+		case ICAL_THURSDAY_WEEKDAY : return FirstDOW_Thursday;
+		case ICAL_FRIDAY_WEEKDAY   : return FirstDOW_Friday;
+		case ICAL_SATURDAY_WEEKDAY : return FirstDOW_Saturday;
+		default 		   : return FirstDOW_Sunday;
+	}
+}
 
-/** Outlook version indicator (?) **/
-#define VERSION_PREAMBLE 0x00003006
-/* This version-id is equivalent to Outlook 2007 */
-#define VERSION_ID 	 0x00003009
+static uint32_t 
+get_mapi_day (icalrecurrencetype_weekday someday)
+{
+	switch (someday) {
+		case ICAL_SUNDAY_WEEKDAY   : return olSunday;
+		case ICAL_MONDAY_WEEKDAY   : return olMonday;
+		case ICAL_TUESDAY_WEEKDAY  : return olTuesday;
+		case ICAL_WEDNESDAY_WEEKDAY: return olWednesday;
+		case ICAL_THURSDAY_WEEKDAY : return olThursday;
+		case ICAL_FRIDAY_WEEKDAY   : return olFriday;
+		case ICAL_SATURDAY_WEEKDAY : return olSaturday;
+		default 		   : return 0;
+	}
+}
 
+static int32_t 
+get_ical_pos (uint32_t pos) 
+{
+	switch (pos) {
+		case RecurrenceN_First 	: return 1;
+		case RecurrenceN_Second : return 2;
+		case RecurrenceN_Third 	: return 3;
+		case RecurrenceN_Fourth : return 4;
+		case RecurrenceN_Last 	: return (-1);
+		default 		: return 0;
+	}
+}
 
-/* terminal sequence (should add twice) */
-#define TERMINAL_SEQ 	0x00000000
+static uint32_t 
+get_mapi_pos (int32_t pos) 
+{
+	switch (pos) {
+		case 1 	: return RecurrenceN_First;
+		case 2 	: return RecurrenceN_Second;
+		case 3 	: return RecurrenceN_Third;
+		case 4 	: return RecurrenceN_Fourth;
+		case -1 : return RecurrenceN_Last;
+		default : return 0;
+	}
+}
 
-struct icaltimetype dt1601;
-struct icaltimetype dt1970;
+#define cFileTimeUnitsPerSecond 10000000
 
-static icalrecurrencetype_weekday 
-get_ical_weekday (uint32_t olWeekday) {
-	switch (olWeekday) {
-		case olSunday: 
-			return ICAL_SUNDAY_WEEKDAY;
-		case olMonday: 
-			return ICAL_MONDAY_WEEKDAY;
-		case olTuesday: 
-			return ICAL_TUESDAY_WEEKDAY;
-		case olWednesday: 
-			return ICAL_WEDNESDAY_WEEKDAY;
-		case olThursday: 
-			return ICAL_THURSDAY_WEEKDAY;
-		case olFriday: 
-			return ICAL_FRIDAY_WEEKDAY;
-		case olSaturday: 
-			return ICAL_SATURDAY_WEEKDAY;
-		default: 
-			return ICAL_SUNDAY_WEEKDAY;
+static void
+convert_recurrence_minutes_to_date (uint32_t minutes, struct FILETIME *ft)
+{
+	NTTIME nt; 
+
+	nt = (NTTIME) minutes * (60 * cFileTimeUnitsPerSecond); 
+
+	ft->dwLowDateTime = (uint32_t)((nt << 32) >> 32); 
+	ft->dwHighDateTime = (uint32_t)(nt >> 32); 
+}
+
+static uint32_t
+convert_date_to_recurrence_minutes (const struct FILETIME *ft)
+{
+	NTTIME minutes;
+
+	minutes = ft->dwHighDateTime; 
+	minutes = minutes << 32;
+	minutes |= ft->dwLowDateTime;
+
+	minutes = minutes / (60 * cFileTimeUnitsPerSecond); 
+
+	return (uint32_t)(minutes);
+}
+
+static time_t 
+convert_filetime_to_timet (const struct FILETIME *ft)
+{
+	NTTIME time; 
+
+	time = ft->dwHighDateTime;
+	time = time << 32;
+	time |= ft->dwLowDateTime;
+
+	return nt_time_to_unix (time);
+}
+
+static void 
+convert_timet_to_filetime (time_t t, struct FILETIME *ft)
+{
+	NTTIME nt; 
+
+	unix_to_nt_time (&nt, t);
+
+	ft->dwLowDateTime = (uint32_t)((nt << 32) >> 32); 
+	ft->dwHighDateTime = (uint32_t)(nt >> 32); 
+}
+
+static time_t
+convert_recurrence_minutes_to_timet (uint32_t minutes)
+{
+	NTTIME nt; 
+
+	nt = (NTTIME) minutes * (60 * cFileTimeUnitsPerSecond); 
+
+	return nt_time_to_unix (nt);
+}
+
+static uint32_t
+convert_timet_to_recurrence_minutes (time_t t)
+{
+	NTTIME minutes;
+
+	unix_to_nt_time (&minutes, t);
+
+	minutes = minutes / (60 * cFileTimeUnitsPerSecond); 
+
+	return (uint32_t)(minutes);
+}
+
+static gboolean 
+check_calendar_type (guint16 type) 
+{
+	/* Calendar Type - We support Gregorian only. */
+	if (type == CAL_DEFAULT || type == CAL_GREGORIAN)
+		return TRUE; 
+	else {
+		g_warning ("Calendar type = 0x%04X - Evolution does not handle such calendar types.", type); 
+		return FALSE; 
 	}
 }
 
@@ -76,29 +236,42 @@
 	guint16 flag16;
 	guint32 flag32;
 	guint8 *ptr = ba->data;
-	GSList l;
 	gint i;
+	GSList *exdate_list = NULL, *modified_list = NULL; 
+	gboolean repeats_until_date = FALSE; 
 
 	icalrecurrencetype_clear (&rt);
 
-	/* Major version */
-	flag32 = *((guint32 *)ptr);
-	ptr += sizeof (guint32);
-	if (PREAMBLE != flag32)
+	/* Reader version */
+	flag16 = *((guint16 *)ptr);
+	ptr += sizeof (guint16);
+	if (READER_VERSION != flag16)
+		return FALSE;
+
+	/* Writer version */
+	flag16 = *((guint16 *)ptr);
+	ptr += sizeof (guint16);
+	if (WRITER_VERSION != flag16)
 		return FALSE;
 
 	/* FREQUENCY */
 	flag16 = *((guint16 *)ptr);
 	ptr += sizeof (guint16);
-	if (flag16 == 0x200A) {
+	if (flag16 == RecurFrequency_Daily) {
 		rt.freq = ICAL_DAILY_RECURRENCE;
 
-		flag32 = *((guint32 *)ptr);
-		ptr += sizeof (guint32);
-		if (flag32 == 0x0) {
+		flag16 = *((guint16 *)ptr);
+		ptr += sizeof (guint16);
+		if (flag16 == PatternType_Day) {
 			/* Daily every N days */
 
-			/* some crappy mod here */
+			/* Calendar Type */
+			flag16 = *((guint16 *)ptr);
+			ptr += sizeof (guint16);
+			if (!check_calendar_type (flag16))
+				return FALSE;
+
+			/* FirstDateTime (some crappy mod here) */
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
 
@@ -112,15 +285,22 @@
 			ptr += sizeof (guint32);
 			if (flag32)
 				return FALSE;
-		} else if (flag32 == 0x1) {
+
+		} else if (flag16 == PatternType_Week) {
 			/* Daily every weekday */
 
+			/* Calendar Type */
+			flag16 = *((guint16 *)ptr);
+			ptr += sizeof (guint16);
+			if (!check_calendar_type (flag16))
+				return FALSE;
+
 	/* NOTE: Evolution does not handle daily-every-weekday any different 
 	 * from a weekly recurrence.
 	 */
 			rt.freq = ICAL_WEEKLY_RECURRENCE;
 
-			/* some crappy mod here */
+			/* FirstDateTime (some crappy mod here) */
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
 
@@ -156,15 +336,21 @@
 				rt.by_day[i++] = ICAL_SATURDAY_WEEKDAY;
 		}
 
-	} else if (flag16 == 0x200B) {
+	} else if (flag16 == RecurFrequency_Weekly) {
 		rt.freq = ICAL_WEEKLY_RECURRENCE;
 
-		flag32 = *((guint32 *)ptr);
-		ptr += sizeof (guint32);
-		if (flag32 == 0x1) {
+		flag16 = *((guint16 *)ptr);
+		ptr += sizeof (guint16);
+		if (flag16 == PatternType_Week) {
 			/* weekly every N weeks (for all events and non-regenerating tasks) */
 
-			/* some crappy mod here */
+			/* Calendar Type */
+			flag16 = *((guint16 *)ptr);
+			ptr += sizeof (guint16);
+			if (!check_calendar_type (flag16))
+				return FALSE;
+
+			/* FirstDateTime (some crappy mod here) */
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
 
@@ -198,23 +384,37 @@
 				rt.by_day[i++] = ICAL_FRIDAY_WEEKDAY;
 			if (flag32 & olSaturday)
 				rt.by_day[i++] = ICAL_SATURDAY_WEEKDAY;
-		} else if (flag32 == 0x0) {
+
+		} else if (flag16 == 0x0) {
 			/* weekly every N weeks (for all regenerating tasks) */
 
+			/* Calendar Type */
+			flag16 = *((guint16 *)ptr);
+			ptr += sizeof (guint16);
+			if (!check_calendar_type (flag16))
+				return FALSE;
+
 			/* FIXME: we don't handle regenerating tasks */
+			g_warning ("Evolution does not handle recurring tasks."); 
 			return FALSE;
 		}
 
-	} else if (flag16 == 0x200C) {
+	} else if (flag16 == RecurFrequency_Monthly) {
 		rt.freq = ICAL_MONTHLY_RECURRENCE;
 
-		flag32 = *((guint32 *)ptr);
-		ptr += sizeof (guint32);
-
-		if (flag32 == 0x2) {
-			/* Monthly every N months on day D */
+		flag16 = *((guint16 *)ptr);
+		ptr += sizeof (guint16);
+		if (flag16 == PatternType_Month || flag16 == PatternType_MonthEnd) {
+			guint16 pattern = flag16; 
+			/* Monthly every N months on day D or last day. */
+
+			/* Calendar Type */
+			flag16 = *((guint16 *)ptr);
+			ptr += sizeof (guint16);
+			if (!check_calendar_type (flag16))
+				return FALSE;
 
-			/* some crappy mod here */
+			/* FirstDateTime (some crappy mod here) */
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
 
@@ -229,14 +429,26 @@
 			if (flag32)
 				return FALSE;
 
-			/* MONTH_DAY */
+			/* MONTH_DAY */ 
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
-			rt.by_month_day[0] = (short) (flag32);
-		} else if (flag32 == 0x3) {
+			if (pattern == PatternType_Month)
+				rt.by_month_day[0] = (short) (flag32);
+			else if (pattern == PatternType_MonthEnd)
+				rt.by_month_day[0] = (short) (-1);
+
+		} else if (flag16 == PatternType_MonthNth) {
+			gboolean post_process = FALSE; 
+			guint32 mask = 0;
 			/* Monthly every N months on the Xth Y */
 
-			/* some crappy mod here */
+			/* Calendar Type */
+			flag16 = *((guint16 *)ptr);
+			ptr += sizeof (guint16);
+			if (!check_calendar_type (flag16))
+				return FALSE;
+
+			/* FirstDateTime (some crappy mod here) */
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
 
@@ -250,23 +462,64 @@
 			ptr += sizeof (guint32);
 			if (flag32)
 				return FALSE;
-
 			
+			/* BITMASK */
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
-			if (flag32 > 4)
-
+			if (flag32 == olSunday)
+				rt.by_day[0] = ICAL_SUNDAY_WEEKDAY;
+			else if (flag32 == olMonday)
+				rt.by_day[0] = ICAL_MONDAY_WEEKDAY;
+			else if (flag32 == olTuesday)
+				rt.by_day[0] = ICAL_TUESDAY_WEEKDAY;
+			else if (flag32 == olWednesday)
+				rt.by_day[0] = ICAL_WEDNESDAY_WEEKDAY;
+			else if (flag32 == olThursday)
+				rt.by_day[0] = ICAL_THURSDAY_WEEKDAY;
+			else if (flag32 == olFriday)
+				rt.by_day[0] = ICAL_FRIDAY_WEEKDAY;
+			else if (flag32 == olSaturday)
+				rt.by_day[0] = ICAL_SATURDAY_WEEKDAY;
+			else {
+				post_process = TRUE; 
+				mask = flag32; 
+			}
+				
+			/* RecurrenceN */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			if (!post_process) {
+				rt.by_set_pos[0] = get_ical_pos (flag32); 
+				if (rt.by_set_pos[0] == 0)
+					return FALSE; 
+			} else {
+				if (mask == (olSunday | olMonday | olTuesday | olWednesday | olThursday | olFriday | olSaturday)) {
+					rt.by_month_day[0] = get_ical_pos (flag32); 
+					if (rt.by_month_day[0] == 0)
+						return FALSE; 
+				} else {
+				/* FIXME: Can we/LibICAL support any other types here? Namely, weekday and weekend-day */
+					g_warning ("Encountered a recurrence type Evolution cannot handle. "); 
+					return FALSE;
+				}
+			}
 		}
 
-	} else if (flag16 == 0x200D) {
+	} else if (flag16 == RecurFrequency_Yearly) {
 		rt.freq = ICAL_YEARLY_RECURRENCE;
 
-		flag32 = *((guint32 *)ptr);
-		ptr += sizeof (guint32);
-
-		if (flag32 == 0x2) {
+		flag16 = *((guint16 *)ptr);
+		ptr += sizeof (guint16);
+		if (flag16 == PatternType_Month) {
 			/* Yearly on day D of month M */
 
+			/* Calendar Type */
+			flag16 = *((guint16 *)ptr);
+			ptr += sizeof (guint16);
+			if (!check_calendar_type (flag16))
+				return FALSE;
+
+			/* FirstDateTime (some crappy mod here) */
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
 
@@ -281,12 +534,22 @@
 			if (flag32)
 				return FALSE;
 
+			/* MONTH_DAY - but we don't need this */
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
-		} else if (flag32 == 0x3) {
+
+		} else if (flag16 == PatternType_MonthNth) {
 			/* Yearly on the Xth Y of month M */
-			g_warning ("Encountered a recurrence pattern Evolution cannot handle");
 
+			g_warning ("Encountered a recurrence pattern Evolution cannot handle.");
+
+			/* Calendar Type */
+			flag16 = *((guint16 *)ptr);
+			ptr += sizeof (guint16);
+			if (!check_calendar_type (flag16))
+				return FALSE;
+
+			/* FirstDateTime (some crappy mod here) */
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
 
@@ -301,9 +564,11 @@
 			if (flag32)
 				return FALSE;
 
+			/* BITMASK */
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
 
+			/* RecurrenceN */
 			flag32 = *((guint32 *)ptr);
 			ptr += sizeof (guint32);
 
@@ -313,108 +578,575 @@
 	} else 
 		return FALSE;
 
-	/* repeat */
+	/* End Type - followed by Occurence count */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-	if (flag32 == REPEAT_UNTIL) {
+	if (flag32 == END_AFTER_DATE) {
 		flag32 = *((guint32 *)ptr);
 		ptr += sizeof (guint32);
-	} else if (flag32 == REPEAT_FOR_N) {
+
+		repeats_until_date = TRUE;
+	} else if (flag32 == END_AFTER_N_OCCURRENCES) {
 		flag32 = *((guint32 *)ptr);
 		ptr += sizeof (guint32);
 
 		rt.count = flag32;
-	} else if (flag32 == REPEAT_FOREVER) {
+	} else if (flag32 == END_NEVER_END) {
 		flag32 = *((guint32 *)ptr);
 		ptr += sizeof (guint32);
-		if (flag32)
-			return FALSE;
 	}
 
 	/* week_start */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-	rt.week_start = get_ical_weekday (flag32);
-g_print ("week start %x\n", flag32);
+	rt.week_start = get_ical_weekstart (flag32);
 
 	/* number of exceptions */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-	/* fixme: exceptions */
-	if (flag32) 
-		ptr += flag32 * sizeof (guint32);
-g_print ("excpt no %x\n", flag32);
+	if (flag32) {
+		for (i = 0; i < flag32; ++i) {
+			uint32_t exdate; 
+			struct icaltimetype tt, *val; 
+			ECalComponentDateTime *dt = g_new0 (ECalComponentDateTime, 1); 
+
+			exdate = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			tt = icaltime_from_timet_with_zone (convert_recurrence_minutes_to_timet (exdate), 1, 0);
+
+			val = g_new0(struct icaltimetype, 1); 
+			memcpy (val, &tt, sizeof(struct icaltimetype)); 
+
+			dt->value = val; 
+			dt->tzid = g_strdup ("UTC"); 
+
+			exdate_list = g_slist_append (exdate_list, dt); 
+		}
+	}
 
 	/* number of changed exceptions */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-	/* fixme: exceptions */
+	/* FIXME: Parse modified instances */
 	if (flag32) 
 		ptr += flag32 * sizeof (guint32);
-g_print ("changed excpt %x\n", flag32);
 	
 	/* start date */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-g_print ("start date %x\n", flag32);
 
 	/* end date */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-g_print ("end date %x\n", flag32);
+	if (repeats_until_date) {
+		rt.until = icaltime_from_timet_with_zone (convert_recurrence_minutes_to_timet (flag32), 1, 0);
+	}
 
 	/* some constant */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-	if (flag32 != VERSION_PREAMBLE)
+	if (flag32 != READER_VERSION2)
 		return FALSE;
-g_print ("constant %x\n", flag32);
 
-	/* version info */
+	/* some constant */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-	if (flag32 != VERSION_ID)
+	if (flag32 != WRITER_VERSION2)
 		return FALSE;
-g_print ("ver info %x\n", flag32);
 
 	/* start time in mins */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-g_print ("start time in mins %x\n", flag32);
 
 	/* end time in mins */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-g_print ("end time in mins %x\n", flag32);
 
-	/* exceptions */
+	/* modified exceptions */
 	flag16 = *((guint16 *)ptr);
 	ptr += sizeof (guint16);
 	if (flag16 != 0x0)
 		return FALSE;
-g_print ("excpt no %x\n", flag16);
 
-	/* term seq */
+	/* reserved block1 size - has to be 0 */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-	if (flag32 != TERMINAL_SEQ)
+	if (flag32 != 0x0)
 		return FALSE;
-g_print ("term seq 1 %x\n", flag32);
 
-	/* term seq */
+	/* reserved block2 size - has to be 0 */
 	flag32 = *((guint32 *)ptr);
 	ptr += sizeof (guint32);
-	if (flag32 != TERMINAL_SEQ)
+	if (flag32 != 0x0)
 		return FALSE;
 
 	/* Set the recurrence */
+	{
+		GSList l;
 
-	l.data = &rt;
-	l.next = NULL;
+		l.data = &rt; 
+		l.next = NULL;
 
-	e_cal_component_set_rrule_list (comp, &l);
+		e_cal_component_set_rrule_list (comp, &l);
+	}
 
-	g_print ("\n\nyipppeee... parsed the blob..\n\n");
+	/* FIXME: this also has modified instances */
+	e_cal_component_set_exdate_list (comp, exdate_list); 
+
+	g_print ("\n== MAPI to ICAL == 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"); 
 
 	return TRUE;
 }
+
+static guint32
+compute_startdate (ECalComponent *comp)
+{
+	ECalComponentDateTime dtstart; 
+	guint32 flag32; 
+
+	e_cal_component_get_dtstart (comp, &dtstart);
+	dtstart.value->hour = dtstart.value->minute = dtstart.value->second = 0; 
+	flag32 = convert_timet_to_recurrence_minutes (icaltime_as_timet_with_zone (*(dtstart.value), 0));
+
+	e_cal_component_free_datetime (&dtstart); 
+
+	return flag32; 
+}
+
+static guint32
+compute_rdaily_firstdatetime (ECalComponent *comp, guint32 period)
+{
+	return (compute_startdate (comp) % period);
+}
+
+static guint32
+compute_rweekly_firstdatetime (ECalComponent *comp, icalrecurrencetype_weekday week_start, guint32 period)
+{
+	ECalComponentDateTime dtstart; 
+	guint32 flag32; 
+	int cur_weekday = 0, weekstart_weekday = 0, diff = 0;
+	time_t t; 
+
+	e_cal_component_get_dtstart (comp, &dtstart);
+	dtstart.value->hour = dtstart.value->minute = dtstart.value->second = 0; 
+	cur_weekday = icaltime_day_of_week (*(dtstart.value));
+	t = icaltime_as_timet_with_zone (*(dtstart.value), 0);
+	e_cal_component_free_datetime (&dtstart); 
+
+	switch (week_start) {
+		case ICAL_SUNDAY_WEEKDAY 	: weekstart_weekday = 1; break; 
+		case ICAL_MONDAY_WEEKDAY 	: weekstart_weekday = 2; break; 
+		case ICAL_TUESDAY_WEEKDAY 	: weekstart_weekday = 3; break; 
+		case ICAL_WEDNESDAY_WEEKDAY 	: weekstart_weekday = 4; break; 
+		case ICAL_THURSDAY_WEEKDAY 	: weekstart_weekday = 5; break; 
+		case ICAL_FRIDAY_WEEKDAY 	: weekstart_weekday = 6; break; 
+		case ICAL_SATURDAY_WEEKDAY 	: weekstart_weekday = 7; break; 
+		default 			: weekstart_weekday = 1; break; 
+	};
+
+	diff = cur_weekday - weekstart_weekday; 
+
+	if (diff == 0); 
+	else if (diff > 0)
+		t -= (diff * 24 * 60 * 60);
+	else if (diff < 0)
+		t -= ((diff + 7) * 24 * 60 * 60);
+
+	flag32 = convert_timet_to_recurrence_minutes (t);
+
+	return (flag32 % period);
+}
+
+/* The most fucked up algorithm ever conceived by (..you know who..) */
+static guint32
+compute_rmonthly_firstdatetime (ECalComponent *comp, guint32 period)
+{
+	const guint8 dinm[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+	ECalComponentDateTime dtstart; 
+	guint32 flag32, monthindex, i; 
+
+	e_cal_component_get_dtstart (comp, &dtstart);
+	monthindex = (guint32)((((guint64)(12) * (dtstart.value->year - 1601)) + (dtstart.value->month - 1)) % period); 
+	e_cal_component_free_datetime (&dtstart); 
+
+	for (flag32 = 0, i = 0; i < monthindex; ++i)
+		flag32 += dinm[(i % 12) + 1] * 24 * 60;
+
+	return flag32; 
+}
+
+static guint32
+calculate_no_of_occurrences (ECalComponent *comp, const struct icalrecurrencetype *rt)
+{
+	ECalComponentDateTime dtstart; 
+	icalrecur_iterator *iter; 
+	struct icaltimetype next; 
+	guint32 count = 1; 
+
+	e_cal_component_get_dtstart (comp, &dtstart);
+
+	for (iter = icalrecur_iterator_new (*rt, *(dtstart.value)), 
+	     next = icalrecur_iterator_next(iter);
+	     !icaltime_is_null_time(next);
+	     next = icalrecur_iterator_next(iter))
+		++count; 
+
+	icalrecur_iterator_free (iter); 
+	e_cal_component_free_datetime (&dtstart); 
+
+	return count; 
+}
+
+static gint 
+compare_guint32 (gconstpointer a, gconstpointer b, gpointer user_data)
+{
+	return (*((guint32 *) a) - *((guint32 *) b));
+}
+
+GByteArray *
+exchange_mapi_cal_util_rrule_to_bin (ECalComponent *comp, GSList *modified_comps)
+{
+	struct icalrecurrencetype *rt;
+	guint16 flag16;
+	guint32 flag32, end_type;
+	gint i; 
+	GSList *rrule_list = NULL, *exdate_list = NULL; 
+	GByteArray *ba = NULL;
+
+	if (!e_cal_component_has_recurrences (comp))
+		return NULL; 
+
+	e_cal_component_get_rrule_list (comp, &rrule_list); 
+	e_cal_component_get_exdate_list (comp, &exdate_list); 
+
+	if (g_slist_length (rrule_list) != 1)
+		goto cleanup; 
+
+	rt = (struct icalrecurrencetype *)(rrule_list->data);
+
+	ba = g_byte_array_new (); 
+
+	/* Reader Version */
+	flag16 = READER_VERSION;
+	ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+	/* Writer Version */
+	flag16 = WRITER_VERSION;
+	ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+	if (rt->freq == ICAL_DAILY_RECURRENCE) {
+		flag16 = RecurFrequency_Daily;
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		/* Pattern Type - it would be PatternType_Day since we have only "Daily every N days" 
+		 * The other type would be parsed as a weekly recurrence. 
+		 */
+		flag16 = PatternType_Day;
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		/* Calendar Type */
+		flag16 = CAL_DEFAULT; 
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		/* FirstDateTime */
+		flag32 = compute_rdaily_firstdatetime (comp, (rt->interval * (60 * 24)));
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		/* INTERVAL */
+		flag32 = (rt->interval * (60 * 24)); 
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		/* This would be 0 for the stuff we handle */
+		flag32 = 0x0;
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		/* No PatternTypeSpecific for PatternType_Day */
+
+	} else if (rt->freq == ICAL_WEEKLY_RECURRENCE) {
+		flag16 = RecurFrequency_Weekly;
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		/* Pattern Type - it would be PatternType_Week since we don't support any other type. */
+		flag16 = PatternType_Week;
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		/* Calendar Type */
+		flag16 = CAL_DEFAULT; 
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		/* FirstDateTime */
+		flag32 = compute_rweekly_firstdatetime (comp, rt->week_start, (rt->interval * (60 * 24 * 7)));
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		/* INTERVAL */
+		flag32 = rt->interval; 
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		/* This would be 0 for the stuff we handle */
+		flag32 = 0x0;
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		/* BITMASK */
+		for (flag32 = 0x0, i = 0; i < ICAL_BY_DAY_SIZE; ++i) {
+			if (rt->by_day[i] == ICAL_SUNDAY_WEEKDAY)
+				flag32 |= olSunday; 
+			else if (rt->by_day[i] == ICAL_MONDAY_WEEKDAY)
+				flag32 |= olMonday; 
+			else if (rt->by_day[i] == ICAL_TUESDAY_WEEKDAY)
+				flag32 |= olTuesday; 
+			else if (rt->by_day[i] == ICAL_WEDNESDAY_WEEKDAY)
+				flag32 |= olWednesday; 
+			else if (rt->by_day[i] == ICAL_THURSDAY_WEEKDAY)
+				flag32 |= olThursday; 
+			else if (rt->by_day[i] == ICAL_FRIDAY_WEEKDAY)
+				flag32 |= olFriday; 
+			else if (rt->by_day[i] == ICAL_SATURDAY_WEEKDAY)
+				flag32 |= olSaturday; 
+			else 
+				break; 
+		}
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	} else if (rt->freq == ICAL_MONTHLY_RECURRENCE) {
+		guint16 pattern = 0x0; guint32 mask = 0x0, flag = 0x0; 
+
+		flag16 = RecurFrequency_Monthly;
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		if (rt->by_month_day[0] >= 1 && rt->by_month_day[0] <= 31) {
+			pattern = PatternType_Month;
+			flag = rt->by_month_day[0]; 
+		} else if (rt->by_month_day[0] == -1) {
+			pattern = PatternType_MonthNth; 
+			mask = (olSunday | olMonday | olTuesday | olWednesday | olThursday | olFriday | olSaturday); 
+			flag = RecurrenceN_Last; 
+		} else if (rt->by_day[0] >= ICAL_SUNDAY_WEEKDAY && rt->by_day[0] <= ICAL_SATURDAY_WEEKDAY) {
+			pattern = PatternType_MonthNth;
+			mask = get_mapi_day (rt->by_day[0]);
+			flag = get_mapi_pos (rt->by_set_pos[0]);
+		}
+
+		/* Pattern Type */
+		flag16 = pattern;
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		/* Calendar Type */
+		flag16 = CAL_DEFAULT; 
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		/* FirstDateTime */
+		flag32 = compute_rmonthly_firstdatetime (comp, rt->interval);
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		/* INTERVAL */
+		flag32 = rt->interval; 
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		/* This would be 0 for the stuff we handle */
+		flag32 = 0x0;
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		if (pattern == PatternType_Month) {
+			flag32 = flag;
+			ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+			if (!(flag))
+				g_warning ("Possibly setting incorrect values in the stream. "); 
+		} else if (pattern == PatternType_MonthNth) {
+			flag32 = mask;
+			ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+			flag32 = flag;
+			ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+			if (!(flag && mask))
+				g_warning ("Possibly setting incorrect values in the stream. "); 
+		} else 
+			g_warning ("Possibly setting incorrect values in the stream. "); 
+
+	} else if (rt->freq == ICAL_YEARLY_RECURRENCE) {
+		flag16 = RecurFrequency_Yearly;
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		/* Pattern Type - it would be PatternType_Month since we don't support any other type. */
+		flag16 = PatternType_Month;
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		/* Calendar Type */
+		flag16 = CAL_DEFAULT; 
+		ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+		/* FirstDateTime - uses the same function as monthly recurrence */
+		flag32 = compute_rmonthly_firstdatetime (comp, 0xC);
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		/* INTERVAL - should be 12 for yearly recurrence */
+		flag32 = 0xC; 
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		/* This would be 0 for the stuff we handle */
+		flag32 = 0x0;
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		/* MONTH_DAY */
+		{
+			ECalComponentDateTime dtstart; 
+			e_cal_component_get_dtstart (comp, &dtstart);
+			flag32 = dtstart.value->day; 
+			e_cal_component_free_datetime (&dtstart); 
+		}
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	} 
+
+	/* End Type followed by Occurence count */
+	if (!icaltime_is_null_time (rt->until)) {
+		flag32 = END_AFTER_DATE;
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		flag32 = calculate_no_of_occurrences (comp, rt); 
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		end_type = END_AFTER_DATE;
+	} else if (rt->count) {
+		flag32 = END_AFTER_N_OCCURRENCES;
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		flag32 = rt->count;
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		end_type = END_AFTER_N_OCCURRENCES;
+	} else {
+		flag32 = END_NEVER_END;
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		flag32 = 0x0;
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+		end_type = END_NEVER_END;
+	}
+
+	/* FirstDOW */
+	flag32 = get_mapi_weekstart (rt->week_start); 
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	/* DeletedInstances */
+	flag32 = g_slist_length (exdate_list);
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+	if (flag32) {
+		GSList *l; 
+		guint32 *sorted_list = g_new0(guint32, flag32);
+		/* FIXME: This should include modified dates */
+		for (i = 0, l = exdate_list; l; ++i, l = l->next) {
+			ECalComponentDateTime *dt = (ECalComponentDateTime *)(l->data); 
+			dt->value->hour = dt->value->minute = dt->value->second = 0; 
+			sorted_list[i] = convert_timet_to_recurrence_minutes (icaltime_as_timet_with_zone (*(dt->value), 0)); 
+		}
+
+		g_qsort_with_data (sorted_list, flag32, sizeof (guint32), compare_guint32, NULL); 
+
+		for (i = 0; i < flag32; ++i)
+			ba = g_byte_array_append (ba, &(sorted_list[i]), sizeof (guint32));
+
+		g_free (sorted_list);
+	}
+
+	/* FIXME: Add support for modified instances */
+	/* ModifiedInstanceCount */
+	flag32 = 0x0;
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+	if (flag32) {
+	}
+
+	/* StartDate */
+	flag32 = compute_startdate (comp); 
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	/* EndDate */
+	{
+		if (end_type == END_NEVER_END) 
+			flag32 = 0x5AE980DF; 
+		else if (end_type == END_AFTER_N_OCCURRENCES) {
+			ECalComponentDateTime dtstart; 
+			gchar *rrule_str = icalrecurrencetype_as_string (rt); 
+			time_t *array = g_new0 (time_t, rt->count); 
+
+			e_cal_component_get_dtstart (comp, &dtstart);
+			dtstart.value->hour = dtstart.value->minute = dtstart.value->second = 0; 
+
+			icalrecur_expand_recurrence (rrule_str, icaltime_as_timet_with_zone (*(dtstart.value), 0), rt->count, array); 
+
+			flag32 = convert_timet_to_recurrence_minutes (array[(rt->count) - 1]); 
+
+			g_free (array); 
+			g_free (rrule_str); 
+			e_cal_component_free_datetime (&dtstart); 
+		} else if (end_type == END_AFTER_DATE) {
+			struct icaltimetype until; 
+			memcpy (&until, &(rt->until), sizeof(struct icaltimetype));
+			until.hour = until.minute = until.second = 0; 
+			flag32 = convert_timet_to_recurrence_minutes (icaltime_as_timet_with_zone (until, 0));
+		} else 
+			flag32 = 0x0; 
+	}
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	/* Reader Version 2 */
+	flag32 = READER_VERSION2;
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	/* Writer Version 2 */
+	flag32 = WRITER_VERSION2;
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	/* StartTimeOffset */
+	{
+		ECalComponentDateTime dtstart; 
+		e_cal_component_get_dtstart (comp, &dtstart);
+		flag32 = (dtstart.value->hour * 60) + dtstart.value->minute; 
+		e_cal_component_free_datetime (&dtstart); 
+	}
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	/* EndTimeOffset */
+	{
+		ECalComponentDateTime dtend; 
+		e_cal_component_get_dtend (comp, &dtend);
+		flag32 = (dtend.value->hour * 60) + dtend.value->minute; 
+		e_cal_component_free_datetime (&dtend); 
+	}
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	/* FIXME: Add support for modified instances */
+	/* ModifiedExceptionCount */
+	flag16 = 0x0; 
+	ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+	/* FIXME: Add the ExceptionInfo here */
+
+	/* Reserved Block 1 Size */
+	flag32 = 0x0;
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	/* FIXME: Add the ExtendedExceptionInfo here */
+
+	/* Reserved Block 2 Size */
+	flag32 = 0x0;
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+cleanup: 
+	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");
+	for (i = 0; i < ba->len; ++i)
+		g_print ("0x%02X ", ba->data[i]);
+	g_print("\n== End of stream ==\n"); 
+
+	return ba; 
+}
+

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h	Fri Sep  5 05:54:08 2008
@@ -28,11 +28,16 @@
 
 #include <glib.h>
 
+#include "exchange-mapi-cal-utils.h"
+
 G_BEGIN_DECLS
 
 gboolean
 exchange_mapi_cal_util_bin_to_rrule (GByteArray *ba, ECalComponent *comp);
 
+GByteArray *
+exchange_mapi_cal_util_rrule_to_bin (ECalComponent *comp, GSList *modified_comps);
+
 G_END_DECLS
 
 #endif

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h	Fri Sep  5 05:54:08 2008
@@ -27,6 +27,7 @@
 #define EXCHANGE_MAPI_CAL_TZ_UTILS_H
 
 #include <glib.h>
+
 #include "exchange-mapi-cal-utils.h"
 
 G_BEGIN_DECLS

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c	Fri Sep  5 05:54:08 2008
@@ -701,8 +701,6 @@
 		subject = ""; 
 
 	body = (const gchar *)exchange_mapi_util_find_array_propval(properties, PR_BODY);
-	if (!body)
-		body = (const gchar *)exchange_mapi_util_find_array_propval(properties, PR_BODY_HTML);
 	if (!body) {
 		body_stream = exchange_mapi_util_find_stream (streams, PR_HTML);
 		body = body_stream ? (const gchar *) body_stream->value->data : ""; 
@@ -800,16 +798,6 @@
 			icalcomponent_add_property (ical_comp, prop);
 		}
 
-		b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8223));
-		if (b && *b) {
-			/* FIXME: recurrence */
-			g_warning ("Encountered a recurring event.");
-/*			stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x8216));
-			if (stream) {
-				e_cal_backend_mapi_util_bin_to_rrule (stream->value, comp);
-			}
-*/		} 
-
 		if (recipients) {
 			b = (const bool *)find_mapi_SPropValue_data(properties, PR_RESPONSE_REQUESTED);
 			ical_attendees_from_props (ical_comp, recipients, (b && *b));
@@ -845,6 +833,14 @@
 			}
 		}
 
+		b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8223));
+		if (b && *b) {
+			stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x8216));
+			if (stream) {
+				exchange_mapi_cal_util_bin_to_rrule (stream->value, comp);
+			}
+		} 
+
 		b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8503));
 		if (b && *b) {
 			struct timeval start, displaytime;
@@ -1098,7 +1094,7 @@
 #if 0
 		gchar *filename = g_build_filename (g_get_home_dir (), TEMP_ATTACH_STORE, NULL);
 		gchar *fileuri = g_filename_to_uri (filename, NULL, NULL);
-		GSList *attachments = NULL, *recipients = NULL;
+		GSList *attachments = NULL, *recipients = NULL, *streams = NULL;
 
 		if (e_cal_component_has_attachments (cbdata.comp))
 			exchange_mapi_cal_util_fetch_attachments (cbdata.comp, &attachments, fileuri);
@@ -1116,7 +1112,7 @@
 		status = exchange_mapi_modify_item (olFolderCalendar, fid, mid, 
 				exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER (kind), 
 				exchange_mapi_cal_util_build_props, &cbdata, 
-				recipients, attachments, MAPI_OPTIONS_DONT_SUBMIT);
+				recipients, attachments, streams, MAPI_OPTIONS_DONT_SUBMIT);
 		g_free (cbdata.props);
 
 		exchange_mapi_util_free_recipient_list (&recipients);
@@ -1387,7 +1383,7 @@
  */
 
 
-#define APPT_NAMED_PROPS_N  30
+#define APPT_NAMED_PROPS_N  29
 #define DEFAULT_APPT_REMINDER_MINS 15
 
 typedef enum 
@@ -1396,37 +1392,37 @@
 	I_APPT_BUSYSTATUS , 
 	I_APPT_LOCATION , 
 	I_APPT_START , 
-/*5*/	I_APPT_END , 
+	I_APPT_END , 
 	I_APPT_DURATION , 
 	I_APPT_ALLDAY , 
-/**/	I_APPT_RECURBLOB , 
+	I_APPT_RECURBLOB , 
 	I_APPT_STATEFLAGS , 
-/*10*/	I_APPT_RESPONSESTATUS , 
+	I_APPT_RESPONSESTATUS , 
 	I_APPT_RECURRING , 
 	I_APPT_INTENDEDBUSY , 
-/**/	I_APPT_RECURBASE , 
+	I_APPT_RECURBASE , 
 	I_APPT_INVITED , 
-/*15*/	I_APPT_RECURTYPE , 
-/**/	I_APPT_RECURPATTERN , 
+	I_APPT_RECURTYPE , 
 	I_APPT_CLIPSTART , 
 	I_APPT_CLIPEND , 
 	I_APPT_AUTOLOCATION , 
-/*20*/	I_APPT_ISCOUNTERPROPOSAL , 
+	I_APPT_ISCOUNTERPROPOSAL , 
 	I_APPT_NOTALLOWPROPOSE , 
 	I_APPT_STARTTZBLOB , 
 	I_APPT_ENDTZBLOB , 
 
 	I_MEET_WHERE , 
-/*25*/	I_MEET_GUID , 
+	I_MEET_GUID , 
 	I_MEET_ISRECURRING , 
 	I_MEET_ISEXCEPTION , 
 	I_MEET_CLEANGUID , 
 	I_MEET_APPTMSGCLASS , 
-/*30*/	I_MEET_TYPE
+	I_MEET_TYPE
 
 //	I_APPT_SENDASICAL , 
 //	I_APPT_SEQTIME , 
 //	I_APPT_LABEL , 
+//	I_APPT_RECURPATTERN , 
 //	I_APPT_DISPTZ , 
 //	I_APPT_ALLATTENDEES , 
 //	I_APPT_TOATTENDEES , 
@@ -1451,7 +1447,6 @@
 	mapi_nameid_lid_add(nameid, 0x8228, PSETID_Appointment); 	// PT_SYSTIME - RecurrenceBase
 	mapi_nameid_lid_add(nameid, 0x8229, PSETID_Appointment); 	// PT_BOOLEAN - FInvited
 	mapi_nameid_lid_add(nameid, 0x8231, PSETID_Appointment); 	// PT_LONG - RecurrenceType
-	mapi_nameid_lid_add(nameid, 0x8232, PSETID_Appointment); 	// PT_STRING8 - RecurrencePattern
 	mapi_nameid_lid_add(nameid, 0x8235, PSETID_Appointment); 	// PT_SYSTIME - (dtstart)(for recurring events UTC 12 AM of day of start)
 	mapi_nameid_lid_add(nameid, 0x8236, PSETID_Appointment); 	// PT_SYSTIME - (dtend)(for recurring events UTC 12 AM of day of end)
 	mapi_nameid_lid_add(nameid, 0x823A, PSETID_Appointment); 	// PT_BOOLEAN - AutoFillLocation
@@ -1472,6 +1467,7 @@
 //	mapi_nameid_lid_add(nameid, 0x8200, PSETID_Appointment); 	// PT_BOOLEAN - SendAsICAL
 //	mapi_nameid_lid_add(nameid, 0x8202, PSETID_Appointment); 	// PT_SYSTIME - ApptSequenceTime
 //	mapi_nameid_lid_add(nameid, 0x8214, PSETID_Appointment); 	// PT_LONG - Label
+//	mapi_nameid_lid_add(nameid, 0x8232, PSETID_Appointment); 	// PT_STRING8 - RecurrencePattern
 //	mapi_nameid_lid_add(nameid, 0x8234, PSETID_Appointment); 	// PT_STRING8 - display TimeZone
 //	mapi_nameid_lid_add(nameid, 0x8238, PSETID_Appointment); 	// PT_STRING8 - AllAttendees
 //	mapi_nameid_lid_add(nameid, 0x823B, PSETID_Appointment); 	// PT_STRING8 - ToAttendeesString (dupe PR_DISPLAY_TO)
@@ -1802,8 +1798,27 @@
 		b = (icaltime_is_date (dtstart) && icaltime_is_date (dtend));
 		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_ALLDAY], (const void *) &b);
 
-		/* FIXME: for RecurrenceType */
-		flag32 = rectypeNone ;
+		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_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RECURTYPE], (const void *) &flag32);
 
 		flag32 = cbdata->appt_id;
@@ -1959,10 +1974,10 @@
 			break;
 		}
 
-		/* FIXME: Recurring */
-		b = e_cal_component_has_recurrences (comp) && FALSE; b = 0;
+		b = e_cal_component_has_recurrences (comp);
 		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RECURRING], (const void *) &b);
 		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_ISRECURRING], (const void *) &b);
+		/* FIXME: Modified exceptions */
 		b = e_cal_component_has_exceptions (comp) && FALSE; b = 0;
 		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_ISEXCEPTION], (const void *) &b);
 

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h	Fri Sep  5 05:54:08 2008
@@ -32,9 +32,7 @@
 #include "exchange-mapi-utils.h"
 
 #include "exchange-mapi-cal-tz-utils.h"
-#if 0
 #include "exchange-mapi-cal-recur-utils.h"
-#endif
 
 G_BEGIN_DECLS
 
@@ -112,8 +110,6 @@
 	PR_CONVERSATION_TOPIC_UNICODE, 
 	PR_BODY, 
 	PR_BODY_UNICODE, 
-	PR_BODY_HTML, 
-	PR_BODY_HTML_UNICODE, 
 
 	PR_CREATION_TIME, 
 	PR_LAST_MODIFICATION_TIME, 

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c	Fri Sep  5 05:54:08 2008
@@ -571,10 +571,10 @@
 		/* If there are any streams to be set, write them. */
 		exchange_mapi_util_write_generic_streams (&obj_attach, attachment->streams);
 
-		/* message->SaveChanges() */
+		/* message->SaveChangesAttachment() */
 		retval = SaveChangesAttachment(obj_message, &obj_attach, KEEP_OPEN_READWRITE);
 		if (retval != MAPI_E_SUCCESS) {
-			mapi_errstr("SaveChanges", GetLastError());
+			mapi_errstr("SaveChangesAttachment", GetLastError());
 			goto cleanup;
 		}
 
@@ -2022,7 +2022,7 @@
 exchange_mapi_modify_item (uint32_t olFolder, mapi_id_t fid, mapi_id_t mid, 
 			   BuildNameID build_name_id, gpointer ni_data, 
 			   BuildProps build_props, gpointer p_data, 
-			   GSList *recipients, GSList *attachments, 
+			   GSList *recipients, GSList *attachments, GSList *generic_streams, 
 			   uint32_t options)
 {
 	enum MAPISTATUS retval;
@@ -2110,6 +2110,10 @@
 		goto cleanup;
 	}
 
+	if (generic_streams) {
+		exchange_mapi_util_write_generic_streams (&obj_message, generic_streams);
+	}
+
 	/* Set attachments if any */
 	if (attachments) {
 		exchange_mapi_util_set_attachments (&obj_message, attachments, TRUE);

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h	Fri Sep  5 05:54:08 2008
@@ -148,7 +148,7 @@
 exchange_mapi_modify_item (uint32_t olFolder, mapi_id_t fid, mapi_id_t mid, 
 			   BuildNameID build_name_id, gpointer ni_data, 
 			   BuildProps build_props, gpointer p_data,
-			   GSList *recipients, GSList *attachments,
+			   GSList *recipients, GSList *attachments, GSList *generic_streams,
 			   uint32_t options);
 
 gboolean

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h	Fri Sep  5 05:54:08 2008
@@ -237,6 +237,7 @@
     olApptException = 3
 } OlRecurrenceState;
 
+#if 0
 typedef enum {
     olRecursDaily = 0,
     olRecursWeekly = 1,
@@ -245,6 +246,7 @@
     olRecursYearly = 5,
     olRecursYearNth = 6
 } OlRecurrencePatternType;
+#endif 
 
 
 #define IPM_CONTACT 				"IPM.Contact"



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