diff --git a/src/lib-sieve/plugins/copy/ext-copy.c b/src/lib-sieve/plugins/copy/ext-copy.c
index 82ac36548ca7ed641c181e80da19bc065966771e..cdfca15752d81e332fbf3b47da4ffe21335b84ef 100644
--- a/src/lib-sieve/plugins/copy/ext-copy.c
+++ b/src/lib-sieve/plugins/copy/ext-copy.c
@@ -57,7 +57,7 @@ static bool tag_copy_validate
 	return TRUE;
 }
 
-/* Command registration */
+/* Tag */
 
 static const struct sieve_argument copy_tag = { 
 	"copy", NULL, 
diff --git a/src/lib-sieve/plugins/imapflags/Makefile.am b/src/lib-sieve/plugins/imapflags/Makefile.am
index 87d1d9e6662afdca2eae0341bafbbbb07a51564c..8d551234e48944b06588925bfba6bb077fff4428 100644
--- a/src/lib-sieve/plugins/imapflags/Makefile.am
+++ b/src/lib-sieve/plugins/imapflags/Makefile.am
@@ -15,10 +15,14 @@ cmds = \
 tsts = \
 	tst-hasflag.c
 
+tags = \
+	tag-flags.c
+
 libsieve_ext_imapflags_la_SOURCES = \
 	ext-imapflags-common.c \
 	$(cmds) \
 	$(tsts) \
+	$(tags) \
 	ext-imapflags.c
 
 noinst_HEADERS = \
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags.c b/src/lib-sieve/plugins/imapflags/ext-imapflags.c
index 04361bd36f6c8fc1734c940e8934f2da03d537b0..82be527f9532731fa4d05010f5f8ac3b8ad21b59 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags.c
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags.c
@@ -39,6 +39,10 @@ extern const struct sieve_command cmd_removeflag;
 
 extern const struct sieve_command tst_hasflag;
 
+/* Tagged arguments */
+
+extern const struct sieve_argument tag_flags;
+
 /* Opcodes */
 
 extern const struct sieve_opcode setflag_opcode;
@@ -75,11 +79,18 @@ static bool ext_imapflags_load(int ext_id)
 static bool ext_imapflags_validator_load
 	(struct sieve_validator *validator)
 {
-	/* Register new command */
+	/* Register commands */
 	sieve_validator_register_command(validator, &cmd_setflag);
 	sieve_validator_register_command(validator, &cmd_addflag);
 	sieve_validator_register_command(validator, &cmd_removeflag);
 	sieve_validator_register_command(validator, &tst_hasflag);
+	
+	/* Register :flags tag with keep and fileinto commands and we don't care
+	 * whether these commands are registered or even whether they will be
+	 * registered at all. The validator handles either situation gracefully 
+	 */
+	sieve_validator_register_external_tag(validator, &tag_flags, "keep", 0);
+	sieve_validator_register_external_tag(validator, &tag_flags, "fileinto", 0);
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/imapflags/imapflags.sieve b/src/lib-sieve/plugins/imapflags/imapflags.sieve
index c58c72c34a970e02cfa4f832dc84bf474d7fa83b..a05a2f68b72acc8a3a0da58e5f119e261f0b4262 100644
--- a/src/lib-sieve/plugins/imapflags/imapflags.sieve
+++ b/src/lib-sieve/plugins/imapflags/imapflags.sieve
@@ -24,3 +24,5 @@ if header :contains "from" "imap@cac.washington.example.edu" {
 if hasflag :count "ge" :comparator "i;ascii-numeric" "2" {
 	fileinto "INBOX.imap-twoflags";
 }
+
+fileinto :flags "\\Seen" "INBOX";
diff --git a/src/lib-sieve/plugins/imapflags/tag-flags.c b/src/lib-sieve/plugins/imapflags/tag-flags.c
new file mode 100644
index 0000000000000000000000000000000000000000..2d4ba5d0d7c61b26163e764cf59703ecf8108d34
--- /dev/null
+++ b/src/lib-sieve/plugins/imapflags/tag-flags.c
@@ -0,0 +1,45 @@
+#include "lib.h"
+
+#include "sieve-commands.h"
+#include "sieve-validator.h" 
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+
+#include "ext-imapflags-common.h"
+
+static bool tag_flags_validate
+	(struct sieve_validator *validator,	struct sieve_ast_argument **arg, 
+	struct sieve_command_context *cmd);
+
+/* Tag */
+
+const struct sieve_argument tag_flags = { 
+	"flags", NULL, 
+	tag_flags_validate, 
+	NULL, NULL 
+};
+
+/* Tag validation */
+
+static bool tag_flags_validate
+(struct sieve_validator *validator,	struct sieve_ast_argument **arg, 
+	struct sieve_command_context *cmd)
+{
+	struct sieve_ast_argument *tag = *arg;
+
+	/* Detach the tag itself */
+	*arg = sieve_ast_arguments_detach(*arg,1);
+	
+	/* Check syntax:
+	 *   :flags <list-of-flags: string-list>
+	 */
+	if ( !sieve_validate_tag_parameter
+		(validator, cmd, tag, *arg, SAAT_STRING_LIST) ) {
+		return FALSE;
+	}
+	
+	/* Detach parameter */
+	*arg = sieve_ast_arguments_detach(*arg,1);
+
+	return TRUE;
+}
diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c
index 73f24b11206046c4c2bef9b9fb295b33c2f31429..fb569f250e6b1cac6c9bf5275a8b6a5d9446de9e 100644
--- a/src/lib-sieve/sieve-actions.c
+++ b/src/lib-sieve/sieve-actions.c
@@ -192,7 +192,8 @@ static bool act_store_commit
 	
 	act_store_log_status(trans, aenv->msgdata, FALSE, status);
 	
-	mailbox_close(&trans->box);
+	if ( trans->box != NULL )
+		mailbox_close(&trans->box);
 	
 	return status;
 }
@@ -208,8 +209,9 @@ static void act_store_rollback
 	  mailbox_transaction_rollback(&trans->mail_trans);
   
   act_store_log_status(trans, aenv->msgdata, TRUE, success);
-  
-  mailbox_close(&trans->box);
+
+	if ( trans->box != NULL )  
+	  mailbox_close(&trans->box);
 }
 
 
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index 66c3e45adbc28b19bb2fd5d8c7a0c839435a7a58..369cdc3563ae6c8cfae9794f5349311e0d02ac5f 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -178,9 +178,8 @@ bool sieve_result_execute
 	
 	printf("\nTransaction execute:\n");
 	
-	if ( success )
-		rac = result->first_action;
-	
+	last_attempted = rac;
+	rac = result->first_action;
 	while ( success && rac != NULL ) {
 		const struct sieve_action *act = rac->action;
 	
@@ -201,7 +200,6 @@ bool sieve_result_execute
 		printf("\nTransaction rollback:\n");
 
 	commit_ok = success;
-	last_attempted = rac;
 	rac = result->first_action;
 	while ( rac != NULL && rac != last_attempted ) {
 		const struct sieve_action *act = rac->action;