diff --git a/TODO b/TODO
index 53f6f693c8b11f8c4be0be1eb8b0209ff8132c2e..199916f6561ba2aad7c57d291f1882a2737848ef 100644
--- a/TODO
+++ b/TODO
@@ -9,8 +9,6 @@ Next (in order of descending priority/precedence):
 
 * Improve error handling. Now it is not very consistent, especially for the sieve
   command line tools and multiscript. 
-* Imapflags: merge execution of setflags, removeflags and addflags into one 
-  common implementation. 
 * Implement dropping errors in the user's mailbox as a mail message.
 * Fix remaining RFC deviations:
 	- Fix issues listed in doc/rfc/RFC-questions.txt based on answers
diff --git a/src/lib-sieve/plugins/imapflags/Makefile.am b/src/lib-sieve/plugins/imapflags/Makefile.am
index eee48e7a29be481d8d98c750018631505a3e6ad8..0ac8bb48b6db5f490878459324107b57cdc32ade 100644
--- a/src/lib-sieve/plugins/imapflags/Makefile.am
+++ b/src/lib-sieve/plugins/imapflags/Makefile.am
@@ -8,12 +8,10 @@ AM_CPPFLAGS = \
 	-I$(dovecot_incdir)/src/lib-mail \
 	-I$(dovecot_incdir)/src/lib-storage 
 
-cmds = \
-	cmd-setflag.c \
-	cmd-addflag.c \
-	cmd-removeflag.c 
+commands = \
+	cmd-flag.c
 
-tsts = \
+tests = \
 	tst-hasflag.c
 
 tags = \
@@ -21,8 +19,8 @@ tags = \
 
 libsieve_ext_imapflags_la_SOURCES = \
 	ext-imapflags-common.c \
-	$(cmds) \
-	$(tsts) \
+	$(commands) \
+	$(tests) \
 	$(tags) \
 	ext-imapflags.c
 
diff --git a/src/lib-sieve/plugins/imapflags/cmd-addflag.c b/src/lib-sieve/plugins/imapflags/cmd-addflag.c
deleted file mode 100644
index fada6c57aab96b0f13eefbffa887d866c4a05995..0000000000000000000000000000000000000000
--- a/src/lib-sieve/plugins/imapflags/cmd-addflag.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
- */
-
-#include "lib.h"
-
-#include "sieve-commands.h"
-#include "sieve-code.h"
-#include "sieve-validator.h" 
-#include "sieve-generator.h"
-#include "sieve-interpreter.h"
-
-#include "ext-imapflags-common.h"
-
-/* 
- * Addflag command 
- *
- * Syntax:
- *   addflag [<variablename: string>] <list-of-flags: string-list>
- */
-
-static bool cmd_addflag_generate
-	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
-  
-const struct sieve_command cmd_addflag = { 
-	"addflag", 
-	SCT_COMMAND,
-	-1, /* We check positional arguments ourselves */
-	0, FALSE, FALSE, 
-	NULL, NULL,
-	ext_imapflags_command_validate, 
-	cmd_addflag_generate, 
-	NULL 
-};
-
-/* 
- * Addflag operation 
- */
-
-static int cmd_addflag_operation_execute
-	(const struct sieve_operation *op,	
-		const struct sieve_runtime_env *renv, sieve_size_t *address);
-
-const struct sieve_operation addflag_operation = { 
-	"ADDFLAG",
-	&imapflags_extension,
-	EXT_IMAPFLAGS_OPERATION_ADDFLAG,
-	ext_imapflags_command_operation_dump,
-	cmd_addflag_operation_execute
-};
-
-/* 
- * Code generation 
- */
-
-static bool cmd_addflag_generate
-	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
-{
-	sieve_operation_emit_code(cgenv->sbin, &addflag_operation);
-
-	/* Generate arguments */
-	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
-		return FALSE;	
-
-	return TRUE;
-}
-
-/*
- * Execution
- */
-
-static int cmd_addflag_operation_execute
-(const struct sieve_operation *op ATTR_UNUSED,
-	const struct sieve_runtime_env *renv, sieve_size_t *address)
-{
-	bool result = TRUE;
-	string_t *flag_item;
-	struct sieve_coded_stringlist *flag_list;
-	struct sieve_variable_storage *storage;
-	unsigned int var_index;
-	int ret;
-		
-	if ( (ret=ext_imapflags_command_operands_read
-		(renv, address, &flag_list, &storage, &var_index)) <= 0 )
-		return ret;
-
-	sieve_runtime_trace(renv, "ADDFLAG command");
-	
-	/* Iterate through all added flags */	
-	while ( (result=sieve_coded_stringlist_next_item(flag_list, &flag_item)) && 
-		flag_item != NULL ) {
-
-		if ( (ret=ext_imapflags_add_flags(renv, storage, var_index, flag_item)) <= 0 )
-			return ret;
-	}
-
-	if ( !result ) {
-		sieve_runtime_trace_error(renv, "invalid flag-list item");
-		return SIEVE_EXEC_BIN_CORRUPT;
-	}
-
-	return SIEVE_EXEC_OK;
-}
diff --git a/src/lib-sieve/plugins/imapflags/cmd-flag.c b/src/lib-sieve/plugins/imapflags/cmd-flag.c
new file mode 100644
index 0000000000000000000000000000000000000000..8722134f39ac15a7d8b91df9395868edf18291fd
--- /dev/null
+++ b/src/lib-sieve/plugins/imapflags/cmd-flag.c
@@ -0,0 +1,264 @@
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
+ */
+
+#include "lib.h"
+
+#include "sieve-code.h"
+#include "sieve-commands.h"
+#include "sieve-validator.h" 
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+#include "sieve-dump.h"
+
+#include "ext-imapflags-common.h"
+
+/*
+ * Commands
+ */
+
+/* Forward declarations */
+
+static bool cmd_flag_generate
+	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
+
+/* Setflag command 
+ *
+ * Syntax: 
+ *   setflag [<variablename: string>] <list-of-flags: string-list>
+ */
+ 
+const struct sieve_command cmd_setflag = { 
+	"setflag", 
+	SCT_COMMAND,
+	-1, /* We check positional arguments ourselves */
+	0, FALSE, FALSE, 
+	NULL, NULL,
+	ext_imapflags_command_validate, 
+	cmd_flag_generate, 
+	NULL 
+};
+
+/* Addflag command 
+ *
+ * Syntax:
+ *   addflag [<variablename: string>] <list-of-flags: string-list>
+ */
+
+const struct sieve_command cmd_addflag = { 
+	"addflag", 
+	SCT_COMMAND,
+	-1, /* We check positional arguments ourselves */
+	0, FALSE, FALSE, 
+	NULL, NULL,
+	ext_imapflags_command_validate, 
+	cmd_flag_generate, 
+	NULL 
+};
+
+
+/* Removeflag command 
+ *
+ * Syntax:
+ *   removeflag [<variablename: string>] <list-of-flags: string-list>
+ */
+
+const struct sieve_command cmd_removeflag = { 
+	"removeflag", 
+	SCT_COMMAND,
+	-1, /* We check positional arguments ourselves */
+	0, FALSE, FALSE, 
+	NULL, NULL,
+	ext_imapflags_command_validate, 
+	cmd_flag_generate, 
+	NULL 
+};
+
+/*
+ * Operations
+ */
+
+/* Forward declarations */
+
+bool cmd_flag_operation_dump
+	(const struct sieve_operation *op,
+		const struct sieve_dumptime_env *denv, sieve_size_t *address);
+static int cmd_flag_operation_execute
+	(const struct sieve_operation *op,	
+		const struct sieve_runtime_env *renv, sieve_size_t *address);
+
+/* Setflag operation */
+
+const struct sieve_operation setflag_operation = { 
+	"SETFLAG",
+	&imapflags_extension,
+	EXT_IMAPFLAGS_OPERATION_SETFLAG,
+	cmd_flag_operation_dump,
+	cmd_flag_operation_execute
+};
+
+/* Addflag operation */
+
+const struct sieve_operation addflag_operation = { 
+	"ADDFLAG",
+	&imapflags_extension,
+	EXT_IMAPFLAGS_OPERATION_ADDFLAG,
+	cmd_flag_operation_dump,	
+	cmd_flag_operation_execute
+};
+
+/* Removeflag operation */
+
+const struct sieve_operation removeflag_operation = { 
+	"REMOVEFLAG",
+	&imapflags_extension,
+	EXT_IMAPFLAGS_OPERATION_REMOVEFLAG,
+	cmd_flag_operation_dump, 
+	cmd_flag_operation_execute 
+};
+
+/* 
+ * Code generation 
+ */
+
+static bool cmd_flag_generate
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
+{
+	const struct sieve_command *command = ctx->command;
+
+	/* Emit operation */
+	if ( command == &cmd_setflag ) 
+		sieve_operation_emit_code(cgenv->sbin, &setflag_operation);
+	else if ( command == &cmd_addflag ) 
+		sieve_operation_emit_code(cgenv->sbin, &addflag_operation);
+	else if ( command == &cmd_removeflag ) 
+		sieve_operation_emit_code(cgenv->sbin, &removeflag_operation);
+
+	/* Generate arguments */
+	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
+		return FALSE;	
+
+	return TRUE;
+}
+
+/*
+ * Code dump
+ */
+
+bool cmd_flag_operation_dump
+(const struct sieve_operation *op,
+	const struct sieve_dumptime_env *denv, sieve_size_t *address)
+{
+	const struct sieve_operand *operand;
+
+	sieve_code_dumpf(denv, "%s", op->mnemonic);
+	sieve_code_descend(denv);
+	
+	sieve_code_mark(denv);
+	operand = sieve_operand_read(denv->sbin, address);
+
+	if ( sieve_operand_is_variable(operand) ) {	
+		return 
+			sieve_opr_string_dump_data(denv, operand, address, 
+				"variable name") &&
+			sieve_opr_stringlist_dump(denv, address, 
+				"list of flags");
+	}
+	
+	return 
+		sieve_opr_stringlist_dump_data(denv, operand, address,
+			"list of flags");
+}
+ 
+/*
+ * Code execution
+ */
+
+static int cmd_flag_operation_execute
+(const struct sieve_operation *op,
+	const struct sieve_runtime_env *renv, sieve_size_t *address)
+{
+	const struct sieve_operand *operand;
+	sieve_size_t op_address = *address;
+	bool result = TRUE;
+	string_t *flag_item;
+	struct sieve_coded_stringlist *flag_list;
+	struct sieve_variable_storage *storage;
+	unsigned int var_index;
+	ext_imapflag_flag_operation_t flag_op;
+	int ret;
+		
+	/* 
+	 * Read operands 
+	 */
+
+	operand = sieve_operand_read(renv->sbin, address);
+	if ( operand == NULL ) {
+		sieve_runtime_trace_error(renv, "invalid operand");
+		return SIEVE_EXEC_BIN_CORRUPT;
+	}
+		
+	if ( sieve_operand_is_variable(operand) ) {		
+
+		/* Read the variable operand */
+		if ( !sieve_variable_operand_read_data
+			(renv, operand, address, &storage, &var_index) ) {
+			sieve_runtime_trace_error(renv, "invalid variable operand");
+			return SIEVE_EXEC_BIN_CORRUPT;
+		}
+		
+		/* Read flag list */
+		if ( (flag_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
+			sieve_runtime_trace_error(renv, "invalid flag-list operand");
+			return SIEVE_EXEC_BIN_CORRUPT;
+		}
+
+	} else if ( sieve_operand_is_stringlist(operand) ) {	
+		storage = NULL;
+		var_index = 0;
+		
+		/* Read flag list */
+		if ( (flag_list=sieve_opr_stringlist_read_data
+			(renv, operand, op_address, address)) == NULL ) {
+			sieve_runtime_trace_error(renv, "invalid flag-list operand");
+			return SIEVE_EXEC_BIN_CORRUPT;
+		}
+
+	} else {
+		sieve_runtime_trace_error(renv, "unexpected operand '%s'", 
+			operand->name);
+		return SIEVE_EXEC_BIN_CORRUPT;
+	}
+	
+	/*
+	 * Perform operation
+	 */	
+	
+	sieve_runtime_trace(renv, "%s command", op->mnemonic);
+
+	/* Determine what to do */
+
+	if ( op == &setflag_operation )
+		flag_op = ext_imapflags_set_flags;
+	else if ( op == &addflag_operation )
+		flag_op = ext_imapflags_add_flags;
+	else if ( op == &removeflag_operation )
+		flag_op = ext_imapflags_remove_flags;
+	else
+		i_unreached();
+
+	/* Iterate through all flags and perform requested operation */
+	
+	while ( (result=sieve_coded_stringlist_next_item(flag_list, &flag_item)) && 
+		flag_item != NULL ) {
+
+		if ( (ret=flag_op(renv, storage, var_index, flag_item)) <= 0)
+			return ret;
+	}
+
+	if ( !result ) {	
+		sieve_runtime_trace_error(renv, "invalid flag-list item");
+		return SIEVE_EXEC_BIN_CORRUPT;
+	}
+
+	return SIEVE_EXEC_OK;
+}
diff --git a/src/lib-sieve/plugins/imapflags/cmd-removeflag.c b/src/lib-sieve/plugins/imapflags/cmd-removeflag.c
deleted file mode 100644
index 65d0c74b69a10f7f23c89e7fd2874ca90603a503..0000000000000000000000000000000000000000
--- a/src/lib-sieve/plugins/imapflags/cmd-removeflag.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
- */
-
-#include "lib.h"
-
-#include "sieve-code.h"
-#include "sieve-commands.h"
-#include "sieve-validator.h" 
-#include "sieve-generator.h"
-#include "sieve-interpreter.h"
-
-#include "ext-imapflags-common.h"
-
-/* 
- * Removeflag command 
- *
- * Syntax:
- *   removeflag [<variablename: string>] <list-of-flags: string-list>
- */
-
-static bool cmd_removeflag_generate
-	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
- 
-const struct sieve_command cmd_removeflag = { 
-	"removeflag", 
-	SCT_COMMAND,
-	-1, /* We check positional arguments ourselves */
-	0, FALSE, FALSE, 
-	NULL, NULL,
-	ext_imapflags_command_validate, 
-	cmd_removeflag_generate, 
-	NULL 
-};
-
-/* 
- * Removeflag operation 
- */
-
-static int cmd_removeflag_operation_execute
-	(const struct sieve_operation *op,	
-		const struct sieve_runtime_env *renv, sieve_size_t *address);
-
-const struct sieve_operation removeflag_operation = { 
-	"REMOVEFLAG",
-	&imapflags_extension,
-	EXT_IMAPFLAGS_OPERATION_REMOVEFLAG,
-	ext_imapflags_command_operation_dump, 
-	cmd_removeflag_operation_execute 
-};
-
-/* 
- * Code generation 
- */
-
-static bool cmd_removeflag_generate
-(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
-{
-	sieve_operation_emit_code(cgenv->sbin, &removeflag_operation);
-
-	/* Generate arguments */
-	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
-		return FALSE;	
-
-	return TRUE;
-}
- 
-/*
- * Execution
- */
-
-static int cmd_removeflag_operation_execute
-(const struct sieve_operation *op ATTR_UNUSED,
-	const struct sieve_runtime_env *renv, sieve_size_t *address)
-{
-	bool result = TRUE;
-	string_t *flag_item;
-	struct sieve_coded_stringlist *flag_list;
-	struct sieve_variable_storage *storage;
-	unsigned int var_index;
-	int ret;
-		
-	if ( (ret=ext_imapflags_command_operands_read
-		(renv, address, &flag_list, &storage, &var_index)) <= 0 )
-		return ret;
-	
-	sieve_runtime_trace(renv, "REMOVEFLAG command");
-
-	/* Iterate through all flags to remove */
-	while ( (result=sieve_coded_stringlist_next_item(flag_list, &flag_item)) && 
-		flag_item != NULL ) {
-
-		if ( (ret=ext_imapflags_remove_flags(renv, storage, var_index, flag_item)) <= 0)
-			return ret;
-	}
-
-	if ( !result ) {	
-		sieve_runtime_trace_error(renv, "invalid flag-list item");
-		return SIEVE_EXEC_BIN_CORRUPT;
-	}
-
-	return SIEVE_EXEC_OK;
-}
diff --git a/src/lib-sieve/plugins/imapflags/cmd-setflag.c b/src/lib-sieve/plugins/imapflags/cmd-setflag.c
deleted file mode 100644
index fb50cb03ad9a58855d8a75e094fa85e2ab07f817..0000000000000000000000000000000000000000
--- a/src/lib-sieve/plugins/imapflags/cmd-setflag.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
- */
-
-#include "lib.h"
-
-#include "sieve-commands.h"
-#include "sieve-code.h"
-#include "sieve-validator.h" 
-#include "sieve-generator.h"
-#include "sieve-interpreter.h"
-
-#include "ext-imapflags-common.h"
-
-/* 
- * Setflag command 
- *
- * Syntax: 
- *   setflag [<variablename: string>] <list-of-flags: string-list>
- */
-
-static bool cmd_setflag_generate
-	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
- 
-const struct sieve_command cmd_setflag = { 
-	"setflag", 
-	SCT_COMMAND,
-	-1, /* We check positional arguments ourselves */
-	0, FALSE, FALSE, 
-	NULL, NULL,
-	ext_imapflags_command_validate, 
-	cmd_setflag_generate, 
-	NULL 
-};
-
-/* 
- * Setflag operation 
- */
-
-static int cmd_setflag_operation_execute
-	(const struct sieve_operation *op,
-		const struct sieve_runtime_env *renv, sieve_size_t *address);
-
-const struct sieve_operation setflag_operation = { 
-	"SETFLAG",
-	&imapflags_extension,
-	EXT_IMAPFLAGS_OPERATION_SETFLAG,
-	ext_imapflags_command_operation_dump,
-	cmd_setflag_operation_execute
-};
-
-/* 
- * Code generation 
- */
-
-static bool cmd_setflag_generate
-(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
-{
-	sieve_operation_emit_code(cgenv->sbin, &setflag_operation);
-
-	/* Generate arguments */
-	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
-		return FALSE;	
-
-	return TRUE;
-}
-
-/*
- * Execution
- */
-
-static int cmd_setflag_operation_execute
-(const struct sieve_operation *op ATTR_UNUSED,
-	const struct sieve_runtime_env *renv, sieve_size_t *address)
-{
-	bool result = TRUE;
-	string_t *flag_item;
-	struct sieve_coded_stringlist *flag_list;
-	struct sieve_variable_storage *storage;
-	unsigned int var_index;
-	int ret;
-		
-	if ( (ret=ext_imapflags_command_operands_read
-		(renv, address, &flag_list, &storage, &var_index)) <=0 ) 
-		return ret;
-
-	sieve_runtime_trace(renv, "SETFLAG command");
-			
-	/* Iterate through all flags to set */
-	while ( (result=sieve_coded_stringlist_next_item(flag_list, &flag_item)) && 
-		flag_item != NULL ) {
-
-		if ( (ret=ext_imapflags_set_flags(renv, storage, var_index, flag_item)) <= 0)
-			return ret;
-	}
-
-	if ( !result ) {
-		sieve_runtime_trace_error(renv, "invalid flag-list item operand");
-		return SIEVE_EXEC_BIN_CORRUPT;
-	}
-
-	return SIEVE_EXEC_OK;
-}
-
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
index 543c3a1b7c2721b9fd33e68866f0a2d8abdaabb8..485f784f343d2cbd87818d9b04ab808012fe5087 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
@@ -138,82 +138,6 @@ bool ext_imapflags_command_validate
 	return TRUE;
 }
 
-bool ext_imapflags_command_operands_dump
-(const struct sieve_dumptime_env *denv, sieve_size_t *address)
-{
-	const struct sieve_operand *operand;
-	
-	sieve_code_mark(denv);
-	operand = sieve_operand_read(denv->sbin, address);
-
-	if ( sieve_operand_is_variable(operand) ) {	
-		return 
-			sieve_opr_string_dump_data(denv, operand, address, 
-				"variable name") &&
-			sieve_opr_stringlist_dump(denv, address, 
-				"list of flags");
-	}
-	
-	return 
-		sieve_opr_stringlist_dump_data(denv, operand, address,
-			"list of flags");
-}
-
-bool ext_imapflags_command_operation_dump
-(const struct sieve_operation *op,
-	const struct sieve_dumptime_env *denv, sieve_size_t *address)
-{
-	sieve_code_dumpf(denv, "%s", op->mnemonic);
-	sieve_code_descend(denv);
-
-	return ext_imapflags_command_operands_dump(denv, address); 
-}
-
-int ext_imapflags_command_operands_read
-(const struct sieve_runtime_env *renv, sieve_size_t *address,
-	struct sieve_coded_stringlist **flag_list, 
-	struct sieve_variable_storage **storage, unsigned int *var_index)
-{
-	sieve_size_t op_address = *address;
-	const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
-
-	if ( operand == NULL ) {
-		sieve_runtime_trace_error(renv, "invalid operand");
-		return SIEVE_EXEC_BIN_CORRUPT;
-	}
-		
-	if ( sieve_operand_is_variable(operand) ) {		
-		/* Read the variable operand */
-		if ( !sieve_variable_operand_read_data
-			(renv, operand, address, storage, var_index) ) {
-			sieve_runtime_trace_error(renv, "invalid variable operand");
-			return SIEVE_EXEC_BIN_CORRUPT;
-		}
-		
-		/* Read flag list */
-		if ( (*flag_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
-			sieve_runtime_trace_error(renv, "invalid flag-list operand");
-			return SIEVE_EXEC_BIN_CORRUPT;
-		}
-	} else if ( sieve_operand_is_stringlist(operand) ) {	
-		*storage = NULL;
-		*var_index = 0;
-		
-		/* Read flag list */
-		if ( (*flag_list=sieve_opr_stringlist_read_data
-			(renv, operand, op_address, address)) == NULL ) {
-			sieve_runtime_trace_error(renv, "invalid flag-list operand");
-			return SIEVE_EXEC_BIN_CORRUPT;
-		}
-	} else {
-		sieve_runtime_trace_error(renv, "unexpected operand '%s'", 
-			operand->name);
-		return SIEVE_EXEC_BIN_CORRUPT;
-	}
-	
-	return SIEVE_EXEC_OK;
-}
-
 /* 
  * Flags tag registration 
  */
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h
index 9b1f256215454c9b862504a0f33fb60f17aada2a..8812dfc6166aa014bf42bc03ad0e00e3cfff868a 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h
@@ -62,17 +62,6 @@ extern const struct sieve_command tst_hasflag;
 bool ext_imapflags_command_validate
 	(struct sieve_validator *validator, struct sieve_command_context *cmd);
 
-bool ext_imapflags_command_operands_dump
-(const struct sieve_dumptime_env *denv, sieve_size_t *address);
-bool ext_imapflags_command_operation_dump
-(const struct sieve_operation *op,	
-	const struct sieve_dumptime_env *denv, sieve_size_t *address);
-	
-int ext_imapflags_command_operands_read
-(	const struct sieve_runtime_env *renv, sieve_size_t *address,
-	struct sieve_coded_stringlist **flag_list, 
-	struct sieve_variable_storage **storage, unsigned int *var_index);
-
 /*
  * Flags tagged argument
  */	
@@ -96,6 +85,10 @@ void ext_imapflags_iter_init
 const char *ext_imapflags_iter_get_flag
 	(struct ext_imapflags_iter *iter);
 
+typedef int (*ext_imapflag_flag_operation_t)
+	(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
+		unsigned int var_index, string_t *flags);
+
 int ext_imapflags_set_flags
 	(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
 		unsigned int var_index, string_t *flags);