diff --git a/.hgignore b/.hgignore
index 9f30fb8d02758b3361d3db69ef6617f66fd43301..724452b3b19da0b2a694daf39f1ce5da4209552f 100644
--- a/.hgignore
+++ b/.hgignore
@@ -51,6 +51,6 @@ Makefile.in
 src/sieve-tools/sievec
 src/sieve-tools/sieved
 src/sieve-tools/sieve-test
-src/sieve-tools/sieve-exec
+src/sieve-tools/sieve-filter
 
 src/testsuite/testsuite
diff --git a/src/sieve-tools/Makefile.am b/src/sieve-tools/Makefile.am
index 361feb1795b15c3d5a8ff44ce1d4ff764d912a11..7cbc30106c6aefd5d006b8ab2417b45e6c8022c8 100644
--- a/src/sieve-tools/Makefile.am
+++ b/src/sieve-tools/Makefile.am
@@ -1,6 +1,6 @@
 pkglibexecdir = $(libexecdir)/dovecot
 
-bin_PROGRAMS = sievec sieved sieve-test
+bin_PROGRAMS = sievec sieved sieve-test sieve-filter
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/lib-sieve \
@@ -12,22 +12,17 @@ AM_CPPFLAGS = \
 	-I$(dovecot_incdir)/src/lib-storage \
 	-I$(dovecot_incdir)/src/deliver
 
-sievec_LDFLAGS = -export-dynamic -Wl,--start-group 
-sieved_LDFLAGS = -export-dynamic -Wl,--start-group 
-sieve_test_LDFLAGS = -export-dynamic -Wl,--start-group
+#sievec_LDFLAGS = -export-dynamic -Wl,--start-group 
+#sieved_LDFLAGS = -export-dynamic -Wl,--start-group 
+#sieve_test_LDFLAGS = -export-dynamic -Wl,--start-group
+#sieve_filter_LDFLAGS = -export-dynamic -Wl,--start-group
 
 libs = \
 	$(top_srcdir)/src/lib-sieve/libsieve.la \
 	$(top_srcdir)/src/lib-sieve-tool/libsieve-tool.la \
 	$(dovecot_incdir)/src/lib-storage/list/libstorage_list.a \
 	$(dovecot_incdir)/src/lib-storage/register/libstorage-register.a \
-	$(STORAGE_LIBS) \
-	$(dovecot_incdir)/src/lib-storage/libstorage.a \
-	$(dovecot_incdir)/src/lib-index/libindex.a \
-	$(dovecot_incdir)/src/lib-imap/libimap.a \
-	$(dovecot_incdir)/src/lib-mail/libmail.a \
-	$(dovecot_incdir)/src/lib-charset/libcharset.a \
-	$(dovecot_incdir)/src/lib/liblib.a
+	$(STORAGE_LIBS) 
 
 ldadd = \
 	$(libs) \
@@ -38,10 +33,12 @@ ldadd = \
 sievec_LDADD = $(ldadd)
 sieved_LDADD = $(ldadd)
 sieve_test_LDADD = $(ldadd)
+sieve_filter_LDADD = $(ldadd)
 
 sievec_DEPENDENCIES = $(libs)
 sieved_DEPENDENCIES = $(libs)
 sieve_test_DEPENDENCIES = $(libs)
+sieve_filter_DEPENDENCIES = $(libs)
 
 sievec_SOURCES = \
 	sievec.c 
@@ -52,4 +49,7 @@ sieved_SOURCES = \
 sieve_test_SOURCES = \
 	sieve-test.c 
 
+sieve_filter_SOURCES = \
+	sieve-filter.c 
+
 noinst_HEADERS =
diff --git a/src/sieve-tools/sieve-filter.c b/src/sieve-tools/sieve-filter.c
new file mode 100644
index 0000000000000000000000000000000000000000..bf64c1c28205554d449401912d4783201d89286a
--- /dev/null
+++ b/src/sieve-tools/sieve-filter.c
@@ -0,0 +1,194 @@
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
+ */
+
+#include "lib.h"
+#include "ostream.h"
+#include "array.h"
+#include "mail-namespace.h"
+#include "mail-storage.h"
+#include "mail-search-build.h"
+#include "env-util.h"
+
+#include "sieve.h"
+#include "sieve-binary.h"
+
+#include "mail-raw.h"
+#include "sieve-tool.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+
+/*
+ * Print help
+ */
+
+static void print_help(void)
+{
+	printf(
+"Usage: sieve-filter [-m <mailbox>] [-x <extensions>]\n"
+"                    [-s <scriptfile>] [-c]\n"
+"                    <scriptfile> <mailstore>\n"
+	);
+}
+
+static int filter_mailbox(struct mailbox *box)
+{
+	struct mail_search_args *search_args;
+	struct mailbox_transaction_context *t;
+	struct mail_search_context *ctx;
+	struct mailbox_status status;
+	struct mail *mail;
+
+	search_args = mail_search_build_init();
+	mail_search_build_add_all(search_args);
+
+	if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ, STATUS_UIDVALIDITY, 
+		&status) < 0) {
+		i_fatal("sync failed");
+	}
+		
+	t = mailbox_transaction_begin(box, 0);
+	ctx = mailbox_search_init(t, search_args, NULL);
+
+	mail = mail_alloc(t, MAIL_FETCH_VIRTUAL_SIZE, NULL);
+	while ( mailbox_search_next(ctx, mail) > 0 ) {
+		const char *subject, *date;
+		
+		(void)mail_get_first_header(mail, "date", &date);
+		(void)mail_get_first_header(mail, "subject", &subject);
+		
+		printf("MAIL: [%s] %s\n", date, subject);
+	}
+	
+	mail_free(&mail);
+	
+	if ( mailbox_search_deinit(&ctx) < 0 ) {
+		i_error("failed to deinit search");
+	}
+
+	(void)mailbox_transaction_commit(&t);
+	
+	mail_search_args_unref(&search_args);
+
+	return FALSE;
+}
+
+/*
+ * Tool implementation
+ */
+
+int main(int argc, char **argv) 
+{
+	const char *scriptfile, *recipient, *sender, *mailbox, *mailstore, 
+		*extensions;
+	bool force_compile;
+	struct mail_namespace *ns = NULL;
+	struct mail_user *mail_user = NULL;
+	struct mail_storage *storage;
+	struct mailbox *box;
+	enum mail_error error;
+	enum mailbox_open_flags open_flags = 
+		MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT | 
+		MAILBOX_OPEN_POST_SESSION;
+	const char *user, *home;
+	int i;
+
+	sieve_tool_init();
+	
+	/* Parse arguments */
+	scriptfile = recipient = sender = mailstore = extensions = NULL;
+	mailbox = "INBOX";
+	force_compile = FALSE;
+	for (i = 1; i < argc; i++) {
+		if (strcmp(argv[i], "-m") == 0) {
+			/* default mailbox (keep box) */
+			i++;
+			if (i == argc) 
+				i_fatal("Missing -m argument");
+			mailbox = argv[i];
+		} else if (strcmp(argv[i], "-x") == 0) {
+			/* extensions */
+			i++;
+			if (i == argc)
+				i_fatal("Missing -x argument");
+			extensions = argv[i];
+		} else if (strcmp(argv[i], "-c") == 0) {
+			/* force compile */
+			force_compile = TRUE;
+		} else if ( scriptfile == NULL ) {
+			scriptfile = argv[i];
+		} else if ( mailstore == NULL ) {
+			mailstore = argv[i];
+		} else {
+			print_help();
+			i_fatal("Unknown argument: %s", argv[i]);
+		}
+	}
+	
+	if ( scriptfile == NULL ) {
+		print_help();
+		i_fatal("Missing <scriptfile> argument");
+	}
+	
+	if ( mailstore == NULL ) {
+		print_help();
+		i_fatal("Missing <mailfile> argument");
+	}
+
+	if ( extensions != NULL ) {
+		sieve_set_extensions(extensions);
+	}
+	
+	user = sieve_tool_get_user();
+	home = getenv("HOME");
+
+	/* Initialize mail storages */
+	mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL);
+	mail_storage_init();
+	mail_storage_register_all();
+	mailbox_list_register_all();
+
+	/* Obtain mail namespaces from -l argument */
+	if ( mailstore != NULL ) {
+		env_put(t_strdup_printf("NAMESPACE_1=%s", mailstore));
+		env_put("NAMESPACE_1_INBOX=1");
+		env_put("NAMESPACE_1_LIST=1");
+		env_put("NAMESPACE_1_SEP=.");
+		env_put("NAMESPACE_1_SUBSCRIPTIONS=1");
+
+		mail_user = mail_user_init(user);
+		mail_user_set_home(mail_user, home);
+		if (mail_namespaces_init(mail_user) < 0)
+			i_fatal("Namespace initialization failed");	
+
+		ns = mail_user->namespaces;
+	}
+
+	storage = ns->storage;
+
+	box = mailbox_open(&storage, mailbox, NULL, open_flags);
+	if ( box == NULL ) {
+		i_fatal("Couldn't open mailbox '%s': %s", 
+				mailbox, mail_storage_get_last_error(storage, &error));
+	}
+
+	filter_mailbox(box);
+	
+	if ( box != NULL )
+		mailbox_close(&box);
+
+	/* De-initialize mail user object */
+	if ( mail_user != NULL )
+		mail_user_unref(&mail_user);
+
+	/* De-initialize mail storages */
+	mail_storage_deinit();
+	mail_users_deinit();	
+	
+	sieve_tool_deinit();
+	
+	return 0;
+}