Index: camel-filter-search.c
===================================================================
--- camel-filter-search.c	(revision 8389)
+++ camel-filter-search.c	(working copy)
@@ -58,6 +58,7 @@
 #include "camel-session.h"
 #include "camel-stream-fs.h"
 #include "camel-stream-mem.h"
+#include "camel-string-utils.h"
 #include "camel-url.h"
 
 #define d(x)
@@ -643,9 +644,35 @@ junk_test (struct _ESExp *f, int argc, s
 {
 	ESExpResult *r;
 	gboolean retval = FALSE;
-
+	
+	d(printf("doing junk test for message from '%s'\n", camel_message_info_from (fms->info)));
 	if (fms->session->junk_plugin != NULL) {
-		retval = camel_junk_plugin_check_junk (fms->session->junk_plugin, camel_filter_search_get_message (fms, f));
+		CamelMessageInfo *info = fms->info;
+		const GHashTable *ht = camel_session_get_junk_headers (fms->session);
+		struct _camel_header_param *node = ((CamelMessageInfoBase *)info)->headers;
+
+		while (node && !retval) {
+			if (node->name) {
+				char *value = (char *) g_hash_table_lookup ((GHashTable *) ht, node->name);
+				d(printf("JunkCheckMatch: %s %s %s\n", node->name, node->value, value));
+				if (value)
+					retval = camel_strstrcase(node->value, value) != NULL;
+		
+			}
+			node = node->next;
+		}
+		if (camel_debug ("junk"))
+			printf("filtered based on junk header ? %d\n", retval);
+		if (!retval) {
+			retval = camel_session_lookup_addressbook (fms->session, camel_message_info_from (info)) != TRUE;
+			if (camel_debug ("junk"))
+				printf("Sender '%s' in book? %d\n", camel_message_info_from (info), !retval);
+			
+			if (retval) /* Not in book. Could be spam. So check for it*/ {
+				d(printf("filtering message\n"));
+				retval = camel_junk_plugin_check_junk (fms->session->junk_plugin, camel_filter_search_get_message (fms, f));
+			}
+		}
 
 		if (camel_debug ("junk"))
 			printf("junk filter => %s\n", retval ? "*JUNK*" : "clean");
Index: providers/imap/camel-imap-folder.c
===================================================================
--- providers/imap/camel-imap-folder.c	(revision 8389)
+++ providers/imap/camel-imap-folder.c	(working copy)
@@ -2419,6 +2419,42 @@ add_message_from_data (CamelFolder *fold
 	messages->pdata[seq - first] = mi;
 }
 
+struct _junk_data {
+	GData *data;
+	CamelMessageInfoBase *mi;
+};
+
+static void
+construct_junk_headers (char *header, char *value, struct _junk_data *jdata)	
+{
+	char *bs, *es, *flag=NULL;
+	char *bdata = g_datalist_get_data (&(jdata->data), "BODY_PART_DATA");
+	struct _camel_header_param *node;
+
+	bs = camel_strstrcase (bdata ? bdata:"", header);
+	if (bs) {
+		bs += strlen(header);
+		bs = strchr (bs, ':');
+		if (bs) {
+			bs++;
+			while (*bs == ' ')
+				bs++;
+			es = strchr (bs, '\n');
+			if (es)
+				flag = g_strndup (bs, es-bs);
+		} else
+			bs = NULL;
+
+	}
+	
+	if (bs) {
+		node = g_new (struct _camel_header_param, 1);
+		node->name = g_strdup (header);
+		node->value = flag;
+		node->next = jdata->mi->headers;
+		jdata->mi->headers = node;
+	}
+}
 
 #define CAMEL_MESSAGE_INFO_HEADERS "DATE FROM TO CC SUBJECT REFERENCES IN-REPLY-TO MESSAGE-ID MIME-VERSION CONTENT-TYPE "
 
@@ -2603,6 +2639,7 @@ imap_update_summary (CamelFolder *folder
 
 	/* Now finish up summary entries (fix UIDs, set flags and size) */
 	for (i = 0; i < fetch_data->len; i++) {
+		struct _junk_data jdata;
 		data = fetch_data->pdata[i];
 
 		seq = GPOINTER_TO_INT (g_datalist_get_data (&data, "SEQUENCE"));
@@ -2663,6 +2700,10 @@ imap_update_summary (CamelFolder *folder
 		if (size)
 			mi->info.size = size;
 
+		/* Just do this to build the junk required headers to be built*/
+		jdata.data = data;
+		jdata.mi = (CamelMessageInfoBase *) mi;
+		g_hash_table_foreach ((GHashTable *)camel_session_get_junk_headers(((CamelService *) store)->session), (GHFunc) construct_junk_headers, &jdata);
 		g_datalist_clear (&data);
 	}
 	g_ptr_array_free (fetch_data, TRUE);
@@ -2699,12 +2740,12 @@ imap_update_summary (CamelFolder *folder
 
 			camel_message_info_free(&info->info);
 			break;
-		}
+		} 
 
 		camel_folder_summary_add (folder->summary, (CamelMessageInfo *)mi);
 		camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
 
-		if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT))
+		if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT)) 
 			camel_folder_change_info_recent_uid(changes, camel_message_info_uid (mi));
 	}
 
Index: camel-session.c
===================================================================
--- camel-session.c	(revision 8389)
+++ camel-session.c	(working copy)
@@ -66,7 +66,8 @@ static void session_thread_msg_free(Came
 static int session_thread_queue(CamelSession *session, CamelSessionThreadMsg *msg, int flags);
 static void session_thread_wait(CamelSession *session, int id);
 static void session_thread_status(CamelSession *session, CamelSessionThreadMsg *msg, const char *text, int pc);
-
+void
+camel_session_set_junk_headers (CamelSession *session, const char **headers, const char **values, int len);
 static void
 camel_session_init (CamelSession *session)
 {
@@ -79,6 +80,7 @@ camel_session_init (CamelSession *sessio
 	session->priv->thread_id = 1;
 	session->priv->thread_active = g_hash_table_new(NULL, NULL);
 	session->priv->thread_pool = NULL;
+	session->priv->junk_headers = NULL;
 }
 
 static void
@@ -99,7 +101,8 @@ camel_session_finalise (CamelObject *o)
 
 	g_mutex_free(session->priv->lock);
 	g_mutex_free(session->priv->thread_lock);
-
+	g_hash_table_remove_all (session->priv->junk_headers);
+	g_hash_table_destroy (session->priv->junk_headers);
 	g_free(session->priv);
 }
 
@@ -428,6 +431,14 @@ camel_session_alert_user (CamelSession *
 	return CS_CLASS (session)->alert_user (session, type, prompt, cancel);
 }
 
+gboolean
+camel_session_lookup_addressbook (CamelSession *session, const char *name)
+{
+	g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE);
+	g_return_val_if_fail (name != NULL, FALSE);
+
+	return CS_CLASS (session)->lookup_addressbook (session, name);
+}
 
 /**
  * camel_session_is_online:
@@ -703,3 +714,26 @@ camel_session_set_network_state (CamelSe
 
 	session->network_state = network_state;
 }
+
+void
+camel_session_set_junk_headers (CamelSession *session, const char **headers, const char **values, int len)
+{
+	int i;
+
+	if (session->priv->junk_headers) {
+		g_hash_table_remove_all (session->priv->junk_headers);
+		g_hash_table_destroy (session->priv->junk_headers);
+	}
+
+	session->priv->junk_headers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+	for (i=0; i<len; i++) {
+		g_hash_table_insert (session->priv->junk_headers, g_strdup (headers[i]), g_strdup(values[i]));
+	}
+}
+
+const GHashTable *
+camel_session_get_junk_headers (CamelSession *session)
+{
+	return session->priv->junk_headers;
+}
Index: camel-session.h
===================================================================
--- camel-session.h	(revision 8389)
+++ camel-session.h	(working copy)
@@ -108,6 +108,7 @@ typedef struct {
 	int (*thread_queue)(CamelSession *session, CamelSessionThreadMsg *msg, int flags);
 	void (*thread_wait)(CamelSession *session, int id);
 	void (*thread_status)(CamelSession *session, CamelSessionThreadMsg *msg, const char *text, int pc);
+	gboolean (*lookup_addressbook) (CamelSession *session, char *name);
 } CamelSessionClass;
 
 
@@ -192,6 +193,9 @@ int camel_session_thread_queue(CamelSess
 void camel_session_thread_wait(CamelSession *session, int id);
 gboolean camel_session_get_network_state (CamelSession *session);
 void camel_session_set_network_state (CamelSession *session, gboolean network_state);
+const GHashTable * camel_session_get_junk_headers (CamelSession *session);
+void camel_session_set_junk_headers (CamelSession *session, const char **headers, const char **values, int len);
+gboolean camel_session_lookup_addressbook (CamelSession *session, const char *name);
 
 G_END_DECLS
 
Index: camel-private.h
===================================================================
--- camel-private.h	(revision 8389)
+++ camel-private.h	(working copy)
@@ -99,6 +99,8 @@ struct _CamelSessionPrivate {
 	GThreadPool *thread_pool;
 
 	GHashTable *thread_msg_op;
+	GHashTable *junk_headers;
+	
 };
 
 #define CAMEL_SESSION_LOCK(f, l) \
Index: camel-folder-summary.h
===================================================================
--- camel-folder-summary.h	(revision 8389)
+++ camel-folder-summary.h	(working copy)
@@ -179,6 +179,7 @@ struct _CamelMessageInfoBase {
 
 	/* tree of content description - NULL if it is not available */
 	CamelMessageContentInfo *content;
+	struct _camel_header_param *headers;
 };
 
 /* probably do this as well, removing CamelFolderChangeInfo and interfaces
