diff --git a/src/lib-sieve/plugins/imap4flags/cmd-flag.c b/src/lib-sieve/plugins/imap4flags/cmd-flag.c
index 13e43100ed4e743a47375d53c0ee6040691587d5..0fbde66ce7599238afb79e620904ed6ba1bebb5e 100644
--- a/src/lib-sieve/plugins/imap4flags/cmd-flag.c
+++ b/src/lib-sieve/plugins/imap4flags/cmd-flag.c
@@ -241,17 +241,7 @@ static int cmd_flag_operation_execute
 		i_unreached();
 	}
 
-	/* Iterate through all flags and perform requested operation */
+	/* Perform requested operation */
 	
-	while ( (ret=sieve_stringlist_next_item(flag_list, &flag_item)) > 0 ) {
-		if ( (ret=flag_op(renv, storage, var_index, flag_item)) <= 0)
-			return ret;
-	}
-
-	if ( ret < 0 ) {	
-		sieve_runtime_trace_error(renv, "invalid flag-list item");
-		return SIEVE_EXEC_BIN_CORRUPT;
-	}
-
-	return SIEVE_EXEC_OK;
+	return flag_op(renv, storage, var_index, flag_list);
 }
diff --git a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c
index 771455247007174e2fd8f467ba35fb3c05caf4b0..3c42ebe6d1f3054634a237b036274c3befd8e605 100644
--- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c
+++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c
@@ -457,27 +457,43 @@ static void flags_list_set_flags
 	flags_list_add_flags(flags_list, flags);
 }
 
+static void flags_list_clear_flags
+(string_t *flags_list)
+{
+	str_truncate(flags_list, 0);
+}
+
 int ext_imap4flags_set_flags
 (const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
-	unsigned int var_index, string_t *flags)
+	unsigned int var_index, struct sieve_stringlist *flags)
 {
 	string_t *cur_flags;
 	
 	if ( storage != NULL ) {
 		if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) )
 			return SIEVE_EXEC_BIN_CORRUPT;
-	} else
+	} else {
 		cur_flags = _get_flags_string(renv->oprtn->ext, renv->result);
+	}
+	
+	if ( cur_flags != NULL ) {
+		string_t *flags_item;
+		int ret;
 
-	if ( cur_flags != NULL )
-		flags_list_set_flags(cur_flags, flags);		
+		flags_list_clear_flags(cur_flags);
+		while ( (ret=sieve_stringlist_next_item(flags, &flags_item)) > 0 ) {
+			flags_list_add_flags(cur_flags, flags_item);
+		}
+
+		if ( ret < 0 ) return SIEVE_EXEC_BIN_CORRUPT;
+	}
 
 	return SIEVE_EXEC_OK;
 }
 
 int ext_imap4flags_add_flags
 (const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, 
-	unsigned int var_index, string_t *flags)
+	unsigned int var_index, struct sieve_stringlist *flags)
 {
 	string_t *cur_flags;
 	
@@ -486,16 +502,24 @@ int ext_imap4flags_add_flags
 			return SIEVE_EXEC_BIN_CORRUPT;
 	} else
 		cur_flags = _get_flags_string(renv->oprtn->ext, renv->result);
-	
-	if ( cur_flags != NULL )
-		flags_list_add_flags(cur_flags, flags);
-	
-	return SIEVE_EXEC_OK;	
+
+	if ( cur_flags != NULL ) {
+		string_t *flags_item;
+		int ret;
+
+		while ( (ret=sieve_stringlist_next_item(flags, &flags_item)) > 0 ) {
+			flags_list_add_flags(cur_flags, flags_item);
+		}
+
+		if ( ret < 0 ) return SIEVE_EXEC_BIN_CORRUPT;
+	}
+
+	return SIEVE_EXEC_OK;
 }
 
 int ext_imap4flags_remove_flags
 (const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, 
-	unsigned int var_index, string_t *flags)
+	unsigned int var_index, struct sieve_stringlist *flags)
 {
 	string_t *cur_flags;
 	
@@ -505,8 +529,16 @@ int ext_imap4flags_remove_flags
 	} else
 		cur_flags = _get_flags_string(renv->oprtn->ext, renv->result);
 	
-	if ( cur_flags != NULL )
-		flags_list_remove_flags(cur_flags, flags);		
+	if ( cur_flags != NULL ) {
+		string_t *flags_item;
+		int ret;
+
+		while ( (ret=sieve_stringlist_next_item(flags, &flags_item)) > 0 ) {
+			flags_list_remove_flags(cur_flags, flags_item);
+		}
+
+		if ( ret < 0 ) return SIEVE_EXEC_BIN_CORRUPT;
+	}
 
 	return SIEVE_EXEC_OK;
 }
diff --git a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h
index 5e4140a36797c763b0015c1fc172018bd7a19c2e..9194463c8aa1948b4fd478ac3e1c3e0ed5a7ee71 100644
--- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h
+++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h
@@ -90,17 +90,17 @@ const char *ext_imap4flags_iter_get_flag
 
 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);
+		unsigned int var_index, struct sieve_stringlist *flags);
 
 int ext_imap4flags_set_flags
 	(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
-		unsigned int var_index, string_t *flags);
+		unsigned int var_index, struct sieve_stringlist *flags);
 int ext_imap4flags_add_flags
 	(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
-		unsigned int var_index, string_t *flags);
+		unsigned int var_index, struct sieve_stringlist *flags);
 int ext_imap4flags_remove_flags
 	(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
-		unsigned int var_index, string_t *flags);
+		unsigned int var_index, struct sieve_stringlist *flags);
 
 /* Flags access */
 
diff --git a/tests/extensions/imap4flags/basic.svtest b/tests/extensions/imap4flags/basic.svtest
index ec94ca18f167bf0a73dc100bdf3d55ece896738f..874c40de5b4a0895822dc59413f7f720a2aa3966 100644
--- a/tests/extensions/imap4flags/basic.svtest
+++ b/tests/extensions/imap4flags/basic.svtest
@@ -104,6 +104,30 @@ test "Flag operations" {
 	}
 }
 
+test "Setflag; string list" {
+	setflag ["A B", "C D"];
+
+	if not hasflag "A" {
+		test_fail "hasflag misses A flag";
+	}
+
+	if not hasflag "B" {
+		test_fail "hasflag misses B flag";
+	}
+
+	if not hasflag "C" {
+		test_fail "hasflag misses C flag";
+	}
+
+	if not hasflag "D" {
+		test_fail "hasflag misses D flag";
+	}
+
+	if hasflag :comparator "i;ascii-numeric" :count "ne" "4" {
+		test_fail "hasflag sees incorrect number of flags";
+	}
+}
+
 test "Removal: one" {
 	setflag "\\seen";