Index: mail-config.glade
===================================================================
--- mail-config.glade	(revision 34846)
+++ mail-config.glade	(working copy)
@@ -550,8 +550,8 @@ For example: &quot;Work&quot; or &quot;P
 			      <property name="invisible_char">*</property>
 			      <property name="activates_default">False</property>
 			      <accessibility>
-				<atkrelation target="label464" type="labelled-by"/>
 				<atkrelation target="identity_address_label" type="labelled-by"/>
+				<atkrelation target="label464" type="labelled-by"/>
 			      </accessibility>
 			    </widget>
 			    <packing>
@@ -633,8 +633,8 @@ For example: &quot;Work&quot; or &quot;P
 			      <property name="invisible_char">*</property>
 			      <property name="activates_default">False</property>
 			      <accessibility>
-				<atkrelation target="identity_full_name_label" type="labelled-by"/>
 				<atkrelation target="label464" type="labelled-by"/>
+				<atkrelation target="identity_full_name_label" type="labelled-by"/>
 			      </accessibility>
 			    </widget>
 			    <packing>
@@ -836,8 +836,8 @@ For example: &quot;Work&quot; or &quot;P
 			  <property name="invisible_char">*</property>
 			  <property name="activates_default">False</property>
 			  <accessibility>
-			    <atkrelation target="label466" type="labelled-by"/>
 			    <atkrelation target="identity_organization_label" type="labelled-by"/>
+			    <atkrelation target="label466" type="labelled-by"/>
 			  </accessibility>
 			</widget>
 			<packing>
@@ -890,8 +890,8 @@ For example: &quot;Work&quot; or &quot;P
 			  <property name="invisible_char">*</property>
 			  <property name="activates_default">False</property>
 			  <accessibility>
-			    <atkrelation target="reply_to_label" type="labelled-by"/>
 			    <atkrelation target="label466" type="labelled-by"/>
+			    <atkrelation target="reply_to_label" type="labelled-by"/>
 			  </accessibility>
 			</widget>
 			<packing>
@@ -2804,7 +2804,7 @@ For example: &quot;Work&quot; or &quot;P
 				<widget class="Custom" id="sent_button">
 				  <property name="visible">True</property>
 				  <property name="creation_function">em_account_editor_folder_selector_button_new</property>
-				  <property name="string1" translatable="yes">Select Sent Folder</property>
+				  <property name="string1">Select Sent Folder</property>
 				  <property name="int1">0</property>
 				  <property name="int2">0</property>
 				  <property name="last_modification_time">Tue, 14 Dec 2004 17:07:09 GMT</property>
@@ -2823,7 +2823,7 @@ For example: &quot;Work&quot; or &quot;P
 				<widget class="Custom" id="drafts_button">
 				  <property name="visible">True</property>
 				  <property name="creation_function">em_account_editor_folder_selector_button_new</property>
-				  <property name="string1" translatable="yes">Select Drafts Folder</property>
+				  <property name="string1">Select Drafts Folder</property>
 				  <property name="int1">0</property>
 				  <property name="int2">0</property>
 				  <property name="last_modification_time">Tue, 14 Dec 2004 17:07:02 GMT</property>
@@ -5268,6 +5268,7 @@ For example: &quot;Work&quot; or &quot;P
 			      <property name="fill">True</property>
 			    </packing>
 			  </child>
+
 			  <child>
 			    <widget class="GtkHBox" id="hboxEnableSearchFolders">
 			      <property name="visible">True</property>
@@ -6477,7 +6478,7 @@ For example: &quot;Work&quot; or &quot;P
 		<widget class="GtkTable" id="table34">
 		  <property name="border_width">12</property>
 		  <property name="visible">True</property>
-		  <property name="n_rows">4</property>
+		  <property name="n_rows">8</property>
 		  <property name="n_columns">1</property>
 		  <property name="homogeneous">False</property>
 		  <property name="row_spacing">3</property>
@@ -6533,8 +6534,8 @@ For example: &quot;Work&quot; or &quot;P
 		    <packing>
 		      <property name="left_attach">0</property>
 		      <property name="right_attach">1</property>
-		      <property name="top_attach">2</property>
-		      <property name="bottom_attach">3</property>
+		      <property name="top_attach">6</property>
+		      <property name="bottom_attach">7</property>
 		      <property name="x_options">fill</property>
 		    </packing>
 		  </child>
@@ -6573,7 +6574,7 @@ For example: &quot;Work&quot; or &quot;P
 			<widget class="GtkImage" id="plugin_image">
 			  <property name="visible">True</property>
 			  <property name="icon_size">4</property>
-			  <property name="icon_name">gtk-dialog-info</property>
+			  <property name="icon_name">gtk-info</property>
 			  <property name="xalign">0.5</property>
 			  <property name="yalign">0.5</property>
 			  <property name="xpad">0</property>
@@ -6614,8 +6615,8 @@ For example: &quot;Work&quot; or &quot;P
 		    <packing>
 		      <property name="left_attach">0</property>
 		      <property name="right_attach">1</property>
-		      <property name="top_attach">3</property>
-		      <property name="bottom_attach">4</property>
+		      <property name="top_attach">7</property>
+		      <property name="bottom_attach">8</property>
 		      <property name="x_padding">15</property>
 		      <property name="x_options">fill</property>
 		    </packing>
@@ -6668,6 +6669,192 @@ For example: &quot;Work&quot; or &quot;P
 		      <property name="x_options">fill</property>
 		    </packing>
 		  </child>
+
+		  <child>
+		    <widget class="GtkCheckButton" id="junk_header_check">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="label" translatable="yes">C_heck custom headers for junk</property>
+		      <property name="use_underline">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+		      <property name="focus_on_click">True</property>
+		      <property name="active">False</property>
+		      <property name="inconsistent">False</property>
+		      <property name="draw_indicator">True</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">2</property>
+		      <property name="bottom_attach">3</property>
+		      <property name="x_padding">4</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox243">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">6</property>
+
+		      <child>
+			<widget class="GtkScrolledWindow" id="scrolledwindow51">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+			  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+			  <property name="shadow_type">GTK_SHADOW_IN</property>
+			  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+			  <child>
+			    <widget class="GtkTreeView" id="junk_header_tree">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="headers_visible">True</property>
+			      <property name="rules_hint">False</property>
+			      <property name="reorderable">False</property>
+			      <property name="enable_search">True</property>
+			      <property name="fixed_height_mode">False</property>
+			      <property name="hover_selection">False</property>
+			      <property name="hover_expand">False</property>
+			    </widget>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkVButtonBox" id="vbuttonbox26">
+			  <property name="visible">True</property>
+			  <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
+			  <property name="spacing">0</property>
+
+			  <child>
+			    <widget class="GtkButton" id="junk_header_add">
+			      <property name="visible">True</property>
+			      <property name="can_default">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label">gtk-add</property>
+			      <property name="use_stock">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			      <property name="focus_on_click">True</property>
+			    </widget>
+			  </child>
+
+			  <child>
+			    <widget class="GtkButton" id="junk_header_remove">
+			      <property name="visible">True</property>
+			      <property name="can_default">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label">gtk-remove</property>
+			      <property name="use_stock">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			      <property name="focus_on_click">True</property>
+			    </widget>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">3</property>
+		      <property name="bottom_attach">4</property>
+		      <property name="x_padding">22</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkCheckButton" id="lookup_book">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="label" translatable="yes">Do _not mark messages as junk if sender is in my addressbook</property>
+		      <property name="use_underline">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+		      <property name="focus_on_click">True</property>
+		      <property name="active">False</property>
+		      <property name="inconsistent">False</property>
+		      <property name="draw_indicator">True</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">4</property>
+		      <property name="bottom_attach">5</property>
+		      <property name="x_padding">4</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox244">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">6</property>
+
+		      <child>
+			<widget class="GtkImage" id="image11">
+			  <property name="visible">True</property>
+			  <property name="stock">gtk-info</property>
+			  <property name="icon_size">4</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label590">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">This option will be overridden if a match for custom junk headers is found.</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">5</property>
+		      <property name="bottom_attach">6</property>
+		      <property name="x_padding">23</property>
+		      <property name="x_options">fill</property>
+		    </packing>
+		  </child>
 		</widget>
 		<packing>
 		  <property name="padding">0</property>
Index: em-utils.c
===================================================================
--- em-utils.c	(revision 34846)
+++ em-utils.c	(working copy)
@@ -1932,11 +1932,11 @@ emu_addr_cancel_book(void *data)
 gboolean
 em_utils_in_addressbook(CamelInternetAddress *iaddr)
 {
+	const char *addr;
 	GError *err = NULL;
 	GSList *s, *g, *addr_sources = NULL;
 	int stop = FALSE, found = FALSE;
 	EBookQuery *query;
-	const char *addr;
 	struct _addr_node *node;
 	time_t now;
 
Index: evolution-mail.schemas.in
===================================================================
--- evolution-mail.schemas.in	(revision 34846)
+++ evolution-mail.schemas.in	(working copy)
@@ -1098,6 +1098,47 @@
       </locale>
     </schema>
 
+    <schema>
+      <key>/schemas/apps/evolution/mail/junk/lookup_addressbook</key>
+      <applyto>/apps/evolution/mail/junk/lookup_addressbook</applyto>
+      <owner>evolution-mail</owner>
+      <type>bool</type>
+      <default>false</default>
+      <locale name="C">
+         <short>Determines whether to lookup in addressbook for sender email</short>
+         <long>
+	 Determines whether to loopup the sender email in addressbook. If found, it shouldn't be a spam. It looks up in the books marked for autocompletion. It can be slow, if remote addressbooks (like ldap) are marked for autocompletion.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/evolution/mail/junk/check_custom_header</key>
+      <applyto>/apps/evolution/mail/junk/check_custom_header</applyto>
+      <owner>evolution-mail</owner>
+      <type>bool</type>
+      <default>true</default>
+      <locale name="C">
+         <short>Determines whether to use custom headers to check for junk</short>
+         <long>
+          Determines whether to use custom headers to check for junk. If this option is enabled and the headers are mentioned, it will be improve the junk checking speed.
+         </long>
+      </locale>
+    </schema>
+    <schema>
+      <key>/schemas/apps/evolution/mail/junk/custom_header</key>
+      <applyto>/apps/evolution/mail/junk/custom_header</applyto>
+      <owner>evolution-mail</owner>
+       <type>list</type>
+      <list_type>string</list_type>
+      <default>[X-Spam-Flag=YES,X-Spam-Level=*****]</default>
+      <locale name="C">
+         <short>Specifies the header to check for junk.</short>
+         <long>
+	 Specifies the header to check for junk. The format is headername=value in gconf.
+         </long>
+      </locale>
+    </schema>
     <!-- Account settings -->
 
     <schema>
Index: mail-session.c
===================================================================
--- mail-session.c	(revision 34846)
+++ mail-session.c	(working copy)
@@ -86,6 +86,7 @@ static char *get_password(CamelSession *
 static void forget_password(CamelSession *session, CamelService *service, const char *domain, const char *item, CamelException *ex);
 static gboolean alert_user(CamelSession *session, CamelSessionAlertType type, const char *prompt, gboolean cancel);
 static CamelFilterDriver *get_filter_driver(CamelSession *session, const char *type, CamelException *ex);
+static gboolean lookup_addressbook(CamelSession *session, char *name);
 
 static void ms_thread_status(CamelSession *session, CamelSessionThreadMsg *msg, const char *text, int pc);
 static void *ms_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size);
@@ -117,7 +118,7 @@ class_init (MailSessionClass *mail_sessi
 	camel_session_class->forget_password = forget_password;
 	camel_session_class->alert_user = alert_user;
 	camel_session_class->get_filter_driver = get_filter_driver;
-
+	camel_session_class->lookup_addressbook = lookup_addressbook;
 	camel_session_class->thread_msg_new = ms_thread_msg_new;
 	camel_session_class->thread_msg_free = ms_thread_msg_free;
 	camel_session_class->thread_status = ms_thread_status;
@@ -377,6 +378,20 @@ static MailMsgInfo user_message_info = {
 };
 
 static gboolean
+lookup_addressbook(CamelSession *session, char *name)
+{
+	CamelInternetAddress *addr;
+	gboolean ret;
+
+	addr = camel_internet_address_new ();
+	camel_address_decode ((CamelAddress *)addr, name);
+	ret = em_utils_in_addressbook(addr);
+	camel_object_unref (addr);
+
+	return ret;
+}
+
+static gboolean
 alert_user(CamelSession *session, CamelSessionAlertType type, const char *prompt, gboolean cancel)
 {
 	MailSession *mail_session = MAIL_SESSION (session);
@@ -679,7 +694,7 @@ mail_session_init (const char *base_dire
 
 	/* The shell will tell us to go online. */
 	camel_session_set_online ((CamelSession *) session, FALSE);
-
+	mail_config_reload_junk_headers ();
 	g_free (camel_dir);
 }
 
@@ -760,3 +775,12 @@ mail_session_get_junk_plugins (void)
 	MailSession *ms = (MailSession *) session;
 	return ms->junk_plugins;
 }
+
+void
+mail_session_set_junk_headers (char **name, char **value, int len)
+{
+	if (!session)
+		return;
+
+	camel_session_set_junk_headers (session, (const char **)name, (const char **)value, len);
+}
Index: mail-session.h
===================================================================
--- mail-session.h	(revision 34846)
+++ mail-session.h	(working copy)
@@ -52,6 +52,7 @@ void mail_session_flush_filter_log (void
 void mail_session_add_junk_plugin (const char *plugin_name, CamelJunkPlugin *junk_plugin);
 
 const GList * mail_session_get_junk_plugins (void);
+void mail_session_set_junk_headers (char **name, char **value, int len);
 
 extern CamelSession *session;
 
Index: mail-config.c
===================================================================
--- mail-config.c	(revision 34846)
+++ mail-config.c	(working copy)
@@ -111,6 +111,13 @@ typedef struct {
 
 	GPtrArray *mime_types;
 	guint mime_types_notify_id;
+
+	GSList *jh_header;
+	gboolean jh_check;
+	guint jh_header_id;
+	guint jh_check_id;
+	gboolean book_lookup;
+	guint book_lookup_id;
 } MailConfig;
 
 static MailConfig *config = NULL;
@@ -251,6 +258,59 @@ gconf_style_changed (GConfClient *client
 }
 
 static void
+gconf_jh_check_changed (GConfClient *client, guint cnxn_id,
+		     GConfEntry *entry, gpointer user_data)
+{
+	config->jh_check = gconf_client_get_bool (config->gconf, "/apps/evolution/mail/junk/check_custom_header", NULL);
+	if (!config->jh_check) {
+		mail_session_set_junk_headers (NULL, NULL, 0);
+	} else {
+		config->jh_header = gconf_client_get_list (config->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, NULL);
+		GSList *node = config->jh_header;
+		GPtrArray *name, *value;
+		name = g_ptr_array_new ();
+		value = g_ptr_array_new ();
+		while (node && node->data) {
+			char **tok = g_strsplit (node->data, "=", 2);
+			g_ptr_array_add (name, g_strdup(tok[0]));
+			g_ptr_array_add (value, g_strdup(tok[1]));
+			node = node->next;
+			g_strfreev (tok);
+		}
+		mail_session_set_junk_headers ((char **)name->pdata, (char **)value->pdata, name->len);
+		g_ptr_array_free (name, TRUE);
+		g_ptr_array_free (value, TRUE);
+	}
+}
+
+static void
+gconf_lookup_book_changed (GConfClient *client, guint cnxn_id,
+			  GConfEntry *entry, gpointer data)
+{
+	config->book_lookup = gconf_client_get_bool (config->gconf, "/apps/evolution/mail/junk/lookup_addressbook", NULL);
+}
+
+static void
+gconf_jh_headers_changed (GConfClient *client, guint cnxn_id,
+		     GConfEntry *entry, gpointer user_data)
+{
+	config->jh_header = gconf_client_get_list (config->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, NULL);
+	GSList *node = config->jh_header;
+	GPtrArray *name, *value;
+	name = g_ptr_array_new ();
+	value = g_ptr_array_new ();
+	while (node && node->data) {
+		char **tok = g_strsplit (node->data, "=", 2);
+		g_ptr_array_add (name, g_strdup(tok[0]));
+		g_ptr_array_add (value, g_strdup(tok[1]));
+		node = node->next;
+		g_strfreev (tok);
+	}
+	mail_session_set_junk_headers ((char **)name->pdata, (char **)value->pdata, name->len);
+}
+
+
+static void
 gconf_address_count_changed (GConfClient *client, guint cnxn_id,
 			     GConfEntry *entry, gpointer user_data)
 {
@@ -329,6 +389,9 @@ mail_config_init (void)
 			      GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
 	gconf_client_add_dir (config->gconf, "/GNOME/Spell",
 			      GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+	gconf_client_add_dir (config->gconf, "/apps/evolution/mail/junk",
+			      GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+
 	config->font_notify_id = gconf_client_notify_add (config->gconf, "/apps/evolution/mail/display/fonts",
 							  gconf_style_changed, NULL, NULL, NULL);
 	config->font_notify_id = gconf_client_notify_add (config->gconf, "/apps/evolution/mail/display/address_compress",
@@ -377,6 +440,18 @@ mail_config_init (void)
 	config->magic_spacebar = gconf_client_get_bool (config->gconf, "/apps/evolution/mail/display/magic_spacebar", NULL);
 	config->accounts = e_account_list_new (config->gconf);
 	config->signatures = e_signature_list_new (config->gconf);
+
+	config->jh_check = gconf_client_get_bool (config->gconf, "/apps/evolution/mail/junk/check_custom_header", NULL);
+	config->jh_check_id = gconf_client_notify_add (config->gconf, "/apps/evolution/mail/junk/check_custom_header",
+								     gconf_jh_check_changed, NULL, NULL, NULL);
+	config->jh_header_id = gconf_client_notify_add (config->gconf, "/apps/evolution/mail/junk/custom_header",
+								     gconf_jh_headers_changed, NULL, NULL, NULL);
+	config->book_lookup = gconf_client_get_bool (config->gconf, "/apps/evolution/mail/junk/lookup_addressbook", NULL);
+	config->book_lookup_id  = gconf_client_notify_add (config->gconf, "/apps/evolution/mail/junk/lookup_addressbook",
+								     gconf_lookup_book_changed, NULL, NULL, NULL);
+
+	gconf_jh_check_changed (config->gconf, 0, NULL, config);
+
 }
 
 
@@ -1025,6 +1100,17 @@ mail_config_remove_signature (ESignature
 	mail_config_save_signatures ();
 }
 
+void
+mail_config_reload_junk_headers ()
+{
+	/* It automatically sets in the session */
+	if (config == NULL)
+		mail_config_init ();
+	else 
+		gconf_jh_check_changed (config->gconf, 0, NULL, config);
+
+}
+
 char *
 mail_config_signature_run_script (const char *script)
 {
Index: em-mailer-prefs.c
===================================================================
--- em-mailer-prefs.c	(revision 34846)
+++ em-mailer-prefs.c	(working copy)
@@ -197,6 +197,10 @@ enum {
 	LABEL_LIST_COLUMN_NAME
 };
 
+enum {
+	JH_LIST_COLUMN_NAME,
+	JH_LIST_COLUMN_VALUE,
+};
 static void
 label_sensitive_buttons (EMMailerPrefs *prefs)
 {
@@ -302,6 +306,156 @@ label_tree_refill (GConfClient *client, 
 	e_util_labels_free (labels);
 }
 
+
+static void
+jh_tree_refill (EMMailerPrefs *prefs)
+{
+	GtkListStore *store = prefs->junk_header_list_store;
+	GSList *l, *cjh = gconf_client_get_list (prefs->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, NULL);
+
+	gtk_list_store_clear (store);
+
+	for (l = cjh; l; l = l->next) {
+		GtkTreeIter iter;
+		char **tokens = g_strsplit (l->data, "=", 2);
+
+		gtk_list_store_append (store, &iter);
+		gtk_list_store_set (
+			store, &iter,
+			JH_LIST_COLUMN_NAME , tokens[0] ? tokens[0] : "",
+			JH_LIST_COLUMN_VALUE, tokens[1] ? tokens[1] : "" ,
+			-1);
+		g_strfreev (tokens);
+	}
+
+	g_slist_foreach (cjh, (GFunc) g_free, NULL);
+	g_slist_free (cjh);
+}
+
+static void
+jh_add_cb (GtkWidget *widget, gpointer user_data)
+{
+	EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
+	GtkWidget *dialog, *l1, *l2, *entry1, *entry2, *vbox, *hbox;
+	int response;
+	dialog = gtk_dialog_new_with_buttons (_("Add Custom Junk Header"), (GtkWindow *)gtk_widget_get_toplevel (widget), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
+
+	vbox = gtk_vbox_new (FALSE, 6);
+	hbox = gtk_hbox_new (FALSE, 0);
+	l1 = gtk_label_new_with_mnemonic (_("Header Name:"));
+	l2 = gtk_label_new_with_mnemonic (_("Header Value Contains:"));
+	entry1 = gtk_entry_new ();
+	entry2 = gtk_entry_new ();
+	gtk_box_pack_start ((GtkBox *) hbox, l1, FALSE, FALSE, 6);
+	gtk_box_pack_start ((GtkBox *)hbox, entry1, FALSE, FALSE, 6);
+	gtk_box_pack_start ((GtkBox *)vbox, hbox, FALSE, FALSE, 6);
+
+	hbox = gtk_hbox_new (FALSE, 0);
+	gtk_box_pack_start ((GtkBox *)hbox, l2, FALSE, FALSE, 6);
+	gtk_box_pack_start ((GtkBox *)hbox, entry2, FALSE, FALSE, 6);
+	gtk_box_pack_start ((GtkBox *)vbox, hbox, FALSE, FALSE, 6);
+	
+	gtk_widget_show_all (vbox);
+	gtk_container_add ((GtkContainer *)((GtkDialog *)dialog)->vbox, vbox);
+	response = gtk_dialog_run ((GtkDialog *)dialog);
+	if (response == GTK_RESPONSE_ACCEPT) {
+		const char *name = gtk_entry_get_text ((GtkEntry *)entry1);
+		const char *value = gtk_entry_get_text ((GtkEntry *)entry2);
+		char *tok;
+		GSList *list = gconf_client_get_list (prefs->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, NULL);
+		
+		//FIXME: Validate the values
+		
+		tok = g_strdup_printf ("%s=%s", name, value);
+		list = g_slist_append (list, tok);
+		gconf_client_set_list (prefs->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, list, NULL);
+		g_slist_foreach (list, (GFunc)g_free, NULL);
+
+		g_slist_free (list);
+	}
+	gtk_widget_destroy (dialog);
+	jh_tree_refill (prefs);
+}
+
+static void
+jh_remove_cb (GtkWidget *widget, gpointer user_data)
+{
+	EMMailerPrefs *prefs = user_data;
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	g_return_if_fail (prefs != NULL);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->junk_header_tree));
+	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+		char *name=NULL, *value=NULL;
+		GSList *prev = NULL, *node, *list = gconf_client_get_list (prefs->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, NULL);
+		gtk_tree_model_get (model, &iter, JH_LIST_COLUMN_NAME, &name, JH_LIST_COLUMN_VALUE, &value, -1);
+		node = list;
+		while (node) {
+			char *test;
+			int len = strlen (name);
+			test = strncmp (node->data, name, len) == 0 ? node->data+len:NULL;
+
+			if (test) {
+				test++;
+				if (strcmp (test, value) == 0)
+					break;
+			}
+				
+			prev = node;
+			node = node->next;
+		}
+
+		if (prev && !node) {
+			/* Not found. So what? */
+		} else if (prev && node) {
+			prev->next = node->next;
+			g_free (node->data);
+		} else if (!prev && node) {
+			list = list->next;
+			g_free (node->data);
+		}
+
+		gconf_client_set_list (prefs->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, list, NULL);
+
+		g_slist_foreach (list, (GFunc)g_free, NULL);
+		g_slist_free (list);
+		g_free (name);
+		g_free (value);
+
+		jh_tree_refill (prefs);
+	}
+}
+
+
+static GtkListStore *
+init_junk_tree (GtkWidget *label_tree, EMMailerPrefs *prefs)
+{
+	GtkListStore *store;
+	GtkCellRenderer *renderer;
+	gint col;
+
+	g_return_val_if_fail (label_tree != NULL, NULL);
+	g_return_val_if_fail (prefs != NULL, NULL);
+
+	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+	gtk_tree_view_set_model (GTK_TREE_VIEW (label_tree), GTK_TREE_MODEL (store));
+
+	renderer = gtk_cell_renderer_text_new ();
+	col = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Header"), renderer, "text", JH_LIST_COLUMN_NAME, NULL);
+	g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
+
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Contains Value"), renderer, "text", JH_LIST_COLUMN_VALUE, NULL);
+	g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
+
+	label_tree_refill (NULL, 0, NULL, prefs);
+
+	return store;
+}
+
 static GtkListStore *
 init_label_tree (GtkWidget *label_tree, EMMailerPrefs *prefs, gboolean locked)
 {
@@ -670,6 +824,23 @@ photo_toggle_changed (GtkToggleButton *t
 		gtk_widget_set_sensitive ((GtkWidget *) prefs->photo_local, FALSE);
 }
 
+static void
+custom_junk_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs)
+{
+	toggle_button_toggled (toggle, prefs);
+	if (gtk_toggle_button_get_active (toggle)) {
+		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_remove, TRUE);
+		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_add, TRUE);
+		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_tree, TRUE);
+	} else {
+		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_tree, FALSE);
+		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_add, FALSE);
+		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_remove, FALSE);
+	}
+
+
+}
+
 #if 0
 // not used at the moment, commenting out
 static void
@@ -1317,6 +1488,25 @@ em_mailer_prefs_construct (EMMailerPrefs
 	prefs->plugin_image = GTK_IMAGE (glade_xml_get_widget (gui, "plugin_image"));
 	junk_plugin_setup (GTK_WIDGET (prefs->default_junk_plugin), prefs);
 
+	prefs->junk_header_check = (GtkToggleButton *)glade_xml_get_widget (gui, "junk_header_check");
+	prefs->junk_header_tree = (GtkTreeView *)glade_xml_get_widget (gui, "junk_header_tree");
+	prefs->junk_header_add = (GtkButton *)glade_xml_get_widget (gui, "junk_header_add");
+	prefs->junk_header_remove = (GtkButton *)glade_xml_get_widget (gui, "junk_header_remove");
+	prefs->junk_book_lookup = (GtkToggleButton *)glade_xml_get_widget (gui, "lookup_book");
+	toggle_button_init (prefs, prefs->junk_book_lookup, FALSE,
+			    "/apps/evolution/mail/junk/lookup_addressbook",
+			    G_CALLBACK (toggle_button_init));
+
+	prefs->junk_header_list_store = init_junk_tree ((GtkWidget *)prefs->junk_header_tree, prefs);
+	toggle_button_init (prefs, prefs->junk_header_check, FALSE,
+			    "/apps/evolution/mail/junk/check_custom_header",
+			    G_CALLBACK (custom_junk_button_toggled));
+
+	custom_junk_button_toggled (prefs->junk_header_check, prefs);
+	jh_tree_refill (prefs);
+	g_signal_connect (G_OBJECT (prefs->junk_header_add), "clicked", G_CALLBACK (jh_add_cb), prefs);
+	g_signal_connect (G_OBJECT (prefs->junk_header_remove), "clicked", G_CALLBACK (jh_remove_cb), prefs);
+
 	/* get our toplevel widget */
 	target = em_config_target_new_prefs(ec, prefs->gconf);
 	e_config_set_target((EConfig *)ec, (EConfigTarget *)target);
Index: mail-config.h
===================================================================
--- mail-config.h	(revision 34846)
+++ mail-config.h	(working copy)
@@ -154,6 +154,8 @@ char *mail_config_folder_to_safe_url (st
 guint mail_config_get_error_timeout  (void);
 guint mail_config_get_error_level  (void);
 
+void mail_config_reload_junk_headers (void);
+
 GType evolution_mail_config_get_type (void);
 
 gboolean evolution_mail_config_factory_init (void);
Index: em-mailer-prefs.h
===================================================================
--- em-mailer-prefs.h	(revision 34846)
+++ em-mailer-prefs.h	(working copy)
@@ -123,12 +123,20 @@ struct _EMMailerPrefs {
 	struct _GtkToggleButton *check_incoming;
 	struct _GtkToggleButton *empty_junk;
 	struct _GtkOptionMenu *empty_junk_days;
-
+	
 	struct _GtkToggleButton *sa_local_tests_only;
 	struct _GtkToggleButton *sa_use_daemon;
 	struct _GtkComboBox *default_junk_plugin;
 	struct _GtkLabel *plugin_status;
 	struct _GtkImage *plugin_image;
+
+	struct _GtkToggleButton *junk_header_check;
+	struct _GtkTreeView *junk_header_tree;
+	struct _GtkListStore *junk_header_list_store;	
+	struct _GtkButton *junk_header_add;
+	struct _GtkButton *junk_header_remove;
+	struct _GtkToggleButton *junk_book_lookup;
+
 };
 
 struct _EMMailerPrefsClass {
