diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index 7b8e78762da52d6a2da2bc6cf748ac9dce4d5982..31b64c0149e258e2f0f7c36fa30f5bc34daa7c57 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -159,6 +159,41 @@ struct sieve_binary *sieve_compile
 	return sbin;
 }
 
+/*
+ * Sieve runtime
+ */
+
+static int sieve_run
+(struct sieve_binary *sbin, struct sieve_result **result, 
+	const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, 
+	struct sieve_error_handler *ehandler)
+{
+	struct sieve_interpreter *interp;
+	int ret = 0;
+
+	/* Create the interpreter */
+	if ( (interp=sieve_interpreter_create(sbin, ehandler)) == NULL )
+		return SIEVE_EXEC_BIN_CORRUPT;
+
+	/* Reset execution status */
+	if ( senv->exec_status != NULL )
+		memset(senv->exec_status, 0, sizeof(*senv->exec_status));
+	
+	/* Create result object */
+	if ( *result == NULL )
+		*result = sieve_result_create(ehandler);
+	else
+		sieve_result_ref(*result);
+							
+	/* Run the interpreter */
+	ret = sieve_interpreter_run(interp, msgdata, senv, *result);
+	
+	/* Free the interpreter */
+	sieve_interpreter_free(&interp);
+
+	return ret;
+}
+
 /*
  * Reading/writing sieve binaries
  */
@@ -246,27 +281,12 @@ int sieve_test
 	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
 	struct ostream *stream) 	
 {
-	struct sieve_result *result;
-	struct sieve_interpreter *interp; 
-	int ret = 0;
-		
-	/* Create interpreter */
-	if ( (interp=sieve_interpreter_create(sbin, ehandler)) == NULL )
-		return SIEVE_EXEC_BIN_CORRUPT;
-
-	/* Reset execution status */
-	if ( senv->exec_status != NULL )
-		memset(senv->exec_status, 0, sizeof(*senv->exec_status));
+	struct sieve_result *result = NULL;
+	int ret;
 	
-	/* Create result object */	
-	result = sieve_result_create(ehandler);	
+	/* Run the script */
+	ret = sieve_run(sbin, &result, msgdata, senv, ehandler);
 				
-	/* Run interpreter */				
-	ret = sieve_interpreter_run(interp, msgdata, senv, result);
-
-	/* Free interpreter */
-	sieve_interpreter_free(&interp);
-		
 	/* Print result if successful */
 	if ( ret > 0 ) 
 		ret = sieve_result_print(result, senv, stream, NULL);
@@ -283,29 +303,14 @@ int sieve_test
 
 int sieve_execute
 (struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
-	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler) 	
+	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler)
 {
-	struct sieve_result *result;
-	struct sieve_interpreter *interp;
-	int ret = 0;
-
-	/* Create the interpreter */
-	if ( (interp=sieve_interpreter_create(sbin, ehandler)) == NULL )
-		return SIEVE_EXEC_BIN_CORRUPT;
-
-	/* Reset execution status */
-	if ( senv->exec_status != NULL )
-		memset(senv->exec_status, 0, sizeof(*senv->exec_status));
-	
-	/* Create result object */	
-	result = sieve_result_create(ehandler);	
-							
-	/* Run the interpreter */
-	ret = sieve_interpreter_run(interp, msgdata, senv, result);
-	
-	/* Free the interpreter */
-	sieve_interpreter_free(&interp);
+	struct sieve_result *result = NULL;
+	int ret;
 	
+	/* Run the script */
+	ret = sieve_run(sbin, &result, msgdata, senv, ehandler);
+		
 	/* Evaluate status and execute the result:
 	 *   Strange situations, e.g. currupt binaries, must be handled by the caller. 
 	 *   In that case no implicit keep is attempted, because the situation may be 
@@ -327,3 +332,86 @@ int sieve_execute
 
 	return ret;
 }
+
+/*
+ * Multiscript support
+ */
+ 
+struct sieve_multiscript {
+	struct sieve_result *result;
+	const struct sieve_message_data *msgdata;
+	const struct sieve_script_env *scriptenv;
+	struct sieve_error_handler *ehandler;
+	int status;
+};
+ 
+struct sieve_multiscript *sieve_multiscript_start
+(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
+	struct sieve_error_handler *ehandler)
+{
+	pool_t pool;
+	struct sieve_result *result;
+	struct sieve_multiscript *mscript;
+	
+	result = sieve_result_create(ehandler);
+	pool = sieve_result_pool(result);
+	
+	mscript = p_new(pool, struct sieve_multiscript, 1);
+	mscript->result = result;
+	mscript->msgdata = msgdata;
+	mscript->scriptenv = senv;
+	mscript->ehandler = ehandler;
+	mscript->status = SIEVE_EXEC_OK;
+	
+	return mscript;
+}
+
+int sieve_multiscript_test
+(struct sieve_multiscript *mscript, struct sieve_binary *sbin, 
+	struct ostream *stream)
+{	
+	/* Run the script */
+	mscript->status = sieve_run(sbin, &mscript->result, mscript->msgdata, 
+		mscript->scriptenv, mscript->ehandler);
+				
+	/* Print result if successful */
+	if ( mscript->status > 0 ) 
+		mscript->status = sieve_result_print
+			(mscript->result, mscript->scriptenv, stream, NULL);
+	
+	return mscript->status;
+}
+
+int sieve_multiscript_execute
+(struct sieve_multiscript *mscript, struct sieve_binary *sbin)
+{
+	if ( mscript->status <= 0 )
+		return mscript->status;
+
+	/* Run the script */
+	mscript->status = sieve_run(sbin, &mscript->result, mscript->msgdata, 
+		mscript->scriptenv, mscript->ehandler);
+		
+	if ( mscript->status >= 0 ) {
+		if ( mscript->status > 0 )
+			mscript->status = sieve_result_execute
+				(mscript->result, mscript->msgdata, mscript->scriptenv, NULL);
+		else {
+			if ( !sieve_result_implicit_keep
+				(mscript->result, mscript->msgdata, mscript->scriptenv) )
+				mscript->status = SIEVE_EXEC_KEEP_FAILED;
+		}
+	}
+
+	return mscript->status;
+}
+
+void sieve_multiscript_finish(struct sieve_multiscript **mscript)
+{
+	struct sieve_result *result = (*mscript)->result;
+	 
+	/* Cleanup */
+	sieve_result_unref(&result);
+	*mscript = NULL;
+}	
+
diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h
index cf0cd20a67fcaa4ab6763e21516cb93925593b0e..30f57164b2e7c911d9798051f094c41e8acc0802 100644
--- a/src/lib-sieve/sieve.h
+++ b/src/lib-sieve/sieve.h
@@ -112,5 +112,23 @@ int sieve_test
 int sieve_execute
 	(struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
 		const struct sieve_script_env *senv, struct sieve_error_handler *ehandler);
+		
+/*
+ * Multiscript support
+ */
+ 
+struct sieve_multiscript;
+ 
+struct sieve_multiscript *sieve_multiscript_start
+	(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
+		struct sieve_error_handler *ehandler);
+		
+int sieve_multiscript_test
+	(struct sieve_multiscript *mscript, struct sieve_binary *sbin, 
+		struct ostream *stream);
+int sieve_multiscript_execute
+	(struct sieve_multiscript *mscript, struct sieve_binary *sbin);
+	
+void sieve_multiscript_finish(struct sieve_multiscript **mscript);
 
 #endif