[evolution-mapi] Public calendar/task/address book support in mapi.



commit 5814933ec3e6420b9f5fc590982f31790d0a55eb
Author: Punit Jain <jpunit novell com>
Date:   Thu Jun 24 19:30:45 2010 +0530

    Public calendar/task/address book support in mapi.
    
    Bug #600661 - Support to subscribe to Esource type public folders.

 .../exchange-mapi-account-listener.c               |  148 +++++++++++++++++-
 .../exchange-mapi-account-listener.h               |    4 +-
 src/addressbook/e-book-backend-mapi.c              |   68 ++++++--
 src/calendar/e-cal-backend-mapi.c                  |  107 +++++++++----
 src/camel/camel-mapi-folder.c                      |    2 +-
 src/camel/camel-mapi-store.c                       |  166 +++++++++++++-------
 src/camel/camel-mapi-store.h                       |    1 +
 7 files changed, 388 insertions(+), 108 deletions(-)
---
diff --git a/src/account-setup-eplugin/exchange-mapi-account-listener.c b/src/account-setup-eplugin/exchange-mapi-account-listener.c
index 5f4062e..23aa805 100644
--- a/src/account-setup-eplugin/exchange-mapi-account-listener.c
+++ b/src/account-setup-eplugin/exchange-mapi-account-listener.c
@@ -179,7 +179,7 @@ find_source_by_fid (GSList *sources, const gchar *fid)
 #define SELECTED_CALENDARS	"/apps/evolution/calendar/display/selected_calendars"
 #define SELECTED_TASKS		"/apps/evolution/calendar/tasks/selected_tasks"
 #define SELECTED_JOURNALS	"/apps/evolution/calendar/memos/selected_memos"
-
+#define ADDRESSBOOK_SOURCES     "/apps/evolution/addressbook/sources"
 #define ITIP_MESSAGE_HANDLING	"/apps/evolution/itip/delete_processed"
 
 static void
@@ -269,6 +269,7 @@ add_cal_esource (EAccount *account, GSList *folders, ExchangeMAPIFolderType fold
 		e_source_set_property (source, "profile", camel_url_get_param (url, "profile"));
 		e_source_set_property (source, "domain", camel_url_get_param (url, "domain"));
 		e_source_set_property (source, "folder-id", fid);
+		e_source_set_property (source, "public", "no");
 		e_source_set_property (source, "offline_sync",
 					camel_url_get_param (url, "offline_sync") ? "1" : "0");
 
@@ -308,9 +309,11 @@ add_cal_esource (EAccount *account, GSList *folders, ExchangeMAPIFolderType fold
 		/* these were not found on the server by fid, thus remove them */
 		for (temp_list = old_sources; temp_list; temp_list = temp_list->next) {
 			ESource *source = temp_list->data;
-
-			if (source && E_IS_SOURCE (source))
-				e_source_group_remove_source (group, source);
+		
+			if (source && E_IS_SOURCE (source)) {
+				if (strcmp (e_source_get_property (source, "public"), "yes") != 0)
+					e_source_group_remove_source (group, source);
+			}
 		}
 
 		g_slist_free (old_sources);
@@ -327,6 +330,136 @@ add_cal_esource (EAccount *account, GSList *folders, ExchangeMAPIFolderType fold
 	g_object_unref (client);
 }
 
+void exchange_mapi_add_esource (CamelURL *url, const gchar *folder_name, const gchar *fid, gint folder_type)
+{
+	ESourceList *source_list = NULL;
+	ESourceGroup *group = NULL;
+	const gchar *conf_key = NULL;
+	GConfClient* client;
+	GSList *sources;
+	ESource *source = NULL;
+	gchar *relative_uri = NULL;
+	gchar *base_uri = NULL;
+	
+	if (url == NULL)
+		return;
+	
+	if (folder_type == MAPI_FOLDER_TYPE_APPOINTMENT) 
+		conf_key = CALENDAR_SOURCES;
+	else if (folder_type == MAPI_FOLDER_TYPE_TASK) 
+		conf_key = TASK_SOURCES;
+	else if (folder_type == MAPI_FOLDER_TYPE_MEMO) 
+		conf_key = JOURNAL_SOURCES;
+	else if (folder_type == MAPI_FOLDER_TYPE_JOURNAL)
+		conf_key = JOURNAL_SOURCES;
+	else if (folder_type == MAPI_FOLDER_TYPE_CONTACT)
+		conf_key = ADDRESSBOOK_SOURCES;
+	else {
+		g_warning ("%s: %s: Unknown ExchangeMAPIFolderType\n", G_STRLOC, G_STRFUNC);
+		return;
+	}
+
+	client = gconf_client_get_default ();
+	source_list = e_source_list_new_for_gconf (client, conf_key);
+	base_uri = g_strdup_printf ("%s%s %s/", MAPI_URI_PREFIX, url->user, url->host);
+	group = e_source_list_peek_group_by_base_uri (source_list, base_uri);
+	sources = e_source_group_peek_sources (group);	
+	for (; sources != NULL; sources = g_slist_next (sources)) {
+		ESource *source = E_SOURCE (sources->data);
+		gchar* folder_id = e_source_get_duped_property (source, "folder-id");
+		if (folder_id && fid) { 
+			if (strcmp (fid, folder_id) != 0) 
+				continue;
+			else {
+				g_warning ("%s: %s: Esource Already exist \n", G_STRLOC, G_STRFUNC);
+				return;	
+			}
+		}
+	}
+
+	
+	relative_uri = g_strconcat (";", fid, NULL);
+	source = e_source_new (folder_name, relative_uri);
+	e_source_set_property (source, "auth", "1");
+	e_source_set_property (source, "auth-domain", EXCHANGE_MAPI_PASSWORD_COMPONENT);
+	e_source_set_property (source, "auth-type", "plain/password");
+	e_source_set_property (source, "username", url->user);
+	e_source_set_property (source, "host", url->host);
+	e_source_set_property (source, "profile", camel_url_get_param (url, "profile"));
+	e_source_set_property (source, "domain", camel_url_get_param (url, "domain"));
+	e_source_set_property (source, "folder-id", fid);
+	e_source_set_property (source, "offline_sync",
+				camel_url_get_param (url, "offline_sync") ? "1" : "0");
+	e_source_set_property (source, "public", "yes");
+	e_source_set_property (source, "delete", "yes");
+
+	e_source_group_add_source (group, source, -1);
+
+	g_object_unref (source);
+	g_free (relative_uri);
+			
+	if (!e_source_list_add_group (source_list, group, -1))
+		return;
+
+	if (!e_source_list_sync (source_list, NULL))
+		return;
+
+	g_object_unref (group);
+	g_object_unref (source_list);
+	g_object_unref (client);
+}
+
+
+void exchange_mapi_remove_esource (CamelURL *url, const gchar* folder_name, const gchar *fid, gint folder_type)
+{
+	ESourceList *source_list = NULL;
+	ESourceGroup *group = NULL;
+	const gchar *conf_key = NULL;
+	GConfClient* client;
+	GSList *sources=NULL;
+	gchar *base_uri = NULL;
+	
+	if (url == NULL)
+		return;
+
+	if (folder_type == MAPI_FOLDER_TYPE_APPOINTMENT) 
+		conf_key = CALENDAR_SOURCES;
+	else if (folder_type == MAPI_FOLDER_TYPE_TASK) 
+		conf_key = TASK_SOURCES;
+	else if (folder_type == MAPI_FOLDER_TYPE_MEMO) 
+		conf_key = JOURNAL_SOURCES;
+	else if (folder_type == MAPI_FOLDER_TYPE_JOURNAL)
+		conf_key = JOURNAL_SOURCES;
+	else if (folder_type == MAPI_FOLDER_TYPE_CONTACT)
+		conf_key = ADDRESSBOOK_SOURCES;
+	else {
+		g_warning ("%s: %s: Unknown ExchangeMAPIFolderType\n", G_STRLOC, G_STRFUNC);
+		return;
+	}
+
+	client = gconf_client_get_default ();
+	source_list = e_source_list_new_for_gconf (client, conf_key);
+	base_uri = g_strdup_printf ("%s%s %s/", MAPI_URI_PREFIX, url->user, url->host);
+	group = e_source_list_peek_group_by_base_uri (source_list, base_uri);
+	sources = e_source_group_peek_sources (group);	
+	
+	for (; sources != NULL; sources = g_slist_next (sources)) {
+		ESource *source = E_SOURCE (sources->data);
+		gchar* folder_id = e_source_get_duped_property (source, "folder-id"); 
+		if (folder_id && fid)
+			if (strcmp(fid, folder_id) == 0) {
+				e_source_group_remove_source(group, source);
+				break;
+			}
+	}
+
+	g_free (base_uri);
+	g_object_unref (source_list);
+	g_object_unref (client);
+
+}
+
+
 static void
 remove_cal_esource (EAccount *existing_account_info, ExchangeMAPIFolderType folder_type, CamelURL *url)
 {
@@ -501,6 +634,7 @@ add_addressbook_sources (EAccount *account, GSList *folders, mapi_id_t trash_fid
 		e_source_set_property(source, "profile", camel_url_get_param (url, "profile"));
 		e_source_set_property(source, "domain", camel_url_get_param (url, "domain"));
 		e_source_set_property(source, "folder-id", fid);
+		e_source_set_property (source, "public", "no");
 		e_source_set_property (source, "offline_sync",
 					       camel_url_get_param (url, "offline_sync") ? "1" : "0");
 		e_source_set_property (source, "completion", "true");
@@ -568,8 +702,10 @@ add_addressbook_sources (EAccount *account, GSList *folders, mapi_id_t trash_fid
 		for (temp_list = old_sources; temp_list; temp_list = temp_list->next) {
 			ESource *source = temp_list->data;
 
-			if (source && E_IS_SOURCE (source))
-				e_source_group_remove_source (group, source);
+			if (source && E_IS_SOURCE (source)) {
+				if (strcmp(e_source_get_property(source, "public"), "yes") != 0)
+					e_source_group_remove_source (group, source);
+			}
 		}
 
 		g_slist_free (old_sources);
diff --git a/src/account-setup-eplugin/exchange-mapi-account-listener.h b/src/account-setup-eplugin/exchange-mapi-account-listener.h
index 2312188..6b52982 100644
--- a/src/account-setup-eplugin/exchange-mapi-account-listener.h
+++ b/src/account-setup-eplugin/exchange-mapi-account-listener.h
@@ -25,7 +25,7 @@
 
 #include <glib.h>
 #include <glib-object.h>
-
+#include <camel/camel.h>
 G_BEGIN_DECLS
 
 #define EXCHANGE_MAPI_ACCOUNT_LISTENER_TYPE		(exchange_mapi_account_listener_get_type ())
@@ -47,6 +47,8 @@ struct _ExchangeMAPIAccountListenerClass {
 	GObjectClass parent_class;
 };
 
+void				exchange_mapi_add_esource (CamelURL *url, const gchar *folder_name, const gchar *fid, gint folder_type);
+void				exchange_mapi_remove_esource (CamelURL *url, const gchar *folder_name, const gchar *fid, gint folder_type);
 GType				exchange_mapi_account_listener_get_type (void);
 ExchangeMAPIAccountListener *	exchange_mapi_account_listener_new (void);
 
diff --git a/src/addressbook/e-book-backend-mapi.c b/src/addressbook/e-book-backend-mapi.c
index d20e509..a0995f6 100644
--- a/src/addressbook/e-book-backend-mapi.c
+++ b/src/addressbook/e-book-backend-mapi.c
@@ -896,7 +896,16 @@ e_book_backend_mapi_get_contact (EBookBackend *backend,
 	EBookBackendMAPIPrivate *priv = ((EBookBackendMAPI *) backend)->priv;
 	EContact *contact = NULL;
 	gchar *vcard;
-
+	ESource *source;
+	guint32 options = MAPI_OPTIONS_FETCH_ALL; 
+	gboolean is_public = FALSE; 
+	
+	source = e_book_backend_get_source(backend);
+	if (strcmp (e_source_get_property(source, "public"), "yes") == 0 ) {
+		options |= MAPI_OPTIONS_USE_PFSTORE;
+		is_public = TRUE;
+	}
+ 
 	if (enable_debug)
 		printf("mapi: get_contact %s\n", id);
 
@@ -947,9 +956,9 @@ e_book_backend_mapi_get_contact (EBookBackend *backend,
 
 			exchange_mapi_util_mapi_ids_from_uid (id, &fid, &mid);
 			exchange_mapi_connection_fetch_item (priv->conn, priv->fid, mid,
-							mapi_book_utils_get_prop_list, GET_ALL_KNOWN_IDS,
+							is_public ? NULL : mapi_book_utils_get_prop_list, GET_ALL_KNOWN_IDS,
 							create_contact_item, contact,
-							MAPI_OPTIONS_FETCH_ALL);
+							options);
 
 			if (contact) {
 				e_contact_set (contact, E_CONTACT_BOOK_URI, priv->uri);
@@ -1012,6 +1021,14 @@ e_book_backend_mapi_get_contact_list (EBookBackend *backend,
 					    const gchar   *query )
 {
 	EBookBackendMAPIPrivate *priv = ((EBookBackendMAPI *) backend)->priv;
+	ESource *source;
+	guint32 options = MAPI_OPTIONS_FETCH_ALL; 
+	gboolean is_public = FALSE; 	
+	source = e_book_backend_get_source(backend);
+	if (strcmp (e_source_get_property(source, "public"), "yes") == 0 ) {
+		options |= MAPI_OPTIONS_USE_PFSTORE;
+		is_public = TRUE;
+	}
 
 	printf("mapi: get contact list %s\n", query);
 	switch (priv->mode) {
@@ -1074,9 +1091,9 @@ e_book_backend_mapi_get_contact_list (EBookBackend *backend,
 			}
 
 			if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, no_summary_search ? NULL : &res, NULL,
-								mapi_book_utils_get_prop_list, GET_ALL_KNOWN_IDS,
+								is_public ? NULL : mapi_book_utils_get_prop_list, GET_ALL_KNOWN_IDS,
 								create_contact_list_cb, &vcard_str,
-								MAPI_OPTIONS_FETCH_ALL)) {
+								options)) {
 				e_data_book_respond_get_contact_list (book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);
 				return;
 			}
@@ -1198,6 +1215,15 @@ book_view_thread (gpointer data)
 	GList *contacts = NULL, *temp_list = NULL;
 	//Number of multiple restriction to apply
 	guint res_count = 6;
+	ESource *source;
+	guint32 options = MAPI_OPTIONS_FETCH_ALL; 
+	gboolean is_public = FALSE; 
+
+	source = e_book_backend_get_source(E_BOOK_BACKEND(backend));
+	if (strcmp (e_source_get_property(source, "public"), "yes") == 0 ) {
+		options |= MAPI_OPTIONS_USE_PFSTORE;
+		is_public = TRUE;
+	}
 
 	if (enable_debug)
 		printf("mapi: book view\n");
@@ -1322,9 +1348,9 @@ book_view_thread (gpointer data)
 
 			//FIXME: We need to fetch only the query from the server live and not everything.
 			if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
-							   mapi_book_utils_get_prop_list, GET_SHORT_SUMMARY,
+							   is_public ? NULL : mapi_book_utils_get_prop_list, GET_SHORT_SUMMARY,
 							   create_contact_cb, book_view,
-							   MAPI_OPTIONS_FETCH_ALL)) {
+							   options)) {
 			if (e_flag_is_set (closure->running))
 				e_data_book_view_notify_complete (book_view,
 								  GNOME_Evolution_Addressbook_OtherError);
@@ -1337,9 +1363,9 @@ book_view_thread (gpointer data)
 			}
 		} else {
 			if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
-							mapi_book_utils_get_prop_list, GET_ALL_KNOWN_IDS,
+							is_public ? NULL : mapi_book_utils_get_prop_list, GET_ALL_KNOWN_IDS,
 							create_contact_cb, book_view,
-							MAPI_OPTIONS_FETCH_ALL)) {
+							options)) {
 				if (e_flag_is_set (closure->running))
 					e_data_book_view_notify_complete (book_view,
 									  GNOME_Evolution_Addressbook_OtherError);
@@ -1427,6 +1453,15 @@ build_cache (EBookBackendMAPI *ebmapi)
 {
 	EBookBackendMAPIPrivate *priv = ((EBookBackendMAPI *) ebmapi)->priv;
 	gchar *tmp;
+	ESource *source;
+	guint32 options = MAPI_OPTIONS_FETCH_ALL; 
+	gboolean is_public = FALSE; 
+
+	source = e_book_backend_get_source(E_BOOK_BACKEND(ebmapi));
+	if (strcmp (e_source_get_property(source, "public"), "yes") == 0 ) {
+		options |= MAPI_OPTIONS_USE_PFSTORE;
+		is_public = TRUE;
+	}
 
 	//FIXME: What if book view is NULL? Can it be? Check that.
 	if (!priv->cache) {
@@ -1443,9 +1478,9 @@ build_cache (EBookBackendMAPI *ebmapi)
 	e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
 
 	if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
-						mapi_book_utils_get_prop_list, GET_ALL_KNOWN_IDS,
+						is_public ? NULL : mapi_book_utils_get_prop_list, GET_ALL_KNOWN_IDS,
 						cache_contact_cb, ebmapi,
-						MAPI_OPTIONS_FETCH_ALL)) {
+						options)) {
 		printf("Error during caching addressbook\n");
 		e_file_cache_thaw_changes (E_FILE_CACHE (priv->cache));
 		return NULL;
@@ -1624,8 +1659,9 @@ e_book_backend_mapi_remove (EBookBackend *backend,
 {
 	EBookBackendMAPIPrivate *priv = ((EBookBackendMAPI *) backend)->priv;
 	gchar *cache_uri = NULL;
-	gboolean status;
-
+	gboolean status = TRUE;
+	ESource *source;
+	source = e_book_backend_get_source (backend);
 	if (enable_debug)
 		printf("mapi: remove\n");
 
@@ -1636,8 +1672,10 @@ e_book_backend_mapi_remove (EBookBackend *backend,
 		return;
 
 	case GNOME_Evolution_Addressbook_MODE_REMOTE:
-
-		status = exchange_mapi_connection_remove_folder (priv->conn, priv->fid, 0);
+		
+		if (strcmp (e_source_get_property(source, "public"), "yes") != 0)
+			status = exchange_mapi_connection_remove_folder (priv->conn, priv->fid, 0);
+		
 		if (!status) {
 			e_data_book_respond_remove (book, opid, GNOME_Evolution_Addressbook_OtherError);
 			return;
diff --git a/src/calendar/e-cal-backend-mapi.c b/src/calendar/e-cal-backend-mapi.c
index 6704202..66e4601 100644
--- a/src/calendar/e-cal-backend-mapi.c
+++ b/src/calendar/e-cal-backend-mapi.c
@@ -338,15 +338,18 @@ e_cal_backend_mapi_remove (ECalBackendSync *backend, EDataCal *cal)
 {
 	ECalBackendMAPI *cbmapi;
 	ECalBackendMAPIPrivate *priv;
-	gboolean status = FALSE;
+	gboolean status = TRUE;
+	ESource *source = NULL;
 
 	cbmapi = E_CAL_BACKEND_MAPI (backend);
 	priv = cbmapi->priv;
 
+	source = e_cal_backend_get_source (E_CAL_BACKEND (cbmapi));
+
 	if (priv->mode == CAL_MODE_LOCAL || !priv->conn || !exchange_mapi_connection_connected (priv->conn))
 		return GNOME_Evolution_Calendar_RepositoryOffline;
-
-	status = exchange_mapi_connection_remove_folder (priv->conn, priv->fid, 0);
+	if (strcmp (e_source_get_property (source, "public"), "yes") != 0)
+		status = exchange_mapi_connection_remove_folder (priv->conn, priv->fid, 0);
 	if (!status)
 		return GNOME_Evolution_Calendar_OtherError;
 
@@ -674,6 +677,9 @@ get_deltas (gpointer handle)
 	gboolean use_restriction = FALSE;
 	GSList *ls = NULL;
 	struct deleted_items_data did;
+	ESource *source = NULL;
+	guint32 options= MAPI_OPTIONS_FETCH_ALL;
+	gboolean is_public = FALSE; 
 
 	if (!handle)
 		return FALSE;
@@ -681,7 +687,7 @@ get_deltas (gpointer handle)
 	cbmapi = (ECalBackendMAPI *) handle;
 	priv= cbmapi->priv;
 	kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbmapi));
-
+	source = e_cal_backend_get_source (E_CAL_BACKEND (cbmapi));
 	if (priv->mode == CAL_MODE_LOCAL)
 		return FALSE;
 
@@ -716,25 +722,39 @@ get_deltas (gpointer handle)
 //	e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
 	/* FIXME: GetProps does not seem to work for tasks :-( */
 	if (kind == ICAL_VTODO_COMPONENT) {
+		if (strcmp (e_source_get_property(source, "public"), "yes") == 0 ) {
+			options |= MAPI_OPTIONS_USE_PFSTORE;
+			is_public = TRUE;
+			use_restriction = FALSE;	
+		}
+
 		if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, use_restriction ? &res : NULL, NULL,
-						mapi_cal_get_known_ids, NULL,
+						is_public ? NULL : mapi_cal_get_known_ids, NULL,
 						mapi_cal_get_changes_cb, cbmapi,
-						MAPI_OPTIONS_FETCH_ALL)) {
+						options)) {
 			/* FIXME: String : We need to restart evolution-data-server */
 			e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Error fetching changes from the server."));
 //			e_file_cache_thaw_changes (E_FILE_CACHE (priv->cache));
 			g_static_mutex_unlock (&updating);
 			return FALSE;
 		}
-	} else if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, use_restriction ? &res : NULL, NULL,
-						exchange_mapi_cal_utils_get_props_cb, GINT_TO_POINTER (kind),
+	} else {
+		if (strcmp (e_source_get_property(source, "public"), "yes") == 0) {
+			options |= MAPI_OPTIONS_USE_PFSTORE;
+			is_public = TRUE;
+			use_restriction = FALSE;
+		} 
+
+		if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, use_restriction ? &res : NULL, NULL,
+						is_public ? NULL : exchange_mapi_cal_utils_get_props_cb, GINT_TO_POINTER (kind),
 						mapi_cal_get_changes_cb, cbmapi,
-						MAPI_OPTIONS_FETCH_ALL)) {
+						options)) {
 		/* FIXME: String : We need to restart evolution-data-server */
 		e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Error fetching changes from the server."));
 //		e_file_cache_thaw_changes (E_FILE_CACHE (priv->cache));
 		g_static_mutex_unlock (&updating);
 		return FALSE;
+		}
 	}
 //	e_file_cache_thaw_changes (E_FILE_CACHE (priv->cache));
 
@@ -753,10 +773,15 @@ get_deltas (gpointer handle)
 	did.cbmapi = cbmapi;
 	did.cache_keys = e_cal_backend_cache_get_keys (priv->cache);
 	did.unknown_mids = NULL;
+	options = 0;
+
+	if (strcmp (e_source_get_property(source, "public"), "yes") == 0 )
+		options = MAPI_OPTIONS_USE_PFSTORE;
+
 	if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
 						mapi_cal_get_idlist, NULL,
 						handle_deleted_items_cb, &did,
-						0)) {
+						options)) {
 		/* FIXME: String : We need to restart evolution-data-server */
 		e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Error fetching changes from the server."));
 		g_slist_free (did.cache_keys);
@@ -764,6 +789,7 @@ get_deltas (gpointer handle)
 		return FALSE;
 	}
 
+	options = MAPI_OPTIONS_FETCH_ALL;
 	e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
 	for (ls = did.cache_keys; ls; ls = g_slist_next (ls)) {
 		ECalComponent *comp = NULL;
@@ -816,25 +842,37 @@ get_deltas (gpointer handle)
 		g_slist_free (did.unknown_mids);
 
 		if (kind == ICAL_VTODO_COMPONENT) {
+			if (strcmp (e_source_get_property(source, "public"), "yes") == 0) {
+				options |= MAPI_OPTIONS_USE_PFSTORE;
+				is_public = TRUE;
+			}
+ 			
 			if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
-						mapi_cal_get_known_ids, NULL,
+						is_public ? NULL : mapi_cal_get_known_ids, NULL,
 						mapi_cal_get_changes_cb, cbmapi,
-						MAPI_OPTIONS_FETCH_ALL)) {
+						options)) {
+								
 				e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Error fetching changes from the server."));
 				g_static_mutex_unlock (&updating);
 				g_free (or_res);
 				return FALSE;
 			}
-		} else if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
-						exchange_mapi_cal_utils_get_props_cb, GINT_TO_POINTER (kind),
+		} else {
+			if (strcmp (e_source_get_property(source, "public"), "yes") == 0) {
+				options |= MAPI_OPTIONS_USE_PFSTORE;
+				is_public = TRUE;
+			}
+
+			if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
+						is_public ? NULL : exchange_mapi_cal_utils_get_props_cb, GINT_TO_POINTER (kind),
 						mapi_cal_get_changes_cb, cbmapi,
-						MAPI_OPTIONS_FETCH_ALL)) {
+						options)) {
 			e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Error fetching changes from the server."));
 			g_free (or_res);
 			g_static_mutex_unlock (&updating);
 			return FALSE;
+			}
 		}
-
 		g_free (or_res);
 	}
 
@@ -1135,7 +1173,8 @@ populate_cache (ECalBackendMAPI *cbmapi)
 	struct tm tm;
 	gchar *time_string = NULL;
 	gchar t_str [26];
-
+	guint32 options= MAPI_OPTIONS_FETCH_ALL;
+	gboolean is_public = FALSE;  
 	priv = cbmapi->priv;
 
 	g_mutex_lock (priv->mutex);
@@ -1159,10 +1198,15 @@ populate_cache (ECalBackendMAPI *cbmapi)
 //	e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
 	/* FIXME: GetProps does not seem to work for tasks :-( */
 	if (kind == ICAL_VTODO_COMPONENT) {
+		if (strcmp (e_source_get_property(source, "public"), "yes") == 0) {
+			options |= MAPI_OPTIONS_USE_PFSTORE;
+			is_public = TRUE;	
+		}
+		
 		if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
-						mapi_cal_get_known_ids, NULL,
+						is_public ? NULL : mapi_cal_get_known_ids, NULL,
 						mapi_cal_cache_create_cb, cbmapi,
-						MAPI_OPTIONS_FETCH_ALL)) {
+						options)) {
 			e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Could not create cache file"));
 			e_file_cache_thaw_changes (E_FILE_CACHE (priv->cache));
 			g_mutex_lock (priv->mutex);
@@ -1170,16 +1214,23 @@ populate_cache (ECalBackendMAPI *cbmapi)
 			g_mutex_unlock (priv->mutex);
 			return GNOME_Evolution_Calendar_OtherError;
 		}
-	} else if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
-						exchange_mapi_cal_utils_get_props_cb, GINT_TO_POINTER (kind),
+	} else {
+		if (strcmp (e_source_get_property(source, "public"), "yes") ==0 ) {
+			options |= MAPI_OPTIONS_USE_PFSTORE;
+			is_public = TRUE;
+		}
+		
+		if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
+						is_public ? NULL : exchange_mapi_cal_utils_get_props_cb, 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"));
-		e_file_cache_thaw_changes (E_FILE_CACHE (priv->cache));
-		g_mutex_lock (priv->mutex);
-		priv->populating_cache = FALSE;
-		g_mutex_unlock (priv->mutex);
-		return GNOME_Evolution_Calendar_OtherError;
+						options)) {
+			e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Could not create cache file"));
+			e_file_cache_thaw_changes (E_FILE_CACHE (priv->cache));
+			g_mutex_lock (priv->mutex);
+			priv->populating_cache = FALSE;
+			g_mutex_unlock (priv->mutex);
+			return GNOME_Evolution_Calendar_OtherError;
+		}
 	}
 //	e_file_cache_thaw_changes (E_FILE_CACHE (priv->cache));
 
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index c657a6b..e987aa2 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -155,7 +155,7 @@ fetch_items_summary_cb (FetchItemsCallbackData *item_data, gpointer data)
 
 	GSList **slist = &(fi_data->items_list);
 
-	long *flags;
+	long *flags = NULL;
 	struct FILETIME *delivery_date = NULL;
 	struct FILETIME *last_modification_time = NULL;
 	struct timeval item_modification_time = { 0 };
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index 93b1d0b..fd79ac1 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -38,7 +38,7 @@
 #include "camel-mapi-store-summary.h"
 #include "camel-mapi-summary.h"
 #include "camel-mapi-notifications.h"
-
+#include "account-setup-eplugin/exchange-mapi-account-listener.h"
 #include <exchange-mapi-utils.h>
 //#define d(x) x
 
@@ -67,6 +67,7 @@ struct _CamelMapiStorePrivate {
 
 	GHashTable *id_hash; /*get names from ids*/
 	GHashTable *name_hash;/*get ids from names*/
+	GHashTable *container_hash;
 	GHashTable *parent_hash;
 	GHashTable *default_folders; /*Default Type : Folder ID*/
 
@@ -97,10 +98,11 @@ static gboolean		mapi_unsubscribe_folder(CamelStore *, const gchar *, CamelExcep
 static gboolean		mapi_noop(CamelStore *, CamelException *);
 static CamelFolderInfo * mapi_build_folder_info(CamelMapiStore *mapi_store, const gchar *parent_name, const gchar *folder_name);
 static gboolean mapi_fid_is_system_folder (CamelMapiStore *mapi_store, const gchar *fid);
+static void mapi_update_hash_table_type (CamelMapiStore *store, const gchar *full_name, guint *folder_type);
 static CamelFolder *mapi_get_trash (CamelStore *store, CamelException *ex);
 static CamelFolder *mapi_get_junk (CamelStore *store, CamelException *ex);
-
 static void mapi_update_folder_hash_tables (CamelMapiStore *store, const gchar *name, const gchar *fid, const gchar *parent_id);
+guint mapi_folders_hash_table_type_lookup (CamelMapiStore *store, const gchar *name);
 /* static const gchar * mapi_folders_hash_table_name_lookup (CamelMapiStore *store, const gchar *fid, gboolean use_cache); */
 #if 0
 static const gchar * mapi_folders_hash_table_fid_lookup (CamelMapiStore *store, const gchar *name, gboolean use_cache);
@@ -194,7 +196,8 @@ mapi_store_finalize (GObject *object)
 
 	if (priv->default_folders != NULL)
 		g_hash_table_destroy (priv->default_folders);
-
+	if (priv->container_hash != NULL)
+		g_hash_table_destroy (priv->container_hash);
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (camel_mapi_store_parent_class)->finalize (object);
 }
@@ -297,7 +300,7 @@ static gboolean mapi_construct(CamelService *service, CamelSession *session,
 	priv->name_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* folder Full name to folder ID */
 	/*priv->parent_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); / * folder ID to its parent folder ID */
 	priv->default_folders = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_free); /* default folder type to folder ID */
-
+	priv->container_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 	store->flags &= ~CAMEL_STORE_VJUNK;
 	store->flags &= ~CAMEL_STORE_VTRASH;
 
@@ -1036,7 +1039,7 @@ mapi_build_folder_info(CamelMapiStore *mapi_store, const gchar *parent_name, con
 	} else
 		fi->full_name = g_strdup(folder_name);
 
-	url = camel_url_new(priv->base_url,NULL);
+	url = camel_url_new (priv->base_url, NULL);
 	g_free(url->path);
 
 	url->path = g_strdup_printf("/%s", fi->full_name);
@@ -1102,8 +1105,11 @@ mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
 			camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
 			continue;
 		}
-
-		if ( !strcmp(name, camel_mapi_store_info_full_name (mapi_store->summary, si))
+		
+		if (!subscription_list && !(si->flags & CAMEL_MAPI_FOLDER_MAIL) && si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED && 
+												si->flags & CAMEL_MAPI_FOLDER_PUBLIC)
+			continue;
+		if (!strcmp(name, camel_mapi_store_info_full_name (mapi_store->summary, si))
 		     || match_path (path, camel_mapi_store_info_full_name (mapi_store->summary, si))) {
 
 			const gchar *store_info_path = camel_store_info_path((CamelStoreSummary *)mapi_store->summary, si);
@@ -1249,6 +1255,16 @@ camel_mapi_store_connected (CamelMapiStore *store, CamelException *ex)
 	return FALSE;
 }
 
+static void 
+mapi_update_hash_table_type (CamelMapiStore *store, const gchar *full_name, guint *folder_type)
+{
+	CamelMapiStorePrivate  *priv = store->priv;
+	if (full_name && folder_type) {
+		if (!g_hash_table_lookup (priv->container_hash, full_name))
+			g_hash_table_insert (priv->container_hash, g_strdup (full_name), folder_type);
+	}
+}
+
 static void
 mapi_update_folder_hash_tables (CamelMapiStore *store, const gchar *full_name, const gchar *fid, const gchar *parent_id)
 {
@@ -1288,6 +1304,16 @@ mapi_folders_update_hash_tables_from_cache (CamelMapiStore *store)
 }
 
 /* static const gchar * */
+
+guint 
+mapi_folders_hash_table_type_lookup (CamelMapiStore *store, const gchar *name) 
+{
+	CamelMapiStorePrivate  *priv = store->priv;
+	guint *folder_type = g_hash_table_lookup (priv->container_hash, name);
+	
+	return *folder_type;
+}
+
 const gchar *
 mapi_folders_hash_table_name_lookup (CamelMapiStore *store, const gchar *fid,
 				     gboolean use_cache)
@@ -1432,6 +1458,7 @@ mapi_folders_sync (CamelMapiStore *store, guint32 flags, CamelException *ex)
 	for (;temp_list != NULL; temp_list = g_slist_next (temp_list) ) {
 		const gchar *full_name = NULL;
 		gchar *fid = NULL, *parent_id = NULL, *tmp = NULL;
+		guint *folder_type = g_new0 (guint, 1);
 
 		fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(temp_list->data)));
 		parent_id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_parent_id ((ExchangeMAPIFolder *)(temp_list->data)));
@@ -1450,9 +1477,9 @@ mapi_folders_sync (CamelMapiStore *store, guint32 flags, CamelException *ex)
 
 		/* remove from here; what lefts is not on the server any more */
 		g_hash_table_remove (old_cache_folders, full_name);
-
+		*folder_type = ((ExchangeMAPIFolder *)(temp_list->data))->container_class;
 		mapi_update_folder_hash_tables (store, full_name, fid, parent_id);
-
+		mapi_update_hash_table_type (store, full_name, folder_type);
 		if (((ExchangeMAPIFolder *)(temp_list->data))->is_default) {
 			guint *type = g_new0 (guint, 1);
 			*type = ((ExchangeMAPIFolder *)(temp_list->data))->default_type;
@@ -1470,42 +1497,61 @@ mapi_folders_sync (CamelMapiStore *store, guint32 flags, CamelException *ex)
 		if (folder->default_type == olPublicFoldersAllPublicFolders)
 			continue;
 
-		if ( folder->container_class != MAPI_FOLDER_TYPE_MAIL)
-			continue;
-
-		info = mapi_convert_to_folder_info (store, folder, (const gchar *)url, ex);
-		mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name);
-		if (!mapi_si) {
+		if ( folder->container_class == MAPI_FOLDER_TYPE_MAIL) {
+			info = mapi_convert_to_folder_info (store, folder, (const gchar *)url, ex);
+			info->flags |= CAMEL_MAPI_FOLDER_MAIL;
+			mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name);
+			
+			if (!mapi_si) {
+				gchar *fid, *pfid = NULL;
+	
+				fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
+						       exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
+				pfid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
+							exchange_mapi_folder_get_parent_id((ExchangeMAPIFolder *)(folder_list->data)));
+	
+				mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/', fid, pfid);
+				g_free (fid);
+				g_free (pfid);
+				if (mapi_si == NULL)
+					continue;
+	
+				camel_store_summary_info_ref ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
+	
+				if (!subscription_list) {
+					camel_store_folder_created (CAMEL_STORE (store), info);
+					camel_store_folder_subscribed (CAMEL_STORE (store), info);
+				}
+			}
+		
+			mapi_si->info.flags |= info->flags;
+			mapi_si->info.total = info->total;
+			mapi_si->info.unread = info->unread;
+			
+			camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
+			camel_folder_info_free (info);
+		} else if (folder->category == MAPI_FAVOURITE_FOLDER) {
 			gchar *fid, *pfid = NULL;
-
+			info = mapi_convert_to_folder_info (store, folder, (const gchar *)url, ex);
+			mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name);
 			fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
-					       exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
+						exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
 			pfid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
 						exchange_mapi_folder_get_parent_id((ExchangeMAPIFolder *)(folder_list->data)));
-
 			mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/', fid, pfid);
 			g_free (fid);
 			g_free (pfid);
-			if (mapi_si == NULL) {
+
+			if (mapi_si == NULL)
 				continue;
-			}
 
 			camel_store_summary_info_ref ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
-
-			if (!subscription_list) {
-				camel_store_folder_created (CAMEL_STORE (store), info);
-				camel_store_folder_subscribed (CAMEL_STORE (store), info);
-			}
+			mapi_si->info.flags |= info->flags;
+			camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
+			camel_folder_info_free (info);	
 		}
-
-		mapi_si->info.flags |= info->flags;
-		mapi_si->info.total = info->total;
-		mapi_si->info.unread = info->unread;
-
-		camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
-		camel_folder_info_free (info);
 	}
-
+	
 	/* Weed out deleted folders */
 	g_hash_table_foreach (old_cache_folders, (GHFunc) remove_path_from_store_summary, store);
 	g_hash_table_destroy (old_cache_folders);
@@ -1629,11 +1675,14 @@ static gboolean
 mapi_subscribe_folder(CamelStore *store, const gchar *folder_name, CamelException *ex)
 {
 	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+	guint folder_type = mapi_folders_hash_table_type_lookup(mapi_store, folder_name);
 	CamelFolderInfo *fi;
 	CamelStoreInfo *si = NULL;
-	const gchar *parent_name = NULL, *use_folder_name = folder_name;
+	const gchar *parent_name = NULL, *use_folder_name = folder_name, *fid = NULL;
 	gboolean favourites = FALSE;
 	/* TODO : exchange_mapi_add_to_favorites (); */
+	
+	fid = camel_mapi_store_folder_id_lookup(mapi_store, folder_name);
 
 	if (g_str_has_prefix (folder_name, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) ) {
 		const gchar *f_name = NULL;
@@ -1649,41 +1698,39 @@ mapi_subscribe_folder(CamelStore *store, const gchar *folder_name, CamelExceptio
 		use_folder_name = ++f_name;
 		favourites = TRUE;
 	}
-
-	fi = mapi_build_folder_info (mapi_store, parent_name, use_folder_name);
-
 	si = camel_store_summary_path((CamelStoreSummary *)mapi_store->summary, folder_name);
+
 	if (si != NULL) {
 		if ((si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) == 0) {
 			si->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
 			si->flags |= CAMEL_FOLDER_SUBSCRIBED;
 			camel_store_summary_touch((CamelStoreSummary *)mapi_store->summary);
 		}
+	}
 
+	if (folder_type == MAPI_FOLDER_TYPE_MAIL || folder_type == MAPI_FOLDER_TYPE_UNKNOWN) {
+		fi = mapi_build_folder_info (mapi_store, parent_name, use_folder_name);		
 		if (favourites) {
 			CamelURL *url;
-
 			url = camel_url_new (mapi_store->priv->base_url, NULL);
 			url->path = g_strdup_printf ("/%s", camel_store_info_path (mapi_store->summary, si));
 			g_free (fi->uri);
 			fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
-
 			camel_url_free (url);
 		}
 
 		fi->unread = si->unread;
 		fi->total = si->total;
 		fi->flags = si->flags;
-		camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
-	}
-
-	fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
-	fi->flags |= CAMEL_FOLDER_NOCHILDREN;
-	fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
-
-	camel_store_folder_subscribed (store, fi);
-	camel_folder_info_free (fi);
-
+		fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
+		fi->flags |= CAMEL_FOLDER_NOCHILDREN;
+		fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+		camel_store_folder_subscribed (store, fi);
+		camel_folder_info_free (fi);
+	} else
+		exchange_mapi_add_esource (CAMEL_SERVICE(mapi_store)->url, use_folder_name, fid, folder_type);
+	
+	camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
 	return TRUE;
 }
 
@@ -1708,10 +1755,13 @@ mapi_unsubscribe_folder(CamelStore *store, const gchar *folder_name, CamelExcept
 	CamelFolderInfo *fi;
 	CamelStoreInfo *si;
 	gchar *parent_name = NULL;
+	const gchar *fid = NULL;
 	gchar *f_name = NULL;
 
 	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
-
+	CamelURL *url = CAMEL_SERVICE (mapi_store)->url;
+	guint folder_type = mapi_folders_hash_table_type_lookup(mapi_store, folder_name);
+	fid = camel_mapi_store_folder_id_lookup(mapi_store, folder_name);
 	si = camel_store_summary_path((CamelStoreSummary *)mapi_store->summary, folder_name);
 	if (si) {
 		if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
@@ -1719,7 +1769,6 @@ mapi_unsubscribe_folder(CamelStore *store, const gchar *folder_name, CamelExcept
 			camel_store_summary_touch((CamelStoreSummary *)mapi_store->summary);
 			camel_store_summary_save((CamelStoreSummary *)mapi_store->summary);
 		}
-		camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
 	}
 
 	if (g_str_has_prefix (folder_name, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) ) {
@@ -1731,12 +1780,15 @@ mapi_unsubscribe_folder(CamelStore *store, const gchar *folder_name, CamelExcept
 		else //Don't process All Public Folder.
 			return TRUE;
 	}
-
-	fi = mapi_build_folder_info (mapi_store, parent_name, folder_name);
-
-	camel_store_folder_unsubscribed (store, fi);
-	camel_folder_info_free (fi);
-
+	if (si->flags & CAMEL_MAPI_FOLDER_MAIL) {
+		fi = mapi_build_folder_info (mapi_store, parent_name, folder_name);
+		camel_store_folder_unsubscribed (store, fi);
+		camel_folder_info_free (fi);
+	} else 
+		exchange_mapi_remove_esource(url, folder_name, fid, folder_type);
+	
+	camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
+		
 	return TRUE;
 }
 
diff --git a/src/camel/camel-mapi-store.h b/src/camel/camel-mapi-store.h
index 24d965d..7817f98 100644
--- a/src/camel/camel-mapi-store.h
+++ b/src/camel/camel-mapi-store.h
@@ -56,6 +56,7 @@
 #define CAMEL_MAPI_FOLDER_PUBLIC (CAMEL_FOLDER_FLAGS_LAST << 1)
 #define CAMEL_MAPI_FOLDER_PERSONAL (CAMEL_FOLDER_FLAGS_LAST << 2)
 #define CAMEL_MAPI_FOLDER_FORIEGN (CAMEL_FOLDER_FLAGS_LAST << 3)
+#define CAMEL_MAPI_FOLDER_MAIL (CAMEL_FOLDER_FLAGS_LAST << 4)
 
 #define DISPLAY_NAME_FAVOURITES _("Favorites")
 #define DISPLAY_NAME_ALL_PUBLIC_FOLDERS _("All Public Folders")



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