--- mail-folder-cache.h.orig	2007-03-02 13:11:50.000000000 +0000
+++ mail-folder-cache.h	2007-03-02 11:49:43.000000000 +0000
@@ -25,6 +25,9 @@
 #ifndef _MAIL_FOLDER_CACHE_H
 #define _MAIL_FOLDER_CACHE_H
 
+/* min no. seconds between newmail notifications */
+#define NOTIFY_THROTTLE 30
+
 #include <camel/camel-store.h>
 
 /* Add a store whose folders should appear in the shell
--- mail-folder-cache.c.orig	2007-03-02 13:11:42.000000000 +0000
+++ mail-folder-cache.c	2007-03-20 16:40:28.000000000 +0000
@@ -62,6 +62,7 @@
 #include "em-folder-tree-model.h"
 
 #include "em-event.h"
+#include "em-utils.h"
 
 #define w(x)
 #define d(x)
@@ -104,6 +105,9 @@ struct _folder_update {
 
 	int unread;
 	CamelStore *store;
+	CamelFolder *folder;
+	GPtrArray *uid_added;
+	int filter_thread;
 };
 
 struct _store_info {
@@ -127,6 +131,7 @@ static guint notify_id = 0;
 static int notify_type = -1;
 
 static time_t last_notify = 0;
+static time_t last_newmail = 0;
 static guint notify_idle_id = 0;
 static gboolean notify_idle_cb (gpointer user_data);
 
@@ -151,6 +156,8 @@ free_update(struct _folder_update *up)
 		camel_object_unref(up->store);
 	g_free(up->oldfull);
 	g_free(up->olduri);
+	if (up->uid_added)
+		em_utils_uids_free(up->uid_added);
 	g_free(up);
 }
 
@@ -191,14 +198,42 @@ notify_type_changed (GConfClient *client
 	notify_type = gconf_client_get_int (client, "/apps/evolution/mail/notify/type", NULL);
 }
 
+static gboolean
+check_brand_new(CamelFolder *folder, GPtrArray *uid_added, int filter_thread)
+{
+        CamelMessageInfo *info;
+        int i = 0;
+        guint32 flags;
+        gboolean result = FALSE;
+    
+        /* If we have a folder where filtering is done in a parallel thread,
+         * then wait for it to finish: the filter may mark the new mail
+         * as junk or move it to another folder. */
+        if (filter_thread)
+	        camel_session_thread_wait(session, filter_thread);
+    
+        while (!result && (i < uid_added->len)) {
+		info = camel_folder_get_message_info (folder, uid_added->pdata[i]);
+		flags = camel_message_info_flags(info);
+	        if (((flags & CAMEL_MESSAGE_SEEN) == 0) &&
+		    ((flags & CAMEL_MESSAGE_JUNK) == 0) &&
+		    (camel_message_info_date_received(info) > last_newmail))
+		        result = TRUE;
+	        i++;
+	}
+    
+        if (result) time (&last_newmail);
+        return result;
+}
+
 static void
 real_flush_updates(void *o, void *event_data, void *data)
 {
 	struct _MailComponent *component;
 	struct _EMFolderTreeModel *model;
 	struct _folder_update *up;
-	time_t now;
-	
+	gboolean brand_new;
+
 	component = mail_component_peek ();
 	model = mail_component_peek_tree_model (component);
 	
@@ -244,13 +279,17 @@ real_flush_updates(void *o, void *event_
 			notify_type = gconf_client_get_int (gconf, "/apps/evolution/mail/notify/type", NULL);
 		}
 		
-		time (&now);
-		if (notify_type != 0 && up->new && notify_idle_id == 0 && (now - last_notify >= 5))
+	        /* Check for brand new mail */
+	        if (up->new && up->unread > 0) {
+		    brand_new = check_brand_new (up->folder, up->uid_added, up->filter_thread);
+		} else { brand_new = FALSE; }
+		
+		if (notify_type != 0 && brand_new && notify_idle_id == 0 && (last_newmail - last_notify >= NOTIFY_THROTTLE))
 			notify_idle_id = g_idle_add_full (G_PRIORITY_LOW, notify_idle_cb, NULL, NULL);
 		
 		if (up->uri) {
 			EMEvent *e = em_event_peek();
-			EMEventTargetFolder *t = em_event_target_new_folder(e, up->uri, up->new?EM_EVENT_FOLDER_NEWMAIL:0);
+			EMEventTargetFolder *t = em_event_target_new_folder(e, up->uri, brand_new?EM_EVENT_FOLDER_NEWMAIL:0);
 
 			/** @Event: folder.changed
 			 * @Title: Folder changed
@@ -338,7 +377,7 @@ free_folder_info(struct _folder_info *mf
  * it's correct.  */
 
 static void
-update_1folder(struct _folder_info *mfi, int new, CamelFolderInfo *info)
+update_1folder(struct _folder_info *mfi, GPtrArray *uid_added, CamelFolderInfo *info)
 {
 	struct _folder_update *up;
 	CamelFolder *folder;
@@ -377,9 +416,14 @@ update_1folder(struct _folder_info *mfi,
 	up = g_malloc0(sizeof(*up));
 	up->full_name = g_strdup(mfi->full_name);
 	up->unread = unread;
-	up->new = new ? 1 : 0;
+	up->new = uid_added ? 1 : 0;
 	up->store = mfi->store_info->store;
 	up->uri = g_strdup(mfi->uri);
+        up->folder = folder;
+        up->uid_added = uid_added;
+        if (uid_added && unread > 0) {
+	        up->filter_thread = camel_folder_get_filter_thread(folder);
+	}
 	camel_object_ref(up->store);
 	e_dlist_addtail(&updates, (EDListNode *)up);
 	flush_updates();
@@ -393,7 +437,7 @@ setup_folder(CamelFolderInfo *fi, struct
 
 	mfi = g_hash_table_lookup(si->folders, fi->full_name);
 	if (mfi) {
-		update_1folder(mfi, 0, fi);
+		update_1folder(mfi, NULL, fi);
 	} else {
 		d(printf("Adding new folder: %s (%s)\n", fi->full_name, fi->uri));
 		mfi = g_malloc0(sizeof(*mfi));
@@ -443,23 +487,25 @@ folder_changed (CamelObject *o, gpointer
 	CamelStore *store = folder->parent_store;
 	struct _store_info *si;
 	struct _folder_info *mfi;
-	int new = 0;
-	
+	GPtrArray *uid_added = NULL;
+
 	d(printf("folder '%s' changed\n", folder->full_name));
 
 	if (!CAMEL_IS_VEE_FOLDER(folder)
 	    && folder != mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX)
 	    && folder != mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)
 	    && folder != mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT)
-	    && changes && changes->uid_added)
-		new = changes->uid_added->len;
-	
+	    && changes && (changes->uid_added->len > 0)) {
+	        /* Take a copy of added uids for later inspection */
+	        uid_added = em_utils_uids_copy(changes->uid_added);
+        }
+
 	LOCK(info_lock);
 	if (stores != NULL
 	    && (si = g_hash_table_lookup(stores, store)) != NULL
 	    && (mfi = g_hash_table_lookup(si->folders, folder->full_name)) != NULL
 	    && mfi->folder == folder) {
-		update_1folder(mfi, new, NULL);
+		update_1folder(mfi, uid_added, NULL);
 	}
 	UNLOCK(info_lock);
 }
@@ -521,7 +567,7 @@ void mail_note_folder(CamelFolder *folde
 
 	mfi->folder = folder;
 
-	update_1folder(mfi, 0, NULL);
+	update_1folder(mfi, NULL, NULL);
 
 	UNLOCK(info_lock);
 
