diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c
index 924d216571e7e6b483d3359d28b86c1f9919f44c..791029b417eb06844924a380d0e003420be00092 100644
--- a/src/lib-sieve/ext-envelope.c
+++ b/src/lib-sieve/ext-envelope.c
@@ -52,15 +52,14 @@ static bool tst_envelope_validate(struct sieve_validator *validator, struct siev
 		!sieve_validate_command_subtests(validator, tst, 0) ) {
 		return FALSE;
 	}
-		
-	tst->data = (void *) arg;	
-		
+				
 	if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) {
 		sieve_command_validate_error(validator, tst, 
 			"the envelope test expects a string-list as first argument (envelope part), but %s was found", 
 			sieve_ast_argument_name(arg));
 		return FALSE; 
 	}
+	sieve_validator_argument_activate(validator, arg);
 	
 	arg = sieve_ast_argument_next(arg);
 	if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) {
@@ -69,6 +68,7 @@ static bool tst_envelope_validate(struct sieve_validator *validator, struct siev
 			sieve_ast_argument_name(arg));
 		return FALSE; 
 	}
+	sieve_validator_argument_activate(validator, arg);
 	
 	return TRUE;
 }
@@ -89,20 +89,12 @@ static bool ext_envelope_validator_load(struct sieve_validator *validator)
 static bool tst_envelope_generate
 	(struct sieve_generator *generator,	struct sieve_command_context *ctx) 
 {
-	struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data;
-	
 	sieve_generator_emit_ext_opcode(generator, &envelope_extension);
 
-	/* Emit envelope-part */  	
-	if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) 
-		return FALSE;
-		
-	arg = sieve_ast_argument_next(arg);
-	
-	/* Emit key-list */  	
-	if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) 
-		return FALSE;
-	
+	/* Generate arguments */
+    if ( !sieve_generate_arguments(generator, ctx, NULL) )
+        return FALSE;
+
 	return TRUE;
 }
 
diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c
index 37a7527767aa55ba8877b494ecf22fae92f05283..20de6ef5064763ebc3df5466685d5ad28664a0fc 100644
--- a/src/lib-sieve/ext-fileinto.c
+++ b/src/lib-sieve/ext-fileinto.c
@@ -39,7 +39,8 @@ static bool cmd_fileinto_validate(struct sieve_validator *validator, struct siev
 		return FALSE;
 	}
 	
-	cmd->data = (void *) arg;
+
+	sieve_validator_argument_activate(validator, arg);
 	
 	return TRUE;
 }
@@ -60,13 +61,11 @@ static bool ext_fileinto_validator_load(struct sieve_validator *validator)
 static bool cmd_fileinto_generate
 	(struct sieve_generator *generator,	struct sieve_command_context *ctx) 
 {
-	struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data;
-	
 	sieve_generator_emit_ext_opcode(generator, &fileinto_extension);
 
-	/* Emit folder string */  	
-	if ( !sieve_generator_emit_string_argument(generator, arg) ) 
-		return FALSE;
+	/* Generate arguments */
+    if ( !sieve_generate_arguments(generator, ctx, NULL) )
+        return FALSE;
 	
 	return TRUE;
 }
diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c
index c98a82cf37df594f9d650f627cdc9fe037ca85c5..610d9a56ff99b49abecf1dba3d0bf1ebe7811361 100644
--- a/src/lib-sieve/ext-reject.c
+++ b/src/lib-sieve/ext-reject.c
@@ -39,8 +39,8 @@ static bool cmd_reject_validate(struct sieve_validator *validator, struct sieve_
 	 	
 		return FALSE;
 	}
-	
-	cmd->data = (void *) arg;
+		
+	sieve_validator_argument_activate(validator, arg);
 	
 	return TRUE;
 }
@@ -61,13 +61,11 @@ static bool ext_reject_validator_load(struct sieve_validator *validator)
 static bool cmd_reject_generate
 	(struct sieve_generator *generator,	struct sieve_command_context *ctx) 
 {
-	struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data;
-	
 	sieve_generator_emit_ext_opcode(generator, &reject_extension);
 
-	/* Emit reason string */  	
-	if ( !sieve_generator_emit_string_argument(generator, arg) ) 
-		return FALSE;
+	/* Generate arguments */
+    if ( !sieve_generate_arguments(generator, ctx, NULL) )
+        return FALSE;
 	
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/vacation/ext-vacation.c b/src/lib-sieve/plugins/vacation/ext-vacation.c
index a24ffc3389cb6a713482f049799619c7eea323f4..9638e2e4a87a06db0e6f3b2a6beded76442af037 100644
--- a/src/lib-sieve/plugins/vacation/ext-vacation.c
+++ b/src/lib-sieve/plugins/vacation/ext-vacation.c
@@ -198,8 +198,8 @@ static bool cmd_vacation_validate(struct sieve_validator *validator, struct siev
 	
 	/* Check valid syntax: 
 	 *    vacation [":days" number] [":subject" string]
-   *                 [":from" string] [":addresses" string-list]
-   *                 [":mime"] [":handle" string] <reason: string>
+	 *                 [":from" string] [":addresses" string-list]
+	 *                 [":mime"] [":handle" string] <reason: string>
 	 */
 	if ( !sieve_validate_command_arguments(validator, cmd, 1, &arg) ||
 		!sieve_validate_command_subtests(validator, cmd, 0) || 
@@ -207,8 +207,8 @@ static bool cmd_vacation_validate(struct sieve_validator *validator, struct siev
 	 	
 		return FALSE;
 	}
-	
-	cmd->data = (void *) arg;
+
+	sieve_validator_argument_activate(validator, arg);	
 	
 	return TRUE;
 }
@@ -229,14 +229,12 @@ static bool ext_vacation_validator_load(struct sieve_validator *validator)
 static bool cmd_vacation_generate
 	(struct sieve_generator *generator,	struct sieve_command_context *ctx) 
 {
-	struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data;
-	
 	sieve_generator_emit_ext_opcode(generator, &vacation_extension);
 
-	/* Emit folder string */  	
-	if ( !sieve_generator_emit_string_argument(generator, arg) ) 
-		return FALSE;
-	
+	/* Generate arguments */
+    if ( !sieve_generate_arguments(generator, ctx, NULL) )
+        return FALSE;	
+
 	return TRUE;
 }
 
diff --git a/src/lib-sieve/sieve-binary.h b/src/lib-sieve/sieve-binary.h
index f27b615df2d6cb09739060d5b7e1750c66fb1cf5..f731deea813ba09a25beb7cb99cb81d30711ddb4 100644
--- a/src/lib-sieve/sieve-binary.h
+++ b/src/lib-sieve/sieve-binary.h
@@ -1,8 +1,11 @@
 #ifndef __SIEVE_BINARY_H
 #define __SIEVE_BINARY_H
 
-#include "sieve-extensions.h"
+#include "lib.h"
+#include "str.h"
+
 #include "sieve-code.h"
+#include "sieve-extensions.h"
 
 struct sieve_binary;
 
diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c
index b3c6ecde1ed3f181d1319031aaf155a6a387f71a..d1c13b5fa0ddebaf426deb1c24429aeb97bd142b 100644
--- a/src/lib-sieve/sieve-code.c
+++ b/src/lib-sieve/sieve-code.c
@@ -1,11 +1,55 @@
-#include <stdio.h>
+#include "lib.h"
+#include "str.h"
 
-#include "sieve-code.h"
+#include "sieve-generator.h"
 #include "sieve-interpreter.h"
 
+#include "sieve-code.h"
+
+#include <stdio.h>
+
 /* Operands */
 
+void sieve_operand_number_emit(struct sieve_generator *generator, sieve_size_t number) {
+	(void) sieve_generator_emit_operand(generator, SIEVE_OPERAND_NUMBER);
+  (void) sieve_generator_emit_integer(generator, number);
+}
 
+void sieve_operand_string_emit(struct sieve_generator *generator, string_t *str)
+{
+	(void) sieve_generator_emit_operand(generator, SIEVE_OPERAND_STRING);
+  (void) sieve_generator_emit_string(generator, str);
+}
+
+void sieve_operand_stringlist_emit_start
+	(struct sieve_generator *generator, unsigned int listlen, void **context)
+{
+  sieve_size_t *end_offset = t_new(sieve_size_t, 1);
+
+	/* Emit byte identifying the type of operand */	  
+  (void) sieve_generator_emit_operand(generator, SIEVE_OPERAND_STRING_LIST);
+  
+  /* Give the interpreter an easy way to skip over this string list */
+  *end_offset = sieve_generator_emit_offset(generator, 0);
+	*context = (void *) end_offset;
+
+  /* Emit the length of the list */
+  (void) sieve_generator_emit_integer(generator, (int) listlen);
+}
+
+void sieve_operand_stringlist_emit_item
+	(struct sieve_generator *generator, void *context ATTR_UNUSED, string_t *item)
+{
+	(void) sieve_generator_emit_string(generator, item);
+}
+
+void sieve_operand_stringlist_emit_end
+	(struct sieve_generator *generator, void *context)
+{
+	sieve_size_t *end_offset = (sieve_size_t *) context;
+
+	(void) sieve_generator_resolve_offset(generator, *end_offset);
+}
 
 /* Opcodes */
 
diff --git a/src/lib-sieve/sieve-code.h b/src/lib-sieve/sieve-code.h
index c3a2041c1af3a0e920fe831206a1a356bb191f00..56389a84d5dd575f804138f4b56ff78ff9189cac 100644
--- a/src/lib-sieve/sieve-code.h
+++ b/src/lib-sieve/sieve-code.h
@@ -34,8 +34,11 @@ extern const unsigned int sieve_opcode_count;
 
 /* Operand: argument to and opcode */
 struct sieve_operand {
+	/* Code generator */
+	bool (*emit)(struct sieve_generator *generator, struct sieve_ast_argument *arg);
+
+	/* Interpreter */
 	bool (*dump)(struct sieve_interpreter *interpreter);
-	bool (*execute)(struct sieve_interpreter *interpreter);
 };
 
 enum sieve_core_operand {
@@ -47,10 +50,18 @@ enum sieve_core_operand {
   SIEVE_OPERAND_ADDR_PART  
 };
 
+void sieve_operand_number_emit(struct sieve_generator *generator, sieve_size_t number);
+void sieve_operand_string_emit(struct sieve_generator *generator, string_t *str);
+void sieve_operand_stringlist_emit_start
+	(struct sieve_generator *generator, unsigned int listlen, void **context);
+void sieve_operand_stringlist_emit_item
+	(struct sieve_generator *generator, void *context ATTR_UNUSED, string_t *item);
+void sieve_operand_stringlist_emit_end
+	(struct sieve_generator *generator, void *context);
+
 #define SIEVE_OPCODE_CORE_MASK  0x1F
 #define SIEVE_OPCODE_EXT_OFFSET (SIEVE_OPCODE_CORE_MASK + 1)
 
-#define SIEVE_CORE_OPERAND_MASK 0x0F
-#define SIEVE_CORE_OPERAND_BITS 4
+#define SIEVE_OPERAND_CORE_MASK 0x1F
 
 #endif
diff --git a/src/lib-sieve/sieve-commands.c b/src/lib-sieve/sieve-commands.c
index a9959202be63294480963173de3a4594f60e705b..d5030d2dfb04a4e63bb9d48f2942becaedb92ccc 100644
--- a/src/lib-sieve/sieve-commands.c
+++ b/src/lib-sieve/sieve-commands.c
@@ -8,6 +8,100 @@
 #include "sieve-commands-private.h"
 #include "sieve-interpreter.h"
 
+/* Default arguments implemented in this file */
+
+static bool arg_number_generate(struct sieve_generator *generator, struct sieve_ast_argument **arg, 
+	struct sieve_command_context *context);
+static bool arg_string_generate(struct sieve_generator *generator, struct sieve_ast_argument **arg, 
+	struct sieve_command_context *context);
+static bool arg_string_list_generate(struct sieve_generator *generator, struct sieve_ast_argument **arg, 
+	struct sieve_command_context *context);
+
+const struct sieve_argument number_argument =
+	{ "@number", NULL, arg_number_generate };
+const struct sieve_argument string_argument =
+	{ "@string", NULL, arg_string_generate };
+const struct sieve_argument string_list_argument =
+	{ "@string-list", NULL, arg_string_list_generate };	
+
+static bool arg_number_generate(struct sieve_generator *generator, struct sieve_ast_argument **arg, 
+	struct sieve_command_context *context ATTR_UNUSED)
+{
+	if ( sieve_ast_argument_type(*arg) != SAAT_NUMBER ) {
+		return FALSE;
+	}
+	
+	sieve_operand_number_emit(generator, sieve_ast_argument_number(*arg));
+
+	*arg = sieve_ast_argument_next(*arg);
+
+  return TRUE;
+}
+
+static bool arg_string_generate(struct sieve_generator *generator, struct sieve_ast_argument **arg, 
+	struct sieve_command_context *context ATTR_UNUSED)
+{
+  if ( sieve_ast_argument_type(*arg) != SAAT_STRING ) {
+		return FALSE;
+	} 
+
+	sieve_operand_string_emit(generator, sieve_ast_argument_str(*arg));
+  
+  *arg = sieve_ast_argument_next(*arg);
+  return TRUE;
+}
+
+static void emit_string_list_operand
+	(struct sieve_generator *generator, const struct sieve_ast_argument *strlist)
+{
+	void *list_context;
+  const struct sieve_ast_argument *stritem;
+  
+  t_push();
+  
+  printf("STRLIST: %d\n", sieve_ast_strlist_count(strlist));
+	sieve_operand_stringlist_emit_start
+		(generator, sieve_ast_strlist_count(strlist), &list_context);
+
+	stritem = sieve_ast_strlist_first(strlist);
+	while ( stritem != NULL ) {
+		sieve_operand_stringlist_emit_item
+			(generator, list_context, sieve_ast_strlist_str(stritem));
+		printf("STR: %s\n", sieve_ast_strlist_strc(stritem));
+		stritem = sieve_ast_strlist_next(stritem);
+	}
+
+  sieve_operand_stringlist_emit_end
+		(generator, list_context);
+
+  t_pop();
+}
+
+static bool arg_string_list_generate(struct sieve_generator *generator, struct sieve_ast_argument **arg, 
+	struct sieve_command_context *context ATTR_UNUSED)
+{
+	if ( sieve_ast_argument_type(*arg) == SAAT_STRING ) {
+		
+		sieve_operand_string_emit(generator, sieve_ast_argument_str(*arg));
+		
+		*arg = sieve_ast_argument_next(*arg);
+		return TRUE;
+		
+	} else if ( sieve_ast_argument_type(*arg) == SAAT_STRING_LIST ) {
+
+		if ( sieve_ast_strlist_count(*arg) == 1 ) 
+			sieve_operand_string_emit(generator, 
+				sieve_ast_argument_str(sieve_ast_strlist_first(*arg)));
+		else
+			(void) emit_string_list_operand(generator, *arg);
+		
+		*arg = sieve_ast_argument_next(*arg);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
 /* Trivial commands implemented in this file */
 
 const struct sieve_command sieve_core_tests[] = {
diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h
index 42a9efb557d9d26b9129146366bbf0b1c555044d..128289ba4073ba347840ad92547940b7a7621acb 100644
--- a/src/lib-sieve/sieve-commands.h
+++ b/src/lib-sieve/sieve-commands.h
@@ -1,5 +1,5 @@
-#ifndef __SIEVE_COMMANDS_H__
-#define __SIEVE_COMMANDS_H__
+#ifndef __SIEVE_COMMANDS_H
+#define __SIEVE_COMMANDS_H
 
 #include "lib.h"
 
@@ -8,10 +8,7 @@
 #include "sieve-validator.h"
 #include "sieve-generator.h"
 
-struct sieve_test_context;
-struct sieve_command_context;
-
-/* Command */
+/* Argument */
 
 struct sieve_argument {
 	const char *identifier;
@@ -22,6 +19,12 @@ struct sieve_argument {
 		struct sieve_command_context *context);
 };
 
+extern const struct sieve_argument number_argument;
+extern const struct sieve_argument string_argument;
+extern const struct sieve_argument string_list_argument;
+
+/* Command */
+
 enum sieve_command_type {
 	SCT_COMMAND,
 	SCT_TEST
@@ -63,4 +66,4 @@ const char *sieve_command_type_name(const struct sieve_command *command);
 struct sieve_command_context *sieve_command_prev_context	
 	(struct sieve_command_context *context); 
 
-#endif /* __SIEVE_COMMANDS_H__ */
+#endif /* __SIEVE_COMMANDS_H */
diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c
index 5a58a3650992eecc2628f31dd850217d6702e487..29aa555550d658ffd56f8061d339eac47e10e670 100644
--- a/src/lib-sieve/sieve-generator.c
+++ b/src/lib-sieve/sieve-generator.c
@@ -127,90 +127,22 @@ inline sieve_size_t sieve_generator_emit_integer(struct sieve_generator *generat
   return sieve_binary_emit_integer(generator->binary, integer);
 }
 
-inline static sieve_size_t sieve_generator_emit_string_item(struct sieve_generator *generator, const string_t *str)
+inline sieve_size_t sieve_generator_emit_string(struct sieve_generator *generator, const string_t *str)
 {
   return sieve_binary_emit_string(generator->binary, str);
 }
 
-/* Operand emission */
+/* Emit operands */
 
-sieve_size_t sieve_generator_emit_number(struct sieve_generator *generator, sieve_size_t number)
+sieve_size_t sieve_generator_emit_operand
+	(struct sieve_generator *generator, int operand)
 {
-  sieve_size_t address = sieve_binary_emit_byte(generator->binary, SIEVE_OPERAND_NUMBER);
-  
-  (void) sieve_generator_emit_integer(generator, number);
-
-  return address;
-}
-
-sieve_size_t sieve_generator_emit_string(struct sieve_generator *generator, const string_t *str)
-{
-  sieve_size_t address = sieve_binary_emit_byte(generator->binary, SIEVE_OPERAND_STRING);
-  
-  (void) sieve_generator_emit_string_item(generator, str);
-  
-  return address;
-}
-
-bool sieve_generator_emit_stringlist_argument
-	(struct sieve_generator *generator, struct sieve_ast_argument *arg)
-{
-	if ( sieve_ast_argument_type(arg) == SAAT_STRING ) {
-		(void) sieve_generator_emit_string(generator, sieve_ast_argument_str(arg));
-		return TRUE;
-	} else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) {
-		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;
-	}
+	unsigned char op = operand & SIEVE_OPERAND_CORE_MASK;
 	
-	return FALSE;
-}
-
-bool sieve_generator_emit_string_argument
-	(struct sieve_generator *generator, struct sieve_ast_argument *arg)
-{
-	if ( sieve_ast_argument_type(arg) == SAAT_STRING ) {
-		(void) sieve_generator_emit_string(generator, sieve_ast_argument_str(arg));
-		return TRUE;
-	} 
-	
-	return FALSE;
-}
-
-sieve_size_t sieve_generator_emit_string_list
-	(struct sieve_generator *generator, const struct sieve_ast_argument *strlist)
-{
-	sieve_size_t address;
-  const struct sieve_ast_argument *stritem;
-  unsigned int listlen = sieve_ast_strlist_count(strlist);
-  sieve_size_t end_offset = 0;
-
-	/* Emit byte identifying the type of operand */	  
-  address = sieve_binary_emit_byte(generator->binary, SIEVE_OPERAND_STRING_LIST);
-  
-  /* Give the interpreter an easy way to skip over this string list */
-  end_offset = sieve_generator_emit_offset(generator, 0);
-
-  /* Emit the length of the list */
-  (void) sieve_generator_emit_integer(generator, (int) listlen);
-
-	stritem = sieve_ast_strlist_first(strlist);
-	while ( stritem != NULL ) {
-		(void) sieve_generator_emit_string_item(generator, sieve_ast_strlist_str(stritem));
-		
-		stritem = sieve_ast_strlist_next(stritem);
-	}
-
-  (void) sieve_generator_resolve_offset(generator, end_offset);
-
-  return address;
+	return sieve_binary_emit_byte(generator->binary, op);
 }
 
-/* Emit commands */
+/* Emit opcodes */
 
 sieve_size_t sieve_generator_emit_opcode
 	(struct sieve_generator *generator, int opcode)
@@ -231,19 +163,24 @@ sieve_size_t sieve_generator_emit_ext_opcode
 /* Generator functions */
 
 bool sieve_generate_arguments(struct sieve_generator *generator, 
-	struct sieve_command_context *cmd, struct sieve_ast_argument **arg)
+	struct sieve_command_context *cmd, struct sieve_ast_argument **last_arg)
 {
+	struct sieve_ast_argument *arg = sieve_ast_argument_first(cmd->ast_node);
+	
 	/* Parse all arguments with assigned generator function */
-	while ( *arg != NULL && (*arg)->argument != NULL) {
-		const struct sieve_argument *argument = (*arg)->argument;
+	while ( arg != NULL && arg->argument != NULL) {
+		const struct sieve_argument *argument = arg->argument;
 		
 		/* Call the generation function for the argument */ 
 		if ( argument->generate != NULL ) { 
-			if ( !argument->generate(generator, arg, cmd) ) 
+			if ( !argument->generate(generator, &arg, cmd) ) 
 				return FALSE;
 		} else break;
 	}
 	
+	if ( last_arg != NULL )
+		*last_arg = arg;
+	
 	return TRUE;
 }
 
diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h
index 1ded7072735851a5f5b592b0eba10f2dab30013d..0079b5834ccb87c0b7c19b601322cd3a60004afa 100644
--- a/src/lib-sieve/sieve-generator.h
+++ b/src/lib-sieve/sieve-generator.h
@@ -31,6 +31,8 @@ inline void sieve_generator_update_data
 	(struct sieve_generator *generator, sieve_size_t address, void *data, sieve_size_t size);
 inline sieve_size_t sieve_generator_get_current_address(struct sieve_generator *generator);
 
+sieve_size_t sieve_generator_emit_operand
+	(struct sieve_generator *generator, int operand);
 sieve_size_t sieve_generator_emit_opcode
 	(struct sieve_generator *generator, int opcode);
 sieve_size_t sieve_generator_emit_ext_opcode
@@ -45,21 +47,9 @@ inline void sieve_generator_resolve_offset(struct sieve_generator *generator, si
 
 inline sieve_size_t sieve_generator_emit_integer
 	(struct sieve_generator *generator, sieve_size_t integer);
-	
-/* Operand emission */
-	
-sieve_size_t sieve_generator_emit_number
-	(struct sieve_generator *generator, sieve_size_t number);
-sieve_size_t sieve_generator_emit_string
+inline sieve_size_t sieve_generator_emit_string
 	(struct sieve_generator *generator, const string_t *str);
-sieve_size_t sieve_generator_emit_string_list
-	(struct sieve_generator *generator, const struct sieve_ast_argument *strlist);
 	
-bool sieve_generator_emit_string_argument
-	(struct sieve_generator *generator, struct sieve_ast_argument *arg);
-bool sieve_generator_emit_stringlist_argument
-	(struct sieve_generator *generator, struct sieve_ast_argument *arg);
-
 /* AST generation API */
 bool sieve_generate_arguments(struct sieve_generator *generator, 
 	struct sieve_command_context *cmd, struct sieve_ast_argument **arg);
diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c
index a1702edfb7008d77dd714b8edf08772147dc6913..771dcadccfc9af0ec9e04235284bc15bf35c1272 100644
--- a/src/lib-sieve/sieve-interpreter.c
+++ b/src/lib-sieve/sieve-interpreter.c
@@ -472,7 +472,7 @@ bool sieve_interpreter_dump_operand
 	printf("%08x:   ", interpreter->pc);
   CODE_JUMP(interpreter, 1);
   
-  if ( opcode < SIEVE_CORE_OPERAND_MASK ) {  	
+  if ( opcode < SIEVE_OPERAND_CORE_MASK ) {  	
     switch (opcode) {
     case SIEVE_OPERAND_NUMBER:
     	sieve_interpreter_dump_number(interpreter);
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index 22b501d8cbec549fe9cd0064b5a399bcd1458cfe..51e8ef50f158b75f5c97627c7de648e37e45a436 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -269,15 +269,12 @@ static bool sieve_validate_match_type_tag
 	struct sieve_ast_argument **arg, 
 	struct sieve_command_context *cmd ATTR_UNUSED)
 {
-	/* Skip tag */
-	*arg = sieve_ast_argument_next(*arg);
-
-
 	/* Syntax:   
 	 *   ":is" / ":contains" / ":matches"
    */
-
-	/* FIXME: Set appropriate setting somewhere */
+	
+	/* Not implemented, so delete it */
+	*arg = sieve_ast_arguments_delete(*arg, 1);
 		
 	return TRUE;
 }
@@ -304,15 +301,13 @@ static bool sieve_validate_address_part_tag
 	struct sieve_ast_argument **arg, 
 	struct sieve_command_context *cmd ATTR_UNUSED)
 {
-	/* Skip argument */
-	*arg = sieve_ast_argument_next(*arg);
-
 	/* Syntax:   
 	 *   ":localpart" / ":domain" / ":all"
    */
 
-	/* FIXME: Set appropriate setting somewhere */
-		
+	/* Not implemented, so delete it */
+	*arg = sieve_ast_arguments_delete(*arg, 1);		
+
 	return TRUE;
 }
 
@@ -421,6 +416,27 @@ bool sieve_validate_command_arguments
 
 	return TRUE;
 }
+
+void sieve_validator_argument_activate
+	(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast_argument *arg)
+{
+	switch ( sieve_ast_argument_type(arg) ) {
+	case SAAT_NUMBER:
+		arg->argument = &number_argument;
+		break;
+	case SAAT_STRING:
+		arg->argument = &string_argument;
+		break;
+	case SAAT_STRING_LIST:
+		arg->argument = &string_list_argument;
+		break;
+	case SAAT_TAG:
+		i_error("!!BUG!!: sieve_validator_argument_activate: cannot activate tagged argument.");
+		break;
+	default:
+		break;
+	}
+}
  
 /* Command Validation API */ 
                  
diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h
index 9ee059aeec58e538e9ad2888e30b6088486c9a9b..e3aaf3b80904013d9fd2329ba807a0e11d9fab94 100644
--- a/src/lib-sieve/sieve-validator.h
+++ b/src/lib-sieve/sieve-validator.h
@@ -45,10 +45,14 @@ void sieve_validator_link_match_type_tags
 void sieve_validator_link_address_part_tags
 	(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); 
 
-/* Command validation */
+/* Argument validation */
 bool sieve_validate_command_arguments
 	(struct sieve_validator *validator, struct sieve_command_context *tst, 
 	 const unsigned int count, struct sieve_ast_argument **first_positional);
+void sieve_validator_argument_activate
+	(struct sieve_validator *validator, struct sieve_ast_argument *arg);	 
+
+/* Command validation */	 
 bool sieve_validate_command_subtests
 	(struct sieve_validator *validator, struct sieve_command_context *cmd, const unsigned int count);
 bool sieve_validate_command_block(struct sieve_validator *validator, struct sieve_command_context *cmd, 
diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c
index ed849e8a69e7515732607fd3de472a5fb4da2082..e7957f50612feeb63c02e0da957b260568160851 100644
--- a/src/lib-sieve/tst-address.c
+++ b/src/lib-sieve/tst-address.c
@@ -48,6 +48,7 @@ bool tst_address_validate(struct sieve_validator *validator, struct sieve_comman
 			sieve_ast_argument_name(arg));
 		return FALSE; 
 	}
+	sieve_validator_argument_activate(validator, arg);
 	
 	arg = sieve_ast_argument_next(arg);
 	if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) {
@@ -56,6 +57,7 @@ bool tst_address_validate(struct sieve_validator *validator, struct sieve_comman
 			sieve_ast_argument_name(arg));
 		return FALSE; 
 	}
+	sieve_validator_argument_activate(validator, arg);
 	
 	return TRUE;
 }
@@ -64,18 +66,12 @@ bool tst_address_validate(struct sieve_validator *validator, struct sieve_comman
 
 bool tst_address_generate
 	(struct sieve_generator *generator, 
-		struct sieve_command_context *ctx ATTR_UNUSED) 
+		struct sieve_command_context *ctx) 
 {
-	struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data;
 	sieve_generator_emit_opcode(generator, SIEVE_OPCODE_ADDRESS);
 	
-	/* Emit header names */  	
-	if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) 
-		return FALSE;
-	
-	/* Emit key list */
-	arg = sieve_ast_argument_next(arg);
-	if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) 
+	/* Generate arguments */  	
+	if ( !sieve_generate_arguments(generator, ctx, NULL) )
 		return FALSE;
 	
 	return TRUE;
diff --git a/src/lib-sieve/tst-exists.c b/src/lib-sieve/tst-exists.c
index 30f8b25f6b76a2d5ce7ca2dcc896c60304a82421..1d08e7081bec467e08a97fc794fc98d0967d72eb 100644
--- a/src/lib-sieve/tst-exists.c
+++ b/src/lib-sieve/tst-exists.c
@@ -34,6 +34,7 @@ bool tst_exists_validate(struct sieve_validator *validator, struct sieve_command
 			sieve_ast_argument_name(arg));
 		return FALSE; 
 	}
+	sieve_validator_argument_activate(validator, arg);
 	
 	tst->data = arg;
 	
@@ -46,12 +47,11 @@ bool tst_exists_generate
 	(struct sieve_generator *generator, 
 		struct sieve_command_context *ctx) 
 {
-	struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data;
 	sieve_generator_emit_opcode(generator, SIEVE_OPCODE_EXISTS);
-	
-	/* Emit header names */
-	if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) 
-		return FALSE;
+
+ 	/* Generate arguments */
+    if ( !sieve_generate_arguments(generator, ctx, NULL) )
+        return FALSE;	
 	
 	return TRUE;
 }
diff --git a/src/lib-sieve/tst-header.c b/src/lib-sieve/tst-header.c
index 3c29357a64a6794c45de1cecbe2577d51e4ba566..164e958a99472fd2de49019c5e04e11a3f552229 100644
--- a/src/lib-sieve/tst-header.c
+++ b/src/lib-sieve/tst-header.c
@@ -39,14 +39,13 @@ bool tst_header_validate(struct sieve_validator *validator, struct sieve_command
 		!sieve_validate_command_subtests(validator, tst, 0) ) 
 		return FALSE;
 	
-	tst->data = arg;
-		
 	if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) {
 		sieve_command_validate_error(validator, tst, 
 			"the header test expects a string-list as first argument (header names), but %s was found", 
 			sieve_ast_argument_name(arg));
 		return FALSE; 
 	}
+	sieve_validator_argument_activate(validator, arg);
 	
 	arg = sieve_ast_argument_next(arg);
 	if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) {
@@ -55,6 +54,7 @@ bool tst_header_validate(struct sieve_validator *validator, struct sieve_command
 			sieve_ast_argument_name(arg));
 		return FALSE; 
 	}
+	sieve_validator_argument_activate(validator, arg);
 	
 	return TRUE;
 }
@@ -64,18 +64,12 @@ bool tst_header_validate(struct sieve_validator *validator, struct sieve_command
 bool tst_header_generate
 	(struct sieve_generator *generator,	struct sieve_command_context *ctx) 
 {
-	struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data;
 	sieve_generator_emit_opcode(generator, SIEVE_OPCODE_HEADER);
 
-	/* Emit header names */  	
-	if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) 
-		return FALSE;
+ 	/* Generate arguments */
+    if ( !sieve_generate_arguments(generator, ctx, NULL) )
+        return FALSE;
 	
-	/* Emit key list */
-	arg = sieve_ast_argument_next(arg);
-	if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) 
-		return FALSE;
-
 	return TRUE;
 }
 
diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c
index 4a1bb828825bcd79879ba8afb0ad15c5ef253953..4af67cb9864ed9a701110958b083669c3c5fe63a 100644
--- a/src/lib-sieve/tst-size.c
+++ b/src/lib-sieve/tst-size.c
@@ -116,6 +116,7 @@ bool tst_size_validate(struct sieve_validator *validator, struct sieve_command_c
 			sieve_ast_argument_name(arg));
 		return FALSE; 
 	}
+	sieve_validator_argument_activate(validator, arg);
 	
 	return TRUE;
 }
@@ -126,7 +127,6 @@ bool tst_size_generate
 	(struct sieve_generator *generator, 
 		struct sieve_command_context *ctx) 
 {
-	struct sieve_ast_argument *arg = sieve_ast_argument_first(ctx->ast_node);
 	struct tst_size_context_data *ctx_data = (struct tst_size_context_data *) ctx->data;
 
 	if ( ctx_data->type == SIZE_OVER ) 
@@ -134,7 +134,9 @@ bool tst_size_generate
 	else
 		sieve_generator_emit_opcode(generator, SIEVE_OPCODE_SIZEUNDER);
 
-	sieve_generator_emit_number(generator, sieve_ast_argument_number(arg));
+ 	/* Generate arguments */
+    if ( !sieve_generate_arguments(generator, ctx, NULL) )
+        return FALSE;
 	  
 	return TRUE;
 }