evolution-data-server r9086 - in branches/EXCHANGE_MAPI_BRANCH: calendar/backends/mapi servers/mapi



Author: msuman
Date: Thu Jul  3 08:02:54 2008
New Revision: 9086
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9086&view=rev

Log:
MAPI - Move the calendar utility files to servers.

Added:
   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.c
   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/tz-ical-to-mapi
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/tz-mapi-to-ical
Removed:
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-recur-utils.c
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-recur-utils.h
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-tz-utils.c
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-tz-utils.h
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-utils.c
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-utils.h
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/tz-ical-to-mapi
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/tz-mapi-to-ical
Modified:
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/Makefile.am
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-factory.c
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.h
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am

Modified: branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/Makefile.am
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/Makefile.am	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/Makefile.am	Thu Jul  3 08:02:54 2008
@@ -10,25 +10,16 @@
 	-I$(top_builddir)/libical/src/libical		\
 	-I$(top_srcdir)/servers/mapi			\
 	-I$(top_builddir)/servers/mapi			\
-	-DMAPI_DATADIR=\""$(mapidatadir)"\"		\
 	$(EVOLUTION_CALENDAR_CFLAGS)			\
 	$(LIBMAPI_CFLAGS)
 
 extension_LTLIBRARIES = libecalbackendmapi.la
 
-mapidata_DATA = \
-	tz-mapi-to-ical 	\
-	tz-ical-to-mapi 
-
 libecalbackendmapi_la_SOURCES =		\
 	e-cal-backend-mapi-factory.c	\
 	e-cal-backend-mapi-factory.h	\
 	e-cal-backend-mapi.c		\
-	e-cal-backend-mapi.h		\
-	e-cal-backend-mapi-utils.c	\
-	e-cal-backend-mapi-utils.h	\
-	e-cal-backend-mapi-tz-utils.c	\
-	e-cal-backend-mapi-tz-utils.h
+	e-cal-backend-mapi.h
 
 libecalbackendmapi_la_LIBADD =						\
 	$(top_builddir)/calendar/libecal/libecal-1.2.la			\
@@ -42,5 +33,3 @@
 libecalbackendmapi_la_LDFLAGS =		\
 	-module -avoid-version $(NO_UNDEFINED)
 
-EXTRA_DIST = 	\
-	$(mapidata_DATA)

Modified: branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-factory.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-factory.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-factory.c	Thu Jul  3 08:02:54 2008
@@ -29,7 +29,7 @@
 
 #include "e-cal-backend-mapi-factory.h"
 #include "e-cal-backend-mapi.h"
-#include "e-cal-backend-mapi-tz-utils.h"
+
 #define d(x) 
 
 typedef struct {
@@ -205,14 +205,14 @@
 	mapi_types[1] = events_backend_factory_get_type (module);
 	mapi_types[2] = journal_backend_factory_get_type (module);
 
-	e_cal_backend_mapi_tz_util_populate ();
-	d(e_cal_backend_mapi_tz_util_dump ());
+	exchange_mapi_cal_tz_util_populate ();
+	d(exchange_mapi_cal_tz_util_dump ());
 }
 
 void
 eds_module_shutdown   (void)
 {
-	e_cal_backend_mapi_tz_util_destroy ();
+	exchange_mapi_cal_tz_util_destroy ();
 }
 
 void

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	Thu Jul  3 08:02:54 2008
@@ -27,7 +27,7 @@
 #include <gio/gio.h>
 
 #include "e-cal-backend-mapi.h"
-#include "e-cal-backend-mapi-utils.h"
+
 #define d(x) x
 
 #ifdef G_OS_WIN32
@@ -346,59 +346,13 @@
 	return GNOME_Evolution_Calendar_Success;
 }
 
-/* we don't have to specify the PR_BODY_* tags since it is fetched by default */
-static const uint32_t GetPropsList[] = {
-	PR_FID, 
-	PR_MID, 
-	PR_SUBJECT, 
-	PR_SUBJECT_UNICODE, 
-	PR_SUBJECT_ERROR, 
-	PR_NORMALIZED_SUBJECT, 
-	PR_NORMALIZED_SUBJECT_UNICODE, 
-	PR_NORMALIZED_SUBJECT_ERROR, 
-	PR_CREATION_TIME, 
-	PR_LAST_MODIFICATION_TIME, 
-	PR_PRIORITY, 
-	PR_SENSITIVITY, 
-	PR_START_DATE, 
-	PR_END_DATE, 
-	PR_RESPONSE_REQUESTED, 
-
-	PR_SENT_REPRESENTING_NAME, 
-	PR_SENT_REPRESENTING_NAME_UNICODE, 
-	PR_SENT_REPRESENTING_ADDRTYPE, 
-	PR_SENT_REPRESENTING_ADDRTYPE_UNICODE, 
-	PR_SENT_REPRESENTING_EMAIL_ADDRESS, 
-	PR_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE, 
-
-	PR_SENDER_NAME, 
-	PR_SENDER_NAME_UNICODE, 
-	PR_SENDER_ADDRTYPE, 
-	PR_SENDER_ADDRTYPE_UNICODE, 
-	PR_SENDER_EMAIL_ADDRESS, 
-	PR_SENDER_EMAIL_ADDRESS_UNICODE, 
-
-	PR_RCVD_REPRESENTING_NAME, 
-	PR_RCVD_REPRESENTING_NAME_UNICODE, 
-	PR_RCVD_REPRESENTING_ADDRTYPE, 
-	PR_RCVD_REPRESENTING_ADDRTYPE_UNICODE, 
-	PR_RCVD_REPRESENTING_EMAIL_ADDRESS, 
-	PR_RCVD_REPRESENTING_EMAIL_ADDRESS_UNICODE
-};
-static const uint16_t n_GetPropsList = G_N_ELEMENTS (GetPropsList);
-
-static const uint32_t IDList[] = {
-	PR_FID, 
-	PR_MID
-};
-static const uint16_t n_IDList = G_N_ELEMENTS (IDList);
-
 static gboolean
 mapi_cal_get_changes_cb (struct mapi_SPropValue_array *array, const mapi_id_t fid, const mapi_id_t mid, 
 			 GSList *streams, GSList *recipients, GSList *attachments, gpointer data)
 {
 	ECalBackendMAPI *cbmapi	= data;
 	ECalBackendMAPIPrivate *priv = cbmapi->priv;
+	icalcomponent_kind kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbmapi));
 	gchar *tmp = NULL;
 	ECalComponent *cache_comp = NULL;
 	const bool *recurring;
@@ -431,7 +385,9 @@
 	cache_comp = e_cal_backend_cache_get_component (priv->cache, tmp, NULL);
 
 	if (cache_comp == NULL) {
-		ECalComponent *comp = e_cal_backend_mapi_props_to_comp (cbmapi, tmp, array, streams, recipients, attachments, priv->default_zone);
+		ECalComponent *comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, tmp, array, 
+									streams, recipients, attachments, 
+									priv->local_attachments_store, priv->default_zone);
 
 		if (E_IS_CAL_COMPONENT (comp)) {
 			char *comp_str;
@@ -462,8 +418,9 @@
 				e_cal_component_commit_sequence (cache_comp);
 				cache_comp_str = e_cal_component_get_as_string (cache_comp);
 
-				comp = e_cal_backend_mapi_props_to_comp (cbmapi, tmp, array, 
-									streams, recipients, attachments, priv->default_zone);
+				comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, tmp, array, 
+									streams, recipients, attachments, 
+									priv->local_attachments_store, priv->default_zone);
 
 				e_cal_component_commit_sequence (comp);
 				modif_comp_str = e_cal_component_get_as_string (comp);
@@ -533,8 +490,8 @@
 		return FALSE;
 
 	cbmapi = (ECalBackendMAPI *) handle;
-	kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbmapi));
 	priv= cbmapi->priv;
+	kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbmapi));
 
 	if (priv->mode == CAL_MODE_LOCAL)
 		return FALSE;
@@ -566,8 +523,8 @@
 
 //	e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
 	if (!exchange_mapi_connection_fetch_items (priv->fid, use_restriction ? &res : NULL, 
-						GetPropsList, n_GetPropsList, 
-						mapi_cal_build_name_id, cbmapi, 
+						cal_GetPropsList, n_cal_GetPropsList, 
+						exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind), 
 						mapi_cal_get_changes_cb, cbmapi, 
 						MAPI_OPTIONS_FETCH_ALL)) {
 		/* FIXME: better string please... */
@@ -590,7 +547,7 @@
 	 * so should not be freed, only the list should. */
 	priv->cache_keys = e_cal_backend_cache_get_keys (priv->cache);
 	if (!exchange_mapi_connection_fetch_items (priv->fid, NULL, 
-						IDList, n_IDList, 
+						cal_IDList, n_cal_IDList, 
 						NULL, NULL, 
 						handle_deleted_items_cb, cbmapi, 
 						0)) {
@@ -863,13 +820,14 @@
 {
 	ECalBackendMAPI *cbmapi	= E_CAL_BACKEND_MAPI (data);
 	ECalBackendMAPIPrivate *priv = cbmapi->priv;
+	icalcomponent_kind kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbmapi));
         ECalComponent *comp = NULL;
 	gchar *tmp = NULL;
 	const bool *recurring = NULL;
 
 //	exchange_mapi_debug_property_dump (properties);
 
-	switch (e_cal_backend_get_kind (E_CAL_BACKEND (cbmapi))) {
+	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));
@@ -899,7 +857,9 @@
 	}
 	
 	tmp = exchange_mapi_util_mapi_id_to_string (mid);
-	comp = e_cal_backend_mapi_props_to_comp (cbmapi, tmp, properties, streams, recipients, attachments, priv->default_zone);
+	comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, tmp, properties, 
+							streams, recipients, attachments, 
+							priv->local_attachments_store, priv->default_zone);
 	g_free (tmp);
 
 	if (E_IS_CAL_COMPONENT (comp)) {
@@ -948,8 +908,8 @@
 
 //	e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
 	if (!exchange_mapi_connection_fetch_items (priv->fid, NULL, 
-						GetPropsList, n_GetPropsList, 
-						mapi_cal_build_name_id, cbmapi, 
+						cal_GetPropsList, n_cal_GetPropsList, 
+						exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind), 
 						mapi_cal_cache_create_cb, cbmapi, 
 						MAPI_OPTIONS_FETCH_ALL)) {
 		e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Could not create cache file"));
@@ -1222,6 +1182,7 @@
 {
 	ECalBackendMAPI *cbmapi;
 	ECalBackendMAPIPrivate *priv;
+	icalcomponent_kind kind;
 	icalcomponent *icalcomp;
 	ECalComponent *comp;
 	mapi_id_t mid = 0;
@@ -1232,6 +1193,7 @@
 
 	cbmapi = E_CAL_BACKEND_MAPI (backend);
 	priv = cbmapi->priv;
+	kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
 
 	g_return_val_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), GNOME_Evolution_Calendar_InvalidObject);
 	g_return_val_if_fail (calobj != NULL && *calobj != NULL, GNOME_Evolution_Calendar_InvalidObject);
@@ -1244,7 +1206,7 @@
 	if (!icalcomp)
 		return GNOME_Evolution_Calendar_InvalidObject;
 
-	if (e_cal_backend_get_kind (E_CAL_BACKEND (backend)) != icalcomponent_isa (icalcomp)) {
+	if (kind != icalcomponent_isa (icalcomp)) {
 		icalcomponent_free (icalcomp);
 		return GNOME_Evolution_Calendar_InvalidObject;
 	}
@@ -1260,22 +1222,29 @@
 
 	/* FIXME: [WIP] Add support for meetings/assigned tasks */
 	if (e_cal_component_has_attendees (comp)) 
-		e_cal_backend_mapi_util_fetch_recipients (cbmapi, comp, &recipients);
+		exchange_mapi_cal_util_fetch_recipients (comp, &recipients);
 
 	if (e_cal_component_has_attachments (comp))
-		e_cal_backend_mapi_util_fetch_attachments (cbmapi, comp, &attachments);
+		exchange_mapi_cal_util_fetch_attachments (comp, &attachments, priv->local_attachments_store);
+
+	cbdata.username = e_cal_backend_mapi_get_user_name (cbmapi);
+	cbdata.userid = e_cal_backend_mapi_get_user_email (cbmapi);
+	cbdata.ownername = e_cal_backend_mapi_get_owner_name (cbmapi);
+	cbdata.ownerid = e_cal_backend_mapi_get_owner_email (cbmapi);
 
 	/* Check if object exists */
 	switch (priv->mode) {
 		case CAL_MODE_ANY:
 		case CAL_MODE_REMOTE:
 			/* Create an appointment */
-			cbdata.cbmapi = cbmapi;
 			cbdata.comp = comp;
 			cbdata.meeting_type = (recipients != NULL) ? MEETING_OBJECT : NOT_A_MEETING;
 			cbdata.msgflags = MSGFLAG_READ;
 			cbdata.new_appt_id = get_new_appt_id (cbmapi);
-			mid = exchange_mapi_create_item (priv->olFolder, priv->fid, mapi_cal_build_name_id, cbmapi, mapi_cal_build_props, &cbdata, recipients, attachments, NULL, MAPI_OPTIONS_DONT_SUBMIT);
+			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);
 			if (!mid) {
 				g_object_unref (comp);
 				exchange_mapi_util_free_recipient_list (&recipients);
@@ -1309,6 +1278,7 @@
 {
 	ECalBackendMAPI *cbmapi;
         ECalBackendMAPIPrivate *priv;
+	icalcomponent_kind kind;
 	icalcomponent *icalcomp;
 	ECalComponent *comp, *cache_comp = NULL;
 	gboolean status;
@@ -1323,6 +1293,7 @@
 	*old_object = *new_object = NULL;
 	cbmapi = E_CAL_BACKEND_MAPI (backend);
 	priv = cbmapi->priv;
+	kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
 
 	g_return_val_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), GNOME_Evolution_Calendar_InvalidObject);
 	g_return_val_if_fail (calobj != NULL, GNOME_Evolution_Calendar_InvalidObject);
@@ -1346,14 +1317,19 @@
 
 	/* FIXME: [WIP] Add support for meetings/assigned tasks */
 	if (e_cal_component_has_attendees (comp)) 
-		e_cal_backend_mapi_util_fetch_recipients (cbmapi, comp, &recipients);
+		exchange_mapi_cal_util_fetch_recipients (comp, &recipients);
 
 	if (e_cal_component_has_attachments (comp))
-		e_cal_backend_mapi_util_fetch_attachments (cbmapi, comp, &attachments);
+		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);
 
+	cbdata.username = e_cal_backend_mapi_get_user_name (cbmapi);
+	cbdata.userid = e_cal_backend_mapi_get_user_email (cbmapi);
+	cbdata.ownername = e_cal_backend_mapi_get_owner_name (cbmapi);
+	cbdata.ownerid = e_cal_backend_mapi_get_owner_email (cbmapi);
+
 	switch (priv->mode) {
 	case CAL_MODE_ANY :
 	case CAL_MODE_REMOTE :	/* when online, send the item to the server */
@@ -1366,12 +1342,14 @@
 		}
 		exchange_mapi_util_mapi_id_from_string (uid, &mid);
 
-		cbdata.cbmapi = cbmapi;
 		cbdata.comp = comp;
 //		cbdata.meeting_type = (recipients != NULL) ? MEETING_OBJECT : NOT_A_MEETING;
 		cbdata.msgflags = MSGFLAG_READ;
 		cbdata.new_appt_id = 0x0;
-		status = exchange_mapi_modify_item (priv->olFolder, priv->fid, mid, mapi_cal_build_name_id, cbmapi, mapi_cal_build_props, &cbdata, NULL, NULL, MAPI_OPTIONS_DONT_SUBMIT);
+		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, 
+						NULL, NULL, MAPI_OPTIONS_DONT_SUBMIT);
 		if (!status) {
 			g_object_unref (comp);
 			g_object_unref (cache_comp);
@@ -1547,7 +1525,7 @@
 	res.res.resProperty.relop = RELOP_EQ;
 	res.res.resProperty.ulPropTag = proptag;
 
-	e_cal_backend_mapi_util_generate_globalobjectid (TRUE, uid, &sb);
+	exchange_mapi_cal_util_generate_globalobjectid (TRUE, uid, &sb);
 
 	set_SPropValue_proptag (&sprop, proptag, (const void *) &sb);
 	cast_mapi_SPropValue (&(res.res.resProperty.lpProp), &sprop);
@@ -1566,10 +1544,12 @@
 	ECalBackendSyncStatus status = GNOME_Evolution_Calendar_OtherError;
 	ECalBackendMAPI *cbmapi;
 	ECalBackendMAPIPrivate *priv;
+	icalcomponent_kind kind;
 	icalcomponent *icalcomp;
 
 	cbmapi = E_CAL_BACKEND_MAPI (backend);
 	priv = cbmapi->priv;
+	kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
 
 	g_return_val_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), GNOME_Evolution_Calendar_InvalidObject);
 	g_return_val_if_fail (calobj != NULL, GNOME_Evolution_Calendar_InvalidObject);
@@ -1587,8 +1567,7 @@
 
 	if (icalcomponent_isa (icalcomp) == ICAL_VCALENDAR_COMPONENT) {
 		icalproperty_method method = icalcomponent_get_method (icalcomp);
-		icalcomponent *subcomp = icalcomponent_get_first_component (icalcomp,
-							     e_cal_backend_get_kind (E_CAL_BACKEND (backend)));
+		icalcomponent *subcomp = icalcomponent_get_first_component (icalcomp, kind);
 		while (subcomp) {
 			ECalComponent *comp = e_cal_component_new ();
 			struct cbdata cbdata;
@@ -1606,14 +1585,18 @@
 
 			/* FIXME: [WIP] Add support for meetings/assigned tasks */
 			if (e_cal_component_has_attendees (comp)) {
-				e_cal_backend_mapi_util_fetch_recipients (cbmapi, comp, &recipients);
+				exchange_mapi_cal_util_fetch_recipients (comp, &recipients);
 				method = icalcomponent_get_method (icalcomp);
 			}
 
 			if (e_cal_component_has_attachments (comp))
-				e_cal_backend_mapi_util_fetch_attachments (cbmapi, comp, &attachments);
+				exchange_mapi_cal_util_fetch_attachments (comp, &attachments, priv->local_attachments_store);
+
+			cbdata.username = e_cal_backend_mapi_get_user_name (cbmapi);
+			cbdata.userid = e_cal_backend_mapi_get_user_email (cbmapi);
+			cbdata.ownername = e_cal_backend_mapi_get_owner_name (cbmapi);
+			cbdata.ownerid = e_cal_backend_mapi_get_owner_email (cbmapi);
 
-			cbdata.cbmapi = cbmapi;
 			cbdata.comp = comp;
 			cbdata.new_appt_id = 0x0;
 			switch (method) {
@@ -1633,7 +1616,10 @@
 
 			get_server_data (cbmapi, subcomp, &cbdata);
 
-			mid = exchange_mapi_create_item (olFolderOutbox, 0, mapi_cal_build_name_id, cbmapi, mapi_cal_build_props, &cbdata, recipients, attachments, NULL, 0);
+			mid = exchange_mapi_create_item (olFolderOutbox, 0, 
+							exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind), 
+							exchange_mapi_cal_util_build_props, &cbdata, 
+							recipients, attachments, NULL, 0);
 			if (!mid) {
 				g_object_unref (comp);
 				exchange_mapi_util_free_recipient_list (&recipients);

Modified: branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.h	Thu Jul  3 08:02:54 2008
@@ -42,6 +42,7 @@
 
 #include <exchange-mapi-connection.h>
 #include <exchange-mapi-defs.h>
+#include <exchange-mapi-cal-utils.h>
 #include <exchange-mapi-folder.h>
 #include <exchange-mapi-utils.h>
 
@@ -92,30 +93,6 @@
 const char *	
 e_cal_backend_mapi_get_user_email (ECalBackendMAPI *cbmapi);
 
-typedef enum {
-	NOT_A_MEETING = 0, 
-	MEETING_OBJECT = (1 << 0),
-	MEETING_OBJECT_SENT = (1 << 1),
-	MEETING_REQUEST = (1 << 2), 
-	MEETING_RESPONSE = (1 << 3)
-} MAPIMeetingOptions;
-
-struct dup_data {
-	struct SBinary *globalid;
-	struct SBinary *cleanglobalid;
-	uint32_t owner_appt_id;
-	uint32_t appt_seq;
-};
-
-struct cbdata { 
-	ECalBackendMAPI *cbmapi;
-	ECalComponent *comp;
-	MAPIMeetingOptions meeting_type;
-	uint32_t msgflags;
-	uint32_t new_appt_id;
-	struct dup_data dup;
-};
-
 G_END_DECLS
 
 #endif

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	Thu Jul  3 08:02:54 2008
@@ -1,26 +1,42 @@
-
-INCLUDES =						\
-	-DG_LOG_DOMAIN=\"libexchangemapi\"		\
-	-I$(top_srcdir)					\
-	-I$(top_builddir)				\
-	$(LIBMAPI_CFLAGS)				\
-	$(E_DATA_SERVER_CFLAGS)
+INCLUDES =					\
+	-DG_LOG_DOMAIN=\"libexchangemapi\"	\
+	-I$(top_srcdir)				\
+	-I$(top_builddir)			\
+	-I$(top_srcdir)/calendar		\
+	-I$(top_builddir)/calendar		\
+	-I$(top_srcdir)/libical/src		\
+	-I$(top_builddir)/libical/src		\
+	-I$(top_srcdir)/libical/src/libical	\
+	-I$(top_builddir)/libical/src/libical	\
+	$(LIBMAPI_CFLAGS)			\
+	$(E_DATA_SERVER_CFLAGS)			\
+	-DMAPI_DATADIR=\""$(mapidatadir)"\"	\
+	$(EVOLUTION_CALENDAR_CFLAGS)
 
 
 lib_LTLIBRARIES = libexchangemapi-1.0.la
 
-libexchangemapi_1_0_la_SOURCES =			\
-	exchange-mapi-defs.h				\
-	exchange-mapi-folder.c				\
-	exchange-mapi-folder.h				\
-	exchange-mapi-connection.c			\
-	exchange-mapi-connection.h			\
-	exchange-mapi-utils.c				\
-	exchange-mapi-utils.h
-
-libexchangemapi_1_0_la_LIBADD =						\
-	$(E_DATA_SERVER_LIBS)						\
-	$(LIBMAPI_LIBS)
+mapidata_DATA = 				\
+	tz-mapi-to-ical 			\
+	tz-ical-to-mapi 
+
+libexchangemapi_1_0_la_SOURCES =		\
+	exchange-mapi-defs.h			\
+	exchange-mapi-folder.c			\
+	exchange-mapi-folder.h			\
+	exchange-mapi-connection.c		\
+	exchange-mapi-connection.h		\
+	exchange-mapi-utils.c			\
+	exchange-mapi-utils.h			\
+	exchange-mapi-cal-utils.c		\
+	exchange-mapi-cal-utils.h		\
+	exchange-mapi-cal-tz-utils.c		\
+	exchange-mapi-cal-tz-utils.h
+
+libexchangemapi_1_0_la_LIBADD =			\
+	$(LIBMAPI_LIBS)				\
+	$(E_DATA_SERVER_LIBS)			\
+	$(EVOLUTION_CALENDAR_LIBS)
 
 libexchangemapiincludedir = $(privincludedir)/mapi
 
@@ -28,7 +44,9 @@
 	exchange-mapi-defs.h			\
 	exchange-mapi-folder.h			\
 	exchange-mapi-connection.h		\
-	exchange-mapi-utils.h
+	exchange-mapi-utils.h			\
+	exchange-mapi-cal-utils.h		\
+	exchange-mapi-cal-tz-utils.h
 
 %-1.0.pc: %.pc
 	 cp $< $@
@@ -36,7 +54,9 @@
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libexchangemapi-1.0.pc
 
-EXTRA_DIST = $(pkgconfig_DATA:-$(API_VERSION).pc=.pc.in)
+EXTRA_DIST = 						\
+	$(pkgconfig_DATA:-$(API_VERSION).pc=.pc.in) 	\
+	$(mapidata_DATA)
 
 DISTCLEANFILES = $(pkgconfig_DATA)
 

Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c	Thu Jul  3 08:02:54 2008
@@ -0,0 +1,420 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Authors: 
+ *    Suman Manjunath <msuman novell com>
+ *
+ *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public 
+ *  License along with this program; if not, write to: 
+ *  Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#include "exchange-mapi-cal-recur-utils.h"
+
+#define ZERO_BYTE 	0x00
+
+/* preamble */
+#define PREAMBLE 0x30043004
+
+/** Pattern termination **/
+#define REPEAT_UNTIL 	0x00002021
+#define REPEAT_FOR_N 	0x00002022
+#define REPEAT_FOREVER 	0x00002023
+
+/** Outlook version indicator (?) **/
+#define VERSION_PREAMBLE 0x00003006
+/* This version-id is equivalent to Outlook 2007 */
+#define VERSION_ID 	 0x00003009
+
+
+/* terminal sequence (should add twice) */
+#define TERMINAL_SEQ 	0x00000000
+
+struct icaltimetype dt1601;
+struct icaltimetype dt1970;
+
+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;
+	}
+}
+
+gboolean
+exchange_mapi_cal_util_bin_to_rrule (GByteArray *ba, ECalComponent *comp)
+{
+	struct icalrecurrencetype rt;
+	guint16 flag16;
+	guint32 flag32;
+	guint8 *ptr = ba->data;
+	GSList l;
+	gint i;
+
+	icalrecurrencetype_clear (&rt);
+
+	/* Major version */
+	flag32 = *((guint32 *)ptr);
+	ptr += sizeof (guint32);
+	if (PREAMBLE != flag32)
+		return FALSE;
+
+	/* FREQUENCY */
+	flag16 = *((guint16 *)ptr);
+	ptr += sizeof (guint16);
+	if (flag16 == 0x200A) {
+		rt.freq = ICAL_DAILY_RECURRENCE;
+
+		flag32 = *((guint32 *)ptr);
+		ptr += sizeof (guint32);
+		if (flag32 == 0x0) {
+			/* Daily every N days */
+
+			/* some crappy mod here */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			/* INTERVAL */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			rt.interval = (short) (flag32 / (24 * 60));
+
+			/* some constant 0 for the stuff we handle */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			if (flag32)
+				return FALSE;
+		} else if (flag32 == 0x1) {
+			/* Daily every weekday */
+
+	/* NOTE: Evolution does not handle daily-every-weekday any different 
+	 * from a weekly recurrence.
+	 */
+			rt.freq = ICAL_WEEKLY_RECURRENCE;
+
+			/* some crappy mod here */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			/* INTERVAL */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			rt.interval = (short) (flag32);
+
+			/* some constant 0 for the stuff we handle */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			if (flag32)
+				return FALSE;
+
+			/* BITMASK */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			i = 0;
+			if (flag32 & olSunday)
+				rt.by_day[i++] = ICAL_SUNDAY_WEEKDAY;
+			if (flag32 & olMonday)
+				rt.by_day[i++] = ICAL_MONDAY_WEEKDAY;
+			if (flag32 & olTuesday)
+				rt.by_day[i++] = ICAL_TUESDAY_WEEKDAY;
+			if (flag32 & olWednesday)
+				rt.by_day[i++] = ICAL_WEDNESDAY_WEEKDAY;
+			if (flag32 & olThursday)
+				rt.by_day[i++] = ICAL_THURSDAY_WEEKDAY;
+			if (flag32 & olFriday)
+				rt.by_day[i++] = ICAL_FRIDAY_WEEKDAY;
+			if (flag32 & olSaturday)
+				rt.by_day[i++] = ICAL_SATURDAY_WEEKDAY;
+		}
+
+	} else if (flag16 == 0x200B) {
+		rt.freq = ICAL_WEEKLY_RECURRENCE;
+
+		flag32 = *((guint32 *)ptr);
+		ptr += sizeof (guint32);
+		if (flag32 == 0x1) {
+			/* weekly every N weeks (for all events and non-regenerating tasks) */
+
+			/* some crappy mod here */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			/* INTERVAL */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			rt.interval = (short) (flag32);
+
+			/* some constant 0 */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			if (flag32)
+				return FALSE;
+
+			/* BITMASK */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			i = 0;
+			if (flag32 & olSunday)
+				rt.by_day[i++] = ICAL_SUNDAY_WEEKDAY;
+			if (flag32 & olMonday)
+				rt.by_day[i++] = ICAL_MONDAY_WEEKDAY;
+			if (flag32 & olTuesday)
+				rt.by_day[i++] = ICAL_TUESDAY_WEEKDAY;
+			if (flag32 & olWednesday)
+				rt.by_day[i++] = ICAL_WEDNESDAY_WEEKDAY;
+			if (flag32 & olThursday)
+				rt.by_day[i++] = ICAL_THURSDAY_WEEKDAY;
+			if (flag32 & olFriday)
+				rt.by_day[i++] = ICAL_FRIDAY_WEEKDAY;
+			if (flag32 & olSaturday)
+				rt.by_day[i++] = ICAL_SATURDAY_WEEKDAY;
+		} else if (flag32 == 0x0) {
+			/* weekly every N weeks (for all regenerating tasks) */
+
+			/* FIXME: we don't handle regenerating tasks */
+			return FALSE;
+		}
+
+	} else if (flag16 == 0x200C) {
+		rt.freq = ICAL_MONTHLY_RECURRENCE;
+
+		flag32 = *((guint32 *)ptr);
+		ptr += sizeof (guint32);
+
+		if (flag32 == 0x2) {
+			/* Monthly every N months on day D */
+
+			/* some crappy mod here */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			/* INTERVAL */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			rt.interval = (short) (flag32);
+
+			/* some constant 0 for the stuff we handle */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			if (flag32)
+				return FALSE;
+
+			/* MONTH_DAY */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			rt.by_month_day[0] = (short) (flag32);
+		} else if (flag32 == 0x3) {
+			/* Monthly every N months on the Xth Y */
+
+			/* some crappy mod here */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			/* INTERVAL */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			rt.interval = (short) (flag32);
+
+			/* some constant 0 for the stuff we handle */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			if (flag32)
+				return FALSE;
+
+			
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			if (flag32 > 4)
+
+		}
+
+	} else if (flag16 == 0x200D) {
+		rt.freq = ICAL_YEARLY_RECURRENCE;
+
+		flag32 = *((guint32 *)ptr);
+		ptr += sizeof (guint32);
+
+		if (flag32 == 0x2) {
+			/* Yearly on day D of month M */
+
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			/* INTERVAL */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			rt.interval = (short) (flag32 / 12);
+
+			/* some constant 0 for the stuff we handle */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			if (flag32)
+				return FALSE;
+
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+		} else if (flag32 == 0x3) {
+			/* Yearly on the Xth Y of month M */
+			g_warning ("Encountered a recurrence pattern Evolution cannot handle");
+
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			/* INTERVAL */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			rt.interval = (short) (flag32 / 12);
+
+			/* some constant 0 */
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+			if (flag32)
+				return FALSE;
+
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			flag32 = *((guint32 *)ptr);
+			ptr += sizeof (guint32);
+
+			/* TODO: Add support for this kinda recurrence in Evolution */
+			return FALSE;
+		}
+	} else 
+		return FALSE;
+
+	/* repeat */
+	flag32 = *((guint32 *)ptr);
+	ptr += sizeof (guint32);
+	if (flag32 == REPEAT_UNTIL) {
+		flag32 = *((guint32 *)ptr);
+		ptr += sizeof (guint32);
+	} else if (flag32 == REPEAT_FOR_N) {
+		flag32 = *((guint32 *)ptr);
+		ptr += sizeof (guint32);
+
+		rt.count = flag32;
+	} else if (flag32 == REPEAT_FOREVER) {
+		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);
+
+	/* number of exceptions */
+	flag32 = *((guint32 *)ptr);
+	ptr += sizeof (guint32);
+	/* fixme: exceptions */
+	if (flag32) 
+		ptr += flag32 * sizeof (guint32);
+g_print ("excpt no %x\n", flag32);
+
+	/* number of changed exceptions */
+	flag32 = *((guint32 *)ptr);
+	ptr += sizeof (guint32);
+	/* fixme: exceptions */
+	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);
+
+	/* some constant */
+	flag32 = *((guint32 *)ptr);
+	ptr += sizeof (guint32);
+	if (flag32 != VERSION_PREAMBLE)
+		return FALSE;
+g_print ("constant %x\n", flag32);
+
+	/* version info */
+	flag32 = *((guint32 *)ptr);
+	ptr += sizeof (guint32);
+	if (flag32 != VERSION_ID)
+		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 */
+	flag16 = *((guint16 *)ptr);
+	ptr += sizeof (guint16);
+	if (flag16 != 0x0)
+		return FALSE;
+g_print ("excpt no %x\n", flag16);
+
+	/* term seq */
+	flag32 = *((guint32 *)ptr);
+	ptr += sizeof (guint32);
+	if (flag32 != TERMINAL_SEQ)
+		return FALSE;
+g_print ("term seq 1 %x\n", flag32);
+
+	/* term seq */
+	flag32 = *((guint32 *)ptr);
+	ptr += sizeof (guint32);
+	if (flag32 != TERMINAL_SEQ)
+		return FALSE;
+
+	/* Set the recurrence */
+
+	l.data = &rt;
+	l.next = NULL;
+
+	e_cal_component_set_rrule_list (comp, &l);
+
+	g_print ("\n\nyipppeee... parsed the blob..\n\n");
+
+	return TRUE;
+}

Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h	Thu Jul  3 08:02:54 2008
@@ -0,0 +1,39 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Authors: 
+ *    Suman Manjunath <msuman novell com>
+ *
+ *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public 
+ *  License along with this program; if not, write to: 
+ *  Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#ifndef EXCHANGE_MAPI_CAL_RECUR_UTILS_H
+#define EXCHANGE_MAPI_CAL_RECUR_UTILS_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+gboolean
+exchange_mapi_cal_util_bin_to_rrule (GByteArray *ba, ECalComponent *comp);
+
+G_END_DECLS
+
+#endif
+

Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.c
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.c	Thu Jul  3 08:02:54 2008
@@ -0,0 +1,563 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Authors: 
+ *    Suman Manjunath <msuman novell com>
+ *
+ *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public 
+ *  License along with this program; if not, write to: 
+ *  Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#include "exchange-mapi-cal-tz-utils.h"
+
+#define d(x) 
+
+#define MAPPING_SEPARATOR "~~~"
+
+static GStaticRecMutex mutex = G_STATIC_REC_MUTEX_INIT;
+
+static GHashTable *mapi_to_ical = NULL;
+static GHashTable *ical_to_mapi = NULL;
+
+static const gchar *lru_mapi_id = NULL;
+static const gchar *lru_ical_id = NULL;
+
+const gchar *
+exchange_mapi_cal_tz_util_get_mapi_equivalent (const gchar *ical_tzid)
+{
+	g_return_val_if_fail ((ical_tzid && *ical_tzid), NULL);
+
+	g_static_rec_mutex_lock(&mutex);
+	if (!(mapi_to_ical && ical_to_mapi)) {
+		g_static_rec_mutex_unlock(&mutex);
+		return NULL;
+	}
+
+	d(g_message("%s(%d): %s of '%s' ", __FILE__, __LINE__, __PRETTY_FUNCTION__, ical_tzid));
+
+	if (lru_ical_id && !g_ascii_strcasecmp (ical_tzid, lru_ical_id)) {
+		g_static_rec_mutex_unlock(&mutex);
+		return lru_mapi_id;
+	}
+
+	lru_mapi_id = lru_ical_id = NULL;
+	if ((lru_mapi_id = g_hash_table_lookup (ical_to_mapi, ical_tzid)) != NULL)
+		lru_ical_id = ical_tzid;
+
+	g_static_rec_mutex_unlock(&mutex);
+
+	return lru_mapi_id;
+}
+
+const gchar *
+exchange_mapi_cal_tz_util_get_ical_equivalent (const gchar *mapi_tzid)
+{
+	g_return_val_if_fail ((mapi_tzid && *mapi_tzid), NULL);
+
+	g_static_rec_mutex_lock(&mutex);
+	if (!(mapi_to_ical && ical_to_mapi)) {
+		g_static_rec_mutex_unlock(&mutex);
+		return NULL;
+	}
+
+	d(g_message("%s(%d): %s of '%s' ", __FILE__, __LINE__, __PRETTY_FUNCTION__, mapi_tzid));
+
+	if (lru_mapi_id && !g_ascii_strcasecmp (mapi_tzid, lru_mapi_id)) {
+		g_static_rec_mutex_unlock(&mutex);
+		return lru_ical_id;
+	}
+
+	lru_ical_id = lru_mapi_id = NULL;
+	if ((lru_ical_id = g_hash_table_lookup (mapi_to_ical, mapi_tzid)) != NULL)
+		lru_mapi_id = mapi_tzid;
+
+	g_static_rec_mutex_unlock(&mutex);
+
+	return lru_ical_id;
+}
+
+void
+exchange_mapi_cal_tz_util_destroy ()
+{
+	g_static_rec_mutex_lock(&mutex);
+	if (!(mapi_to_ical && ical_to_mapi)) {
+		g_static_rec_mutex_unlock(&mutex);
+		return;
+	}
+
+	g_hash_table_destroy (mapi_to_ical);
+	g_hash_table_destroy (ical_to_mapi);
+
+	/* Reset all the values */
+	mapi_to_ical = NULL;
+	ical_to_mapi = NULL;
+
+	lru_mapi_id = NULL;
+	lru_ical_id = NULL;
+
+	g_static_rec_mutex_unlock(&mutex);
+}
+
+static void 
+file_contents_to_hashtable (const char *contents, GHashTable *table) 
+{
+	gchar **array = NULL;
+	guint len = 0, i;
+
+	array = g_strsplit (contents, "\n", -1);
+	len = g_strv_length (array);
+
+	for (i=0; i < len-1; ++i) {
+		gchar **mapping = g_strsplit (array[i], MAPPING_SEPARATOR, -1);
+		if (g_strv_length (mapping) == 2) 
+			g_hash_table_insert (table, g_strdup (mapping[0]), g_strdup (mapping[1]));
+		g_strfreev (mapping);
+	}
+
+	g_strfreev (array);
+}
+
+gboolean
+exchange_mapi_cal_tz_util_populate ()
+{
+	gchar *mtoi_fn = NULL, *itom_fn = NULL;
+	GMappedFile *mtoi_mf = NULL, *itom_mf = NULL;
+
+	g_static_rec_mutex_lock(&mutex);
+	if (mapi_to_ical && ical_to_mapi) {
+		g_static_rec_mutex_unlock(&mutex);
+		return TRUE;
+	}
+
+	mtoi_fn = g_build_filename (MAPI_DATADIR, "tz-mapi-to-ical", NULL);
+	itom_fn = g_build_filename (MAPI_DATADIR, "tz-ical-to-mapi", NULL);
+
+	mtoi_mf = g_mapped_file_new (mtoi_fn, FALSE, NULL);
+	itom_mf = g_mapped_file_new (itom_fn, FALSE, NULL);
+
+	g_free (mtoi_fn);
+	g_free (itom_fn);
+
+	if (!(mtoi_mf && itom_mf)) {
+		g_warning ("Could not map Exchange MAPI timezone files.");
+
+		if (mtoi_mf)
+			g_mapped_file_free (mtoi_mf);
+		if (itom_mf)
+			g_mapped_file_free (itom_mf);
+
+		g_static_rec_mutex_unlock(&mutex);
+		return FALSE;
+	}
+
+	mapi_to_ical = g_hash_table_new_full   ((GHashFunc) g_str_hash, 
+						(GEqualFunc) g_str_equal, 
+						(GDestroyNotify) g_free, 
+						(GDestroyNotify) g_free);
+
+	file_contents_to_hashtable (g_mapped_file_get_contents (mtoi_mf), mapi_to_ical);
+
+	ical_to_mapi = g_hash_table_new_full   ((GHashFunc) g_str_hash, 
+						(GEqualFunc) g_str_equal, 
+						(GDestroyNotify) g_free, 
+						(GDestroyNotify) g_free);
+
+	file_contents_to_hashtable (g_mapped_file_get_contents (itom_mf), ical_to_mapi);
+
+	if (!(g_hash_table_size (mapi_to_ical) && g_hash_table_size (ical_to_mapi))) {
+		g_warning ("Exchange MAPI timezone files are not valid.");
+
+		exchange_mapi_cal_tz_util_destroy ();
+
+		g_mapped_file_free (mtoi_mf);
+		g_mapped_file_free (itom_mf);
+
+		g_static_rec_mutex_unlock(&mutex);
+		return FALSE;
+	} 
+
+	g_mapped_file_free (mtoi_mf);
+	g_mapped_file_free (itom_mf);
+
+	g_static_rec_mutex_unlock(&mutex);
+	return TRUE;
+}
+
+static void 
+exchange_mapi_cal_tz_util_dump_ical_tzs ()
+{
+	guint i;
+	icalarray *zones;
+	GList *l, *list_items = NULL;
+	
+	/* Get the array of builtin timezones. */
+	zones = icaltimezone_get_builtin_timezones ();
+
+	g_message("%s(%d): %s: ", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+	for (i = 0; i < zones->num_elements; i++) {
+		icaltimezone *zone;
+		char *tzid = NULL;
+
+		zone = icalarray_element_at (zones, i);
+
+		tzid = icaltimezone_get_tzid (zone);
+
+		list_items = g_list_prepend (list_items, tzid);
+	}
+
+	list_items = g_list_sort (list_items, (GCompareFunc) g_ascii_strcasecmp);
+
+	/* Put the "UTC" entry at the top of the combo's list. */
+	list_items = g_list_prepend (list_items, "UTC");
+
+	for (l = list_items, i = 0; l != NULL; l = l->next, ++i) 
+		g_print ("[%3d]\t%s\n", (i+1), (gchar *)(l->data));
+
+//	icaltimezone_free_builtin_timezones ();
+
+	g_list_free (list_items);
+}
+
+void
+exchange_mapi_cal_tz_util_dump ()
+{
+	guint i;
+	GList *keys, *values, *l, *m;
+
+	g_static_rec_mutex_lock(&mutex);
+
+	exchange_mapi_cal_tz_util_dump_ical_tzs ();
+
+	if (!(mapi_to_ical && ical_to_mapi)) {
+		g_static_rec_mutex_unlock(&mutex);
+		return;
+	}
+
+	g_message("%s(%d): %s: ", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+
+	g_message ("Dumping #table mapi_to_ical");
+	keys = g_hash_table_get_keys (mapi_to_ical);
+	values = g_hash_table_get_values (mapi_to_ical);
+	l = g_list_first (keys);
+	m = g_list_first (values);
+	for (i=0; l && m; ++i, l=l->next, m=m->next)
+		g_print ("[%3d]\t%s\t%s\t%s\n", (i+1), (gchar *)(l->data), MAPPING_SEPARATOR, (gchar *)(m->data));
+	g_message ("Dumping differences in #tables");
+	l = g_list_first (keys);
+	m = g_list_first (values);
+	for (i=0; l && m; ++i, l=l->next, m=m->next)
+		if (g_ascii_strcasecmp ((gchar *)(l->data), (gchar *) g_hash_table_lookup (ical_to_mapi, (m->data))))
+			g_print ("[%3d] Possible mis-match for %s\n", (i+1), (gchar *)(l->data));
+	g_list_free (keys);
+	g_list_free (values);
+
+	g_message ("Dumping #table ical_to_mapi");
+	keys = g_hash_table_get_keys (ical_to_mapi);
+	values = g_hash_table_get_values (ical_to_mapi);
+	l = g_list_first (keys);
+	m = g_list_first (values);
+	for (i=0; l && m; ++i, l=l->next, m=m->next)
+		g_print ("[%3d]\t%s\t%s\t%s\n", (i+1), (gchar *)(l->data), MAPPING_SEPARATOR, (gchar *)(m->data));
+	g_list_free (keys);
+	g_list_free (values);
+
+	g_static_rec_mutex_unlock(&mutex);
+}
+
+#if 0
+const WORD TZRULE_FLAG_RECUR_CURRENT_TZREG  = 0x0001; // see dispidApptTZDefRecur
+const WORD TZRULE_FLAG_EFFECTIVE_TZREG      = 0x0002;
+
+// Allocates return value with new.
+// clean up with delete[].
+TZDEFINITION* BinToTZDEFINITION(ULONG cbDef, LPBYTE lpbDef)
+{
+    if (!lpbDef) return NULL;
+
+    // Update this if parsing code is changed!
+    // this checks the size up to the flags member
+    if (cbDef < 2*sizeof(BYTE) + 2*sizeof(WORD)) return NULL;
+
+    TZDEFINITION tzDef;
+    TZRULE* lpRules = NULL;
+    LPBYTE lpPtr = lpbDef;
+    WORD cchKeyName = 0;
+    WCHAR* szKeyName = NULL;
+    WORD i = 0;
+
+    BYTE bMajorVersion = *((BYTE*)lpPtr);
+    lpPtr += sizeof(BYTE);
+    BYTE bMinorVersion = *((BYTE*)lpPtr);
+    lpPtr += sizeof(BYTE);
+
+    // We only understand TZ_BIN_VERSION_MAJOR
+    if (TZ_BIN_VERSION_MAJOR != bMajorVersion) return NULL;
+
+    // We only understand if >= TZ_BIN_VERSION_MINOR
+    if (TZ_BIN_VERSION_MINOR > bMinorVersion) return NULL;
+
+    WORD cbHeader = *((WORD*)lpPtr);
+    lpPtr += sizeof(WORD);
+
+    tzDef.wFlags = *((WORD*)lpPtr);
+    lpPtr += sizeof(WORD);
+
+    if (TZDEFINITION_FLAG_VALID_GUID & tzDef.wFlags)
+    {
+        if (lpbDef + cbDef - lpPtr < sizeof(GUID)) return NULL;
+        tzDef.guidTZID = *((GUID*)lpPtr);
+        lpPtr += sizeof(GUID);
+    }
+
+    if (TZDEFINITION_FLAG_VALID_KEYNAME & tzDef.wFlags)
+    {
+        if (lpbDef + cbDef - lpPtr < sizeof(WORD)) return NULL;
+        cchKeyName = *((WORD*)lpPtr);
+        lpPtr += sizeof(WORD);
+        if (cchKeyName)
+        {
+            if (lpbDef + cbDef - lpPtr < (BYTE)sizeof(WORD)*cchKeyName) return NULL;
+            szKeyName = (WCHAR*)lpPtr;
+            lpPtr += cchKeyName*sizeof(WORD);
+        }
+    }
+
+    if (lpbDef+ cbDef - lpPtr < sizeof(WORD)) return NULL;
+    tzDef.cRules = *((WORD*)lpPtr);
+    lpPtr += sizeof(WORD);
+
+    /* FIXME: parse rules */
+    if (tzDef.cRules) tzDef.cRules = 0;
+#if 0
+    if (tzDef.cRules)
+    {
+        lpRules = new TZRULE[tzDef.cRules];
+        if (!lpRules) return NULL;
+
+        LPBYTE lpNextRule = lpPtr;
+        BOOL bRuleOK = false;
+		
+        for (i = 0;i < tzDef.cRules;i++)
+        {
+            bRuleOK = false;
+            lpPtr = lpNextRule;
+			
+            if (lpbDef + cbDef - lpPtr < 
+                2*sizeof(BYTE) + 2*sizeof(WORD) + 3*sizeof(long) + 2*sizeof(SYSTEMTIME)) return NULL;
+            bRuleOK = true;
+            BYTE bRuleMajorVersion = *((BYTE*)lpPtr);
+            lpPtr += sizeof(BYTE);
+            BYTE bRuleMinorVersion = *((BYTE*)lpPtr);
+            lpPtr += sizeof(BYTE);
+			
+            // We only understand TZ_BIN_VERSION_MAJOR
+            if (TZ_BIN_VERSION_MAJOR != bRuleMajorVersion) return NULL;
+			
+            // We only understand if >= TZ_BIN_VERSION_MINOR
+            if (TZ_BIN_VERSION_MINOR > bRuleMinorVersion) return NULL;
+			
+            WORD cbRule = *((WORD*)lpPtr);
+            lpPtr += sizeof(WORD);
+			
+            lpNextRule = lpPtr + cbRule;
+			
+            lpRules[i].wFlags = *((WORD*)lpPtr);
+            lpPtr += sizeof(WORD);
+			
+            lpRules[i].stStart = *((SYSTEMTIME*)lpPtr);
+            lpPtr += sizeof(SYSTEMTIME);
+			
+            lpRules[i].TZReg.lBias = *((long*)lpPtr);
+            lpPtr += sizeof(long);
+            lpRules[i].TZReg.lStandardBias = *((long*)lpPtr);
+            lpPtr += sizeof(long);
+            lpRules[i].TZReg.lDaylightBias = *((long*)lpPtr);
+            lpPtr += sizeof(long);
+			
+            lpRules[i].TZReg.stStandardDate = *((SYSTEMTIME*)lpPtr);
+            lpPtr += sizeof(SYSTEMTIME);
+            lpRules[i].TZReg.stDaylightDate = *((SYSTEMTIME*)lpPtr);
+            lpPtr += sizeof(SYSTEMTIME);
+        }
+        if (!bRuleOK)
+        {
+            delete[] lpRules;
+            return NULL;			
+        }
+    }
+#endif 
+    // Now we've read everything - allocate a structure and copy it in
+    size_t cbTZDef = sizeof(TZDEFINITION) +
+        sizeof(WCHAR)*(cchKeyName+1) +
+        sizeof(TZRULE)*tzDef.cRules;
+
+    TZDEFINITION* ptzDef = (TZDEFINITION*) malloc (cbTZDef);
+    
+    if (ptzDef)
+    {
+        // Copy main struct over
+        *ptzDef = tzDef;
+        lpPtr = (LPBYTE) ptzDef;
+        lpPtr += sizeof(TZDEFINITION);
+
+        if (szKeyName)
+        {
+            ptzDef->pwszKeyName = (WCHAR*)lpPtr;
+            memcpy(lpPtr,szKeyName,cchKeyName*sizeof(WCHAR));
+            ptzDef->pwszKeyName[cchKeyName] = 0;
+            lpPtr += (cchKeyName+1)*sizeof(WCHAR);
+        }
+
+        if (ptzDef -> cRules)
+        {
+            ptzDef -> rgRules = (TZRULE*)lpPtr;
+            for (i = 0;i < ptzDef -> cRules;i++)
+            {
+                ptzDef -> rgRules[i] = lpRules[i];
+            }
+        }
+    }
+//    delete[] lpRules;
+
+   free (ptzDef);
+   ptzDef = NULL;
+
+    return ptzDef;
+}
+#endif
+
+#define TZDEFINITION_FLAG_VALID_GUID     0x0001 // the guid is valid
+#define TZDEFINITION_FLAG_VALID_KEYNAME  0x0002 // the keyname is valid
+#define TZ_MAX_RULES          1024 
+#define TZ_BIN_VERSION_MAJOR  0x02 
+#define TZ_BIN_VERSION_MINOR  0x01 
+
+void
+exchange_mapi_cal_util_mapi_tz_to_bin (const char *mapi_tzid, struct SBinary *sb)
+{
+	GByteArray *ba;
+	guint8 flag8;
+	guint16 flag16;
+	gunichar2 *buf;
+	glong items_written;
+	guint32 i;
+
+	ba = g_byte_array_new ();
+
+	/* UTF-8 length of the keyname */
+	flag16 = g_utf8_strlen (mapi_tzid, -1);
+	ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+	/* Keyname */
+	buf = g_utf8_to_utf16 (mapi_tzid, flag16, NULL, &items_written, NULL);
+	ba = g_byte_array_append (ba, buf, (sizeof (gunichar2) * items_written));
+	g_free (buf);
+
+	/* number of rules *//* FIXME: Need to support rules */
+	flag16 = 0x0000;
+	ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+	/* wFlags: we know only keyname based names */
+	flag16 = TZDEFINITION_FLAG_VALID_KEYNAME;
+	ba = g_byte_array_prepend (ba, &flag16, sizeof (guint16));
+
+	/* Length in bytes until rules info */
+	flag16 = (guint16) (ba->len);
+	ba = g_byte_array_prepend (ba, &flag16, sizeof (guint16));
+
+	/* Minor version */
+	flag8 = TZ_BIN_VERSION_MINOR;
+	ba = g_byte_array_prepend (ba, &flag8, sizeof (guint8));
+
+	/* Major version */
+	flag8 = TZ_BIN_VERSION_MAJOR;
+	ba = g_byte_array_prepend (ba, &flag8, sizeof (guint8));
+
+	/* Rules may now be appended here */
+
+	sb->lpb = ba->data;
+	sb->cb = 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);
+}
+
+gchar *
+exchange_mapi_cal_util_bin_to_mapi_tz (GByteArray *ba)
+{
+	guint8 flag8;
+	guint16 flag16, cbHeader = 0;
+	guint8 *ptr = ba->data;
+//	guint len = ba->len;
+	gchar *buf = NULL;
+
+	d(g_message ("New timezone stream.. Length: %d bytes.. Info follows:", ba->len));
+
+	/* Major version */
+	flag8 = *((guint8 *)ptr);
+	ptr += sizeof (guint8);
+	d(g_print ("Major version: %d\n", flag8));
+	if (TZ_BIN_VERSION_MAJOR != flag8)
+		return NULL;
+
+	/* Minor version */
+	flag8 = *((guint8 *)ptr);
+	ptr += sizeof (guint8);
+	d(g_print ("Minor version: %d\n", flag8));
+	if (TZ_BIN_VERSION_MINOR > flag8)
+		return NULL;
+
+	/* Length in bytes until rules info */
+	flag16 = *((guint16 *)ptr);
+	ptr += sizeof (guint16);
+	d(g_print ("Length in bytes until rules: %d\n", flag16));
+	cbHeader = flag16;
+
+	/* wFlags: we don't yet understand GUID based names */
+	flag16 = *((guint16 *)ptr);
+	ptr += sizeof (guint16);
+	d(g_print ("wFlags: %d\n", flag16));
+	cbHeader -= sizeof (guint16);
+	if (TZDEFINITION_FLAG_VALID_KEYNAME != flag16)
+		return NULL;
+
+	/* UTF-8 length of the keyname */
+	flag16 = *((guint16 *)ptr);
+	ptr += sizeof (guint16);
+	d(g_print ("UTF8 length of keyname: %d\n", flag16));
+	cbHeader -= sizeof (guint16);
+
+	/* number of rules is at the end of the header.. we'll parse and use later */
+	cbHeader -= sizeof (guint16);
+
+	/* Keyname */
+	buf = g_utf16_to_utf8 ((const gunichar2 *)ptr, cbHeader/sizeof (gunichar2), NULL, NULL, NULL);
+	ptr += cbHeader;
+	d(g_print ("Keyname: %s\n", buf));
+
+	/* number of rules */
+	flag16 = *((guint16 *)ptr);
+	ptr += sizeof (guint16);
+	d(g_print ("Number of rules: %d\n", flag16));
+
+	/* FIXME: Need to support rules */
+
+	return buf;
+}

Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h	Thu Jul  3 08:02:54 2008
@@ -0,0 +1,117 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Authors: 
+ *    Suman Manjunath <msuman novell com>
+ *
+ *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public 
+ *  License along with this program; if not, write to: 
+ *  Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#ifndef EXCHANGE_MAPI_CAL_TZ_UTILS_H
+#define EXCHANGE_MAPI_CAL_TZ_UTILS_H
+
+#include <glib.h>
+#include "exchange-mapi-cal-utils.h"
+
+G_BEGIN_DECLS
+
+const gchar *
+exchange_mapi_cal_tz_util_get_mapi_equivalent (const gchar *ical_tzid);
+
+const gchar *
+exchange_mapi_cal_tz_util_get_ical_equivalent (const gchar *mapi_tzid);
+
+gboolean
+exchange_mapi_cal_tz_util_populate (void);
+
+void
+exchange_mapi_cal_tz_util_destroy (void);
+
+void
+exchange_mapi_cal_tz_util_dump (void);
+
+void
+exchange_mapi_cal_util_mapi_tz_to_bin (const char *mapi_tzid, struct SBinary *sb);
+
+gchar *
+exchange_mapi_cal_util_bin_to_mapi_tz (GByteArray *ba);
+
+G_END_DECLS
+
+#if 0
+typedef int16_t WORD;
+typedef int8_t BYTE;
+typedef uint32_t GUID;
+typedef uint64_t ULONG;
+typedef time_t SYSTEMTIME;
+typedef uint8_t* LPBYTE;
+typedef char* LPWSTR;
+typedef char WCHAR;
+
+// TZREG
+// =====================
+//   This is an individual description that defines when a daylight
+//   saving shift, and the return to standard time occurs, and how
+//   far the shift is.  This is basically the same as
+//   TIME_ZONE_INFORMATION documented in MSDN, except that the strings
+//   describing the names "daylight" and "standard" time are omitted.
+//
+typedef struct RenTimeZone
+{
+    long        lBias;           // offset from GMT
+    long        lStandardBias;   // offset from bias during standard time
+    long        lDaylightBias;   // offset from bias during daylight time
+    SYSTEMTIME  stStandardDate;  // time to switch to standard time
+    SYSTEMTIME  stDaylightDate;  // time to switch to daylight time
+} TZREG;
+
+// TZRULE
+// =====================
+//   This structure represents both a description when a daylight. 
+//   saving shift occurs, and in addition, the year in which that
+//   timezone rule came into effect. 
+//
+typedef struct
+{
+    WORD        wFlags;   // indicates which rule matches legacy recur
+    SYSTEMTIME  stStart;  // indicates when the rule starts
+    TZREG       TZReg;    // the timezone info
+} TZRULE;
+
+// TZDEFINITION
+// =====================
+//   This represents an entire timezone including all historical, current
+//   and future timezone shift rules for daylight saving time, etc.  It's
+//   identified by a unique GUID.
+//
+typedef struct
+{
+    WORD     wFlags;       // indicates which fields are valid
+    GUID     guidTZID;     // guid uniquely identifying this timezone
+    LPWSTR   pwszKeyName;  // the name of the key for this timezone
+    WORD     cRules;       // the number of timezone rules for this definition
+    TZRULE*  rgRules;      // an array of rules describing when shifts occur
+} TZDEFINITION;
+
+// Allocates return value with new.
+// clean up with delete[].
+TZDEFINITION* BinToTZDEFINITION(ULONG cbDef, LPBYTE lpbDef);
+#endif
+
+#endif

Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c	Thu Jul  3 08:02:54 2008
@@ -0,0 +1,1465 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Authors: 
+ *    Suman Manjunath <msuman novell com>
+ *
+ *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public 
+ *  License along with this program; if not, write to: 
+ *  Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#include <glib/gstdio.h>
+#include <fcntl.h>
+#include <libecal/e-cal-util.h>
+#include "exchange-mapi-cal-utils.h"
+
+#define d(x) 
+
+static void appt_build_name_id (struct mapi_nameid *nameid);
+static void task_build_name_id (struct mapi_nameid *nameid);
+static void note_build_name_id (struct mapi_nameid *nameid);
+
+static struct icaltimetype
+foo (const time_t tm, const int is_date, const icaltimezone *comp_zone)
+{
+	struct icaltimetype itt_utc;
+	struct icaltimetype itt;
+	const icaltimezone *utc_zone;
+
+	utc_zone = icaltimezone_get_utc_timezone ();
+
+	/* First, get the time in UTC */
+	itt_utc = icaltime_from_timet_with_zone (tm, is_date, 0);
+	icaltime_set_timezone (&itt_utc, utc_zone);
+
+	if (comp_zone) {
+		itt = icaltime_convert_to_zone (itt_utc, comp_zone);
+		itt = icaltime_set_timezone (&itt, comp_zone);
+	} else {
+		itt = icaltime_convert_to_zone (itt_utc, utc_zone);
+		itt = icaltime_set_timezone (&itt, utc_zone);
+	}
+
+	return itt;
+}
+
+static icalparameter_role
+get_role_from_type (OlMailRecipientType type)
+{
+	switch (type) {
+		case olCC   : return ICAL_ROLE_OPTPARTICIPANT;
+		case olOriginator : 
+		case olTo   : 
+		case olBCC  : 
+		default     : return ICAL_ROLE_REQPARTICIPANT;
+	}
+}
+
+static OlMailRecipientType
+get_type_from_role (icalparameter_role role)
+{
+	switch (role) {
+		case ICAL_ROLE_OPTPARTICIPANT 	: return olCC;
+		case ICAL_ROLE_CHAIR 		:
+		case ICAL_ROLE_REQPARTICIPANT 	:
+		case ICAL_ROLE_NONPARTICIPANT 	: 
+		default 			: return olTo;
+	}
+} 
+
+static icalparameter_partstat
+get_partstat_from_trackstatus (uint32_t trackstatus)
+{
+	switch (trackstatus) {
+		case olMeetingTentative : return ICAL_PARTSTAT_TENTATIVE;
+		case olMeetingAccepted  : return ICAL_PARTSTAT_ACCEPTED;
+		case olMeetingDeclined  : return ICAL_PARTSTAT_DECLINED;
+		default 		: return ICAL_PARTSTAT_NEEDSACTION;
+	}
+}
+
+static uint32_t 
+get_trackstatus_from_partstat (icalparameter_partstat partstat)
+{
+	switch (partstat) {
+		case ICAL_PARTSTAT_ACCEPTED 	: return olMeetingAccepted;
+		case ICAL_PARTSTAT_DECLINED 	: return olMeetingDeclined;
+		case ICAL_PARTSTAT_TENTATIVE 	: 
+		default 			: return olMeetingTentative;
+	}
+}
+
+static icalproperty_transp
+get_transp_from_prop (uint32_t prop) 
+{
+	/* FIXME: is this mapping correct ? */
+	switch (prop) {
+		case olFree 		:
+		case olTentative 	: return ICAL_TRANSP_TRANSPARENT;
+		case olBusy 		:
+		case olOutOfOffice 	:
+		default 		: return ICAL_TRANSP_OPAQUE;
+	}
+}
+
+static uint32_t 
+get_prop_from_transp (icalproperty_transp transp)
+{
+	/* FIXME: is this mapping correct ? */
+	switch (transp) {
+		case ICAL_TRANSP_TRANSPARENT 		:
+		case ICAL_TRANSP_TRANSPARENTNOCONFLICT 	: return olFree; 
+		case ICAL_TRANSP_OPAQUE 		: 
+		case ICAL_TRANSP_OPAQUENOCONFLICT 	:
+		default 				: return olBusy;
+	}
+}
+
+static icalproperty_status
+get_taskstatus_from_prop (uint32_t prop)
+{
+	/* FIXME: is this mapping correct ? */
+	switch (prop) {
+		case olTaskComplete 	: return ICAL_STATUS_COMPLETED;
+		case olTaskWaiting 	:
+		case olTaskInProgress 	: return ICAL_STATUS_INPROCESS;
+		case olTaskDeferred 	: return ICAL_STATUS_CANCELLED;
+		case olTaskNotStarted 	: 
+		default 		: return ICAL_STATUS_NEEDSACTION;
+	}
+}
+
+static uint32_t
+get_prop_from_taskstatus (icalproperty_status status)
+{
+	/* FIXME: is this mapping correct ? */
+	switch (status) {
+		case ICAL_STATUS_INPROCESS 	: return olTaskInProgress;
+		case ICAL_STATUS_COMPLETED 	: return olTaskComplete;
+		case ICAL_STATUS_CANCELLED 	: return olTaskDeferred;
+		default 			: return olTaskNotStarted;
+	}
+}
+
+static icalproperty_class
+get_class_from_prop (uint32_t prop)
+{
+	/* FIXME: is this mapping correct ? */
+	switch (prop) {
+		case olPersonal 	:
+		case olPrivate 		: return ICAL_CLASS_PRIVATE;
+		case olConfidential 	: return ICAL_CLASS_CONFIDENTIAL;
+		case olNormal 		: 
+		default 		: return ICAL_CLASS_PUBLIC;
+	}
+}
+
+static uint32_t 
+get_prop_from_class (icalproperty_class class)
+{
+	/* FIXME: is this mapping correct ? */
+	switch (class) {
+		case ICAL_CLASS_PRIVATE 	: return olPrivate;
+		case ICAL_CLASS_CONFIDENTIAL 	: return olConfidential;
+		default 			: return olNormal;
+	}
+}
+
+static int
+get_priority_from_prop (uint32_t prop)
+{
+	switch (prop) {
+		case PRIORITY_LOW 	: return 7;
+		case PRIORITY_HIGH 	: return 1;
+		case PRIORITY_NORMAL 	: 
+		default 		: return 5;
+	}
+}
+
+static uint32_t
+get_prop_from_priority (int priority)
+{
+	if (priority > 0 && priority <= 4)
+		return PRIORITY_HIGH;
+	else if (priority > 5 && priority <= 9)
+		return PRIORITY_LOW;
+	else
+		return PRIORITY_NORMAL;
+}
+
+void
+exchange_mapi_cal_util_fetch_attachments (ECalComponent *comp, GSList **attach_list, const char *local_store)
+{
+	GSList *comp_attach_list = NULL, *new_attach_list = NULL;
+	GSList *l;
+	char *dest_file;
+	int fd;
+	const char *uid;
+
+	e_cal_component_get_attachment_list (comp, &comp_attach_list);
+	e_cal_component_get_uid (comp, &uid);
+
+	for (l = comp_attach_list; l ; l = l->next) {
+		gchar *sfname = (gchar *) l->data;
+		gchar *filename, *new_filename;
+		GMappedFile *mapped_file;
+		GError *error = NULL;
+		guint filelength = 0;
+
+		mapped_file = g_mapped_file_new (sfname, FALSE, &error);
+		if (!mapped_file) {
+			g_message ("DEBUG: could not map %s: %s\n", sfname, error->message);
+			g_error_free (error);
+			continue;
+		}
+
+		filename = g_path_get_basename (sfname);
+		new_filename = g_strconcat (uid, "-", filename, NULL);
+		g_free (filename);
+		dest_file = g_build_filename (local_store, new_filename, NULL);
+		g_free (new_filename);
+
+		filelength = g_mapped_file_get_length (mapped_file);
+
+		fd = g_open (dest_file, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
+		if (fd == -1) {
+			/* skip gracefully */
+			g_message ("DEBUG: could not open %s for writing\n", dest_file);
+		} else if (write (fd, g_mapped_file_get_contents (mapped_file), filelength) == -1) {
+			/* skip gracefully */
+			g_message ("DEBUG: attachment write failed.\n");
+		}
+		if (fd != -1) {
+			ExchangeMAPIAttachment *attach_item;
+
+			close (fd);
+			new_attach_list = g_slist_append (new_attach_list, g_filename_to_uri (dest_file, NULL, NULL));
+
+			attach_item = g_new0 (ExchangeMAPIAttachment, 1);
+			attach_item->filename = g_path_get_basename (sfname);
+			attach_item->value = g_byte_array_sized_new (filelength);
+			attach_item->value = g_byte_array_append (attach_item->value, g_mapped_file_get_contents (mapped_file), filelength);
+			*attach_list = g_slist_append (*attach_list, attach_item);
+		}
+
+		g_mapped_file_free (mapped_file);
+		g_free (dest_file);
+	}
+
+	e_cal_component_set_attachment_list (comp, new_attach_list);
+
+	for (l = new_attach_list; l != NULL; l = l->next)
+		g_free (l->data);
+	g_slist_free (new_attach_list);
+}
+
+#define RECIP_SENDABLE  0x1
+#define RECIP_ORGANIZER 0x2
+
+void
+exchange_mapi_cal_util_fetch_recipients (ECalComponent *comp, GSList **recip_list)
+{
+	GSList *al = NULL, *l;
+
+	e_cal_component_get_attendee_list (comp, &al);
+
+	for (l = al; l != NULL; l = l->next) {
+		ECalComponentAttendee *attendee = (ECalComponentAttendee *)(l->data);
+		ExchangeMAPIRecipient *recipient = g_new0 (ExchangeMAPIRecipient, 1);
+		uint32_t val = 0;
+		const char *str = NULL;
+		if (attendee->value && !g_ascii_strncasecmp (attendee->value, "mailto:";, 7)) 
+			recipient->email_id = (attendee->value) + 7;
+		else 
+			recipient->email_id = (attendee->value);
+		recipient->in.req_lpProps = g_new0 (struct SPropValue, 5);
+		recipient->in.req_cValues = 5;
+		val = 0;
+		set_SPropValue_proptag (&(recipient->in.req_lpProps[0]), PR_SEND_INTERNET_ENCODING, (const void *)&val);
+		val = RECIP_SENDABLE;
+		set_SPropValue_proptag (&(recipient->in.req_lpProps[1]), PR_RECIPIENTS_FLAGS, (const void *)&val);
+		val = get_trackstatus_from_partstat (attendee->status);
+		set_SPropValue_proptag (&(recipient->in.req_lpProps[2]), PR_RECIPIENT_TRACKSTATUS, (const void *)&val);
+		val = get_type_from_role (attendee->role);
+		set_SPropValue_proptag (&(recipient->in.req_lpProps[3]), PR_RECIPIENT_TYPE, (const void *) &val);
+/*		if (attendee->cn && *(attendee->cn))
+			str = attendee->cn;
+		else 
+			str = "";
+		set_SPropValue_proptag (&(recipient->in.req_lpProps[4]), PR_RECIPIENT_DISPLAY_NAME, (const void *)(str));
+*/
+		*recip_list = g_slist_append (*recip_list, recipient);
+	}
+
+	e_cal_component_free_attendee_list (al);
+}
+
+static void
+set_attachments_to_cal_component (ECalComponent *comp, GSList *attach_list, const char *local_store)
+{
+	GSList *comp_attach_list = NULL, *l;
+	const char *uid;
+
+	e_cal_component_get_uid (comp, &uid);
+	for (l = attach_list; l ; l = l->next) {
+		ExchangeMAPIAttachment *attach_item = (ExchangeMAPIAttachment *) (l->data);
+		gchar *attach_file_url, *filename;
+		struct stat st;
+
+		attach_file_url = g_strconcat (local_store, "/", uid, "-", attach_item->filename, NULL);
+		filename = g_filename_from_uri (attach_file_url, NULL, NULL);
+
+		if (g_stat (filename, &st) == -1) {
+			int fd = g_open (filename, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
+			if (fd == -1) { 
+				/* skip gracefully */
+				g_message ("DEBUG: could not open %s for writing\n", filename);
+			} else if (write (fd, attach_item->value->data, attach_item->value->len) == -1) {
+				/* skip gracefully */
+				g_message ("DEBUG: attachment write failed.\n");
+			}
+			if (fd != -1) {
+				close (fd);
+				comp_attach_list = g_slist_append (comp_attach_list, g_strdup (attach_file_url));
+			}
+		}
+
+		g_free (filename);
+		g_free (attach_file_url);
+	}
+
+	e_cal_component_set_attachment_list (comp, comp_attach_list);
+}
+
+static void 
+ical_attendees_from_props (icalcomponent *ical_comp, GSList *recipients, gboolean rsvp)
+{
+	GSList *l;
+	for (l=recipients; l; l=l->next) {
+		ExchangeMAPIRecipient *recip = (ExchangeMAPIRecipient *)(l->data);
+		icalproperty *prop = NULL;
+		icalparameter *param;
+		gchar *val;
+		const uint32_t *ui32;
+		const char *str;
+		const uint32_t *flags; 
+
+		if (recip->email_id)
+			val = g_strdup_printf ("MAILTO:%s", recip->email_id);
+		else 
+			continue;
+
+		flags = (const uint32_t *) get_SPropValue(recip->out.all_lpProps, PR_RECIPIENTS_FLAGS);
+
+		if (flags && (*flags & RECIP_ORGANIZER)) {
+			prop = icalproperty_new_organizer (val);
+
+			/* CN */
+			str = (const char *) get_SPropValue(recip->out.all_lpProps, PR_RECIPIENT_DISPLAY_NAME);
+			if (str) {
+				param = icalparameter_new_cn (str);
+				icalproperty_add_parameter (prop, param);
+			}
+		} else {
+			prop = icalproperty_new_attendee (val);
+
+			/* CN */
+			str = (const char *) get_SPropValue(recip->out.all_lpProps, PR_RECIPIENT_DISPLAY_NAME);
+			if (str) {
+				param = icalparameter_new_cn (str);
+				icalproperty_add_parameter (prop, param);
+			}
+			/* RSVP */
+			param = icalparameter_new_rsvp (rsvp ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE);
+			icalproperty_add_parameter (prop, param);
+			/* PARTSTAT */
+			ui32 = (const uint32_t *) get_SPropValue(recip->out.all_lpProps, PR_RECIPIENT_TRACKSTATUS);
+			if (ui32) {
+				param = icalparameter_new_partstat (get_partstat_from_trackstatus (*ui32));
+				icalproperty_add_parameter (prop, param);
+			}
+			/* ROLE */
+			ui32 = (const uint32_t *) get_SPropValue(recip->out.all_lpProps, PR_RECIPIENT_TYPE);
+			if (ui32) {
+				param = icalparameter_new_role (get_role_from_type (*ui32));
+				icalproperty_add_parameter (prop, param);
+			}
+#if 0
+			/* CALENDAR USER TYPE */
+			param = icalparameter_new_cutype ();
+			icalproperty_add_parameter (prop, param);
+#endif
+		}
+
+		if (prop)
+			icalcomponent_add_property (ical_comp, prop);
+
+		g_free (val);
+	}
+}
+
+static const uint8_t GID_START_SEQ[] = {
+	0x04, 0x00, 0x00, 0x00, 0x82, 0x00, 0xe0, 0x00,
+	0x74, 0xc5, 0xb7, 0x10, 0x1a, 0x82, 0xe0, 0x08
+};
+
+void
+exchange_mapi_cal_util_generate_globalobjectid (gboolean is_clean, const char *uid, struct SBinary *sb)
+{
+	GByteArray *ba;
+	guint32 flag32;
+	guchar *buf = NULL;
+	gsize len;
+	d(guint32 i);
+
+	ba = g_byte_array_new ();
+
+	ba = g_byte_array_append (ba, GID_START_SEQ, (sizeof (GID_START_SEQ) / sizeof (GID_START_SEQ[0])));
+
+	/* FIXME for exceptions */
+	if (is_clean || TRUE) {
+		flag32 = 0;
+		ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+	}
+
+	/* creation time - may be all 0's  */
+	flag32 = 0;
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+	flag32 = 0;
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	/* RESERVED - should be all 0's  */
+	flag32 = 0;
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+	flag32 = 0;
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+	/* FIXME: cleanup the UID first */
+
+	/* We put Evolution's UID in base64 here */
+	buf = g_base64_decode (uid, &len);
+	if (len % 2 != 0)
+		--len;
+	flag32 = len;
+
+	/* Size in bytes of the following data */
+	ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+	/* Data */
+	ba = g_byte_array_append (ba, buf, flag32);
+	g_free (buf);
+
+	sb->lpb = ba->data;
+	sb->cb = ba->len;
+
+	d(g_message ("New GlobalObjectId.. 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);
+}
+
+static gchar *
+id_to_string (GByteArray *ba)
+{
+	guint8 *ptr;
+	guint len;
+	gchar *buf = NULL;
+	guint32 flag32, i, j;
+
+	g_return_val_if_fail (ba != NULL, NULL);
+	/* MSDN docs: the globalID must have an even number of bytes */
+	if ((ba->len)%2 != 0)
+		return NULL;
+
+	ptr = ba->data;
+	len = ba->len;
+
+	/* starting seq - len = 16 bytes */
+	for (i = 0, j = 0;(i < len) && (j < sizeof (GID_START_SEQ)); ++i, ++ptr, ++j)
+		if (*ptr != GID_START_SEQ[j])
+			return NULL;
+
+	/* FIXME: for exceptions - len = 4 bytes */
+	flag32 = *((guint32 *)ptr);
+	i += sizeof (guint32);
+	if (!(i < len) || flag32 != 0)
+		return NULL;
+	ptr += sizeof (guint32);
+
+	/* Creation time - len = 8 bytes - skip it */
+	flag32 = *((guint32 *)ptr);
+	i += sizeof (guint32);
+	if (!(i < len))
+		return NULL;
+	ptr += sizeof (guint32);
+
+	flag32 = *((guint32 *)ptr);
+	i += sizeof (guint32);
+	if (!(i < len))
+		return NULL;
+	ptr += sizeof (guint32);
+
+	/* Reserved bytes - len = 8 bytes */
+	flag32 = *((guint32 *)ptr);
+	i += sizeof (guint32);
+	if (!(i < len) || flag32 != 0)
+		return NULL;
+	ptr += sizeof (guint32);
+
+	flag32 = *((guint32 *)ptr);
+	i += sizeof (guint32);
+	if (!(i < len) || flag32 != 0)
+		return NULL;
+	ptr += sizeof (guint32);
+
+	/* This is the real data */
+	flag32 = *((guint32 *)ptr);
+	i += sizeof (guint32);
+	if (!(i < len) || flag32 != (len - i))
+		return NULL;
+	ptr += sizeof (guint32);
+
+	buf = g_base64_encode (ptr, flag32);
+
+	return buf;
+}
+
+ECalComponent *
+exchange_mapi_cal_util_mapi_props_to_comp (icalcomponent_kind kind, const gchar *mid, struct mapi_SPropValue_array *properties, 
+					   GSList *streams, GSList *recipients, GSList *attachments, 
+					   const char *local_store, const icaltimezone *default_zone)
+{
+	ECalComponent *comp = NULL;
+	struct timeval t;
+	const gchar *subject = NULL;
+	const uint32_t *ui32;
+	const bool *b;
+	icalcomponent *ical_comp;
+	icalproperty *prop = NULL;
+	icalparameter *param = NULL;
+	ExchangeMAPIStream *body;
+
+	switch (kind) {
+		case ICAL_VEVENT_COMPONENT:
+		case ICAL_VTODO_COMPONENT:
+		case ICAL_VJOURNAL_COMPONENT:
+			comp = e_cal_component_new ();
+			ical_comp = icalcomponent_new (kind);
+			e_cal_component_set_icalcomponent (comp, ical_comp);
+			icalcomponent_set_uid (ical_comp, mid);
+			e_cal_component_set_uid (comp, mid);
+			break;
+		default:
+			return NULL;
+	}
+
+	subject = (const gchar *)exchange_mapi_util_find_array_propval(properties, PR_SUBJECT);
+	if (!subject)
+		subject = (const gchar *)exchange_mapi_util_find_array_propval(properties, PR_NORMALIZED_SUBJECT);
+
+	body = exchange_mapi_util_find_stream (streams, PR_BODY);
+	if (!body)
+		body = exchange_mapi_util_find_stream (streams, PR_BODY_HTML);
+	if (!body)
+		body = exchange_mapi_util_find_stream (streams, PR_HTML);
+
+	/* set dtstamp - in UTC */
+	if (get_mapi_SPropValue_array_date_timeval (&t, properties, PR_CREATION_TIME) == MAPI_E_SUCCESS)
+		icalcomponent_set_dtstamp (ical_comp, foo (t.tv_sec, 0, 0));
+
+	/* created - in UTC */
+	prop = icalproperty_new_created (icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ()));
+	icalcomponent_add_property (ical_comp, prop);
+	
+	/* last modified - in UTC */
+	if (get_mapi_SPropValue_array_date_timeval (&t, properties, PR_LAST_MODIFICATION_TIME) == MAPI_E_SUCCESS) {
+		prop = icalproperty_new_lastmodified (foo (t.tv_sec, 0, 0));
+		icalcomponent_add_property (ical_comp, prop);
+	}
+
+	if (subject && *subject)
+		icalcomponent_set_summary (ical_comp, subject);
+	if (body)
+		icalcomponent_set_description (ical_comp, (const char *) body->value->data);
+
+	if (icalcomponent_isa (ical_comp) == ICAL_VEVENT_COMPONENT) {
+		const char *location = NULL;
+		const gchar *dtstart_tz = NULL, *dtend_tz = NULL;
+		ExchangeMAPIStream *stream;
+
+		/* CleanGlobalObjectId */
+		stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x0023));
+		if (stream) {
+			gchar *value = id_to_string (stream->value);
+			prop = icalproperty_new_x (value);
+			icalproperty_set_x_name (prop, "X-EVOLUTION-MAPI-CLEAN-GLOBALID");
+			icalcomponent_add_property (ical_comp, prop);
+			g_free (value);
+		}
+
+		/* GlobalObjectId */
+		stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x0003));
+		if (stream) {
+			gchar *value = id_to_string (stream->value);
+			prop = icalproperty_new_x (value);
+			icalproperty_set_x_name (prop, "X-EVOLUTION-MAPI-GLOBALID");
+			icalcomponent_add_property (ical_comp, prop);
+			g_free (value);
+		}
+
+		location = (const char *)exchange_mapi_util_find_array_propval(properties, PROP_TAG(PT_STRING8, 0x8208));
+		if (location && *location)
+			icalcomponent_set_location (ical_comp, location);
+
+		b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8215));
+
+		stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x825E));
+		if (stream) {
+			gchar *buf = exchange_mapi_cal_util_bin_to_mapi_tz (stream->value);
+			dtstart_tz = exchange_mapi_cal_tz_util_get_ical_equivalent (buf);
+			g_free (buf);
+		}
+
+		if (get_mapi_SPropValue_array_date_timeval (&t, properties, PROP_TAG(PT_SYSTIME, 0x820D)) == MAPI_E_SUCCESS)
+			icalcomponent_set_dtstart (ical_comp, foo (t.tv_sec, (b && *b), icaltimezone_get_builtin_timezone_from_tzid (dtstart_tz)));
+
+		stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x825F));
+		if (stream) {
+			gchar *buf = exchange_mapi_cal_util_bin_to_mapi_tz (stream->value);
+			dtend_tz = exchange_mapi_cal_tz_util_get_ical_equivalent (buf);
+			g_free (buf);
+		}
+
+		if (get_mapi_SPropValue_array_date_timeval (&t, properties, PROP_TAG(PT_SYSTIME, 0x820E)) == MAPI_E_SUCCESS)
+			icalcomponent_set_dtend (ical_comp, foo (t.tv_sec, (b && *b), icaltimezone_get_builtin_timezone_from_tzid (dtend_tz)));
+
+		ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8205));
+		if (ui32) {
+			prop = icalproperty_new_transp (get_transp_from_prop (*ui32));
+			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));
+			if (icalcomponent_get_first_property (ical_comp, ICAL_ORGANIZER_PROPERTY) == NULL) {
+				gchar *val;
+//				const char *sender_name = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_NAME);
+				const char *sender_email_type = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_ADDRTYPE);
+				const char *sender_email = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_EMAIL_ADDRESS);
+				const char *sent_name = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_NAME);
+				const char *sent_email_type = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_ADDRTYPE);
+				const char *sent_email = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_EMAIL_ADDRESS);
+
+				if (!g_utf8_collate (sender_email_type, "EX"))
+					sender_email = exchange_mapi_util_ex_to_smtp (sender_email);
+				if (!g_utf8_collate (sent_email_type, "EX"))
+					sent_email = exchange_mapi_util_ex_to_smtp (sent_email);
+
+				val = g_strdup_printf ("MAILTO:%s", sent_email);
+				prop = icalproperty_new_organizer (val);
+				g_free (val);
+				/* CN */
+				param = icalparameter_new_cn (sent_name);
+				icalproperty_add_parameter (prop, param);
+				/* SENTBY */
+				if (g_utf8_collate (sent_email, sender_email)) {
+					val = g_strdup_printf ("MAILTO:%s", sender_email);
+					param = icalparameter_new_sentby (val);
+					icalproperty_add_parameter (prop, param);
+					g_free (val);
+				}
+
+				icalcomponent_add_property (ical_comp, prop);
+			}
+		}
+
+		b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8503));
+		if (b && *b) {
+			struct timeval start, displaytime;
+
+			if ((get_mapi_SPropValue_array_date_timeval (&start, properties, PROP_TAG(PT_SYSTIME, 0x8502)) == MAPI_E_SUCCESS) 
+			 && (get_mapi_SPropValue_array_date_timeval (&displaytime, properties, PROP_TAG(PT_SYSTIME, 0x8560)) == MAPI_E_SUCCESS)) {
+				ECalComponentAlarm *e_alarm = e_cal_component_alarm_new ();
+				ECalComponentAlarmTrigger trigger;
+
+				trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START;
+				trigger.u.rel_duration = icaltime_subtract (icaltime_from_timet_with_zone (displaytime.tv_sec, 0, 0), 
+									    icaltime_from_timet_with_zone (start.tv_sec, 0, 0));
+
+				e_cal_component_alarm_set_action (e_alarm, E_CAL_COMPONENT_ALARM_DISPLAY);
+				e_cal_component_alarm_set_trigger (e_alarm, trigger);
+
+				e_cal_component_add_alarm (comp, e_alarm);
+			}
+		} else
+			e_cal_component_remove_all_alarms (comp);
+
+	} else if (icalcomponent_isa (ical_comp) == ICAL_VTODO_COMPONENT) {
+		const double *complete = 0;
+
+		/* NOTE: Exchange tasks are DATE values, not DATE-TIME values, but maybe someday, we could expect Exchange to support it ;) */
+		if (get_mapi_SPropValue_array_date_timeval (&t, properties, PROP_TAG(PT_SYSTIME, 0x8104)) == MAPI_E_SUCCESS)
+			icalcomponent_set_dtstart (ical_comp, foo (t.tv_sec, 1, default_zone));
+		if (get_mapi_SPropValue_array_date_timeval (&t, properties, PROP_TAG(PT_SYSTIME, 0x8105)) == MAPI_E_SUCCESS)
+			icalcomponent_set_due (ical_comp, foo (t.tv_sec, 1, default_zone));
+
+		ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8101));
+		if (ui32) {
+			icalcomponent_set_status (ical_comp, get_taskstatus_from_prop(*ui32));
+			if (*ui32 == olTaskComplete 
+			&& get_mapi_SPropValue_array_date_timeval (&t, properties, PROP_TAG(PT_SYSTIME, 0x810F)) == MAPI_E_SUCCESS) {
+				prop = icalproperty_new_completed (foo (t.tv_sec, 1, default_zone));
+				icalcomponent_add_property (ical_comp, prop);
+			}
+		}
+
+		complete = (const double *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_DOUBLE, 0x8102));
+		if (complete) {
+			prop = icalproperty_new_percentcomplete ((int)(*complete * 100));
+			icalcomponent_add_property (ical_comp, prop);
+		}
+
+		b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8126));
+		if (b && *b) {
+			/* FIXME: Evolution does not support recurring tasks */
+			g_warning ("Encountered a recurring task.");
+		}
+
+		b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8503));
+		if (b && *b) {
+			struct timeval abs;
+
+			if (get_mapi_SPropValue_array_date_timeval (&abs, properties, PROP_TAG(PT_SYSTIME, 0x8502)) == MAPI_E_SUCCESS) {
+				ECalComponentAlarm *e_alarm = e_cal_component_alarm_new ();
+				ECalComponentAlarmTrigger trigger;
+
+				trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE;
+				trigger.u.abs_time = icaltime_from_timet_with_zone (abs.tv_sec, 0, 0);
+
+				e_cal_component_alarm_set_action (e_alarm, E_CAL_COMPONENT_ALARM_DISPLAY);
+				e_cal_component_alarm_set_trigger (e_alarm, trigger);
+
+				e_cal_component_add_alarm (comp, e_alarm);
+			}
+		} else
+			e_cal_component_remove_all_alarms (comp);
+
+	} else if (icalcomponent_isa (ical_comp) == ICAL_VJOURNAL_COMPONENT) {
+		if (get_mapi_SPropValue_array_date_timeval (&t, properties, PR_LAST_MODIFICATION_TIME) == MAPI_E_SUCCESS)
+			icalcomponent_set_dtstart (ical_comp, foo (t.tv_sec, TRUE, default_zone));
+	}
+
+	if (icalcomponent_isa (ical_comp) == ICAL_VEVENT_COMPONENT || icalcomponent_isa (ical_comp) == ICAL_VTODO_COMPONENT) {
+		/* priority */
+		ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PR_PRIORITY);
+		if (ui32) {
+			prop = icalproperty_new_priority (get_priority_from_prop (*ui32));
+			icalcomponent_add_property (ical_comp, prop);
+		}
+	}
+
+	/* classification */
+	ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PR_SENSITIVITY);
+	if (ui32) {
+		prop = icalproperty_new_class (get_class_from_prop (*ui32));
+		icalcomponent_add_property (ical_comp, prop);
+	}
+
+	/* FIXME: categories */
+
+	set_attachments_to_cal_component (comp, attachments, local_store);
+
+	e_cal_component_rescan (comp);
+
+	return comp;
+}
+
+#define COMMON_NAMED_PROPS_N 8
+
+typedef enum 
+{
+	I_COMMON_REMMINS = 0 , 
+	I_COMMON_REMTIME , 
+	I_COMMON_REMSET , 
+	I_COMMON_ISPRIVATE , 
+	I_COMMON_SIDEEFFECTS , 
+	I_COMMON_START , 
+	I_COMMON_END , 
+	I_COMMON_REMNEXTTIME 
+} CommonNamedPropsIndex;
+
+gboolean
+exchange_mapi_cal_util_build_name_id (struct mapi_nameid *nameid, gpointer data)
+{
+	icalcomponent_kind kind = GPOINTER_TO_INT (data);
+
+	/* NOTE: Avoid using mapi_nameid_OOM_add because: 
+	 * a) its inefficient (uses strcmp) 
+	 * b) names may vary in different server/libmapi versions 
+	 */
+
+	mapi_nameid_lid_add(nameid, 0x8501, PSETID_Common); 	// PT_LONG - ReminderMinutesBeforeStart
+	mapi_nameid_lid_add(nameid, 0x8502, PSETID_Common); 	// PT_SYSTIME - ReminderTime
+	mapi_nameid_lid_add(nameid, 0x8503, PSETID_Common); 	// PT_BOOLEAN - ReminderSet
+	mapi_nameid_lid_add(nameid, 0x8506, PSETID_Common); 	// PT_BOOLEAN - Private
+	mapi_nameid_lid_add(nameid, 0x8510, PSETID_Common); 	// PT_LONG - (context menu flags)
+	mapi_nameid_lid_add(nameid, 0x8516, PSETID_Common); 	// PT_SYSTIME - CommonStart
+	mapi_nameid_lid_add(nameid, 0x8517, PSETID_Common); 	// PT_SYSTIME - CommonEnd
+	mapi_nameid_lid_add(nameid, 0x8560, PSETID_Common); 	// PT_SYSTIME - ReminderNextTime
+
+	if (kind == ICAL_VEVENT_COMPONENT) 
+		appt_build_name_id (nameid);
+	else if (kind == ICAL_VTODO_COMPONENT)
+		task_build_name_id (nameid);
+	else if (kind == ICAL_VJOURNAL_COMPONENT)
+		note_build_name_id (nameid);
+
+	return TRUE;
+}
+
+/**
+ * NOTE: The enumerations '(Appt/Task/Note)NamedPropsIndex' have been defined 
+ * only to make life a little easier for developers. Here's the logic 
+ * behind the definition:
+     1) The first element is initialized with 'COMMON_NAMED_PROPS_N' : When 
+	adding named props, we add the common named props first and then the 
+	specific named props. So.. the index of the first specific 
+	named property = COMMON_NAMED_PROPS_N
+     2) The order in the enumeration 'must' be the same as that in the routine 
+	which adds the specific named props - (appt/task/note)_build_name_id
+     3) If a specific named prop is added/deleted, an index needs to
+	be created/deleted at the correct position. [Don't forget to update 
+	(APPT/TASK/NOTE)_NAMED_PROPS_N]. 
+
+ * To summarize the pros: 
+     1) Addition/deletion of a common-named-prop would not affect the indexes 
+	of the specific named props once COMMON_NAMED_PROPS_N is updated. 
+     2) Values of named props can be added in any order. 
+ */
+
+
+#define APPT_NAMED_PROPS_N  31
+#define DEFAULT_APPT_REMINDER_MINS 15
+
+typedef enum 
+{
+	I_APPT_SEQ = COMMON_NAMED_PROPS_N , 
+	I_APPT_SEQTIME , 
+	I_APPT_BUSYSTATUS , 
+	I_APPT_LOCATION , 
+	I_APPT_START , 
+	I_APPT_END , 
+	I_APPT_DURATION , 
+	I_APPT_ALLDAY , 
+/**/	I_APPT_RECURBLOB , 
+	I_APPT_MEETINGSTATUS , 
+	I_APPT_RESPONSESTATUS , 
+	I_APPT_RECURRING , 
+	I_APPT_INTENDEDBUSY , 
+/**/	I_APPT_RECURBASE , 
+	I_APPT_INVITED , 
+/**/	I_APPT_RECURTYPE , 
+/**/	I_APPT_RECURPATTERN , 
+	I_APPT_CLIPSTART , 
+	I_APPT_CLIPEND , 
+	I_APPT_AUTOLOCATION , 
+	I_APPT_ISONLINEMEET , 
+	I_APPT_COUNTERPROPOSAL , 
+	I_APPT_STARTTZBLOB , 
+	I_APPT_ENDTZBLOB ,
+
+	I_MEET_WHERE , 
+	I_MEET_GUID , 
+	I_MEET_ISRECURRING , 
+	I_MEET_ISEXCEPTION , 
+	I_MEET_CLEANGUID , 
+	I_MEET_APPTMSGCLASS , 
+	I_MEET_TYPE
+
+//	I_SENDASICAL , 
+//	I_APPT_LABEL , 
+//	I_APPT_DISPTZ 
+//	I_APPT_ALLATTENDEES , 
+//	I_APPT_TOATTENDEES , 
+//	I_APPT_CCATTENDEES , 
+} ApptNamedPropsIndex;
+
+static void 
+appt_build_name_id (struct mapi_nameid *nameid)
+{
+	mapi_nameid_lid_add(nameid, 0x8201, PSETID_Appointment); 	// PT_LONG - ApptSequence
+	mapi_nameid_lid_add(nameid, 0x8202, PSETID_Appointment); 	// PT_SYSTIME - ApptSequenceTime
+	mapi_nameid_lid_add(nameid, 0x8205, PSETID_Appointment); 	// PT_LONG - BusyStatus
+	mapi_nameid_lid_add(nameid, 0x8208, PSETID_Appointment); 	// PT_STRING8 - Location
+	mapi_nameid_lid_add(nameid, 0x820D, PSETID_Appointment); 	// PT_SYSTIME - Start/ApptStartWhole
+	mapi_nameid_lid_add(nameid, 0x820E, PSETID_Appointment); 	// PT_SYSTIME - End/ApptEndWhole
+	mapi_nameid_lid_add(nameid, 0x8213, PSETID_Appointment); 	// PT_LONG - Duration/ApptDuration
+	mapi_nameid_lid_add(nameid, 0x8215, PSETID_Appointment); 	// PT_BOOLEAN - AllDayEvent (also called ApptSubType)
+	mapi_nameid_lid_add(nameid, 0x8216, PSETID_Appointment); 	// PT_BINARY - (recurrence blob)
+	mapi_nameid_lid_add(nameid, 0x8217, PSETID_Appointment); 	// PT_LONG - MeetingStatus
+	mapi_nameid_lid_add(nameid, 0x8218, PSETID_Appointment); 	// PT_LONG - ResponseStatus
+	mapi_nameid_lid_add(nameid, 0x8223, PSETID_Appointment); 	// PT_BOOLEAN - Recurring
+	mapi_nameid_lid_add(nameid, 0x8224, PSETID_Appointment); 	// PT_LONG - IntendedBusyStatus
+	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
+	mapi_nameid_lid_add(nameid, 0x8240, PSETID_Appointment); 	// PT_BOOLEAN - IsOnlineMeeting
+	mapi_nameid_lid_add(nameid, 0x8257, PSETID_Appointment); 	// PT_BOOLEAN - ApptCounterProposal
+	mapi_nameid_lid_add(nameid, 0x825E, PSETID_Appointment); 	// PT_BINARY - (timezone for dtstart)
+	mapi_nameid_lid_add(nameid, 0x825F, PSETID_Appointment); 	// PT_BINARY - (timezone for dtend)
+
+	mapi_nameid_lid_add(nameid, 0x0002, PSETID_Meeting); 		// PT_STRING8 - Where
+	mapi_nameid_lid_add(nameid, 0x0003, PSETID_Meeting); 		// PT_BINARY - GlobalObjectId
+	mapi_nameid_lid_add(nameid, 0x0005, PSETID_Meeting); 		// PT_BOOLEAN - IsRecurring
+	mapi_nameid_lid_add(nameid, 0x000a, PSETID_Meeting); 		// PT_BOOLEAN - IsException 
+	mapi_nameid_lid_add(nameid, 0x0023, PSETID_Meeting); 		// PT_BINARY - CleanGlobalObjectId
+	mapi_nameid_lid_add(nameid, 0x0024, PSETID_Meeting); 		// PT_STRING8 - AppointmentMessageClass 
+	mapi_nameid_lid_add(nameid, 0x0026, PSETID_Meeting); 		// PT_LONG - MeetingType
+
+	/* These probably would never be used from Evolution */
+//	mapi_nameid_lid_add(nameid, 0x8200, PSETID_Appointment); 	// PT_BOOLEAN - SendAsICAL
+//	mapi_nameid_lid_add(nameid, 0x8214, PSETID_Appointment); 	// PT_LONG - Label
+//	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)
+//	mapi_nameid_lid_add(nameid, 0x823C, PSETID_Appointment); 	// PT_STRING8 - CCAttendeesString (dupe PR_DISPLAY_CC)
+}
+
+#define TASK_NAMED_PROPS_N 13
+#define DEFAULT_TASK_REMINDER_MINS 1080
+
+typedef enum 
+{
+	I_TASK_STATUS = COMMON_NAMED_PROPS_N , 
+	I_TASK_PERCENT , 
+	I_TASK_ISTEAMTASK , 
+	I_TASK_START , 
+	I_TASK_DUE , 
+	I_TASK_COMPLETED , 
+//	I_TASK_RECURBLOB , 
+	I_TASK_ISCOMPLETE , 
+	I_TASK_OWNER , 
+	I_TASK_DELEGATOR , 
+	I_TASK_ISRECURRING , 
+	I_TASK_ROLE , 
+	I_TASK_OWNERSHIP , 
+	I_TASK_DELEGATIONSTATE , 
+//	I_TASK_ACTUALWORK , 
+//	I_TASK_TOTALWORK 
+} TaskNamedPropsIndex;
+
+static void 
+task_build_name_id (struct mapi_nameid *nameid)
+{
+	mapi_nameid_lid_add(nameid, 0x8101, PSETID_Task); 	// PT_LONG - Status
+	mapi_nameid_lid_add(nameid, 0x8102, PSETID_Task); 	// PT_DOUBLE - PercentComplete
+	mapi_nameid_lid_add(nameid, 0x8103, PSETID_Task); 	// PT_BOOLEAN - TeamTask
+	mapi_nameid_lid_add(nameid, 0x8104, PSETID_Task); 	// PT_SYSTIME - StartDate/TaskStartDate
+	mapi_nameid_lid_add(nameid, 0x8105, PSETID_Task); 	// PT_SYSTIME - DueDate/TaskDueDate
+	mapi_nameid_lid_add(nameid, 0x810F, PSETID_Task); 	// PT_SYSTIME - DateCompleted
+//	mapi_nameid_lid_add(nameid, 0x8116, PSETID_Task); 	// PT_BINARY - (recurrence blob)
+	mapi_nameid_lid_add(nameid, 0x811C, PSETID_Task); 	// PT_BOOLEAN - Complete
+	mapi_nameid_lid_add(nameid, 0x811F, PSETID_Task); 	// PT_STRING8 - Owner
+	mapi_nameid_lid_add(nameid, 0x8121, PSETID_Task); 	// PT_STRING8 - Delegator
+	mapi_nameid_lid_add(nameid, 0x8126, PSETID_Task); 	// PT_BOOLEAN - IsRecurring/TaskFRecur
+	mapi_nameid_lid_add(nameid, 0x8127, PSETID_Task); 	// PT_STRING8 - Role
+	mapi_nameid_lid_add(nameid, 0x8129, PSETID_Task); 	// PT_LONG - Ownership
+	mapi_nameid_lid_add(nameid, 0x812A, PSETID_Task); 	// PT_LONG - DelegationState
+
+	/* These probably would never be used from Evolution */
+//	mapi_nameid_lid_add(nameid, 0x8110, PSETID_Task); 	// PT_LONG - ActualWork/TaskActualEffort
+//	mapi_nameid_lid_add(nameid, 0x8111, PSETID_Task); 	// PT_LONG - TotalWork/TaskEstimatedEffort
+}
+
+
+#define NOTE_NAMED_PROPS_N 0
+
+/*
+typedef enum 
+{
+//	I_NOTE_COLOR 
+} NoteNamedPropsIndex;
+*/
+
+static void 
+note_build_name_id (struct mapi_nameid *nameid)
+{
+	/* These probably would never be used from Evolution */
+//	mapi_nameid_lid_add(nameid, 0x8B00, PSETID_Note); 	// PT_LONG - Color
+}
+
+#define MINUTES_IN_HOUR 60
+#define SECS_IN_MINUTE 60
+
+/** 
+ * NOTE: When a new regular property (PR_***) is added, 'REGULAR_PROPS_N' 
+ * should be updated. 
+ */
+#define REGULAR_PROPS_N    21
+
+int
+exchange_mapi_cal_util_build_props (struct SPropValue **value, struct SPropTagArray *proptag_array, gpointer data)
+{
+	struct cbdata *cbdata = (struct cbdata *) data;
+	ECalComponent *comp = cbdata->comp;
+	icalcomponent *ical_comp = e_cal_component_get_icalcomponent (comp);
+	icalcomponent_kind  kind = icalcomponent_isa (ical_comp);
+	gboolean has_attendees = e_cal_component_has_attendees (comp);
+	struct SPropValue *props = NULL;
+	int i=0;
+	uint32_t flag32;
+	bool b;
+	icalproperty *prop;
+	struct icaltimetype dtstart, dtend, utc_dtstart, utc_dtend;
+	const icaltimezone *utc_zone;
+	const char *dtstart_tzid, *dtend_tzid, *text = NULL;
+	const char *uid = NULL;
+	struct timeval t;
+
+	switch (kind) {
+		case ICAL_VEVENT_COMPONENT:
+			props = g_new0 (struct SPropValue, REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + APPT_NAMED_PROPS_N);
+			g_print ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + APPT_NAMED_PROPS_N);
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_APPTMSGCLASS], (const void *) "IPM.Appointment");
+			if (has_attendees) {
+				if (cbdata->meeting_type & MEETING_OBJECT)
+					set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+				else if (cbdata->meeting_type & MEETING_REQUEST)
+					set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Schedule.Meeting.Request");
+				else 
+					set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+			} else
+				set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+			break;
+		case ICAL_VTODO_COMPONENT:
+			props = g_new0 (struct SPropValue, REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + TASK_NAMED_PROPS_N);
+			g_print ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + TASK_NAMED_PROPS_N);
+			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Task");
+			break;
+		case ICAL_VJOURNAL_COMPONENT:
+			props = g_new0 (struct SPropValue, REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + NOTE_NAMED_PROPS_N);
+			g_print ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + NOTE_NAMED_PROPS_N);
+			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.StickyNote");
+			break;
+		default:
+			return 0;
+	} 											/* prop count: 1 */
+
+	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_tzid = icaltime_get_tzid (dtstart);
+	dtend_tzid = icaltime_get_tzid (dtend);
+
+	utc_dtstart = icaltime_convert_to_zone (dtstart, utc_zone);
+	utc_dtend = icaltime_convert_to_zone (dtend, utc_zone);
+
+	/* FIXME: convert to unicode */
+	text = icalcomponent_get_summary (ical_comp);
+	if (!(text && *text)) 
+		text = "";
+	set_SPropValue_proptag(&props[i++], PR_SUBJECT, 					/* prop count: 2 */ 
+					(const void *) text);
+	set_SPropValue_proptag(&props[i++], PR_NORMALIZED_SUBJECT, 				/* prop count: 3 */ 
+					(const void *) text);
+	set_SPropValue_proptag(&props[i++], PR_CONVERSATION_TOPIC, 				/* prop count: 4 */
+					(const void *) text);
+	text = NULL;
+
+	/* we don't support HTML event/task/memo editor */
+	flag32 = olEditorText;
+	set_SPropValue_proptag(&props[i++], PR_MSG_EDITOR_FORMAT, &flag32); 			/* prop count: 5 */
+
+	/* it'd be better to convert, then set it in unicode */
+	text = icalcomponent_get_description (ical_comp);
+	if (!(text && *text)) 
+		text = "";
+	set_SPropValue_proptag(&props[i++], PR_BODY, 						/* prop count: 6 */
+					(const void *) text);
+	text = NULL;
+
+	/* Priority */
+	flag32 = PRIORITY_NORMAL; 	/* default */
+	prop = icalcomponent_get_first_property (ical_comp, ICAL_PRIORITY_PROPERTY);
+	if (prop) 
+		flag32 = get_prop_from_priority (icalproperty_get_priority (prop));
+	set_SPropValue_proptag(&props[i++], PR_PRIORITY, (const void *) &flag32); 		/* prop count: 7 */
+
+	set_SPropValue_proptag(&props[i++], PR_SENT_REPRESENTING_NAME, 
+		(const void *) cbdata->ownerid);
+	text = "SMTP";
+	set_SPropValue_proptag(&props[i++], PR_SENT_REPRESENTING_ADDRTYPE, 
+		(const void *) text);
+	set_SPropValue_proptag(&props[i++], PR_SENT_REPRESENTING_EMAIL_ADDRESS, 
+		(const void *) cbdata->ownername);
+	set_SPropValue_proptag(&props[i++], PR_SENDER_NAME, 
+		(const void *) cbdata->username);
+	text = "SMTP";
+	set_SPropValue_proptag(&props[i++], PR_SENDER_ADDRTYPE, 
+		(const void *) text);
+	set_SPropValue_proptag(&props[i++], PR_SENDER_EMAIL_ADDRESS, 
+		(const void *) cbdata->userid); 						/* prop count: 13 */
+
+	flag32 = cbdata->msgflags;
+	set_SPropValue_proptag(&props[i++], PR_MESSAGE_FLAGS, (const void *) &flag32); 		/* prop count: 14 */
+
+	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 char *)(alarm_uids->data));
+		ECalComponentAlarmAction action;
+		e_cal_component_alarm_get_action (alarm, &action);
+		if (action == E_CAL_COMPONENT_ALARM_DISPLAY) {
+			ECalComponentAlarmTrigger trigger;
+			e_cal_component_alarm_get_trigger (alarm, &trigger);
+			switch (trigger.type) {
+			case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START :
+				flag32 = (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 = (flag32 < 0) ? -(flag32) : 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_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_REMSET], (const void *) &b);
+	set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_REMMINS], (const void *) &flag32);
+	t.tv_sec = icaltime_as_timet (utc_dtstart);
+	t.tv_usec = 0;
+	set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_COMMON_REMTIME], &t);
+	t.tv_sec = icaltime_as_timet (utc_dtstart) - (flag32 * SECS_IN_MINUTE);
+	t.tv_usec = 0;
+	/* ReminderNextTime: FIXME for recurrence */
+	set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_COMMON_REMNEXTTIME], &t);
+												/* prop count: 14 (no regular props added) */
+	/* 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_SPropValue_proptag(&props[i++], PR_SENSITIVITY, (const void *) &flag32); 		/* prop count: 15 */
+	set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_ISPRIVATE], (const void *) &b);
+
+	t.tv_sec = icaltime_as_timet (utc_dtstart);
+	t.tv_usec = 0;
+	set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_COMMON_START], &t);
+	set_SPropValue_proptag_date_timeval(&props[i++], PR_START_DATE, &t); 			/* prop count: 16 */
+
+	t.tv_sec = icaltime_as_timet (utc_dtend);
+	t.tv_usec = 0;
+	set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_COMMON_END], &t);
+	set_SPropValue_proptag_date_timeval(&props[i++], PR_END_DATE, &t); 			/* prop count: 17 */
+
+	b = 1;
+	set_SPropValue_proptag(&props[i++], PR_RESPONSE_REQUESTED, (const void *) &b); 		/* prop count: 18 */
+
+	/* PR_OWNER_APPT_ID needs to be set in certain cases only */				/* prop count: 19 */
+	/* PR_ICON_INDEX needs to be set appropriately */					/* prop count: 20 */
+
+	b = 0;
+	set_SPropValue_proptag(&props[i++], PR_RTF_IN_SYNC, (const void *) &b); 		/* prop count: 21 */
+
+	if (kind == ICAL_VEVENT_COMPONENT) {
+		const char *mapi_tzid;
+		struct SBinary start_tz, end_tz, globalid; 
+
+		/* Busy Status */
+		flag32 = olBusy; 	/* default */
+		prop = icalcomponent_get_first_property (ical_comp, ICAL_TRANSP_PROPERTY);
+		if (prop)
+			flag32 = get_prop_from_transp (icalproperty_get_transp (prop));
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INTENDEDBUSY], (const void *) &flag32);
+		if (cbdata->meeting_type == MEETING_REQUEST) {
+			flag32 = olTentative;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_BUSYSTATUS], (const void *) &flag32);
+		} else 
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_BUSYSTATUS], (const void *) &flag32);
+
+		/* Location */
+		text = icalcomponent_get_location (ical_comp);
+		if (!(text && *text)) 
+			text = "";
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_LOCATION], (const void *) text);
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_WHERE], (const void *) text);
+		text = NULL;
+		/* Auto-Location is always FALSE - Evolution doesn't work that way */
+		b = 0; 
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_AUTOLOCATION], (const void *) &b);
+
+		/* Start */
+		t.tv_sec = icaltime_as_timet (utc_dtstart);
+		t.tv_usec = 0;
+		set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_APPT_START], &t);
+		/* FIXME: for recurrence */
+		set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_APPT_CLIPSTART], &t);
+
+		/* Start TZ */
+		mapi_tzid = exchange_mapi_cal_tz_util_get_mapi_equivalent ((dtstart_tzid && *dtstart_tzid) ? dtstart_tzid : "UTC");
+		if (mapi_tzid && *mapi_tzid) {
+			exchange_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &start_tz);
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_STARTTZBLOB], (const void *) &start_tz);
+		}
+
+		/* End */
+		t.tv_sec = icaltime_as_timet (utc_dtend);
+		t.tv_usec = 0;
+		set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_APPT_END], &t);
+		/* FIXME: for recurrence */
+		set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_APPT_CLIPEND], &t);
+
+		/* End TZ */
+		mapi_tzid = exchange_mapi_cal_tz_util_get_mapi_equivalent ((dtend_tzid && *dtend_tzid) ? dtend_tzid : "UTC");
+		if (mapi_tzid && *mapi_tzid) {
+			exchange_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &end_tz);
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_ENDTZBLOB], (const void *) &end_tz);
+		}
+
+		/* Duration */
+		flag32 = icaldurationtype_as_int (icaltime_subtract (dtend, dtstart));
+		flag32 /= MINUTES_IN_HOUR;
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_DURATION], (const void *) &flag32);
+
+		/* All-day event */
+		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 ;
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RECURTYPE], (const void *) &flag32);
+
+		switch (cbdata->meeting_type) {
+		case MEETING_OBJECT :
+			flag32 = e_cal_component_has_recurrences (comp) ? RecurMeet : SingleMeet; 
+			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
+
+			flag32 = 0x0171;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+
+			flag32 = olMeeting;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_MEETINGSTATUS], (const void *) &flag32);
+
+			flag32 = mtgRequest; 
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_TYPE], (const void *) &flag32);
+
+			flag32 = olResponseOrganized;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RESPONSESTATUS], (const void *) &flag32);
+
+			b = 0;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INVITED], (const void *) &b);
+
+			flag32 = cbdata->new_appt_id;
+			set_SPropValue_proptag(&props[i++], PR_OWNER_APPT_ID, (const void *) &flag32);
+
+			e_cal_component_get_uid (comp, &uid);
+			exchange_mapi_cal_util_generate_globalobjectid (TRUE, uid, &globalid);
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_CLEANGUID], (const void *) &globalid);
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_GUID], (const void *) &globalid);
+
+			break;
+		case MEETING_REQUEST :
+			flag32 = 0xFFFFFFFF;  /* no idea why this has to be -1, but that's what the docs say */
+			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
+
+			flag32 = 0x1C61;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+
+			flag32 = olMeetingReceived;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_MEETINGSTATUS], (const void *) &flag32);
+
+			flag32 = mtgRequest; 
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_TYPE], (const void *) &flag32);
+
+			flag32 = olResponseNotResponded;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RESPONSESTATUS], (const void *) &flag32);
+
+			b = 1;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INVITED], (const void *) &b);
+
+			flag32 = cbdata->dup.owner_appt_id;
+			set_SPropValue_proptag(&props[i++], PR_OWNER_APPT_ID, (const void *) &flag32);
+
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_CLEANGUID], (const void *) cbdata->dup.cleanglobalid);
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_GUID], (const void *) cbdata->dup.globalid);
+
+			break;
+		case MEETING_RESPONSE : 
+			flag32 = RespAccept; 
+			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
+
+			flag32 = 0x0171;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+/*
+			flag32 = olMeeting;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_MEETINGSTATUS], (const void *) &flag32);
+*/
+			flag32 = mtgRequest; 
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_TYPE], (const void *) &flag32);
+
+			flag32 = olResponseAccepted;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RESPONSESTATUS], (const void *) &flag32);
+
+			break;
+		case NOT_A_MEETING :
+		default :
+			flag32 = e_cal_component_has_recurrences (comp) ? RecurAppt : SingleAppt; 
+			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
+
+			flag32 = 0x0171;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+
+			flag32 = olNonMeeting;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_MEETINGSTATUS], (const void *) &flag32);
+
+			flag32 = olResponseNone;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RESPONSESTATUS], (const void *) &flag32);
+
+			b = 0;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INVITED], (const void *) &b);
+
+			break;
+		}
+
+		/* FIXME: Recurring */
+		b = e_cal_component_has_recurrences (comp) && FALSE; b = 0;
+		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);
+		b = e_cal_component_has_exceptions (comp) && FALSE; b = 0;
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_ISEXCEPTION], (const void *) &b);
+
+		/* Online Meeting : we probably would never support this */
+		b = 0;
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_ISONLINEMEET], (const void *) &b);
+
+		/* Counter Proposal for appointments : not supported */
+		b = 0;
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_COUNTERPROPOSAL], (const void *) &b);
+
+	} else if (kind == ICAL_VTODO_COMPONENT) {
+		double d;
+
+		/* Context menu flags */ /* FIXME: for assigned tasks */
+		flag32 = 0x0110; 
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &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_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_TASK_STATUS], (const void *) &flag32);
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_TASK_PERCENT], (const void *) &d);
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_TASK_ISCOMPLETE], (const void *) &b);
+
+		/* Date completed */
+		if (b) {
+			struct icaltimetype completed;
+			prop = icalcomponent_get_first_property (ical_comp, ICAL_COMPLETED_PROPERTY);
+			completed = icalproperty_get_completed (prop);
+
+			t.tv_sec = icaltime_as_timet (completed);
+			t.tv_usec = 0;
+			set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_TASK_COMPLETED], &t);
+		}
+
+		/* Start */
+		t.tv_sec = icaltime_as_timet (dtstart);
+		t.tv_usec = 0;
+		set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_TASK_START], &t);
+
+		/* Due */
+		t.tv_sec = icaltime_as_timet (dtend);
+		t.tv_usec = 0;
+		set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_TASK_DUE], &t);
+
+		/* FIXME: Evolution does not support recurring tasks */
+		b = 0;
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_TASK_ISRECURRING], (const void *) &b);
+
+	} else if (kind == ICAL_VJOURNAL_COMPONENT) {
+		/* Context menu flags */
+		flag32 = 0x0110; 
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+
+		flag32 = 0x0300; 
+		set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
+	}
+
+	*value = props;
+
+	g_print ("\nEnded up setting %d props\n", i);
+
+	return i;
+}
+

Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h	Thu Jul  3 08:02:54 2008
@@ -0,0 +1,131 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Authors: 
+ *    Suman Manjunath <msuman novell com>
+ *
+ *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public 
+ *  License along with this program; if not, write to: 
+ *  Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef EXCHANGE_MAPI_CAL_UTILS_H
+#define EXCHANGE_MAPI_CAL_UTILS_H
+
+#include <libecal/e-cal-component.h>
+#include "exchange-mapi-connection.h"
+#include "exchange-mapi-utils.h"
+#include "exchange-mapi-cal-tz-utils.h"
+#include "exchange-mapi-cal-recur-utils.h"
+#include "exchange-mapi-cal-tz-utils.h"
+
+G_BEGIN_DECLS
+
+typedef enum {
+	NOT_A_MEETING = 0, 
+	MEETING_OBJECT = (1 << 0),
+	MEETING_OBJECT_SENT = (1 << 1),
+	MEETING_REQUEST = (1 << 2), 
+	MEETING_RESPONSE = (1 << 3)
+} MAPIMeetingOptions;
+
+struct dup_data {
+	struct SBinary *globalid;
+	struct SBinary *cleanglobalid;
+	uint32_t owner_appt_id;
+	uint32_t appt_seq;
+};
+
+struct cbdata { 
+	ECalComponent *comp;
+	MAPIMeetingOptions meeting_type;
+	uint32_t msgflags;
+	uint32_t new_appt_id;
+	struct dup_data dup;
+	const char *username;
+	const char *userid;
+	const char *ownername;
+	const char *ownerid;
+};
+
+void
+exchange_mapi_cal_util_fetch_recipients (ECalComponent *comp, GSList **recip_list);
+void
+exchange_mapi_cal_util_fetch_attachments (ECalComponent *comp, GSList **attach_list, const char *local_store);
+
+ECalComponent *
+exchange_mapi_cal_util_mapi_props_to_comp (icalcomponent_kind kind, const gchar *mid, struct mapi_SPropValue_array *properties, 
+					   GSList *streams, GSList *recipients, GSList *attachments, 
+					   const char *local_store, const icaltimezone *default_zone);
+gboolean
+exchange_mapi_cal_util_build_name_id (struct mapi_nameid *nameid, gpointer data);
+
+int
+exchange_mapi_cal_util_build_props (struct SPropValue **value, struct SPropTagArray *proptag_array, gpointer data);
+
+void
+exchange_mapi_cal_util_generate_globalobjectid (gboolean is_clean, const char *uid, struct SBinary *sb);
+
+/* we don't have to specify the PR_BODY_* tags since it is fetched by default */
+static const uint32_t cal_GetPropsList[] = {
+	PR_FID, 
+	PR_MID, 
+	PR_SUBJECT, 
+	PR_SUBJECT_UNICODE, 
+	PR_SUBJECT_ERROR, 
+	PR_NORMALIZED_SUBJECT, 
+	PR_NORMALIZED_SUBJECT_UNICODE, 
+	PR_NORMALIZED_SUBJECT_ERROR, 
+	PR_CREATION_TIME, 
+	PR_LAST_MODIFICATION_TIME, 
+	PR_PRIORITY, 
+	PR_SENSITIVITY, 
+	PR_START_DATE, 
+	PR_END_DATE, 
+	PR_RESPONSE_REQUESTED, 
+
+	PR_SENT_REPRESENTING_NAME, 
+	PR_SENT_REPRESENTING_NAME_UNICODE, 
+	PR_SENT_REPRESENTING_ADDRTYPE, 
+	PR_SENT_REPRESENTING_ADDRTYPE_UNICODE, 
+	PR_SENT_REPRESENTING_EMAIL_ADDRESS, 
+	PR_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE, 
+
+	PR_SENDER_NAME, 
+	PR_SENDER_NAME_UNICODE, 
+	PR_SENDER_ADDRTYPE, 
+	PR_SENDER_ADDRTYPE_UNICODE, 
+	PR_SENDER_EMAIL_ADDRESS, 
+	PR_SENDER_EMAIL_ADDRESS_UNICODE, 
+
+	PR_RCVD_REPRESENTING_NAME, 
+	PR_RCVD_REPRESENTING_NAME_UNICODE, 
+	PR_RCVD_REPRESENTING_ADDRTYPE, 
+	PR_RCVD_REPRESENTING_ADDRTYPE_UNICODE, 
+	PR_RCVD_REPRESENTING_EMAIL_ADDRESS, 
+	PR_RCVD_REPRESENTING_EMAIL_ADDRESS_UNICODE
+};
+static const uint16_t n_cal_GetPropsList = G_N_ELEMENTS (cal_GetPropsList);
+
+static const uint32_t cal_IDList[] = {
+	PR_FID, 
+	PR_MID
+};
+static const uint16_t n_cal_IDList = G_N_ELEMENTS (cal_IDList);
+
+G_END_DECLS
+
+#endif

Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/tz-ical-to-mapi
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/tz-ical-to-mapi	Thu Jul  3 08:02:54 2008
@@ -0,0 +1,399 @@
+UTC~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Africa/Abidjan~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Accra~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Addis_Ababa~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Algiers~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Asmara~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Bamako~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Bangui~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Banjul~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Bissau~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Blantyre~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Brazzaville~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Bujumbura~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Cairo~~~Egypt Standard Time
+/softwarestudio.org/Tzfile/Africa/Casablanca~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Ceuta~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Conakry~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Dakar~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Dar_es_Salaam~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Djibouti~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Douala~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/El_Aaiun~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Freetown~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Gaborone~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Harare~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Johannesburg~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Kampala~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Khartoum~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Kigali~~~Egypt Standard Time
+/softwarestudio.org/Tzfile/Africa/Kinshasa~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Lagos~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Libreville~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Lome~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Luanda~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Lubumbashi~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Lusaka~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Malabo~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Maputo~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Maseru~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Mbabane~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Mogadishu~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Monrovia~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Nairobi~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Ndjamena~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Niamey~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Nouakchott~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Ouagadougou~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Porto-Novo~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Sao_Tome~~~Cape Verde Standard Time
+/softwarestudio.org/Tzfile/Africa/Tripoli~~~Egypt Standard Time
+/softwarestudio.org/Tzfile/Africa/Tunis~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Windhoek~~~Namibia Standard Time
+/softwarestudio.org/Tzfile/America/Adak~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/America/Anchorage~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/America/Anguilla~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Antigua~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Araguaina~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Buenos_Aires~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Catamarca~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Cordoba~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Jujuy~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/La_Rioja~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Mendoza~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Rio_Gallegos~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/San_Juan~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Tucuman~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Ushuaia~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Aruba~~~Venezuela Standard Time
+/softwarestudio.org/Tzfile/America/Asuncion~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Atikokan~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Bahia~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Barbados~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Belem~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Belize~~~Mexico Standard Time
+/softwarestudio.org/Tzfile/America/Blanc-Sablon~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Boa_Vista~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Bogota~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Boise~~~US Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Cambridge_Bay~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Campo_Grande~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Cancun~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Caracas~~~Venezuela Standard Time
+/softwarestudio.org/Tzfile/America/Cayenne~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Cayman~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Chicago~~~Central Standard Time
+/softwarestudio.org/Tzfile/America/Chihuahua~~~Mexico Standard Time 2
+/softwarestudio.org/Tzfile/America/Costa_Rica~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Cuiaba~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Curacao~~~Venezuela Standard Time
+/softwarestudio.org/Tzfile/America/Danmarkshavn~~~GMT Standard Time
+/softwarestudio.org/Tzfile/America/Dawson~~~Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Dawson_Creek~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Denver~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Detroit~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Dominica~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Edmonton~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Eirunepe~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/El_Salvador~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Fortaleza~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Glace_Bay~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Godthab~~~Greenland Standard Time
+/softwarestudio.org/Tzfile/America/Goose_Bay~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Grand_Turk~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Grenada~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Guadeloupe~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Guatemala~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Guayaquil~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Guyana~~~Venezuela Standard Time
+/softwarestudio.org/Tzfile/America/Halifax~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Havana~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Hermosillo~~~Mexico Standard Time 2
+/softwarestudio.org/Tzfile/America/Indiana/Indianapolis~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Knox~~~Canada Central Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Marengo~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Petersburg~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Tell_City~~~Canada Central Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Vevay~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Vincennes~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Winamac~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Inuvik~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Iqaluit~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Jamaica~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Juneau~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/America/Kentucky/Louisville~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Kentucky/Monticello~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/La_Paz~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Lima~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Los_Angeles~~~Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Maceio~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Managua~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Manaus~~~Central Brazilian Standard Time
+/softwarestudio.org/Tzfile/America/Martinique~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Mazatlan~~~Mountain Standard Time (Mexico)
+/softwarestudio.org/Tzfile/America/Menominee~~~Central Standard Time
+/softwarestudio.org/Tzfile/America/Merida~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Mexico_City~~~Mexico Standard Time
+/softwarestudio.org/Tzfile/America/Miquelon~~~Greenland Standard Time
+/softwarestudio.org/Tzfile/America/Moncton~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Monterrey~~~Central Standard Time (Mexico)
+/softwarestudio.org/Tzfile/America/Montevideo~~~Montevideo Standard Time
+/softwarestudio.org/Tzfile/America/Montreal~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Montserrat~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Nassau~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/New_York~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Nipigon~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Nome~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/America/Noronha~~~Mid-Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/North_Dakota/Center~~~Central Standard Time
+/softwarestudio.org/Tzfile/America/North_Dakota/New_Salem~~~Central Standard Time
+/softwarestudio.org/Tzfile/America/Panama~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Pangnirtung~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Paramaribo~~~Venezuela Standard Time
+/softwarestudio.org/Tzfile/America/Phoenix~~~US Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Port-au-Prince~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Port_of_Spain~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Porto_Velho~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Puerto_Rico~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Rainy_River~~~Canada Central Standard Time
+/softwarestudio.org/Tzfile/America/Rankin_Inlet~~~Canada Central Standard Time
+/softwarestudio.org/Tzfile/America/Recife~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Regina~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Resolute~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Rio_Branco~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Santiago~~~Pacific SA Standard Time
+/softwarestudio.org/Tzfile/America/Santo_Domingo~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Sao_Paulo~~~Mid-Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Scoresbysund~~~Azores Standard Time
+/softwarestudio.org/Tzfile/America/Shiprock~~~US Mountain Standard Time
+/softwarestudio.org/Tzfile/America/St_Johns~~~Newfoundland Standard Time
+/softwarestudio.org/Tzfile/America/St_Kitts~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/St_Lucia~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/St_Thomas~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/St_Vincent~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Swift_Current~~~Central Standard Time
+/softwarestudio.org/Tzfile/America/Tegucigalpa~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Thule~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Thunder_Bay~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Tijuana~~~Pacific Standard Time (Mexico)
+/softwarestudio.org/Tzfile/America/Toronto~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Tortola~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Vancouver~~~Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Whitehorse~~~Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Winnipeg~~~Canada Central Standard Time
+/softwarestudio.org/Tzfile/America/Yakutat~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/America/Yellowknife~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Casey~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Davis~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Antarctica/DumontDUrville~~~West Pacific Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Mawson~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Antarctica/McMurdo~~~Tonga Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Palmer~~~Greenland Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Rothera~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Antarctica/South_Pole~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Syowa~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Vostok~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Arctic/Longyearbyen~~~Central Europe Standard Time
+/softwarestudio.org/Tzfile/Asia/Aden~~~Arab Standard Time
+/softwarestudio.org/Tzfile/Asia/Almaty~~~N. Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Amman~~~Jordan Standard Time
+/softwarestudio.org/Tzfile/Asia/Anadyr~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Asia/Aqtau~~~Ekaterinburg Standard Time
+/softwarestudio.org/Tzfile/Asia/Aqtobe~~~Ekaterinburg Standard Time
+/softwarestudio.org/Tzfile/Asia/Ashgabat~~~Ekaterinburg Standard Time
+/softwarestudio.org/Tzfile/Asia/Baghdad~~~Arabic Standard Time
+/softwarestudio.org/Tzfile/Asia/Bahrain~~~Arab Standard Time
+/softwarestudio.org/Tzfile/Asia/Baku~~~Azerbaijan Standard Time
+/softwarestudio.org/Tzfile/Asia/Bangkok~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Beijing~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Beirut~~~Middle East Standard Time
+/softwarestudio.org/Tzfile/Asia/Bishkek~~~Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Brunei~~~Taipei Standard Time
+/softwarestudio.org/Tzfile/Asia/Calcutta~~~India Standard Time
+/softwarestudio.org/Tzfile/Asia/Choibalsan~~~Yakutsk Standard Time
+/softwarestudio.org/Tzfile/Asia/Chongqing~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Colombo~~~India Standard Time
+/softwarestudio.org/Tzfile/Asia/Damascus~~~Israel Standard Time
+/softwarestudio.org/Tzfile/Asia/Dhaka~~~Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Dili~~~Yakutsk Standard Time
+/softwarestudio.org/Tzfile/Asia/Dubai~~~Iran Standard Time
+/softwarestudio.org/Tzfile/Asia/Dushanbe~~~West Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Gaza~~~Israel Standard Time
+/softwarestudio.org/Tzfile/Asia/Harbin~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Hong_Kong~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Hovd~~~North Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Irkutsk~~~North Asia East Standard Time
+/softwarestudio.org/Tzfile/Asia/Jakarta~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Jayapura~~~Yakutsk Standard Time
+/softwarestudio.org/Tzfile/Asia/Jerusalem~~~Israel Standard Time
+/softwarestudio.org/Tzfile/Asia/Kabul~~~Afghanistan Standard Time
+/softwarestudio.org/Tzfile/Asia/Kamchatka~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Asia/Karachi~~~West Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Kashgar~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Katmandu~~~Nepal Standard Time
+/softwarestudio.org/Tzfile/Asia/Krasnoyarsk~~~North Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Kuala_Lumpur~~~Singapore Standard Time
+/softwarestudio.org/Tzfile/Asia/Kuching~~~Taipei Standard Time
+/softwarestudio.org/Tzfile/Asia/Kuwait~~~Arab Standard Time
+/softwarestudio.org/Tzfile/Asia/Macau~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Magadan~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Asia/Makassar~~~Taipei Standard Time
+/softwarestudio.org/Tzfile/Asia/Manila~~~Taipei Standard Time
+/softwarestudio.org/Tzfile/Asia/Muscat~~~Arabian Standard Time
+/softwarestudio.org/Tzfile/Asia/Nicosia~~~Israel Standard Time
+/softwarestudio.org/Tzfile/Asia/Novosibirsk~~~N. Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Omsk~~~N. Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Oral~~~Ekaterinburg Standard Time
+/softwarestudio.org/Tzfile/Asia/Phnom_Penh~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Pontianak~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Pyongyang~~~Korea Standard Time
+/softwarestudio.org/Tzfile/Asia/Qatar~~~Arab Standard Time
+/softwarestudio.org/Tzfile/Asia/Qyzylorda~~~Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Rangoon~~~Myanmar Standard Time
+/softwarestudio.org/Tzfile/Asia/Riyadh~~~Arab Standard Time
+/softwarestudio.org/Tzfile/Asia/Saigon~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Sakhalin~~~Vladivostok Standard Time
+/softwarestudio.org/Tzfile/Asia/Samarkand~~~West Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Seoul~~~Korea Standard Time
+/softwarestudio.org/Tzfile/Asia/Shanghai~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Singapore~~~Singapore Standard Time
+/softwarestudio.org/Tzfile/Asia/Taipei~~~Taipei Standard Time
+/softwarestudio.org/Tzfile/Asia/Tashkent~~~West Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Tbilisi~~~Georgian Standard Time
+/softwarestudio.org/Tzfile/Asia/Tehran~~~Iran Standard Time
+/softwarestudio.org/Tzfile/Asia/Thimphu~~~Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Tokyo~~~Tokyo Standard Time
+/softwarestudio.org/Tzfile/Asia/Ulaanbaatar~~~North Asia East Standard Time
+/softwarestudio.org/Tzfile/Asia/Urumqi~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Vientiane~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Vladivostok~~~Vladivostok Standard Time
+/softwarestudio.org/Tzfile/Asia/Yakutsk~~~Yakutsk Standard Time
+/softwarestudio.org/Tzfile/Asia/Yekaterinburg~~~Ekaterinburg Standard Time
+/softwarestudio.org/Tzfile/Asia/Yerevan~~~Armenian Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Azores~~~Azores Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Bermuda~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Canary~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Cape_Verde~~~Cape Verde Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Faroe~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Jan_Mayen~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Madeira~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Reykjavik~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Atlantic/South_Georgia~~~Mid-Atlantic Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Stanley~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/Atlantic/St_Helena~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Australia/Adelaide~~~Cen. Australia Standard Time
+/softwarestudio.org/Tzfile/Australia/Brisbane~~~E. Australia Standard Time
+/softwarestudio.org/Tzfile/Australia/Broken_Hill~~~Cen. Australia Standard Time
+/softwarestudio.org/Tzfile/Australia/Currie~~~AUS Eastern Standard Time
+/softwarestudio.org/Tzfile/Australia/Darwin~~~AUS Central Standard Time
+/softwarestudio.org/Tzfile/Australia/Eucla~~~AUS Central Standard Time
+/softwarestudio.org/Tzfile/Australia/Hobart~~~Tasmania Standard Time
+/softwarestudio.org/Tzfile/Australia/Lindeman~~~E. Australia Standard Time
+/softwarestudio.org/Tzfile/Australia/Lord_Howe~~~AUS Eastern Standard Time
+/softwarestudio.org/Tzfile/Australia/Melbourne~~~AUS Eastern Standard Time
+/softwarestudio.org/Tzfile/Australia/Perth~~~W. Australia Standard Time
+/softwarestudio.org/Tzfile/Australia/Sydney~~~AUS Eastern Standard Time
+/softwarestudio.org/Tzfile/Europe/Amsterdam~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Andorra~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Athens~~~GTB Standard Time
+/softwarestudio.org/Tzfile/Europe/Belgrade~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Berlin~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Bratislava~~~Central Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Brussels~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Bucharest~~~E. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Budapest~~~Central Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Chisinau~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Copenhagen~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Dublin~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Gibraltar~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Guernsey~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Helsinki~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Isle_of_Man~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Istanbul~~~GTB Standard Time
+/softwarestudio.org/Tzfile/Europe/Jersey~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Kaliningrad~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Kiev~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Lisbon~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Ljubljana~~~Central Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/London~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Luxembourg~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Madrid~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Malta~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Mariehamn~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Minsk~~~E. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Monaco~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Moscow~~~Russian Standard Time
+/softwarestudio.org/Tzfile/Europe/Oslo~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Paris~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Podgorica~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Prague~~~Central Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Riga~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Rome~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Samara~~~Caucasus Standard Time
+/softwarestudio.org/Tzfile/Europe/San_Marino~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Sarajevo~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Simferopol~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Skopje~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Sofia~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Stockholm~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Tallinn~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Tirane~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Uzhgorod~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Vaduz~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Vatican~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Vienna~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Vilnius~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Volgograd~~~Russian Standard Time
+/softwarestudio.org/Tzfile/Europe/Warsaw~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Zagreb~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Zaporozhye~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Zurich~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Indian/Antananarivo~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Indian/Chagos~~~Sri Lanka Standard Time
+/softwarestudio.org/Tzfile/Indian/Christmas~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Indian/Cocos~~~Myanmar Standard Time
+/softwarestudio.org/Tzfile/Indian/Comoro~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Indian/Kerguelen~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Indian/Mahe~~~Iran Standard Time
+/softwarestudio.org/Tzfile/Indian/Maldives~~~West Asia Standard Time
+/softwarestudio.org/Tzfile/Indian/Mauritius~~~Arabian Standard Time
+/softwarestudio.org/Tzfile/Indian/Mayotte~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Indian/Reunion~~~Iran Standard Time
+/softwarestudio.org/Tzfile/Pacific/Apia~~~Dateline Standard Time
+/softwarestudio.org/Tzfile/Pacific/Auckland~~~New Zealand Standard Time
+/softwarestudio.org/Tzfile/Pacific/Chatham~~~Tonga Standard Time
+/softwarestudio.org/Tzfile/Pacific/Easter~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Efate~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Enderbury~~~Tonga Standard Time
+/softwarestudio.org/Tzfile/Pacific/Fakaofo~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/Pacific/Fiji~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Funafuti~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Galapagos~~~Mexico Standard Time
+/softwarestudio.org/Tzfile/Pacific/Gambier~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/Pacific/Guadalcanal~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Guam~~~West Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Honolulu~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/Pacific/Johnston~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/Pacific/Kiritimati~~~Tonga Standard Time
+/softwarestudio.org/Tzfile/Pacific/Kosrae~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Kwajalein~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Majuro~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Marquesas~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/Pacific/Midway~~~Samoa Standard Time
+/softwarestudio.org/Tzfile/Pacific/Nauru~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Niue~~~Samoa Standard Time
+/softwarestudio.org/Tzfile/Pacific/Norfolk~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Noumea~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Pago_Pago~~~Samoa Standard Time
+/softwarestudio.org/Tzfile/Pacific/Palau~~~Yakutsk Standard Time
+/softwarestudio.org/Tzfile/Pacific/Pitcairn~~~Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Ponape~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Port_Moresby~~~West Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Rarotonga~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/Pacific/Saipan~~~West Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Tahiti~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/Pacific/Tarawa~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Tongatapu~~~Tonga Standard Time
+/softwarestudio.org/Tzfile/Pacific/Truk~~~West Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Wake~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Wallis~~~Fiji Standard Time

Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/tz-mapi-to-ical
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/tz-mapi-to-ical	Thu Jul  3 08:02:54 2008
@@ -0,0 +1,87 @@
+Dateline Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Apia
+Samoa Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Midway
+Hawaiian Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Honolulu
+Alaskan Standard Time~~~/softwarestudio.org/Tzfile/America/Anchorage
+Pacific Standard Time~~~/softwarestudio.org/Tzfile/America/Los_Angeles
+Pacific Standard Time (Mexico)~~~/softwarestudio.org/Tzfile/America/Tijuana
+US Mountain Standard Time~~~/softwarestudio.org/Tzfile/America/Phoenix
+Mountain Standard Time (Mexico)~~~/softwarestudio.org/Tzfile/America/Mazatlan
+Mexico Standard Time 2~~~/softwarestudio.org/Tzfile/America/Chihuahua
+Mountain Standard Time~~~/softwarestudio.org/Tzfile/America/Denver
+Central America Standard Time~~~/softwarestudio.org/Tzfile/America/Costa_Rica
+Central Standard Time~~~/softwarestudio.org/Tzfile/America/Chicago
+Central Standard Time (Mexico)~~~/softwarestudio.org/Tzfile/America/Monterrey
+Mexico Standard Time~~~/softwarestudio.org/Tzfile/America/Mexico_City
+Canada Central Standard Time~~~/softwarestudio.org/Tzfile/America/Winnipeg
+SA Pacific Standard Time~~~/softwarestudio.org/Tzfile/America/Bogota
+Eastern Standard Time~~~/softwarestudio.org/Tzfile/America/New_York
+US Eastern Standard Time~~~/softwarestudio.org/Tzfile/America/Indiana/Indianapolis
+Venezuela Standard Time~~~/softwarestudio.org/Tzfile/America/Caracas
+Atlantic Standard Time~~~/softwarestudio.org/Tzfile/America/Halifax
+SA Western Standard Time~~~/softwarestudio.org/Tzfile/America/La_Paz
+Central Brazilian Standard Time~~~/softwarestudio.org/Tzfile/America/Manaus
+Pacific SA Standard Time~~~/softwarestudio.org/Tzfile/America/La_Paz
+Newfoundland Standard Time~~~/softwarestudio.org/Tzfile/America/St_Johns
+E. South America Standard Time~~~/softwarestudio.org/Tzfile/America/Bahia
+SA Eastern Standard Time~~~/softwarestudio.org/Tzfile/America/Argentina/Buenos_Aires
+Greenland Standard Time~~~/softwarestudio.org/Tzfile/America/Godthab
+Montevideo Standard Time~~~/softwarestudio.org/Tzfile/America/Montevideo
+Mid-Atlantic Standard Time~~~/softwarestudio.org/Tzfile/Atlantic/South_Georgia
+Azores Standard Time~~~/softwarestudio.org/Tzfile/Atlantic/Azores
+Cape Verde Standard Time~~~/softwarestudio.org/Tzfile/Atlantic/Cape_Verde
+Greenwich Standard Time~~~/softwarestudio.org/Tzfile/Africa/Casablanca
+GMT Standard Time~~~UTC
+W. Europe Standard Time~~~/softwarestudio.org/Tzfile/Europe/Berlin
+Central Europe Standard Time~~~/softwarestudio.org/Tzfile/Europe/Prague
+Romance Standard Time~~~/softwarestudio.org/Tzfile/Europe/Paris
+Central European Standard Time~~~/softwarestudio.org/Tzfile/Europe/Belgrade
+W. Central Africa Standard Time~~~/softwarestudio.org/Tzfile/Africa/Luanda
+Jordan Standard Time~~~/softwarestudio.org/Tzfile/Asia/Amman
+GTB Standard Time~~~/softwarestudio.org/Tzfile/Europe/Athens
+Middle East Standard Time~~~/softwarestudio.org/Tzfile/Asia/Beirut
+Egypt Standard Time~~~/softwarestudio.org/Tzfile/Africa/Cairo
+South Africa Standard Time~~~/softwarestudio.org/Tzfile/Africa/Harare
+FLE Standard Time~~~/softwarestudio.org/Tzfile/Europe/Helsinki
+Israel Standard Time~~~/softwarestudio.org/Tzfile/Asia/Jerusalem
+E. Europe Standard Time~~~/softwarestudio.org/Tzfile/Europe/Minsk
+Namibia Standard Time~~~/softwarestudio.org/Tzfile/Africa/Windhoek
+Arabic Standard Time~~~/softwarestudio.org/Tzfile/Asia/Baghdad
+Arab Standard Time~~~/softwarestudio.org/Tzfile/Asia/Qatar
+Russian Standard Time~~~/softwarestudio.org/Tzfile/Europe/Moscow
+E. Africa Standard Time~~~/softwarestudio.org/Tzfile/Africa/Nairobi
+Georgian Standard Time~~~/softwarestudio.org/Tzfile/Asia/Tbilisi
+Iran Standard Time~~~/softwarestudio.org/Tzfile/Asia/Tehran
+Arabian Standard Time~~~/softwarestudio.org/Tzfile/Asia/Muscat
+Azerbaijan Standard Time~~~/softwarestudio.org/Tzfile/Asia/Baku
+Caucasus Standard Time~~~/softwarestudio.org/Tzfile/Asia/Yerevan
+Armenian Standard Time~~~/softwarestudio.org/Tzfile/Asia/Yerevan
+Afghanistan Standard Time~~~/softwarestudio.org/Tzfile/Asia/Kabul
+Ekaterinburg Standard Time~~~/softwarestudio.org/Tzfile/Asia/Yekaterinburg
+West Asia Standard Time~~~/softwarestudio.org/Tzfile/Asia/Karachi
+India Standard Time~~~/softwarestudio.org/Tzfile/Asia/Calcutta
+Sri Lanka Standard Time~~~/softwarestudio.org/Tzfile/Asia/Colombo
+Nepal Standard Time~~~/softwarestudio.org/Tzfile/Asia/Katmandu
+N. Central Asia Standard Time~~~/softwarestudio.org/Tzfile/Asia/Novosibirsk
+Central Asia Standard Time~~~/softwarestudio.org/Tzfile/Asia/Dhaka
+Myanmar Standard Time~~~/softwarestudio.org/Tzfile/Asia/Rangoon
+SE Asia Standard Time~~~/softwarestudio.org/Tzfile/Asia/Bangkok
+North Asia Standard Time~~~/softwarestudio.org/Tzfile/Asia/Krasnoyarsk
+China Standard Time~~~/softwarestudio.org/Tzfile/Asia/Shanghai
+North Asia East Standard Time~~~/softwarestudio.org/Tzfile/Asia/Ulaanbaatar
+Singapore Standard Time~~~/softwarestudio.org/Tzfile/Asia/Singapore
+W. Australia Standard Time~~~/softwarestudio.org/Tzfile/Australia/Perth
+Taipei Standard Time~~~/softwarestudio.org/Tzfile/Asia/Taipei
+Tokyo Standard Time~~~/softwarestudio.org/Tzfile/Asia/Tokyo
+Korea Standard Time~~~/softwarestudio.org/Tzfile/Asia/Seoul
+Yakutsk Standard Time~~~/softwarestudio.org/Tzfile/Asia/Yakutsk
+Cen. Australia Standard Time~~~/softwarestudio.org/Tzfile/Australia/Adelaide
+AUS Central Standard Time~~~/softwarestudio.org/Tzfile/Australia/Darwin
+E. Australia Standard Time~~~/softwarestudio.org/Tzfile/Australia/Brisbane
+AUS Eastern Standard Time~~~/softwarestudio.org/Tzfile/Australia/Sydney
+West Pacific Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Guam
+Tasmania Standard Time~~~/softwarestudio.org/Tzfile/Australia/Hobart
+Vladivostok Standard Time~~~/softwarestudio.org/Tzfile/Asia/Vladivostok
+Central Pacific Standard Time~~~/softwarestudio.org/Tzfile/Asia/Magadan
+New Zealand Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Auckland
+Fiji Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Fiji
+Tonga Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Tongatapu



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