diff --git a/sieve/tests/basic.sieve b/sieve/tests/basic.sieve
index 876dc5a005077de878a8f88219ddf4c57c787fb0..860259b979ba0912449bef27b8a2a7545caeb530 100644
--- a/sieve/tests/basic.sieve
+++ b/sieve/tests/basic.sieve
@@ -1,4 +1,8 @@
-if address :is ["from", "to", "cc"] "sirius@drunksnipers.com {
+if address :is ["from", "to", "cc"] "sirius@drunksnipers.com" {
+  keep;
+} elsif header :is ["subject"] "WrF" {
+  discard;
+} elsif exists "X-Hufter" {
   keep;
 } elsif size :under 4000 {
   stop;
diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c
index a8e0a932f9480fe1ab1a71454e023c90f00a7b7f..e5a7158172872323cde5ff76ecf2cbc5b12dc2bf 100644
--- a/src/lib-sieve/sieve-generator.c
+++ b/src/lib-sieve/sieve-generator.c
@@ -195,7 +195,11 @@ bool sieve_generator_emit_stringlist_argument
 		(void) sieve_generator_emit_string(generator, sieve_ast_argument_str(arg));
 		return TRUE;
 	} else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) {
-		(void) sieve_generator_emit_string_list(generator, arg);
+		if ( sieve_ast_strlist_count(arg) == 1 )
+			sieve_generator_emit_string(generator, 
+				sieve_ast_argument_str(sieve_ast_strlist_first(arg)));
+		else
+			(void) sieve_generator_emit_string_list(generator, arg);
 		return TRUE;
 	}
 	
diff --git a/src/lib-sieve/tst-exists.c b/src/lib-sieve/tst-exists.c
index 94d4183acdcb57c5f5cda578dc2a0ed1cac01104..b4adbc112d9d0f57e0e0f376796b1f6c5be67044 100644
--- a/src/lib-sieve/tst-exists.c
+++ b/src/lib-sieve/tst-exists.c
@@ -9,9 +9,10 @@
 /* Opcodes */
 
 static bool tst_exists_opcode_dump(struct sieve_interpreter *interpreter);
+static bool tst_exists_opcode_execute(struct sieve_interpreter *interpreter);
 
 const struct sieve_opcode tst_exists_opcode = 
-	{ tst_exists_opcode_dump, NULL };
+	{ tst_exists_opcode_dump, tst_exists_opcode_execute };
 
 /* Test validation */
 
@@ -64,3 +65,40 @@ static bool tst_exists_opcode_dump(struct sieve_interpreter *interpreter)
 
     return TRUE;
 }
+
+/* Code execution */
+
+static bool tst_exists_opcode_execute(struct sieve_interpreter *interpreter)
+{
+	struct mail *mail = sieve_interpreter_get_mail(interpreter);
+	struct sieve_coded_stringlist *hdr_list;
+	string_t *hdr_item;
+	bool matched;
+	
+	printf("?? EXISTS\n");
+
+	t_push();
+		
+	/* Read header-list */
+	if ( (hdr_list=sieve_interpreter_read_stringlist_operand(interpreter)) == NULL ) {
+		t_pop();
+		return FALSE;
+	}
+		
+	/* Iterate through all requested headers to match */
+	hdr_item = NULL;
+	matched = FALSE;
+	while ( !matched && sieve_coded_stringlist_next_item(hdr_list, &hdr_item) && hdr_item != NULL ) {
+		const char *const *headers;
+			
+		if ( mail_get_headers_utf8(mail, str_c(hdr_item), &headers) >= 0 && headers[0] != NULL) {	
+			matched = TRUE;				 
+		}
+	}
+	
+	t_pop();
+	
+	sieve_interpreter_set_test_result(interpreter, matched);
+	
+	return TRUE;
+}
diff --git a/src/lib-sieve/tst-header.c b/src/lib-sieve/tst-header.c
index 1bcdfc66566a6cacf7dd1718f17ff2a5b1f7a726..3c29357a64a6794c45de1cecbe2577d51e4ba566 100644
--- a/src/lib-sieve/tst-header.c
+++ b/src/lib-sieve/tst-header.c
@@ -9,9 +9,10 @@
 /* Opcodes */
 
 static bool tst_header_opcode_dump(struct sieve_interpreter *interpreter);
+static bool tst_header_opcode_execute(struct sieve_interpreter *interpreter);
 
 const struct sieve_opcode tst_header_opcode = 
-	{ tst_header_opcode_dump, NULL };
+	{ tst_header_opcode_dump, tst_header_opcode_execute };
 
 /* Test registration */
 
@@ -88,3 +89,52 @@ static bool tst_header_opcode_dump(struct sieve_interpreter *interpreter)
 
     return TRUE;
 }
+
+/* Code execution */
+
+static bool tst_header_opcode_execute(struct sieve_interpreter *interpreter)
+{
+	struct mail *mail = sieve_interpreter_get_mail(interpreter);
+	struct sieve_coded_stringlist *hdr_list;
+	struct sieve_coded_stringlist *key_list;
+	string_t *hdr_item;
+	bool matched;
+	
+	printf("?? HEADER\n");
+
+	t_push();
+		
+	/* Read header-list */
+	if ( (hdr_list=sieve_interpreter_read_stringlist_operand(interpreter)) == NULL ) {
+		t_pop();
+		return FALSE;
+	}
+	
+	/* Read key-list */
+	if ( (key_list=sieve_interpreter_read_stringlist_operand(interpreter)) == NULL ) {
+		t_pop();
+		return FALSE;
+	}
+	
+	/* Iterate through all requested headers to match */
+	hdr_item = NULL;
+	matched = FALSE;
+	while ( !matched && sieve_coded_stringlist_next_item(hdr_list, &hdr_item) && hdr_item != NULL ) {
+		const char *const *headers;
+			
+		if ( mail_get_headers_utf8(mail, str_c(hdr_item), &headers) >= 0 ) {	
+			
+			int i;
+			for ( i = 0; !matched && headers[i] != NULL; i++ ) {
+				if ( sieve_stringlist_match(key_list, headers[i]) )
+					matched = TRUE;				
+			} 
+		}
+	}
+	
+	t_pop();
+	
+	sieve_interpreter_set_test_result(interpreter, matched);
+	
+	return TRUE;
+}