[evolution] Kill mail_store_set_offline().



commit 2636da7dac1683c7bac98b7a6d1ee084ea2efbca
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Oct 22 17:26:08 2010 -0400

    Kill mail_store_set_offline().
    
    Replace it with new async functions:
    
      e_mail_store_go_offline()
      e_mail_store_go_offline_finish()
    
      e_mail_store_go_online()
      e_mail_store_go_online_finish()

 mail/Makefile.am            |    2 +
 mail/e-mail-backend.c       |   40 +++++----
 mail/e-mail-store-utils.c   |  190 +++++++++++++++++++++++++++++++++++++++++++
 mail/e-mail-store-utils.h   |   47 +++++++++++
 mail/e-mail.h               |    1 +
 mail/em-folder-tree-model.c |    2 -
 mail/mail-folder-cache.c    |   23 +++---
 mail/mail-ops.c             |  179 +----------------------------------------
 mail/mail-ops.h             |    8 --
 9 files changed, 277 insertions(+), 215 deletions(-)
---
diff --git a/mail/Makefile.am b/mail/Makefile.am
index eb7ef84..a88a7c8 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -69,6 +69,7 @@ mailinclude_HEADERS =					\
 	e-mail-session-utils.h				\
 	e-mail-sidebar.h				\
 	e-mail-store.h					\
+	e-mail-store-utils.h				\
 	e-mail-tag-editor.h				\
 	em-account-editor.h				\
 	em-composer-utils.h				\
@@ -141,6 +142,7 @@ libevolution_mail_la_SOURCES =				\
 	e-mail-session-utils.c				\
 	e-mail-sidebar.c				\
 	e-mail-store.c					\
+	e-mail-store-utils.c				\
 	e-mail-tag-editor.c				\
 	em-account-editor.c				\
 	em-composer-utils.c				\
diff --git a/mail/e-mail-backend.c b/mail/e-mail-backend.c
index ce227f8..36b244d 100644
--- a/mail/e-mail-backend.c
+++ b/mail/e-mail-backend.c
@@ -38,6 +38,7 @@
 #include "mail/e-mail-migrate.h"
 #include "mail/e-mail-session.h"
 #include "mail/e-mail-store.h"
+#include "mail/e-mail-store-utils.h"
 #include "mail/em-event.h"
 #include "mail/em-folder-tree-model.h"
 #include "mail/em-utils.h"
@@ -86,9 +87,14 @@ mail_shell_backend_get_config_dir (EShellBackend *backend)
  * the EActivity's reference count is used as a counting semaphore. */
 static void
 mail_backend_store_operation_done_cb (CamelStore *store,
-                                      gpointer user_data)
+                                      GAsyncResult *result,
+                                      EActivity *activity)
 {
-	g_object_unref (E_ACTIVITY (user_data));
+	/* FIXME Not checking result for error.  To fix this, we need
+	 *       separate callbacks to call different finish functions
+	 *       and then submit an EAlert on error. */
+
+	g_object_unref (activity);
 }
 
 /* Helper for mail_backend_prepare_for_offline_cb() */
@@ -97,11 +103,11 @@ mail_store_prepare_for_offline_cb (CamelService *service,
                                    gpointer unused,
                                    EActivity *activity)
 {
-	if (CAMEL_IS_DISCO_STORE (service) || CAMEL_IS_OFFLINE_STORE (service))
-		mail_store_set_offline (
-			CAMEL_STORE (service), TRUE,
-			mail_backend_store_operation_done_cb,
-			g_object_ref (activity));
+	/* FIXME Not passing a GCancellable. */
+	e_mail_store_go_offline (
+		CAMEL_STORE (service), G_PRIORITY_DEFAULT, NULL,
+		(GAsyncReadyCallback) mail_backend_store_operation_done_cb,
+		g_object_ref (activity));
 }
 
 static void
@@ -136,11 +142,11 @@ mail_store_prepare_for_online_cb (CamelService *service,
                                   gpointer unused,
                                   EActivity *activity)
 {
-	if (CAMEL_IS_DISCO_STORE (service) || CAMEL_IS_OFFLINE_STORE (service))
-		mail_store_set_offline (
-			CAMEL_STORE (service), FALSE,
-			mail_backend_store_operation_done_cb,
-			g_object_ref (activity));
+	/* FIXME Not passing a GCancellable. */
+	e_mail_store_go_online (
+		CAMEL_STORE (service), G_PRIORITY_DEFAULT, NULL,
+		(GAsyncReadyCallback) mail_backend_store_operation_done_cb,
+		g_object_ref (activity));
 }
 
 static void
@@ -200,11 +206,11 @@ mail_backend_final_sync (CamelStore *store,
 		gboolean empty_trash;
 	} *sync_data = user_data;
 
-	/* Reffing the activity delays quitting; the reference count
-	 * acts like a counting semaphore. */
-	mail_sync_store (
-		store, sync_data->empty_trash,
-		mail_backend_store_operation_done_cb,
+	/* FIXME Not passing a GCancellable. */
+	/* FIXME This operation should be queued. */
+	camel_store_synchronize (
+		store, sync_data->empty_trash, G_PRIORITY_DEFAULT, NULL,
+		(GAsyncReadyCallback) mail_backend_store_operation_done_cb,
 		g_object_ref (sync_data->activity));
 }
 
diff --git a/mail/e-mail-store-utils.c b/mail/e-mail-store-utils.c
new file mode 100644
index 0000000..57304f9
--- /dev/null
+++ b/mail/e-mail-store-utils.c
@@ -0,0 +1,190 @@
+/*
+ * e-mail-store-utils.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-store-utils.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+typedef struct _AsyncContext AsyncContext;
+
+static void
+mail_store_go_offline_thread (GSimpleAsyncResult *simple,
+                              CamelStore *store,
+                              GCancellable *cancellable)
+{
+	CamelService *service;
+	gchar *service_name;
+	GError *error = NULL;
+
+	service = CAMEL_SERVICE (store);
+
+	service_name = camel_service_get_name (service, TRUE);
+	camel_operation_push_message (
+		cancellable, _("Disconnecting from '%s'"), service_name);
+	g_free (service_name);
+
+	if (CAMEL_IS_DISCO_STORE (store)) {
+		CamelDiscoStore *disco_store;
+
+		disco_store = CAMEL_DISCO_STORE (store);
+
+		if (camel_disco_store_can_work_offline (disco_store))
+			camel_disco_store_set_status (
+				disco_store, CAMEL_DISCO_STORE_OFFLINE,
+				cancellable, &error);
+		else
+			camel_service_disconnect_sync (service, TRUE, &error);
+
+	} else if (CAMEL_IS_OFFLINE_STORE (store)) {
+		CamelOfflineStore *offline_store;
+
+		offline_store = CAMEL_OFFLINE_STORE (store);
+
+		camel_offline_store_set_online_sync (
+			offline_store, FALSE, cancellable, &error);
+
+	} else
+		camel_service_disconnect_sync (service, TRUE, &error);
+
+	if (error != NULL) {
+		g_simple_async_result_set_from_error (simple, error);
+		g_error_free (error);
+	}
+
+	camel_operation_pop_message (cancellable);
+}
+
+void
+e_mail_store_go_offline (CamelStore *store,
+                         gint io_priority,
+                         GCancellable *cancellable,
+                         GAsyncReadyCallback callback,
+                         gpointer user_data)
+{
+	GSimpleAsyncResult *simple;
+
+	g_return_if_fail (CAMEL_IS_STORE (store));
+
+	/* Cancel any pending connect first so the set_offline_op
+	 * thread won't get queued behind a hung connect op. */
+	camel_service_cancel_connect (CAMEL_SERVICE (store));
+
+	simple = g_simple_async_result_new (
+		G_OBJECT (store), callback,
+		user_data, e_mail_store_go_offline);
+
+	g_simple_async_result_run_in_thread (
+		simple, (GSimpleAsyncThreadFunc)
+		mail_store_go_offline_thread,
+		io_priority, cancellable);
+
+	g_object_unref (simple);
+}
+
+gboolean
+e_mail_store_go_offline_finish (CamelStore *store,
+                                GAsyncResult *result,
+                                GError **error)
+{
+	GSimpleAsyncResult *simple;
+
+	g_return_val_if_fail (
+		g_simple_async_result_is_valid (
+		result, G_OBJECT (store), e_mail_store_go_offline), FALSE);
+
+	simple = G_SIMPLE_ASYNC_RESULT (result);
+
+	/* Assume success unless a GError is set. */
+	return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+mail_store_go_online_thread (GSimpleAsyncResult *simple,
+                             CamelStore *store,
+                             GCancellable *cancellable)
+{
+	CamelService *service;
+	gchar *service_name;
+	GError *error = NULL;
+
+	service = CAMEL_SERVICE (store);
+
+	service_name = camel_service_get_name (service, TRUE);
+	camel_operation_push_message (
+		cancellable, _("Reconnecting to '%s'"), service_name);
+	g_free (service_name);
+
+	if (CAMEL_IS_DISCO_STORE (store))
+		camel_disco_store_set_status (
+			CAMEL_DISCO_STORE (store),
+			CAMEL_DISCO_STORE_ONLINE,
+			cancellable, &error);
+
+	else if (CAMEL_IS_OFFLINE_STORE (store))
+		camel_offline_store_set_online_sync (
+			CAMEL_OFFLINE_STORE (store),
+			TRUE, cancellable, &error);
+
+	if (error != NULL) {
+		g_simple_async_result_set_from_error (simple, error);
+		g_error_free (error);
+	}
+
+	camel_operation_pop_message (cancellable);
+}
+
+void
+e_mail_store_go_online (CamelStore *store,
+                        gint io_priority,
+                        GCancellable *cancellable,
+                        GAsyncReadyCallback callback,
+                        gpointer user_data)
+{
+	GSimpleAsyncResult *simple;
+
+	g_return_if_fail (CAMEL_IS_STORE (store));
+
+	simple = g_simple_async_result_new (
+		G_OBJECT (store), callback,
+		user_data, e_mail_store_go_online);
+
+	g_simple_async_result_run_in_thread (
+		simple, (GSimpleAsyncThreadFunc)
+		mail_store_go_online_thread,
+		io_priority, cancellable);
+
+	g_object_unref (simple);
+}
+
+gboolean
+e_mail_store_go_online_finish (CamelStore *store,
+                               GAsyncResult *result,
+                               GError **error)
+{
+	GSimpleAsyncResult *simple;
+
+	g_return_val_if_fail (
+		g_simple_async_result_is_valid (
+		result, G_OBJECT (store), e_mail_store_go_online), FALSE);
+
+	simple = G_SIMPLE_ASYNC_RESULT (result);
+
+	/* Assume success unless a GError is set. */
+	return !g_simple_async_result_propagate_error (simple, error);
+}
diff --git a/mail/e-mail-store-utils.h b/mail/e-mail-store-utils.h
new file mode 100644
index 0000000..daf7a98
--- /dev/null
+++ b/mail/e-mail-store-utils.h
@@ -0,0 +1,47 @@
+/*
+ * e-mail-store-utils.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_STORE_UTILS_H
+#define E_MAIL_STORE_UTILS_H
+
+/* CamelStore wrappers with Evolution-specific policies. */
+
+#include <camel/camel.h>
+
+G_BEGIN_DECLS
+
+void		e_mail_store_go_offline		(CamelStore *store,
+						 gint io_priority,
+						 GCancellable *cancellable,
+						 GAsyncReadyCallback callback,
+						 gpointer user_data);
+gboolean	e_mail_store_go_offline_finish	(CamelStore *store,
+						 GAsyncResult *result,
+						 GError **error);
+void		e_mail_store_go_online		(CamelStore *store,
+						 gint io_priority,
+						 GCancellable *cancellable,
+						 GAsyncReadyCallback callback,
+						 gpointer user_data);
+gboolean	e_mail_store_go_online_finish	(CamelStore *store,
+						 GAsyncResult *result,
+						 GError **error);
+
+G_END_DECLS
+
+#endif /* E_MAIL_STORE_UTILS_H */
diff --git a/mail/e-mail.h b/mail/e-mail.h
index 4e40ac3..aa19737 100644
--- a/mail/e-mail.h
+++ b/mail/e-mail.h
@@ -44,6 +44,7 @@
 #include <mail/e-mail-session-utils.h>
 #include <mail/e-mail-sidebar.h>
 #include <mail/e-mail-store.h>
+#include <mail/e-mail-store-utils.h>
 #include <mail/e-mail-tag-editor.h>
 #include <mail/e-mail-view.h>
 
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index ac147c4..f1f69a7 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -749,8 +749,6 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
 		g_object_unref (folder);
 	}
 
-	/* TODO Maybe this should be handled by mail_get_folderinfo
-	 *      (except em-folder-tree doesn't use it, duh) */
 	flags = fi->flags;
 	name = fi->name;
 	if (si->store == e_mail_local_get_store ()) {
diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c
index 8b19da4..8b3f3d2 100644
--- a/mail/mail-folder-cache.c
+++ b/mail/mail-folder-cache.c
@@ -52,6 +52,7 @@
 #include "em-utils.h"
 #include "e-mail-local.h"
 #include "e-mail-session.h"
+#include "e-mail-store-utils.h"
 
 #define w(x)
 #define d(x)
@@ -856,9 +857,11 @@ ping_cb (MailFolderCache *self)
 }
 
 static void
-store_online_cb (CamelStore *store, gpointer data)
+store_go_online_cb (CamelStore *store,
+                    GAsyncResult *result,
+                    struct _update_data *ud)
 {
-	struct _update_data *ud = data;
+	/* FIXME Not checking result for error. */
 
 	g_mutex_lock (ud->cache->priv->stores_mutex);
 
@@ -1101,10 +1104,8 @@ mail_folder_cache_note_store (MailFolderCache *self,
 		si = g_malloc0 (sizeof (*si));
 		si->folders = g_hash_table_new (g_str_hash, g_str_equal);
 		si->folders_uri = g_hash_table_new (
-			CAMEL_STORE_CLASS (
-			CAMEL_OBJECT_GET_CLASS (store))->hash_folder_name,
-			CAMEL_STORE_CLASS (
-			CAMEL_OBJECT_GET_CLASS (store))->compare_folder_name);
+			CAMEL_STORE_GET_CLASS (store)->hash_folder_name,
+			CAMEL_STORE_GET_CLASS (store)->compare_folder_name);
 		si->store = g_object_ref (store);
 		g_hash_table_insert (self->priv->stores, store, si);
 		g_queue_init (&si->folderinfo_updates);
@@ -1124,8 +1125,9 @@ mail_folder_cache_note_store (MailFolderCache *self,
 		if (camel_session_get_online (session) &&
 			 camel_disco_store_status (CAMEL_DISCO_STORE (store)) ==
 			CAMEL_DISCO_STORE_OFFLINE) {
-			/* Note: we use the 'id' here, even though its not the right id, its still ok */
-			ud->id = mail_store_set_offline (store, FALSE, store_online_cb, ud);
+			e_mail_store_go_online (
+				store, G_PRIORITY_DEFAULT, cancellable,
+				(GAsyncReadyCallback) store_go_online_cb, ud);
 		} else {
 			goto normal_setup;
 		}
@@ -1133,8 +1135,9 @@ mail_folder_cache_note_store (MailFolderCache *self,
 		if (camel_session_get_online (session) &&
 			!camel_offline_store_get_online (
 			CAMEL_OFFLINE_STORE (store))) {
-			/* Note: we use the 'id' here, even though its not the right id, its still ok */
-			ud->id = mail_store_set_offline (store, FALSE, store_online_cb, ud);
+			e_mail_store_go_online (
+				store, G_PRIORITY_DEFAULT, cancellable,
+				(GAsyncReadyCallback) store_go_online_cb, ud);
 		} else {
 			goto normal_setup;
 		}
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index ce219ed..d104736 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -2351,91 +2351,7 @@ mail_save_messages (CamelFolder *folder, GPtrArray *uids, const gchar *path,
 	return id;
 }
 
-/* ** PREPARE OFFLINE ***************************************************** */
-
-struct _prep_offline_msg {
-	MailMsg base;
-
-	EMailSession *session;
-	GCancellable *cancel;
-	gchar *uri;
-	void (*done)(const gchar *uri, gpointer data);
-	gpointer data;
-};
-
-static void
-prep_offline_exec (struct _prep_offline_msg *m,
-                   GCancellable *cancellable,
-                   GError **error)
-{
-	CamelFolder *folder;
-
-	folder = e_mail_session_uri_to_folder_sync (
-		m->session, m->uri, 0,
-		cancellable, error);
-	if (folder) {
-		if (CAMEL_IS_DISCO_FOLDER (folder)) {
-			camel_disco_folder_prepare_for_offline (
-				CAMEL_DISCO_FOLDER (folder),
-				"(match-all)", m->cancel, error);
-		} else if (CAMEL_IS_OFFLINE_FOLDER (folder)) {
-			camel_offline_folder_downsync_sync (
-				CAMEL_OFFLINE_FOLDER (folder),
-				"(match-all)", m->cancel, error);
-		}
-		/* prepare_for_offline should do this? */
-		/* of course it should all be atomic, but ... */
-		/* FIXME Not passing a GCancellable here. */
-		camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
-		g_object_unref (folder);
-	}
-}
-
-static void
-prep_offline_done (struct _prep_offline_msg *m)
-{
-	if (m->done)
-		m->done (m->uri, m->data);
-}
-
-static void
-prep_offline_free (struct _prep_offline_msg *m)
-{
-	g_object_unref (m->session);
-	if (m->cancel)
-		g_object_unref (m->cancel);
-	g_free (m->uri);
-}
-
-static MailMsgInfo prep_offline_info = {
-	sizeof (struct _prep_offline_msg),
-	(MailMsgDescFunc) NULL, /* DO NOT CHANGE THIS, IT MUST BE NULL FOR CANCELLATION TO WORK */
-	(MailMsgExecFunc) prep_offline_exec,
-	(MailMsgDoneFunc) prep_offline_done,
-	(MailMsgFreeFunc) prep_offline_free
-};
-
-void
-mail_prep_offline (EMailSession *session,
-                   const gchar *uri,
-                   CamelOperation *cancel,
-                   void (*done)(const gchar *, gpointer data),
-                   gpointer data)
-{
-	struct _prep_offline_msg *m;
-
-	m = mail_msg_new (&prep_offline_info);
-	m->session = g_object_ref (session);
-	if (G_IS_CANCELLABLE (cancel))
-		m->cancel = g_object_ref (cancel);
-	m->uri = g_strdup (uri);
-	m->data = data;
-	m->done = done;
-
-	mail_msg_slow_ordered_push (m);
-}
-
-/* ** GO OFFLINE ***************************************************** */
+/* ** Prepare OFFLINE ***************************************************** */
 
 struct _set_offline_msg {
 	MailMsg base;
@@ -2447,99 +2363,6 @@ struct _set_offline_msg {
 };
 
 static gchar *
-set_offline_desc (struct _set_offline_msg *m)
-{
-	gchar *service_name = camel_service_get_name (CAMEL_SERVICE (m->store), TRUE);
-	gchar *msg;
-
-	msg = g_strdup_printf (m->offline ? _("Disconnecting from '%s'") : _("Reconnecting to '%s'"),
-			       service_name);
-	g_free (service_name);
-	return msg;
-}
-
-static void
-set_offline_exec (struct _set_offline_msg *m,
-                  GCancellable *cancellable,
-                  GError **error)
-{
-	if (CAMEL_IS_DISCO_STORE (m->store)) {
-		if (!m->offline) {
-			camel_disco_store_set_status (
-				CAMEL_DISCO_STORE (m->store),
-				CAMEL_DISCO_STORE_ONLINE,
-				cancellable, error);
-			return;
-		} else if (camel_disco_store_can_work_offline (CAMEL_DISCO_STORE (m->store))) {
-			camel_disco_store_set_status (
-				CAMEL_DISCO_STORE (m->store),
-				CAMEL_DISCO_STORE_OFFLINE,
-				cancellable, error);
-			return;
-		}
-	} else if (CAMEL_IS_OFFLINE_STORE (m->store)) {
-		camel_offline_store_set_online_sync (
-			CAMEL_OFFLINE_STORE (m->store),
-			!m->offline, cancellable, error);
-		return;
-	}
-
-	if (m->offline)
-		camel_service_disconnect_sync (
-			CAMEL_SERVICE (m->store), TRUE, error);
-}
-
-static void
-set_offline_done (struct _set_offline_msg *m)
-{
-	if (m->done)
-		m->done (m->store, m->data);
-}
-
-static void
-set_offline_free (struct _set_offline_msg *m)
-{
-	g_object_unref (m->store);
-}
-
-static MailMsgInfo set_offline_info = {
-	sizeof (struct _set_offline_msg),
-	(MailMsgDescFunc) set_offline_desc,
-	(MailMsgExecFunc) set_offline_exec,
-	(MailMsgDoneFunc) set_offline_done,
-	(MailMsgFreeFunc) set_offline_free
-};
-
-gint
-mail_store_set_offline (CamelStore *store, gboolean offline,
-			void (*done)(CamelStore *, gpointer data),
-			gpointer data)
-{
-	struct _set_offline_msg *m;
-	gint id;
-
-	/* Cancel any pending connect first so the set_offline_op
-	 * thread won't get queued behind a hung connect op.
-	 */
-	if (offline)
-		camel_service_cancel_connect (CAMEL_SERVICE (store));
-
-	m = mail_msg_new (&set_offline_info);
-	m->store = store;
-	g_object_ref (store);
-	m->offline = offline;
-	m->data = data;
-	m->done = done;
-
-	id = m->base.seq;
-	mail_msg_unordered_push (m);
-
-	return id;
-}
-
-/* ** Prepare OFFLINE ***************************************************** */
-
-static gchar *
 prepare_offline_desc (struct _set_offline_msg *m)
 {
 	gchar *service_name = camel_service_get_name (CAMEL_SERVICE (m->store), TRUE);
diff --git a/mail/mail-ops.h b/mail/mail-ops.h
index 751ac9d..ea9e9f7 100644
--- a/mail/mail-ops.h
+++ b/mail/mail-ops.h
@@ -162,14 +162,6 @@ void		mail_filter_folder		(EMailSession *session,
 						 gboolean notify);
 
 /* Work Offline */
-void		mail_prep_offline		(EMailSession *session,
-						 const gchar *uri,
-						 CamelOperation *cancel,
-						 void (*done)(const gchar *, gpointer data),
-						 gpointer data);
-gint mail_store_set_offline (CamelStore *store, gboolean offline,
-			   void (*done)(CamelStore *, gpointer data),
-			   gpointer data);
 gint mail_store_prepare_offline (CamelStore *store);
 
 /* filter driver execute shell command async callback */



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