diff --git a/sieve/tests/redirect.sieve b/sieve/tests/redirect.sieve
index 57ced4ae3a0118a12555e20f12ad4ec9cabff8d3..6d02c6edca32384f62c8f60792277d505b289735 100644
--- a/sieve/tests/redirect.sieve
+++ b/sieve/tests/redirect.sieve
@@ -1,5 +1,6 @@
 if address :contains "to" "vestingbar" {
 	redirect "stephan@example.com";
+	keep;
 }
 
 redirect "stephan@rename-it.nl";
diff --git a/src/lib-sieve/cmd-keep.c b/src/lib-sieve/cmd-keep.c
index 99838fb74b0c6401474e61e1e3f883b843bbd7b2..6335f3effadd7c7dcc7f6b09c55b1a596fa78846 100644
--- a/src/lib-sieve/cmd-keep.c
+++ b/src/lib-sieve/cmd-keep.c
@@ -51,7 +51,7 @@ static int act_keep_execute
 		
 const struct sieve_action act_keep = {
 	"keep",
-	NULL,
+	NULL, NULL,
 	act_keep_execute
 };
 
@@ -88,7 +88,7 @@ static bool opc_keep_execute
 /*
  * Action
  */
-
+ 
 static int act_keep_execute
 (const struct sieve_action *action ATTR_UNUSED, 
 	const struct sieve_action_exec_env *aenv, void *context)
diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c
index 31de529ac410e35840e2db5ae5a549bc0d12c79c..d8f1eff42e0b25ce7bacdd588a941ae50af574d0 100644
--- a/src/lib-sieve/cmd-redirect.c
+++ b/src/lib-sieve/cmd-redirect.c
@@ -50,6 +50,9 @@ const struct sieve_opcode cmd_redirect_opcode = {
 
 /* Redirect action */
 
+static bool act_redirect_check_duplicate
+	(const struct sieve_action *action1 ATTR_UNUSED, void *context1, 
+		void *context2);
 static void act_redirect_print
 	(const struct sieve_action *action, void *context);	
 static int act_redirect_execute
@@ -62,6 +65,7 @@ struct act_redirect_context {
 
 const struct sieve_action act_redirect = {
 	"redirect",
+	act_redirect_check_duplicate, 
 	act_redirect_print,
 	act_redirect_execute
 };
@@ -146,8 +150,21 @@ static bool cmd_redirect_opcode_execute
 }
 
 /*
- * Action
+ * Actionstatic bool act_redirect_check_duplicate
+(const struct sieve_action *action1 ATTR_UNUSED, void *context1, void *context2)
  */
+ 
+static bool act_redirect_check_duplicate
+(const struct sieve_action *action1 ATTR_UNUSED, void *context1, void *context2)
+{
+	struct act_redirect_context *ctx1 = (struct act_redirect_context *) context1;
+	struct act_redirect_context *ctx2 = (struct act_redirect_context *) context2;
+	
+	if ( strcmp(ctx1->to_address, ctx2->to_address) == 0 ) 
+		return TRUE;
+		
+	return FALSE;
+}
 
 static void act_redirect_print
 (const struct sieve_action *action ATTR_UNUSED, void *context)	
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index 30e49dc6ce228829faa6e24ccf8b432a4a9fe194..cd1bc4f0374f91ef088e794936ff0504d359626c 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -59,11 +59,30 @@ inline pool_t sieve_result_pool(struct sieve_result *result)
 	return result->pool;
 }
 
-void sieve_result_add_action
+bool sieve_result_add_action
 (struct sieve_result *result, const struct sieve_action *action, void *context)		
 {
 	struct sieve_result_action *raction;
 	
+	/* First, check for duplicates */
+	raction = result->first_action;
+	while ( raction != NULL ) {
+		if ( raction->action == action ) {
+			const struct sieve_action *oact = raction->action;
+			
+			if ( oact->check_duplicate != NULL ) {
+				if ( oact->check_duplicate(action, raction->context, context) )
+					return FALSE;
+			} else 
+				return FALSE; 
+		}
+		raction = raction->next;
+	}
+	
+	/* Check for conflicts */
+	
+	/* FIXME: Unimplemented */
+	
 	/* Create new action object */
 	raction = p_new(result->pool, struct sieve_result_action, 1);
 	raction->action = action;
@@ -81,6 +100,8 @@ void sieve_result_add_action
 		result->last_action = raction;
 		raction->next = NULL;
 	}	
+	
+	return TRUE;
 }	
 
 bool sieve_result_print(struct sieve_result *result)
diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h
index 6790cad49570abad2f3c0e9fee185e08e3caa831..4165171c1f131a22042cb7abc7bac927a0330b85 100644
--- a/src/lib-sieve/sieve-result.h
+++ b/src/lib-sieve/sieve-result.h
@@ -13,6 +13,9 @@ struct sieve_action_exec_env {
 struct sieve_action {
 	const char *name;
 
+	bool (*check_duplicate)	
+		(const struct sieve_action *action1, void *context1, void *context2);	
+
 	void (*print)
 		(const struct sieve_action *action, void *context);	
 	int (*execute)
@@ -25,7 +28,7 @@ void sieve_result_ref(struct sieve_result *result);
 void sieve_result_unref(struct sieve_result **result); 
 inline pool_t sieve_result_pool(struct sieve_result *result);
 
-void sieve_result_add_action
+bool sieve_result_add_action
 	(struct sieve_result *result, const struct sieve_action *action, 
 		void *context);