diff --git a/TODO b/TODO
index 1305d77f21bffd58d948c61298099929fddce9ed..a351964854253766f742b69de03445162e48900e 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,8 @@
+Current activities:
+
+* Build a sieve tool to filter an entire existing mailbox through a Sieve 
+  script.
+
 Next (in order of descending priority/precedence):
 
 * Finish the ereject extension
@@ -16,10 +21,6 @@ Next (in order of descending priority/precedence):
 * Cleanup the test suite
 	- Restructure test scripts
 	- Add more comment on purpose of tests
-* Build a sieve tool to filter an entire existing mailbox through a Sieve 
-  script:
-	- Add commandline options to fully customize execution
-	- Write manual page
 * Implement index extension
 * Update include extension to latest draft (v05 currently):
 	- Implement required ManageSieve behavior (pending IETF discussion)
diff --git a/doc/man/sieve-filter.1.in b/doc/man/sieve-filter.1.in
index 5c27038ffc88db8ac19bb0c3cf7bc9fc3c9fb544..05191ef53c33eaca01238ac4bb5c63970bc5393f 100644
--- a/doc/man/sieve-filter.1.in
+++ b/doc/man/sieve-filter.1.in
@@ -38,47 +38,31 @@ remains unchanged. Use the \fB\-W\fP to allow changes in the source mailbox.
 .SS CAUTION
 Although this is a very useful tool, it can also be very destructive when used
 improperly. A small bug in your Sieve script in combination with the wrong
-command line options could cause it to discard the wrong e\-mails. Therefore, 
-users are advised to read this manual carefully and to use the simulation mode 
-first to check what the script will do. 
+command line options could cause it to discard the wrong e\-mails. And, even if
+the source mailbox is opened in read\-only mode to prevent such mishaps, it can
+still litter other mailboxes with spurious copies of your e\-mails if your Sieve
+script decides to do so. Therefore, users are advised to read this manual
+carefully and to use the simulation mode first to check what the script will do.
+And, of course:
 .PP
 \fBMAKING A BACKUP IS IMPERATIVE FOR ANY IMPORTANT MAIL!\fP
-.PP
-By default, it will open the source mailbox in a read\-only mode, such that it
-will not delete any of your e\-mails. However, it can still litter other
-mailboxes with spurious copies of your e\-mails if your Sieve script decides to
-do so.
+
 .\"------------------------------------------------------------------------
 .SH OPTIONS
 .TP
 .BI \-c\  config\-file
 Alternative Dovecot configuration file path.
-.TP 
-.BI \-D\  source\-action
-By default, the sieve\-filter command does not delete the messages from the
-source mailbox. This means that a copy operation is executed by default and the
-source mailbox is not altered. The \fIsource\-action\fP parameter of the 
-\fB\-D\fP option can take four different values:
-.RS 7
-.TP 
-\fBkeep\fP (default)
-Keep messages in source folder. If \fB\-W\fR is specified and the source mailbox
-is the destination of a keep or fileinto action, flags can be changed by the
-Sieve script. Messages are never duplicated in the source mailbox.
-.TP 
-\fBflag\fP
-Flag messages as \\DELETED.
-.TP 
-\fBmove\fP [\fIfolder\fP]
-Move messages to the indicated \fIfolder\fP.
-.TP 
-\fBexpunge\fP
-Expunge messages, meaning that these are removed irreversibly when the tool
-finishes filtering.
-.PP
-Note that values other than `keep' have no effect, unless the \fB\-W\fP option
-is specified as well.
-.RE
+.TP
+.B \-C
+Force compilation. By default, the compiled binary is stored on disk. When this
+binary is found during the next execution of \fBsieve\-filter\fP and its
+modification time is more recent than the script file, it is used and the script
+is not compiled again. This option forces the script to be compiled, thus
+ignoring any present binary. Refer to \fBsievec\fP(1) for more information about
+Sieve compilation.
+.TP
+.B \-D
+Enable Sieve debugging.
 .TP
 .B \-e
 Turns on execution mode. By default, the sieve\-filter command runs in
@@ -87,33 +71,61 @@ in any way and no actions are performed. It only prints what would be done.
 Using this option the sieve\-filter command becomes active and performs the 
 requested actions.
 .TP
-.BI \-f\  envelope\-sender
-The envelope sender or return path. This is what Sieve\(aqs envelope test will
-compare to when the \(dqfrom\(dq envelope part is requested. Also, this is
-where response messages are sent to.
-.TP
 .BI \-m\  default\-mailbox
-The mailbox where the keep action stores the message. This is \(dqINBOX\(dq
+The mailbox where the keep action stores messages. This is \(dqINBOX\(dq
 by default.
 .TP
-.BI \-Q\  mail\-command
-Send outgoing e\-mail through the specified program. By default,
+.BI \-q\  output\-mailbox
+Store outgoing e\-mail into the indicated \fIoutput\-mailbox\fP. By default,
 the sieve\-filter command ignores Sieve actions such as redirect, reject,
-vacation and notify, but using this option outgoing messages can be fed to the
-\fBstdin\fP of an external shell command. This option has no effect in
-simulation mode. Unless you really know what you are doing, \fBDO NOT USE THIS
-TO FEED MAIL TO SENDMAIL!\f.
+vacation and notify, but using this option outgoing messages can be appended to
+the indicated mailbox. This option has no effect in simulation mode.
 .TP
-.BI \-r\  recipient\-address
-The envelope recipient address. This is what Sieve\(aqs envelope test will
-compare to when the \(dqto\(dq envelope part is requested. Some tests and
-actions will also use this as the owner\(aqs e\-mail address.
+.BI \-Q\  mail\-command
+Send outgoing e\-mail (e.g. as produced by redirect, reject and vacation)
+through the specified program. By default, the sieve\-filter command ignores
+Sieve actions such as redirect, reject, vacation and notify, but using this
+option outgoing messages can be fed to the \fBstdin\fP of an external shell
+command. This option has no effect in simulation mode. Unless you really know
+what you are doing, \fBDO NOT USE THIS TO FEED MAIL TO SENDMAIL!\fP.
+.TP 
+.BI \-R\  source\-action
+Specifies what needs to be done with messages in the source mailbox once
+processed by the Sieve script. By default, the sieve\-filter command does not
+remove the messages from the source mailbox. In particular this means that the
+keep and fileinto actions will cause the messages to be copied. To alter this
+behavior, the \fIsource\-action\fP parameter of the \fB\-R\fP option accepts
+one of the following values:
+.RS 7
+.TP 
+\fBkeep\fP (default)
+Keep processed messages in source folder. If \fB\-W\fR is specified and the
+source mailbox is the destination of a keep or fileinto action, flags may be
+changed by the Sieve script, but messages are never duplicated there. 
+.TP 
+\fBflag\fP
+Flag processed messages as \\DELETED.
+.TP 
+\fBmove\fP [\fIfolder\fP]
+Move processed messages to the indicated \fIfolder\fP.
+.TP 
+\fBexpunge\fP
+Expunge processed messages, meaning that these are removed irreversibly when the
+tool finishes filtering.
+.PP
+Note that the chosen \fIsource\-action\fP only has an effect on the source
+mailbox when the \fB\-W\fP option is specified as well.
+.RE
 .TP
 .BI \-s\  script\-file
 Specify additional scripts to be executed before the main script. Multiple
 \fB\-s\fP arguments are allowed and the specified scripts are executed
 sequentially in the order specified at the command
-line..TP
+line.
+.TP
+.BI \-u\  user
+Run the Sieve script for the given \fIuser\fP.
+.TP
 .B \-W
 Enables write access to the source mailbox. This allows deleting the messages
 from the source mailbox and changing the assigned IMAP flags and keywords. 
diff --git a/src/sieve-tools/sieve-filter.c b/src/sieve-tools/sieve-filter.c
index 972ca0ad739fb16055ef5f7f6b91160de88f5ca1..3a67e6659eb0e33423d10f24ecf23c4a1586a00c 100644
--- a/src/sieve-tools/sieve-filter.c
+++ b/src/sieve-tools/sieve-filter.c
@@ -11,6 +11,7 @@
 #include "mail-namespace.h"
 #include "mail-storage.h"
 #include "mail-search-build.h"
+#include "imap-utf7.h"
 
 #include "sieve.h"
 #include "sieve-extensions.h"
@@ -36,25 +37,30 @@ static void print_help(void)
 	printf(
 "Usage: sieve-filter [-m <mailbox>] [-x <extensions>] [-s <script-file>] [-c]\n"
 "                    <script-file> <src-mail-store> [<dest-mail-store>]\n"
+"Usage: sieve-filter [-c <config-file>] [-C] [-D] [-e]\n"
+"                  [-m <default-mailbox>] [-P <plugin>]\n"
+"                  [-r <recipient-address>] [-s <script-file>]\n"
+"                  [-t <trace-file>] [-T <trace-option>] [-x <extensions>]\n"
+"                  <script-file> <mail-file>\n"
 	);
 }
 
-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 */
+enum source_action_type {
+	SOURCE_ACTION_KEEP,            /* Always keep messages in source folder */ 
+	SOURCE_ACTION_DELETE,          /* Flag discarded messages as \DELETED */
+	SOURCE_ACTION_TRASH_FOLDER,    /* Move discarded messages to Trash folder */      
+	SOURCE_ACTION_EXPUNGE          /* Expunge discarded messages */
 };
 
-struct discard_action {
-	enum discard_action_type type;
+struct source_action {
+	enum source_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,
-	struct discard_action discard_action)
+	struct source_action source_action)
 {
 	struct sieve_exec_status estatus;
 	struct sieve_binary *sbin;
@@ -72,7 +78,8 @@ static int filter_message
 	memset(&msgdata, 0, sizeof(msgdata));
 	msgdata.mail = mail;
 	msgdata.return_path = sender;
-	msgdata.to_address = recipient;
+	msgdata.orig_envelope_to = recipient;
+	msgdata.final_envelope_to = recipient;
 	msgdata.auth_user = senv->username;
 	(void)mail_get_first_header(mail, "Message-ID", &msgdata.id);
 
@@ -85,24 +92,24 @@ static int filter_message
 
 	/* Handle message in source folder */
 	if ( ret > 0 && !estatus.keep_original ) {
-		switch ( discard_action.type ) {
+		switch ( source_action.type ) {
 		/* Leave it there */
-		case DISCARD_ACTION_KEEP:
-			sieve_info(ehandler, NULL, "message left in source folder");
+		case SOURCE_ACTION_KEEP:
+			sieve_info(ehandler, NULL, "message left in source mailbox");
 			break;
 		/* Flag message as \DELETED */
-		case DISCARD_ACTION_DELETE:					
-			sieve_info(ehandler, NULL, "message flagged as deleted in source folder");
+		case SOURCE_ACTION_DELETE:					
+			sieve_info(ehandler, NULL, "message flagged as deleted in source mailbox");
 			mail_update_flags(mail, MODIFY_ADD, MAIL_DELETED);
 			break;
 		/* Move message to Trash folder */
-		case DISCARD_ACTION_TRASH_FOLDER:			
+		case SOURCE_ACTION_TRASH_FOLDER:			
 			sieve_info(ehandler, NULL, 
 				"message in source folder moved to folder '%s'", 
-				discard_action.trash_folder);
+				source_action.trash_folder);
 			break;
 		/* Expunge the message immediately */
-		case DISCARD_ACTION_EXPUNGE:
+		case SOURCE_ACTION_EXPUNGE:
 			sieve_info(ehandler, NULL, "message removed from source folder");
 			mail_expunge(mail);
 			break;
@@ -132,9 +139,9 @@ static void mail_search_build_add_flags
 }
 
 static int filter_mailbox
-(struct mailbox *box, struct sieve_binary *main_sbin, 
+(struct mailbox *src_box, struct sieve_binary *main_sbin, 
 	struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
-	struct discard_action discard_action)
+	struct source_action source_action)
 {
 	struct mail_search_args *search_args;
 	struct mailbox_transaction_context *t;
@@ -144,7 +151,7 @@ static int filter_mailbox
 
 	/* Sync mailbox */
 
-	if ( mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0 ) {
+	if ( mailbox_sync(src_box, MAILBOX_SYNC_FLAG_FULL_READ) < 0 ) {
 		return -1;
 	}
 
@@ -155,7 +162,7 @@ static int filter_mailbox
 
 	/* Iterate through all requested messages */
 
-	t = mailbox_transaction_begin(box, 0);
+	t = mailbox_transaction_begin(src_box, 0);
 	search_ctx = mailbox_search_init(t, search_args, NULL);
 	mail_search_args_unref(&search_args);
 
@@ -182,7 +189,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, discard_action);
+		ret = filter_message(mail, main_sbin, senv, ehandler, source_action);
 	}
 	mail_free(&mail);
 	
@@ -203,13 +210,23 @@ static int filter_mailbox
 
 	/* Sync mailbox */
 
-	if ( mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_WRITE) < 0 ) {
+	if ( mailbox_sync(src_box, MAILBOX_SYNC_FLAG_FULL_WRITE) < 0 ) {
 		return -1;
 	}
 	
 	return ret;
 }
 
+static const char *mailbox_name_to_mutf7(const char *mailbox_utf8)
+{
+	string_t *str = t_str_new(128);
+
+	if (imap_utf8_to_utf7(mailbox_utf8, str) < 0)
+		return mailbox_utf8;
+	else
+		return str_c(str);
+}
+
 /*
  * Tool implementation
  */
@@ -217,26 +234,27 @@ static int filter_mailbox
 int main(int argc, char **argv) 
 {
 	struct sieve_instance *svinst;
-	const char *scriptfile, *recipient, *sender,
-	*src_mailbox, *dst_mailbox, *src_mailstore, *dst_mailstore;
+	ARRAY_TYPE (const_string) scriptfiles;
+	const char *scriptfile,	*src_mailbox, *dst_mailbox;
+	struct source_action source_action = { SOURCE_ACTION_KEEP, "Trash" };
 	struct mail_user *mail_user;
-	struct mail_namespace *src_ns, *dst_ns;
 	struct sieve_binary *main_sbin;
 	struct sieve_script_env scriptenv;
 	struct sieve_error_handler *ehandler;
-	bool force_compile = FALSE;
+	bool force_compile = FALSE, execute = FALSE, source_write = FALSE;
+	struct mail_namespace *ns;
+	struct mailbox *src_box;
 	enum mailbox_flags open_flags =
 		MAILBOX_FLAG_KEEP_RECENT | MAILBOX_FLAG_IGNORE_ACLS;
 	enum mail_error error;
-	struct discard_action discard_action = 
-	{ DISCARD_ACTION_KEEP, "Trash" };
-	struct mailbox *src_box;
 	int c;
 
-	sieve_tool = sieve_tool_init("sieve-filter", &argc, &argv, "m:x:P:CD", FALSE);
+	sieve_tool = sieve_tool_init("sieve-filter", &argc, &argv, "m:s:x:P:CD", FALSE);
+
+	t_array_init(&scriptfiles, 16);
 
 	/* Parse arguments */
-	scriptfile = recipient = sender = src_mailstore = dst_mailstore = NULL;
+	scriptfile =  NULL;
 	src_mailbox = dst_mailbox = "INBOX";
 	force_compile = FALSE;
 	while ((c = sieve_tool_getopt(sieve_tool)) > 0) {
@@ -245,9 +263,28 @@ int main(int argc, char **argv)
 			/* default mailbox (keep box) */
 			dst_mailbox = optarg;
 			break;
+		case 's': 
+			/* scriptfile executed before main script */
+			{
+				const char *file;			
+
+				file = t_strdup(optarg);
+				array_append(&scriptfiles, &file, 1);
+
+				/* FIXME: */
+				i_fatal_status(EX_USAGE, 
+					"The -s argument is currently NOT IMPLEMENTED");
+			}
+			break;
+		case 'e':
+			execute = TRUE;
+			break;
 		case 'C':
 			force_compile = TRUE;
 			break;
+		case 'W':
+			source_write = TRUE;
+			break;
 		default:
 			print_help();
 			i_fatal_status(EX_USAGE, "Unknown argument: %c", c);
@@ -263,14 +300,10 @@ int main(int argc, char **argv)
 	}
 
 	if ( optind < argc ) {
-		src_mailstore = t_strdup(argv[optind++]);
+		src_mailbox = t_strdup(argv[optind++]);
 	} else {
 		print_help();
-		i_fatal_status(EX_USAGE, "Missing <mailstore> argument");
-	}
-
-	if ( optind < argc ) {
-		dst_mailstore = t_strdup(argv[optind++]);
+		i_fatal_status(EX_USAGE, "Missing <source-mailbox> argument");
 	}
 
 	if ( optind != argc ) {
@@ -284,39 +317,35 @@ int main(int argc, char **argv)
 	(void) sieve_extension_register(svinst, &debug_extension, TRUE);
 
 	/* Create error handler */
-	ehandler = sieve_stderr_ehandler_create(0);
+	ehandler = sieve_stderr_ehandler_create(svinst, 0);
 	sieve_system_ehandler_set(ehandler);
 	sieve_error_handler_accept_infolog(ehandler, TRUE);
 
 	/* Compile main sieve script */
 	if ( force_compile ) {
 		main_sbin = sieve_tool_script_compile(svinst, scriptfile, NULL);
-		(void) sieve_save(main_sbin, NULL);
+		if ( main_sbin != NULL )
+			(void) sieve_save(main_sbin, NULL, TRUE, NULL);
 	} else {
 		main_sbin = sieve_tool_script_open(svinst, scriptfile);
 	}
 
-	sieve_tool_init_mail_user(sieve_tool, src_mailstore);
+	/* Initialize mail user */
 	mail_user = sieve_tool_get_mail_user(sieve_tool);
 
-/*	if ( dst_mailstore != NULL ) {
-		folder = "#src/";
-		src_ns = mail_namespace_find(mail_user->namespaces, &folder);
-
-		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;	
-/*	}*/
+	/* Find namespace for source mailbox */
+	src_mailbox = mailbox_name_to_mutf7(src_mailbox);
+	ns = mail_namespace_find(mail_user->namespaces, &src_mailbox);
+	if ( ns == NULL )
+		i_fatal("Unknown namespace for source mailbox '%s'", src_mailbox);
 
 	/* Open the source mailbox */	
-	src_box = mailbox_alloc(src_ns->list, src_mailbox, open_flags);
+	if ( !source_write ) 
+		open_flags |= MAILBOX_FLAG_READONLY;
+	src_box = mailbox_alloc(ns->list, src_mailbox, open_flags);
   if ( mailbox_open(src_box) < 0 ) {
 		i_fatal("Couldn't open mailbox '%s': %s", 
-			src_mailbox, mail_storage_get_last_error(src_ns->storage, &error));
+			src_mailbox, mail_storage_get_last_error(ns->storage, &error));
   }
 
 	/* Compose script environment */
@@ -329,13 +358,10 @@ int main(int argc, char **argv)
 	scriptenv.postmaster_address = "postmaster@example.com";
 	scriptenv.smtp_open = NULL;
 	scriptenv.smtp_close = NULL;
-	scriptenv.duplicate_mark = NULL;
-	scriptenv.duplicate_check = NULL;
-	scriptenv.trace_stream = NULL;
 
 	/* Apply Sieve filter to all messages found */
 	(void) filter_mailbox
-		(src_box, main_sbin, &scriptenv, ehandler, discard_action);
+		(src_box, main_sbin, &scriptenv, ehandler, source_action);
 	
 	/* Close the mailbox */
 	if ( src_box != NULL )
@@ -343,7 +369,6 @@ int main(int argc, char **argv)
 
 	/* Cleanup error handler */
 	sieve_error_handler_unref(&ehandler);
-	sieve_system_ehandler_reset();
 
 	sieve_tool_deinit(&sieve_tool);