diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c
index f3882f572e5e3783f79ca54b7dbc5a983df3d108..fdedc7e5b2e0865a1f66340f2e8d49559b873172 100644
--- a/src/lib-sieve/sieve-actions.c
+++ b/src/lib-sieve/sieve-actions.c
@@ -456,7 +456,7 @@ static bool act_store_commit
 		return TRUE;
 	} else if ( trans->redundant ) {
 		act_store_log_status(trans, aenv, FALSE, status);
-		aenv->exec_status->did_redundant_save = TRUE;
+		aenv->exec_status->keep_original = TRUE;
 		aenv->exec_status->message_saved = TRUE;
 		return TRUE;	
 	}
diff --git a/src/lib-sieve/sieve-types.h b/src/lib-sieve/sieve-types.h
index 67938fde5c46fea9059864cbf799d1ee8c63f00e..c0f56cfbbb667684d037d50457c647afb9269c4f 100644
--- a/src/lib-sieve/sieve-types.h
+++ b/src/lib-sieve/sieve-types.h
@@ -91,7 +91,7 @@ struct sieve_exec_status {
 	bool message_saved;
 	bool message_forwarded;
 	bool tried_default_save;
-	bool did_redundant_save;
+	bool keep_original;
 	struct mail_storage *last_storage;
 };
 
diff --git a/src/sieve-tools/sieve-filter.c b/src/sieve-tools/sieve-filter.c
index cd518e35ef938d99d113c29ce55e466d38dcf2dc..2403f9b045c6f6ea7842c34c587314c64d6ee4ea 100644
--- a/src/sieve-tools/sieve-filter.c
+++ b/src/sieve-tools/sieve-filter.c
@@ -36,10 +36,22 @@ static void print_help(void)
 	);
 }
 
+enum discard_action_type {
+	DISCARD_ACTION_KEEP,            /* Always keep messages in source folder */ 
+	DISCARD_ACTION_DELETE,          /* Flag discarded messages as \DELETED */
+	DISCARD_ACTION_TRASH_FOLDER,    /* Move discarded messages to Trash folder */      
+	DISCARD_ACTION_EXPUNGE          /* Expunge discarded messages */
+};
+
+struct discard_action {
+	enum discard_action_type type;
+	const char *trash_folder;
+};
+
 static int filter_message
 (struct mail *mail, struct sieve_binary *main_sbin, 
 	struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
-	bool move)
+	struct discard_action discard_action)
 {
 	struct sieve_exec_status estatus;
 	struct sieve_binary *sbin;
@@ -68,9 +80,34 @@ static int filter_message
 	/* Execute script */
 	ret = sieve_execute(sbin, &msgdata, senv, ehandler, NULL);
 
-	if ( ret > 0 && move && !estatus.did_redundant_save ) {
-		sieve_info(ehandler, NULL, "message removed from source folder");
-		mail_expunge(mail);	
+	/* Handle message in source folder */
+	if ( ret > 0 && !estatus.keep_original ) {
+		switch ( discard_action.type ) {
+		/* Leave it there */
+		case DISCARD_ACTION_KEEP:
+			sieve_info(ehandler, NULL, "message left in source folder");
+			break;
+		/* Flag message as \DELETED */
+		case DISCARD_ACTION_DELETE:					
+			sieve_info(ehandler, NULL, "message flagged as deleted in source folder");
+			mail_update_flags(mail, MODIFY_ADD, MAIL_DELETED);
+			break;
+		/* Move message to Trash folder */
+		case DISCARD_ACTION_TRASH_FOLDER:			
+			sieve_info(ehandler, NULL, 
+				"message in source folder moved to folder '%s'", 
+				discard_action.trash_folder);
+			break;
+		/* Expunge the message immediately */
+		case DISCARD_ACTION_EXPUNGE:
+			sieve_info(ehandler, NULL, "message removed from source folder");
+			mail_expunge(mail);
+			break;
+		/* Unknown */
+		default:
+			i_unreached();
+			break;
+		}
 	}
 
 	return ret;
@@ -94,10 +131,9 @@ static void mail_search_build_add_flags
 static int filter_mailbox
 (struct mailbox *box, struct sieve_binary *main_sbin, 
 	struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
-	bool move)
+	struct discard_action discard_action)
 {
 	struct mail_search_args *search_args;
-	struct mail_search_arg *sarg;
 	struct mailbox_transaction_context *t;
 	struct mail_search_context *search_ctx;
 	struct mail *mail;
@@ -138,7 +174,7 @@ static int filter_mailbox
 		sieve_info(ehandler, NULL,
 			"filtering: [%s; %"PRIuUOFF_T" bytes] %s", date, size, subject);
 	
-		ret = filter_message(mail, main_sbin, senv, ehandler, move);
+		ret = filter_message(mail, main_sbin, senv, ehandler, discard_action);
 	}
 	mail_free(&mail);
 	
@@ -176,6 +212,8 @@ int main(int argc, char **argv)
 	struct sieve_script_env scriptenv;
 	struct sieve_error_handler *ehandler;
 	struct mail_storage *dst_storage, *src_storage;
+	struct discard_action discard_action = 
+		{ DISCARD_ACTION_KEEP, "Trash" };
 	struct mailbox *src_box;
 	enum mail_error error;
 	enum mailbox_open_flags open_flags = 
@@ -284,9 +322,12 @@ int main(int argc, char **argv)
 		src_ns = mail_namespace_find(mail_user->namespaces, &folder);
 
 		folder = "/";
-		dst_ns = mail_namespace_find(mail_user->namespaces, &folder);		
+		dst_ns = mail_namespace_find(mail_user->namespaces, &folder);	
+
+		discard_action.type = DISCARD_ACTION_KEEP;	
 	} else {
 		dst_ns = src_ns = mail_user->namespaces;
+		discard_action.type = DISCARD_ACTION_DELETE;	
 	}
 
 	src_storage = src_ns->storage;
@@ -315,7 +356,7 @@ int main(int argc, char **argv)
 
 	/* Apply Sieve filter to all messages found */
 	(void) filter_mailbox
-		(src_box, main_sbin, &scriptenv, ehandler, ( dst_ns == src_ns ));
+		(src_box, main_sbin, &scriptenv, ehandler, discard_action);
 	
 	/* Close the mailbox */
 	if ( src_box != NULL )