Re: [evolution-patches] 63881 (dragging messages from vfolders)



On Mon, 2004-08-30 at 14:05 +0800, Not Zed wrote:
> 
> Hmm, if we're going to go to this much effort, i'd rather the
> unmatched folder was moved onto the vfolder store itself, and also be
> optional on that store.  This seems to expose too many internals that
> the client code shouldn't need to know about in the first place.

OK, here's the patch, finally. The idea is to move folder_unmatched and
unmatched_uids to CamelVeeStore, and have them created at init time (not
optional currently but that wouldn't be difficult). I think this means
that a lock is not needed, as init is called before the constructed
object is returned so it won't reach other threads yet? Then, a
CamelVeeFolder created on a CamelVeeStore will pick up the
folder_unmatched and unmatched_uids, otherwise they remain NULL; this
can be tested by anything that accesses folder_unmatched.

This means:
	* vtrash and junk folders now avoid the folder_unmatched code
	* UNMATCHED could be made optional
	* multiple UNMATCHED folders for multiple sets (stores) of vee-folders
would be possible

Unfortunately there's quite a bit of re-indenting and changes to
identifier names, so the diff is a little big. Also I've shuffled some
code to reduce the number of times (vf->folder_unmatched != NULL) is
tested. I'm fairly certain this will not break anything.

Changes in full (all in camel/):

	* camel-vee-store.h (struct _CamelVeeStore): add folder_unmatched and
unmatched_uids members (previously camel-vee-folder.c global variables)

	* camel-vee-store.c (camel_vee_store_init): set up unmatched_uids and
folder_unmatched members
	(camel_vee_store_finalise): and free them

	* camel-vee-folder.h (struct _CamelVeeFolder): add folder_unmatched and
unmatched_uids members mirroring those on CamelVeeStore

	* camel-vee-folder.c: get rid of global variables folder_unmatched,
unmatched_uids, unmatched_lock, related macros
	(various): adjust folder_unmatched and unmatched_uids to being on
CamelVeeStore rather than global, mirrored on CamelVeeFolder and NULL
there if parent store is not a CamelVeeStore; add tests to guard against
folder_unmatched and unmatched_uids being NULL

The patch is against the 1.5.94.1 release.

Ed
--- camel/camel-vee-folder.c	2004/09/09 17:46:36	1.1
+++ camel/camel-vee-folder.c	2004/09/10 14:29:48
@@ -85,16 +85,6 @@ static void folder_changed_remove_uid(Ca
 
 static CamelFolderClass *camel_vee_folder_parent;
 
-/* a vfolder for unmatched messages */
-/* use folder_unmatched->summary_lock for access to unmatched_uids or appropriate internals, for consistency */
-static CamelVeeFolder *folder_unmatched;
-static GHashTable *unmatched_uids; /* a refcount of uid's that are matched by any rules */
-static pthread_mutex_t unmatched_lock = PTHREAD_MUTEX_INITIALIZER;
-/* only used to initialise folder_unmatched */
-#define UNMATCHED_LOCK() pthread_mutex_lock(&unmatched_lock)
-#define UNMATCHED_UNLOCK() pthread_mutex_unlock(&unmatched_lock)
-
-
 CamelType
 camel_vee_folder_get_type (void)
 {
@@ -176,21 +166,28 @@ camel_vee_folder_finalise (CamelObject *
 
 	/* FIXME: check leaks */
 	node = p->folders;
-	while (node) {
-		CamelFolder *f = node->data;
+	if (vf == vf->folder_unmatched)
+		while (node) {
+			CamelFolder *f = node->data;
+	
+			camel_object_unref((CamelObject *)f);
 
-		if (vf != folder_unmatched) {
+			node = g_list_next(node);
+		}
+	else
+		while (node) {
+			CamelFolder *f = node->data;
+	
 			camel_object_unhook_event((CamelObject *)f, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf);
 			camel_object_unhook_event((CamelObject *)f, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf);
 			camel_object_unhook_event((CamelObject *)f, "renamed", (CamelObjectEventHookFunc) subfolder_renamed, vf);
 			/* this updates the vfolder */
 			if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0)
 				vee_folder_remove_folder(vf, f, FALSE);
-		}
-		camel_object_unref((CamelObject *)f);
+			camel_object_unref((CamelObject *)f);
 
-		node = g_list_next(node);
-	}
+			node = g_list_next(node);
+		}
 
 	g_free(vf->expression);
 	g_free(vf->vname);
@@ -226,24 +223,16 @@ vee_folder_construct (CamelVeeFolder *vf
 	/* should CamelVeeMessageInfo be subclassable ..? */
 	folder->summary = camel_folder_summary_new();
 	folder->summary->message_info_size = sizeof(CamelVeeMessageInfo);
+
+	if (CAMEL_IS_VEE_STORE (parent_store)) {
+		vf->folder_unmatched = ((CamelVeeStore *) parent_store)->folder_unmatched;
+		vf->unmatched_uids = ((CamelVeeStore *) parent_store)->unmatched_uids;
+	}
 }
 
 void
 camel_vee_folder_construct(CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags)
 {
-	UNMATCHED_LOCK();
-	
-	/* setup unmatched folder if we haven't yet */
-	if (folder_unmatched == NULL) {
-		unmatched_uids = g_hash_table_new (g_str_hash, g_str_equal);
-		folder_unmatched = (CamelVeeFolder *)camel_object_new (camel_vee_folder_get_type ());
-		d(printf("created foldeer unmatched %p\n", folder_unmatched));
-		
-		vee_folder_construct (folder_unmatched, parent_store, CAMEL_UNMATCHED_NAME, CAMEL_STORE_FOLDER_PRIVATE);
-	}
-	
-	UNMATCHED_UNLOCK();
-	
 	vee_folder_construct (vf, parent_store, name, flags);
 }
 
@@ -262,21 +251,9 @@ camel_vee_folder_new(CamelStore *parent_
 {
 	CamelVeeFolder *vf;
 	char *tmp;
-
-	UNMATCHED_LOCK();
-
-	/* setup unmatched folder if we haven't yet */
-	if (folder_unmatched == NULL) {
-		unmatched_uids = g_hash_table_new(g_str_hash, g_str_equal);
-		folder_unmatched = vf = (CamelVeeFolder *)camel_object_new(camel_vee_folder_get_type());
-		d(printf("created foldeer unmatched %p\n", folder_unmatched));
-		vee_folder_construct (vf, parent_store, CAMEL_UNMATCHED_NAME, CAMEL_STORE_FOLDER_PRIVATE);
-	}
-
-	UNMATCHED_UNLOCK();
-
-	if (strcmp(name, CAMEL_UNMATCHED_NAME) == 0) {
-		vf = folder_unmatched;
+	
+	if (CAMEL_IS_VEE_STORE(parent_store) && strcmp(name, CAMEL_UNMATCHED_NAME) == 0) {
+		vf = ((CamelVeeStore *)parent_store)->folder_unmatched;
 		camel_object_ref(vf);
 	} else {
 		vf = (CamelVeeFolder *)camel_object_new(camel_vee_folder_get_type());
@@ -342,7 +319,7 @@ camel_vee_folder_set_expression(CamelVee
 void
 camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
 {
-	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf), *up = _PRIVATE(folder_unmatched);
+	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
 	int i;
 	
 	if (vf == (CamelVeeFolder *)sub) {
@@ -365,17 +342,18 @@ camel_vee_folder_add_folder(CamelVeeFold
 
 		CAMEL_FOLDER_UNLOCK(vf, change_lock);
 	}
-	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub)) {
+	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && vf->folder_unmatched != NULL) {
+		struct _CamelVeeFolderPrivate *up = _PRIVATE(vf->folder_unmatched);
 		camel_object_ref((CamelObject *)sub);
 		up->folders = g_list_append(up->folders, sub);
 
-		CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
+		CAMEL_FOLDER_LOCK(vf->folder_unmatched, change_lock);
 
 		/* update the freeze state of 'sub' to match Unmatched's freeze state */
-		for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
+		for (i = 0; i < ((CamelFolder *)vf->folder_unmatched)->priv->frozen; i++)
 			camel_folder_freeze(sub);
 
-		CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
+		CAMEL_FOLDER_UNLOCK(vf->folder_unmatched, change_lock);
 	}
 
 	CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
@@ -399,7 +377,7 @@ camel_vee_folder_add_folder(CamelVeeFold
 void
 camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
 {
-	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf), *up = _PRIVATE(folder_unmatched);
+	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
 	int killun = FALSE;
 	int i;
 	
@@ -428,36 +406,40 @@ camel_vee_folder_remove_folder(CamelVeeF
 	
 	CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
 
-	CAMEL_VEE_FOLDER_LOCK(folder_unmatched, subfolder_lock);
-	/* if folder deleted, then blow it away from unmatched always, and remove all refs to it */
-	if (sub->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
-		while (g_list_find(up->folders, sub)) {
-			killun = TRUE;
-			up->folders = g_list_remove(up->folders, sub);
-			camel_object_unref((CamelObject *)sub);
-			
-			/* undo the freeze state that Unmatched has imposed on this source folder */
-			CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
-			for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
-				camel_folder_thaw(sub);
-			CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
-		}
-	} else if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
-		if (g_list_find(up->folders, sub) != NULL) {
-			up->folders = g_list_remove(up->folders, sub);
-			camel_object_unref((CamelObject *)sub);
-			
-			/* undo the freeze state that Unmatched has imposed on this source folder */
-			CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
-			for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
-				camel_folder_thaw(sub);
-			CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
-		}
-		if (g_list_find(up->folders, sub) == NULL) {
-			killun = TRUE;
+	if (vf->folder_unmatched != NULL) {
+		struct _CamelVeeFolderPrivate *up = _PRIVATE(vf->folder_unmatched);
+
+		CAMEL_VEE_FOLDER_LOCK(vf->folder_unmatched, subfolder_lock);
+		/* if folder deleted, then blow it away from unmatched always, and remove all refs to it */
+		if (sub->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
+			while (g_list_find(up->folders, sub)) {
+				killun = TRUE;
+				up->folders = g_list_remove(up->folders, sub);
+				camel_object_unref((CamelObject *)sub);
+				
+				/* undo the freeze state that Unmatched has imposed on this source folder */
+				CAMEL_FOLDER_LOCK(vf->folder_unmatched, change_lock);
+				for (i = 0; i < ((CamelFolder *)vf->folder_unmatched)->priv->frozen; i++)
+					camel_folder_thaw(sub);
+				CAMEL_FOLDER_UNLOCK(vf->folder_unmatched, change_lock);
+			}
+		} else if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
+			if (g_list_find(up->folders, sub) != NULL) {
+				up->folders = g_list_remove(up->folders, sub);
+				camel_object_unref((CamelObject *)sub);
+				
+				/* undo the freeze state that Unmatched has imposed on this source folder */
+				CAMEL_FOLDER_LOCK(vf->folder_unmatched, change_lock);
+				for (i = 0; i < ((CamelFolder *)vf->folder_unmatched)->priv->frozen; i++)
+					camel_folder_thaw(sub);
+				CAMEL_FOLDER_UNLOCK(vf->folder_unmatched, change_lock);
+			}
+			if (g_list_find(up->folders, sub) == NULL) {
+				killun = TRUE;
+			}
 		}
+		CAMEL_VEE_FOLDER_UNLOCK(vf->folder_unmatched, subfolder_lock);
 	}
-	CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
 
 	vee_folder_remove_folder(vf, sub, killun);
 
@@ -691,7 +673,7 @@ vee_search_by_expression(CamelFolder *fo
 	
 	CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
 	
-	if (vf != folder_unmatched)
+	if (vf != vf->folder_unmatched)
 		expr = g_strdup_printf ("(and %s %s)", vf->expression, expression);
 	else
 		expr = g_strdup (expression);
@@ -918,7 +900,7 @@ vee_folder_add_uid(CamelVeeFolder *vf, C
 static void
 vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
 {
-	int i, count, n, still, start, last;
+	int i, count, n, still = FALSE, start, last;
 	char *oldkey;
 	CamelFolder *folder = (CamelFolder *)vf;
 	char hash[8];
@@ -926,48 +908,49 @@ vee_folder_remove_folder(CamelVeeFolder 
 	CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
 	void *oldval;
 	
-	if (vf == folder_unmatched)
+	if (vf == vf->folder_unmatched)
 		return;
 
-	/* check if this folder is still to be part of unmatched */
-	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !killun) {
-		CAMEL_VEE_FOLDER_LOCK(folder_unmatched, subfolder_lock);
-		still = g_list_find(_PRIVATE(folder_unmatched)->folders, source) != NULL;
-		CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
-		camel_vee_folder_hash_folder(source, hash);
-	} else {
-		still = FALSE;
-	}
-
 	CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
-	CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
 
-	/* See if we just blow all uid's from this folder away from unmatched, regardless */
-	if (killun) {
-		start = -1;
-		last = -1;
-		count = camel_folder_summary_count(((CamelFolder *)folder_unmatched)->summary);
-		for (i=0;i<count;i++) {
-			CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
-			
-			if (mi) {
-				if (mi->folder == source) {
-					camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
-					if (last == -1) {
-						last = start = i;
-					} else if (last+1 == i) {
-						last = i;
-					} else {
-						camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
-						i -= (last-start)+1;
-						start = last = i;
+	if (vf->folder_unmatched != NULL) {
+		/* check if this folder is still to be part of unmatched */
+		if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !killun) {
+			CAMEL_VEE_FOLDER_LOCK(vf->folder_unmatched, subfolder_lock);
+			still = g_list_find(_PRIVATE(vf->folder_unmatched)->folders, source) != NULL;
+			CAMEL_VEE_FOLDER_UNLOCK(vf->folder_unmatched, subfolder_lock);
+			camel_vee_folder_hash_folder(source, hash);
+		}
+
+		CAMEL_VEE_FOLDER_LOCK(vf->folder_unmatched, summary_lock);
+
+		/* See if we just blow all uid's from this folder away from unmatched, regardless */
+		if (killun) {
+			start = -1;
+			last = -1;
+			count = camel_folder_summary_count(((CamelFolder *)vf->folder_unmatched)->summary);
+			for (i=0;i<count;i++) {
+				CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)vf->folder_unmatched)->summary, i);
+				
+				if (mi) {
+					if (mi->folder == source) {
+						camel_folder_change_info_remove_uid(vf->folder_unmatched->changes, camel_message_info_uid(mi));
+						if (last == -1) {
+							last = start = i;
+						} else if (last+1 == i) {
+							last = i;
+						} else {
+							camel_folder_summary_remove_range(((CamelFolder *)vf->folder_unmatched)->summary, start, last);
+							i -= (last-start)+1;
+							start = last = i;
+						}
 					}
+					camel_folder_summary_info_free(((CamelFolder *)vf->folder_unmatched)->summary, (CamelMessageInfo *)mi);
 				}
-				camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
 			}
+			if (last != -1)
+				camel_folder_summary_remove_range(((CamelFolder *)vf->folder_unmatched)->summary, start, last);
 		}
-		if (last != -1)
-			camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
 	}
 
 	start = -1;
@@ -990,22 +973,22 @@ vee_folder_remove_folder(CamelVeeFolder 
 					i -= (last-start)+1;
 					start = last = i;
 				}
-				if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
+				if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && vf->folder_unmatched != NULL) {
 					if (still) {
-						if (g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
+						if (g_hash_table_lookup_extended(vf->unmatched_uids, uid, (void **)&oldkey, &oldval)) {
 							n = GPOINTER_TO_INT (oldval);
 							if (n == 1) {
-								g_hash_table_remove(unmatched_uids, oldkey);
-								if (vee_folder_add_uid(folder_unmatched, source, oldkey+8, hash))
-									camel_folder_change_info_add_uid(folder_unmatched->changes, oldkey);
+								g_hash_table_remove(vf->unmatched_uids, oldkey);
+								if (vee_folder_add_uid(vf->folder_unmatched, source, oldkey+8, hash))
+									camel_folder_change_info_add_uid(vf->folder_unmatched->changes, oldkey);
 								g_free(oldkey);
 							} else {
-								g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
+								g_hash_table_insert(vf->unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
 							}
 						}
 					} else {
-						if (g_hash_table_lookup_extended(unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
-							g_hash_table_remove(unmatched_uids, oldkey);
+						if (g_hash_table_lookup_extended(vf->unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
+							g_hash_table_remove(vf->unmatched_uids, oldkey);
 							g_free(oldkey);
 						}
 					}
@@ -1018,9 +1001,18 @@ vee_folder_remove_folder(CamelVeeFolder 
 	if (last != -1)
 		camel_folder_summary_remove_range(folder->summary, start, last);
 
-	if (camel_folder_change_info_changed(folder_unmatched->changes)) {
-		unmatched_changes = folder_unmatched->changes;
-		folder_unmatched->changes = camel_folder_change_info_new();
+	if (vf->folder_unmatched) {
+		if (camel_folder_change_info_changed(vf->folder_unmatched->changes)) {
+			unmatched_changes = vf->folder_unmatched->changes;
+			vf->folder_unmatched->changes = camel_folder_change_info_new();
+		}
+
+		CAMEL_VEE_FOLDER_UNLOCK(vf->folder_unmatched, summary_lock);
+
+		if (unmatched_changes) {
+			camel_object_trigger_event((CamelObject *)vf->folder_unmatched, "folder_changed", unmatched_changes);
+			camel_folder_change_info_free(unmatched_changes);
+		}
 	}
 
 	if (camel_folder_change_info_changed(vf->changes)) {
@@ -1028,14 +1020,8 @@ vee_folder_remove_folder(CamelVeeFolder 
 		vf->changes = camel_folder_change_info_new();
 	}
 
-	CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
 	CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
 
-	if (unmatched_changes) {
-		camel_object_trigger_event((CamelObject *)folder_unmatched, "folder_changed", unmatched_changes);
-		camel_folder_change_info_free(unmatched_changes);
-	}
-
 	if (vf_changes) {
 		camel_object_trigger_event((CamelObject *)vf, "folder_changed", vf_changes);
 		camel_folder_change_info_free(vf_changes);
@@ -1054,19 +1040,21 @@ unmatched_check_uid(char *uidin, void *v
 	char *uid;
 	int n;
 
+	g_return_if_fail(u->vf->folder_unmatched != NULL);
+
 	uid = alloca(strlen(uidin)+9);
 	memcpy(uid, u->hash, 8);
 	strcpy(uid+8, uidin);
-	n = GPOINTER_TO_INT(g_hash_table_lookup(unmatched_uids, uid));
+	n = GPOINTER_TO_INT(g_hash_table_lookup(u->vf->unmatched_uids, uid));
 	if (n == 0) {
-		if (vee_folder_add_uid(folder_unmatched, u->source, uidin, u->hash))
-			camel_folder_change_info_add_uid(folder_unmatched->changes, uid);
+		if (vee_folder_add_uid(u->vf->folder_unmatched, u->source, uidin, u->hash))
+			camel_folder_change_info_add_uid(u->vf->folder_unmatched->changes, uid);
 	} else {
-		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)folder_unmatched)->summary, uid);
+		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)u->vf->folder_unmatched)->summary, uid);
 		if (mi) {
-			camel_folder_summary_remove(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
-			camel_folder_change_info_remove_uid(folder_unmatched->changes, uid);
-			camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
+			camel_folder_summary_remove(((CamelFolder *)u->vf->folder_unmatched)->summary, (CamelMessageInfo *)mi);
+			camel_folder_change_info_remove_uid(u->vf->folder_unmatched->changes, uid);
+			camel_folder_summary_info_free(((CamelFolder *)u->vf->folder_unmatched)->summary, (CamelMessageInfo *)mi);
 		}
 	}
 }
@@ -1082,12 +1070,12 @@ folder_added_uid(char *uidin, void *valu
 	if ( (mi = vee_folder_add_uid(u->vf, u->source, uidin, u->hash)) ) {
 		camel_folder_change_info_add_uid(u->vf->changes, camel_message_info_uid(mi));
 
-		if (!CAMEL_IS_VEE_FOLDER(u->source)) {
-			if (g_hash_table_lookup_extended(unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
+		if (!CAMEL_IS_VEE_FOLDER(u->source) && u->vf->unmatched_uids != NULL) {
+			if (g_hash_table_lookup_extended(u->vf->unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
 				n = GPOINTER_TO_INT (oldval);
-				g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
+				g_hash_table_insert(u->vf->unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
 			} else {
-				g_hash_table_insert(unmatched_uids, g_strdup(camel_message_info_uid(mi)), GINT_TO_POINTER(1));
+				g_hash_table_insert(u->vf->unmatched_uids, g_strdup(camel_message_info_uid(mi)), GINT_TO_POINTER(1));
 			}
 		}
 	}
@@ -1105,7 +1093,7 @@ vee_folder_build_folder(CamelVeeFolder *
 	struct _update_data u;
 	CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
 
-	if (vf == folder_unmatched)
+	if (vf == vf->folder_unmatched)
 		return 0;
 
 	/* if we have no expression, or its been cleared, then act as if no matches */
@@ -1135,8 +1123,6 @@ vee_folder_build_folder(CamelVeeFolder *
 		if (g_hash_table_lookup(matchhash, all->pdata[i]) == NULL)
 			g_hash_table_insert(allhash, all->pdata[i], GINT_TO_POINTER (1));
 
-	CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
-
 	/* scan, looking for "old" uid's to be removed */
 	start = -1;
 	last = -1;
@@ -1161,13 +1147,14 @@ vee_folder_build_folder(CamelVeeFolder *
 					}
 					camel_folder_change_info_remove_uid(vf->changes, camel_message_info_uid(mi));
 					if (!CAMEL_IS_VEE_FOLDER(source)
-					    && g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
+					    && vf->unmatched_uids != NULL
+					    && g_hash_table_lookup_extended(vf->unmatched_uids, uid, (void **)&oldkey, &oldval)) {
 						n = GPOINTER_TO_INT (oldval);
 						if (n == 1) {
-							g_hash_table_remove(unmatched_uids, oldkey);
+							g_hash_table_remove(vf->unmatched_uids, oldkey);
 							g_free(oldkey);
 						} else {
-							g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
+							g_hash_table_insert(vf->unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
 						}
 					}
 				} else {
@@ -1183,36 +1170,47 @@ vee_folder_build_folder(CamelVeeFolder *
 	/* now matchhash contains any new uid's, add them, etc */
 	g_hash_table_foreach(matchhash, (GHFunc)folder_added_uid, &u);
 
-	/* scan unmatched, remove any that have vanished, etc */
-	count = camel_folder_summary_count(((CamelFolder *)folder_unmatched)->summary);
-	for (i=0;i<count;i++) {
-		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
+	if (vf->folder_unmatched != NULL) {
+		CAMEL_VEE_FOLDER_LOCK(vf->folder_unmatched, summary_lock);
 
-		if (mi) {
-			if (mi->folder == source) {
-				char *uid = (char *)camel_message_info_uid(mi);
+		/* scan unmatched, remove any that have vanished, etc */
+		count = camel_folder_summary_count(((CamelFolder *)vf->folder_unmatched)->summary);
+		for (i=0;i<count;i++) {
+			CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)vf->folder_unmatched)->summary, i);
 
-				if (g_hash_table_lookup(allhash, uid+8) == NULL) {
-					/* no longer exists at all, just remove it entirely */
-					camel_folder_summary_remove_index(((CamelFolder *)folder_unmatched)->summary, i);
-					camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
-					i--;
-				} else {
-					g_hash_table_remove(allhash, uid+8);
+			if (mi) {
+				if (mi->folder == source) {
+					char *uid = (char *)camel_message_info_uid(mi);
+
+					if (g_hash_table_lookup(allhash, uid+8) == NULL) {
+						/* no longer exists at all, just remove it entirely */
+						camel_folder_summary_remove_index(((CamelFolder *)vf->folder_unmatched)->summary, i);
+						camel_folder_change_info_remove_uid(vf->folder_unmatched->changes, camel_message_info_uid(mi));
+						i--;
+					} else {
+						g_hash_table_remove(allhash, uid+8);
+					}
 				}
+				camel_folder_summary_info_free(((CamelFolder *)vf->folder_unmatched)->summary, (CamelMessageInfo *)mi);
 			}
-			camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
 		}
-	}
 
-	/* now allhash contains all potentially new uid's for the unmatched folder, process */
-	if (!CAMEL_IS_VEE_FOLDER(source))
-		g_hash_table_foreach(allhash, (GHFunc)unmatched_check_uid, &u);
+		/* now allhash contains all potentially new uid's for the unmatched folder, process */
+		if (!CAMEL_IS_VEE_FOLDER(source))
+			g_hash_table_foreach(allhash, (GHFunc)unmatched_check_uid, &u);
+
+		/* copy any changes so we can raise them outside the lock */
+		if (camel_folder_change_info_changed(vf->folder_unmatched->changes)) {
+			unmatched_changes = vf->folder_unmatched->changes;
+			vf->folder_unmatched->changes = camel_folder_change_info_new();
+		}
+
+		CAMEL_VEE_FOLDER_UNLOCK(vf->folder_unmatched, summary_lock);
 
-	/* copy any changes so we can raise them outside the lock */
-	if (camel_folder_change_info_changed(folder_unmatched->changes)) {
-		unmatched_changes = folder_unmatched->changes;
-		folder_unmatched->changes = camel_folder_change_info_new();
+		if (unmatched_changes) {
+			camel_object_trigger_event((CamelObject *)vf->folder_unmatched, "folder_changed", unmatched_changes);
+			camel_folder_change_info_free(unmatched_changes);
+		}
 	}
 
 	if (camel_folder_change_info_changed(vf->changes)) {
@@ -1220,7 +1218,6 @@ vee_folder_build_folder(CamelVeeFolder *
 		vf->changes = camel_folder_change_info_new();
 	}
 
-	CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
 	CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
 
 	g_hash_table_destroy(matchhash);
@@ -1232,11 +1229,6 @@ vee_folder_build_folder(CamelVeeFolder *
 		camel_folder_search_free(f, match);
 	camel_folder_free_uids(f, all);
 
-	if (unmatched_changes) {
-		camel_object_trigger_event((CamelObject *)folder_unmatched, "folder_changed", unmatched_changes);
-		camel_folder_change_info_free(unmatched_changes);
-	}
-
 	if (vf_changes) {
 		camel_object_trigger_event((CamelObject *)vf, "folder_changed", vf_changes);
 		camel_folder_change_info_free(vf_changes);
@@ -1269,18 +1261,18 @@ folder_changed_add_uid(CamelFolder *sub,
 	vuid = camel_message_info_uid(vinfo);
 	camel_folder_change_info_add_uid(vf->changes,  vuid);
 
-	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub)) {
-		if (g_hash_table_lookup_extended(unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
+	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && vf->folder_unmatched != NULL) {
+		if (g_hash_table_lookup_extended(vf->unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
 			n = GPOINTER_TO_INT (oldval);
-			g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
+			g_hash_table_insert(vf->unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
 		} else {
-			g_hash_table_insert(unmatched_uids, g_strdup(vuid), GINT_TO_POINTER (1));
+			g_hash_table_insert(vf->unmatched_uids, g_strdup(vuid), GINT_TO_POINTER (1));
 		}
-		vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)folder_unmatched, vuid);
+		vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)vf->folder_unmatched, vuid);
 		if (vinfo) {
-			camel_folder_change_info_remove_uid(folder_unmatched->changes, vuid);
-			camel_folder_summary_remove(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)vinfo);
-			camel_folder_free_message_info((CamelFolder *)folder_unmatched, (CamelMessageInfo *)vinfo);
+			camel_folder_change_info_remove_uid(vf->folder_unmatched->changes, vuid);
+			camel_folder_summary_remove(((CamelFolder *)vf->folder_unmatched)->summary, (CamelMessageInfo *)vinfo);
+			camel_folder_free_message_info((CamelFolder *)vf->folder_unmatched, (CamelMessageInfo *)vinfo);
 		}
 	}
 }
@@ -1305,33 +1297,33 @@ folder_changed_remove_uid(CamelFolder *s
 		camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
 	}
 
-	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub)) {
+	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && vf->folder_unmatched != NULL) {
 		if (keep) {
-			if (g_hash_table_lookup_extended(unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
+			if (g_hash_table_lookup_extended(vf->unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
 				n = GPOINTER_TO_INT (oldval);
 				if (n == 1) {
-					g_hash_table_remove(unmatched_uids, oldkey);
-					if (vee_folder_add_uid(folder_unmatched, sub, uid, hash))
-						camel_folder_change_info_add_uid(folder_unmatched->changes, oldkey);
+					g_hash_table_remove(vf->unmatched_uids, oldkey);
+					if (vee_folder_add_uid(vf->folder_unmatched, sub, uid, hash))
+						camel_folder_change_info_add_uid(vf->folder_unmatched->changes, oldkey);
 					g_free(oldkey);
 				} else {
-					g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
+					g_hash_table_insert(vf->unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
 				}
 			} else {
-				if (vee_folder_add_uid(folder_unmatched, sub, uid, hash))
-					camel_folder_change_info_add_uid(folder_unmatched->changes, oldkey);
+				if (vee_folder_add_uid(vf->folder_unmatched, sub, uid, hash))
+					camel_folder_change_info_add_uid(vf->folder_unmatched->changes, oldkey);
 			}
 		} else {
-			if (g_hash_table_lookup_extended(unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
-				g_hash_table_remove(unmatched_uids, oldkey);
+			if (g_hash_table_lookup_extended(vf->unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
+				g_hash_table_remove(vf->unmatched_uids, oldkey);
 				g_free(oldkey);
 			}
 
-			vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)folder_unmatched, vuid);
+			vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)vf->folder_unmatched, vuid);
 			if (vinfo) {
-				camel_folder_change_info_remove_uid(folder_unmatched->changes, vuid);
-				camel_folder_summary_remove_uid(((CamelFolder *)folder_unmatched)->summary, vuid);
-				camel_folder_free_message_info((CamelFolder *)folder_unmatched, (CamelMessageInfo *)vinfo);
+				camel_folder_change_info_remove_uid(vf->folder_unmatched->changes, vuid);
+				camel_folder_summary_remove_uid(((CamelFolder *)vf->folder_unmatched)->summary, vuid);
+				camel_folder_free_message_info((CamelFolder *)vf->folder_unmatched, (CamelMessageInfo *)vinfo);
 			}
 		}
 	}
@@ -1341,7 +1333,7 @@ static void
 folder_changed_change_uid(CamelFolder *sub, const char *uid, const char hash[8], CamelVeeFolder *vf)
 {
 	char *vuid;
-	CamelVeeMessageInfo *vinfo, *uinfo;
+	CamelVeeMessageInfo *vinfo, *uinfo = NULL;
 	CamelMessageInfo *info;
 	CamelFolder *folder = (CamelFolder *)vf;
 
@@ -1350,7 +1342,8 @@ folder_changed_change_uid(CamelFolder *s
 	strcpy(vuid+8, uid);
 
 	vinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, vuid);
-	uinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)folder_unmatched)->summary, vuid);
+	if (vf->folder_unmatched != NULL)
+		uinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)vf->folder_unmatched)->summary, vuid);
 	if (vinfo || uinfo) {
 		info = camel_folder_get_message_info(sub, uid);
 		if (info) {
@@ -1370,7 +1363,7 @@ folder_changed_change_uid(CamelFolder *s
 				camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
 			}
 
-			if (uinfo) {
+			if (vf->folder_unmatched != NULL && uinfo) {
 				int changed = FALSE;
 
 				if (uinfo->info.flags != info->flags){
@@ -1381,9 +1374,9 @@ folder_changed_change_uid(CamelFolder *s
 				changed |= camel_flag_list_copy(&uinfo->info.user_flags, &info->user_flags);
 				changed |= camel_tag_list_copy(&uinfo->info.user_tags, &info->user_tags);
 				if (changed)
-					camel_folder_change_info_change_uid(folder_unmatched->changes, vuid);
+					camel_folder_change_info_change_uid(vf->folder_unmatched->changes, vuid);
 
-				camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
+				camel_folder_summary_info_free(((CamelFolder *)vf->folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
 			}
 
 			camel_folder_free_message_info(sub, info);
@@ -1392,8 +1385,8 @@ folder_changed_change_uid(CamelFolder *s
 				folder_changed_remove_uid(sub, uid, hash, FALSE, vf);
 				camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
 			}
-			if (uinfo)
-				camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
+			if (vf->folder_unmatched != NULL && uinfo)
+				camel_folder_summary_info_free(((CamelFolder *)vf->folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
 		}
 	}
 }
@@ -1478,7 +1471,8 @@ folder_changed_change(CamelSession *sess
 	}
 
 	CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
-	CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
+	if (vf->folder_unmatched != NULL)
+		CAMEL_VEE_FOLDER_LOCK(vf->folder_unmatched, summary_lock);
 
 	dd(printf("Vfolder '%s' subfolder changed '%s'\n", folder->full_name, sub->full_name));
 	dd(printf(" changed %d added %d removed %d\n", changes->uid_changed->len, changes->uid_added->len, changes->uid_removed->len));
@@ -1509,14 +1503,14 @@ folder_changed_change(CamelSession *sess
 				memcpy(vuid, hash, 8);
 				strcpy(vuid+8, uid);
 				
-				if (!CAMEL_IS_VEE_FOLDER(sub) && g_hash_table_lookup(unmatched_uids, vuid) == NULL) {
+				if (!CAMEL_IS_VEE_FOLDER(sub) && vf->folder_unmatched != NULL && g_hash_table_lookup(vf->unmatched_uids, vuid) == NULL) {
 					dd(printf("  adding uid '%s' to Unmatched [newly unmatched]\n", (char *)uid));
-					vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)folder_unmatched, vuid);
+					vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)vf->folder_unmatched, vuid);
 					if (vinfo == NULL) {
-						if (vee_folder_add_uid(folder_unmatched, sub, uid, hash))
-							camel_folder_change_info_add_uid(folder_unmatched->changes, vuid);
+						if (vee_folder_add_uid(vf->folder_unmatched, sub, uid, hash))
+							camel_folder_change_info_add_uid(vf->folder_unmatched->changes, vuid);
 					} else {
-						camel_folder_free_message_info((CamelFolder *)folder_unmatched, (CamelMessageInfo *)vinfo);
+						camel_folder_free_message_info((CamelFolder *)vf->folder_unmatched, (CamelMessageInfo *)vinfo);
 					}
 				}
 			}
@@ -1580,19 +1574,6 @@ folder_changed_change(CamelSession *sess
 			folder_changed_change_uid(sub, changed->pdata[i], hash, vf);
 	}
 
-	if (camel_folder_change_info_changed(folder_unmatched->changes)) {
-		unmatched_changes = folder_unmatched->changes;
-		folder_unmatched->changes = camel_folder_change_info_new();
-	}
-		
-	if (camel_folder_change_info_changed(vf->changes)) {
-		vf_changes = vf->changes;
-		vf->changes = camel_folder_change_info_new();
-	}
-
-	CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
-	CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
-
 	/* Cleanup stuff on our folder */
 	if (matches_added)
 		camel_folder_search_free(sub, matches_added);
@@ -1607,12 +1588,28 @@ folder_changed_change(CamelSession *sess
 		g_ptr_array_free(newchanged, TRUE);
 
 	g_free(vuid);
+	
+	if (vf->folder_unmatched != NULL) {
+		if (camel_folder_change_info_changed(vf->folder_unmatched->changes)) {
+			unmatched_changes = vf->folder_unmatched->changes;
+			vf->folder_unmatched->changes = camel_folder_change_info_new();
+		}
+		
+		CAMEL_VEE_FOLDER_UNLOCK(vf->folder_unmatched, summary_lock);
 
-	if (unmatched_changes) {
-		camel_object_trigger_event((CamelObject *)folder_unmatched, "folder_changed", unmatched_changes);
-		camel_folder_change_info_free(unmatched_changes);
+		if (unmatched_changes) {
+			camel_object_trigger_event((CamelObject *)vf->folder_unmatched, "folder_changed", unmatched_changes);
+			camel_folder_change_info_free(unmatched_changes);
+		}
 	}
-	
+
+	if (camel_folder_change_info_changed(vf->changes)) {
+		vf_changes = vf->changes;
+		vf->changes = camel_folder_change_info_new();
+	}
+
+	CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
+
 	if (vf_changes) {
 		/* If not auto-updating, keep track of changed folders for later re-sync */
 		if ((vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0) {
@@ -1698,10 +1695,10 @@ subfolder_renamed_update(CamelVeeFolder 
 				camel_folder_change_info_add_uid(vf->changes, camel_message_info_uid(vinfo));
 
 			/* check unmatched uid's table for any matches */
-			if (vf == folder_unmatched
-			    && g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
-				g_hash_table_remove(unmatched_uids, oldkey);
-				g_hash_table_insert(unmatched_uids, g_strdup(camel_message_info_uid(vinfo)), oldval);
+			if (vf == vf->folder_unmatched
+			    && g_hash_table_lookup_extended(vf->unmatched_uids, uid, (void **)&oldkey, &oldval)) {
+				g_hash_table_remove(vf->unmatched_uids, oldkey);
+				g_hash_table_insert(vf->unmatched_uids, g_strdup(camel_message_info_uid(vinfo)), oldval);
 				g_free(oldkey);
 			}
 		}
@@ -1735,7 +1732,8 @@ subfolder_renamed(CamelFolder *f, void *
 	camel_vee_folder_hash_folder(f, hash);
 
 	subfolder_renamed_update(vf, f, hash);
-	subfolder_renamed_update(folder_unmatched, f, hash);
+	if (vf->folder_unmatched != NULL)
+		subfolder_renamed_update(vf->folder_unmatched, f, hash);
 }
 
 static void
--- camel/camel-vee-folder.h	2004/09/09 17:46:38	1.1
+++ camel/camel-vee-folder.h	2004/09/10 12:41:51
@@ -56,6 +56,9 @@ struct _CamelVeeFolder {
 
 	CamelFolderChangeInfo *changes;
 	CamelFolderSearch *search;
+
+	CamelVeeFolder *folder_unmatched; /* for ease of access */
+	GHashTable *unmatched_uids;
 };
 
 struct _CamelVeeFolderClass {
--- camel/camel-vee-store.c	2004/09/09 17:46:42	1.1
+++ camel/camel-vee-store.c	2004/09/10 12:41:51
@@ -92,12 +92,18 @@ camel_vee_store_init (CamelVeeStore *obj
 
 	/* we dont want a vtrash/vjunk on this one */
 	store->flags &= ~(CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK);	
+
+	/* Set up unmatched folder */
+	obj->unmatched_uids = g_hash_table_new (g_str_hash, g_str_equal);
+	obj->folder_unmatched = (CamelVeeFolder *)camel_object_new (camel_vee_folder_get_type ());
+	camel_vee_folder_construct (obj->folder_unmatched, store, CAMEL_UNMATCHED_NAME, CAMEL_STORE_FOLDER_PRIVATE);
 }
 
 static void
 camel_vee_store_finalise (CamelObject *obj)
 {
-	;
+	g_hash_table_destroy (((CamelVeeStore *)obj)->unmatched_uids);
+	camel_object_unref (((CamelVeeStore *)obj)->folder_unmatched);
 }
 
 /**
--- camel/camel-vee-store.h	2004/09/09 17:46:43	1.1
+++ camel/camel-vee-store.h	2004/09/10 12:41:51
@@ -30,6 +30,7 @@ extern "C" {
 
 #include <glib.h>
 #include <camel/camel-store.h>
+#include <camel/camel-vee-folder.h>
 
 #define CAMEL_VEE_STORE(obj)         CAMEL_CHECK_CAST (obj, camel_vee_store_get_type (), CamelVeeStore)
 #define CAMEL_VEE_STORE_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vee_store_get_type (), CamelVeeStoreClass)
@@ -44,6 +45,9 @@ typedef struct _CamelVeeStoreClass Camel
 struct _CamelVeeStore {
 	CamelStore parent;
 
+	/* Unmatched folder, set up in camel_vee_store_init */
+	CamelVeeFolder *folder_unmatched;
+	GHashTable *unmatched_uids;
 };
 
 struct _CamelVeeStoreClass {


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