diff --git a/Makefile.am b/Makefile.am
index e34e744240c3386579cb568d48ea8d63f2915e53..b9d38a6a2171590f0942e4dbcfb928762984fd44 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -57,6 +57,7 @@ test_cases = \
 	tests/extensions/include/variables.svtest \
 	tests/extensions/imap4flags/basic.svtest \
 	tests/extensions/imap4flags/hasflag.svtest \
+	tests/extensions/imap4flags/errors.svtest \
 	tests/extensions/imap4flags/execute.svtest \
 	tests/extensions/body/basic.svtest \
 	tests/extensions/body/match-values.svtest \
diff --git a/src/lib-sieve/plugins/imap4flags/Makefile.am b/src/lib-sieve/plugins/imap4flags/Makefile.am
index e3af73faf7ec05c4e35af576dc602dc4fcbbea4e..1f8bbad6c65e0e145cbb7980aee4e4262bac3693 100644
--- a/src/lib-sieve/plugins/imap4flags/Makefile.am
+++ b/src/lib-sieve/plugins/imap4flags/Makefile.am
@@ -22,7 +22,9 @@ libsieve_ext_imap4flags_la_SOURCES = \
 	$(commands) \
 	$(tests) \
 	$(tags) \
-	ext-imap4flags.c
+	ext-imap4flags.c \
+	ext-imapflags.c
+	
 
 noinst_HEADERS = \
 	ext-imap4flags-common.h
diff --git a/src/lib-sieve/plugins/imap4flags/ext-imapflags.c b/src/lib-sieve/plugins/imap4flags/ext-imapflags.c
new file mode 100644
index 0000000000000000000000000000000000000000..5023aef4f2aa996a815ef63d7cf06e7526c001f8
--- /dev/null
+++ b/src/lib-sieve/plugins/imap4flags/ext-imapflags.c
@@ -0,0 +1,175 @@
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
+ */
+
+/* Extension imapflags
+ * --------------------
+ *
+ * Authors: Stephan Bosch
+ * Specification: draft-melnikov-sieve-imapflags-03.txt
+ * Implementation: depricated; provided for backwards compatibility
+ * Status: depricated
+ *
+ */
+ 
+#include "lib.h"
+#include "mempool.h"
+#include "str.h"
+
+#include "sieve-common.h"
+
+#include "sieve-ast.h"
+#include "sieve-code.h"
+#include "sieve-extensions.h"
+#include "sieve-actions.h"
+#include "sieve-commands.h"
+#include "sieve-validator.h"
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+
+#include "ext-imap4flags-common.h"
+
+/*
+ * Commands
+ */
+
+static bool cmd_mark_validate
+	(struct sieve_validator *valdtr, struct sieve_command_context *cmd);
+
+/* Mark command
+ *
+ * Syntax:
+ *   mark
+ */
+
+static const struct sieve_command cmd_mark = {
+    "mark",
+    SCT_COMMAND,
+    0, 0, FALSE, FALSE,
+    NULL, NULL,
+    cmd_mark_validate,
+    NULL, NULL,
+};
+
+/* Unmark command
+ *
+ * Syntax:
+ *   unmark
+ */
+static const struct sieve_command cmd_unmark = {
+    "unmark",
+    SCT_COMMAND,
+    0, 0, FALSE, FALSE,
+    NULL, NULL,
+    cmd_mark_validate,
+    NULL, NULL,
+};
+
+/* 
+ * Extension
+ */
+
+static bool ext_imapflags_load(void);
+static bool ext_imapflags_validator_load(struct sieve_validator *valdtr);
+static bool ext_imapflags_interpreter_load
+	(const struct sieve_runtime_env *renv, sieve_size_t *address);
+
+int ext_imapflags_my_id = -1;
+
+const struct sieve_extension imapflags_extension = { 
+	"imapflags", 
+	&ext_imapflags_my_id,
+	ext_imapflags_load, 
+	NULL,
+	ext_imapflags_validator_load, 
+	NULL,
+	ext_imapflags_interpreter_load, 
+	NULL, NULL, NULL,
+	SIEVE_EXT_DEFINE_NO_OPERATIONS, 
+	SIEVE_EXT_DEFINE_NO_OPERANDS
+};
+
+static bool ext_imapflags_load(void)
+{
+	/* Make sure real extension is registered, it is needed by the binary */
+	(void)sieve_extension_require(&imap4flags_extension);
+
+	return TRUE;
+}
+
+/*
+ * Validator
+ */
+
+static bool ext_imapflags_validator_extension_validate
+	(struct sieve_validator *valdtr, void *context, struct sieve_ast_argument *require_arg);
+
+const struct sieve_validator_extension imapflags_validator_extension = {
+	&imapflags_extension,
+	ext_imapflags_validator_extension_validate,
+	NULL
+};
+
+static bool ext_imapflags_validator_load
+(struct sieve_validator *valdtr)
+{
+	sieve_validator_extension_register
+	    (valdtr, &imapflags_validator_extension, NULL);
+
+	/* Register commands */
+	sieve_validator_register_command(valdtr, &cmd_setflag);
+	sieve_validator_register_command(valdtr, &cmd_addflag);
+	sieve_validator_register_command(valdtr, &cmd_removeflag);
+
+	sieve_validator_register_command(valdtr, &cmd_mark);
+	sieve_validator_register_command(valdtr, &cmd_unmark);	
+	
+	return TRUE;
+}
+
+static bool ext_imapflags_validator_extension_validate
+(struct sieve_validator *valdtr, void *context ATTR_UNUSED, 
+	struct sieve_ast_argument *require_arg)
+{
+	if ( sieve_validator_extension_loaded(valdtr, &imap4flags_extension) ) {
+		sieve_argument_validate_error(valdtr, require_arg,
+			"the (depricated) imapflags extension cannot be used "
+			"together with the imap4flags extension");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/*
+ * Interpreter
+ */
+
+static bool ext_imapflags_interpreter_load
+(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED)
+{
+    sieve_interpreter_extension_register
+        (renv->interp, &imap4flags_interpreter_extension, NULL);
+
+    return TRUE;
+}
+
+/*
+ * Command validation
+ */ 
+
+static bool cmd_mark_validate
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd)
+{
+	if ( cmd->command == &cmd_mark )
+		cmd->command = &cmd_addflag;
+	else
+		cmd->command = &cmd_removeflag;
+
+	cmd->first_positional = sieve_ast_argument_cstring_create
+		(cmd->ast_node, "\\flagged", cmd->ast_node->source_line);
+
+	if ( !sieve_validator_argument_activate(valdtr, cmd, cmd->first_positional, FALSE) )
+        return FALSE;	
+		
+	return TRUE;
+}
diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c
index 53b5ad9858966c5613b591600d3c61ff09ccdc2a..2a7cb929b68b7a0c524792391e7916f1e7eb7b41 100644
--- a/src/lib-sieve/sieve-ast.c
+++ b/src/lib-sieve/sieve-ast.c
@@ -493,6 +493,28 @@ struct sieve_ast_argument *sieve_ast_argument_string_create
 	return argument;
 }
 
+struct sieve_ast_argument *sieve_ast_argument_cstring_create
+(struct sieve_ast_node *node, const char *str, unsigned int source_line) 
+{	
+	struct sieve_ast_argument *argument;
+	string_t *newstr;
+	
+	/* Allocate new internal string buffer */
+	newstr = str_new(node->ast->pool, strlen(str));
+	
+	/* Clone string */
+	str_append(newstr, str);
+	 
+	/* Create string argument */
+	argument = sieve_ast_argument_string_create_raw
+		(node->ast, newstr, source_line);
+
+	/* Add argument to command/test node */
+	sieve_ast_node_add_argument(node, argument);
+
+	return argument;
+}
+
 void sieve_ast_argument_string_set
 (struct sieve_ast_argument *argument, string_t *newstr)
 {
diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h
index 3109fab6d69c177a54ff4a63e21667ace4150fb4..77567a2410206dbed1dd2634c29b03e18a12113c 100644
--- a/src/lib-sieve/sieve-ast.h
+++ b/src/lib-sieve/sieve-ast.h
@@ -237,6 +237,8 @@ struct sieve_ast_argument *sieve_ast_argument_string_create_raw
 	(struct sieve_ast *ast, string_t *str, unsigned int source_line);
 struct sieve_ast_argument *sieve_ast_argument_string_create
 	(struct sieve_ast_node *node, const string_t *str, unsigned int source_line);
+struct sieve_ast_argument *sieve_ast_argument_cstring_create
+	(struct sieve_ast_node *node, const char *str, unsigned int source_line);
 	
 struct sieve_ast_argument *sieve_ast_argument_tag_create
 	(struct sieve_ast_node *node, const char *tag, unsigned int source_line);
diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c
index d5441ea3ce4b9be412e62eaa55dee00bcf893ce6..e26f4013dbe6efb3cf57b0ad6666042446f9c5b4 100644
--- a/src/lib-sieve/sieve-extensions.c
+++ b/src/lib-sieve/sieve-extensions.c
@@ -114,6 +114,20 @@ const struct sieve_extension *sieve_core_extensions[] = {
 const unsigned int sieve_core_extensions_count =
 	N_ELEMENTS(sieve_core_extensions);
 
+/*
+ * Depricated extensions
+ */
+
+extern const struct sieve_extension imapflags_extension;
+
+const struct sieve_extension *sieve_depricated_extensions[] = {
+	/* Depricated extensions */
+	&imapflags_extension
+};
+
+const unsigned int sieve_depricated_extensions_count =
+	N_ELEMENTS(sieve_depricated_extensions);
+
 /* 
  * Extensions init/deinit
  */
@@ -127,7 +141,12 @@ bool sieve_extensions_init(void)
 	
 	/* Pre-load core extensions */
 	for ( i = 0; i < sieve_core_extensions_count; i++ ) {
-		(void) sieve_extension_register(sieve_core_extensions[i]);
+		(void)sieve_extension_register(sieve_core_extensions[i], TRUE);
+	}
+
+	/* Pre-load core extensions */
+	for ( i = 0; i < sieve_depricated_extensions_count; i++ ) {
+		(void)sieve_extension_register(sieve_depricated_extensions[i], TRUE);
 	}
 	
 	/* More extensions can be added through plugins */
@@ -149,6 +168,7 @@ struct sieve_extension_registration {
 	const struct sieve_extension *extension;
 	int id;
 	bool required;
+	bool loaded;
 };
 
 static ARRAY_DEFINE(extensions, struct sieve_extension_registration); 
@@ -161,8 +181,21 @@ static void sieve_extensions_init_registry(void)
 		(default_pool, default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp);
 }
 
-static struct sieve_extension_registration *_sieve_extension_register
+static bool _sieve_extension_load
 (const struct sieve_extension *extension)
+{
+	/* Call load handler */
+	if ( extension->load != NULL && !extension->load() ) {
+		sieve_sys_error("failed to load '%s' extension support.", 
+			extension->name);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static struct sieve_extension_registration *_sieve_extension_register
+(const struct sieve_extension *extension, bool load)
 {
 	struct sieve_extension_registration *ereg = (struct sieve_extension_registration *)
         hash_table_lookup(extension_index, extension->name);
@@ -181,18 +214,17 @@ static struct sieve_extension_registration *_sieve_extension_register
 
 	/* Enable extension */
 	if ( ereg->extension == NULL && extension != NULL ) {
-		if ( extension->_id != NULL ) {
-			int ext_id = *(extension->_id);
-
+		if ( extension->_id != NULL && load ) {
 			/* Make sure extension is enabled */
 			*(extension->_id) = ereg->id;
 
-			/* Call load handler if extension was not enabled */
-			if ( ext_id == -1 && extension->load != NULL && !extension->load() ) {
-				sieve_sys_error("failed to load '%s' extension support.", 
-					extension->name);
-				return NULL;
+			/* Call load handler if extension was not loaded already */
+			if ( !ereg->loaded ) {
+				if ( !_sieve_extension_load(extension) )
+					return NULL;
 			}
+
+			ereg->loaded = TRUE;
 		}
 
 		ereg->extension = extension;
@@ -201,12 +233,13 @@ static struct sieve_extension_registration *_sieve_extension_register
 	return ereg;
 }
 
-int sieve_extension_register(const struct sieve_extension *extension) 
+int sieve_extension_register
+(const struct sieve_extension *extension, bool load) 
 {
 	struct sieve_extension_registration *ereg;
 
 	/* Register the extension */
-	if ( (ereg=_sieve_extension_register(extension)) == NULL ) {
+	if ( (ereg=_sieve_extension_register(extension, load)) == NULL ) {
 		return -1;
 	}
 
@@ -218,7 +251,7 @@ int sieve_extension_require(const struct sieve_extension *extension)
 	struct sieve_extension_registration *ereg;
 
 	/* Register (possibly unknown) extension */
-    if ( (ereg=_sieve_extension_register(extension)) == NULL ) {
+    if ( (ereg=_sieve_extension_register(extension, TRUE)) == NULL ) {
         return -1;
     }
 
@@ -302,6 +335,25 @@ const char *sieve_extensions_get_string(void)
 	return str_c(extstr);
 }
 
+static void sieve_extension_enable(struct sieve_extension_registration *ereg)
+{
+	if ( ereg->extension->_id != NULL ) {
+		*(ereg->extension->_id) = ereg->id;
+	
+		if ( !ereg->loaded ) {
+			(void)_sieve_extension_load(ereg->extension);
+		}
+	}
+
+	ereg->loaded = TRUE;
+}
+
+static void sieve_extension_disable(struct sieve_extension_registration *ereg)
+{
+	if ( ereg->extension->_id != NULL )
+		*(ereg->extension->_id) = -1;	
+}
+
 void sieve_extensions_set_string(const char *ext_string)
 {
 	ARRAY_DEFINE(enabled_extensions, const struct sieve_extension_registration *);
@@ -315,10 +367,8 @@ void sieve_extensions_set_string(const char *ext_string)
 		/* Enable all */
 		eregs = array_get_modifiable(&extensions, &ext_count);
 		
-		for ( i = 0; i < ext_count; i++ ) {
-			if ( eregs[i].extension->_id != NULL )
-				*(eregs[i].extension->_id) = eregs[i].id;
-		}
+		for ( i = 0; i < ext_count; i++ )
+			sieve_extension_enable(&eregs[i]);
 
 		return;	
 	}
@@ -373,11 +423,10 @@ void sieve_extensions_set_string(const char *ext_string)
 
 		if ( eregs[i].extension->_id != NULL && 
 			*(eregs[i].extension->name) != '@' ) {
-			if ( disabled && !eregs[i].required ) {
-				*(eregs[i].extension->_id) = -1;
-			} else {
-				*(eregs[i].extension->_id) = eregs[i].id;
-			}
+			if ( disabled && !eregs[i].required )
+				sieve_extension_disable(&eregs[i]);
+			else
+				sieve_extension_enable(&eregs[i]);
 		}
 	}
 }
diff --git a/src/lib-sieve/sieve-extensions.h b/src/lib-sieve/sieve-extensions.h
index 7affa072e247d631667527ea1feae64750f469aa..717dfc145f374efe4887c4d0c61d0cb99150c1dc 100644
--- a/src/lib-sieve/sieve-extensions.h
+++ b/src/lib-sieve/sieve-extensions.h
@@ -89,7 +89,7 @@ void sieve_extensions_deinit(void);
  * Extension registry 
  */
 
-int sieve_extension_register(const struct sieve_extension *extension);
+int sieve_extension_register(const struct sieve_extension *extension, bool load);
 int sieve_extension_require(const struct sieve_extension *extension);
 int sieve_extensions_get_count(void);
 const struct sieve_extension *sieve_extension_get_by_id(unsigned int ext_id);
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index d3fd9cdc38999d0b4d5e92cb1bf7cc68b53bae52..2534a8a2e0d0fff3ef8d87536653b82242eeefc4 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -80,6 +80,8 @@ struct sieve_validator {
 	struct sieve_script *script;
 	
 	struct sieve_error_handler *ehandler;
+
+	bool finished_require;
 	
 	/* Registries */
 	
@@ -1108,12 +1110,32 @@ static bool sieve_validate_command
 		
 		result = FALSE;
 	}
-	
-	/*  
-	 * Descend further into the AST 
-	 */
-	
+		
 	if ( command != NULL ) {
+		/* Check if this is the first non-require command */
+
+		if ( !valdtr->finished_require && command != &cmd_require ) {
+			const struct sieve_validator_extension_reg *extrs;
+		    unsigned int ext_count, i;
+
+		    /* Validate all 'require'd extensions */
+
+		    extrs = array_get(&valdtr->extensions, &ext_count);
+		    for ( i = 0; i < ext_count; i++ ) {
+        	if ( extrs[i].val_ext != NULL && extrs[i].val_ext->validate != NULL ) {
+        		if ( !extrs[i].val_ext->validate
+					(valdtr, extrs[i].context, extrs[i].arg) )
+					return FALSE;
+				} 
+			}
+
+			valdtr->finished_require = TRUE;
+		}
+
+		/*  
+		 * Descend further into the AST 
+	 	*/
+
 		/* Tests */
 		if ( command->subtests > 0 && 
 			(result || sieve_errors_more_allowed(valdtr->ehandler)) )
@@ -1164,19 +1186,8 @@ static bool sieve_validate_block
 	return result;
 }
 
-bool sieve_validator_run(struct sieve_validator *validator) {	
-	const struct sieve_validator_extension_reg *extrs;
-    unsigned int ext_count, i;
-
-    /* Validate registered extensions */
-    extrs = array_get(&validator->extensions, &ext_count);
-    for ( i = 0; i < ext_count; i++ ) {
-        if ( extrs[i].val_ext != NULL && extrs[i].val_ext->validate != NULL ) {
-        	if ( !extrs[i].val_ext->validate(validator, extrs[i].context, extrs[i].arg) )
-				return FALSE;
-		} 
-	}
-
+bool sieve_validator_run(struct sieve_validator *validator) 
+{	
 	return sieve_validate_block(validator, sieve_ast_root(validator->ast));
 }
 
diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c
index 38dde8ab13420c592060143a20fe5baf1fdb4c03..17b8a04a0e0c4d7be015f2fdf28010d867546e97 100644
--- a/src/testsuite/testsuite.c
+++ b/src/testsuite/testsuite.c
@@ -46,7 +46,9 @@ static void testsuite_tool_init(void)
 {
 	sieve_tool_init();
 
-	(void) sieve_extension_register(&testsuite_extension);
+	sieve_extensions_set_string(NULL);
+
+	(void) sieve_extension_register(&testsuite_extension, TRUE);
 	
 	testsuite_init();
 }
diff --git a/tests/extensions/imap4flags/errors.svtest b/tests/extensions/imap4flags/errors.svtest
new file mode 100644
index 0000000000000000000000000000000000000000..02c6c153278b75a27c577f089aa18f3bda03c534
--- /dev/null
+++ b/tests/extensions/imap4flags/errors.svtest
@@ -0,0 +1,14 @@
+require "vnd.dovecot.testsuite";
+
+require "comparator-i;ascii-numeric";
+require "relational";
+
+test "Depricated imapflags extension used with imap4flags" {
+	if test_script_compile "errors/imapflags.sieve" {
+		test_fail "compile should have failed";
+	}
+
+	if not test_error :count "eq" :comparator "i;ascii-numeric" "2" {
+		test_fail "wrong number of errors reported";
+	}
+}
diff --git a/tests/extensions/imap4flags/errors/imapflags.sieve b/tests/extensions/imap4flags/errors/imapflags.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..1b18a4267921f00e9cb0b691fda2b24c8b86a09c
--- /dev/null
+++ b/tests/extensions/imap4flags/errors/imapflags.sieve
@@ -0,0 +1,4 @@
+require "imapflags";
+require "imap4flags";
+
+addflag "\\flagged";
diff --git a/tests/extensions/imap4flags/execute/imapflags.sieve b/tests/extensions/imap4flags/execute/imapflags.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..c071d339b625b083f14c9c995139192fc944fa56
--- /dev/null
+++ b/tests/extensions/imap4flags/execute/imapflags.sieve
@@ -0,0 +1,6 @@
+require "imapflags";
+
+mark;
+unmark;
+mark;
+