diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c
index 7f24e52a314b941febfe3e635faeb7b0d78a4dca..9cd364339d37b94e7b92aa64c0b33a0f7b5aee60 100644
--- a/src/lib-sieve/ext-envelope.c
+++ b/src/lib-sieve/ext-envelope.c
@@ -506,7 +506,7 @@ static int ext_envelope_operation_execute
 	}
 	
 	/* Finish match */
-	if ( (ret=sieve_match_end(mctx)) < 0 ) 
+	if ( (ret=sieve_match_end(&mctx)) < 0 ) 
 		result = FALSE;
 	else
 		matched = ( ret > 0 || matched );
diff --git a/src/lib-sieve/plugins/body/tst-body.c b/src/lib-sieve/plugins/body/tst-body.c
index edc7dc7cd3d9ce725b150e753895a24bac07d1dd..100c8ed25b7d2da2fc42400ba462db6de35e88c8 100644
--- a/src/lib-sieve/plugins/body/tst-body.c
+++ b/src/lib-sieve/plugins/body/tst-body.c
@@ -406,7 +406,7 @@ static int ext_body_operation_execute
 		body_parts++;	
 	}
 
-	if ( (mret=sieve_match_end(mctx)) < 0 ) {
+	if ( (mret=sieve_match_end(&mctx)) < 0 ) {
 		sieve_runtime_trace_error(renv, "invalid string list item");
 		ret = SIEVE_EXEC_BIN_CORRUPT;
 	} else	
diff --git a/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c b/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c
index 3a9b182d794996e8a0e23ca4296d95b0bb6f76ad..f37172c53ca6c19e8739cd0f686e935fdcf229b1 100644
--- a/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c
+++ b/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c
@@ -236,7 +236,7 @@ static int tst_notifymc_operation_execute
 			result = FALSE;
 		matched = ( mret > 0 );		
 
-		if ( (mret=sieve_match_end(mctx)) < 0 ) 
+		if ( (mret=sieve_match_end(&mctx)) < 0 ) 
 			result = FALSE;
 		matched = ( mret > 0 ) || matched;		
 	} else {
diff --git a/src/lib-sieve/plugins/environment/tst-environment.c b/src/lib-sieve/plugins/environment/tst-environment.c
index 0ae60630ca5fad112b457a6101ecd88228bd537c..8e13e1704d16a6bc0493576068ef20c4ba4d462e 100644
--- a/src/lib-sieve/plugins/environment/tst-environment.c
+++ b/src/lib-sieve/plugins/environment/tst-environment.c
@@ -210,7 +210,7 @@ static int tst_environment_operation_execute
 			matched = ( mret > 0 );				
 		}
 
-		if ( (mret=sieve_match_end(mctx)) < 0 )
+		if ( (mret=sieve_match_end(&mctx)) < 0 )
 			result = FALSE;
 		else
 			matched = ( mret > 0 || matched );
diff --git a/src/lib-sieve/plugins/imap4flags/tst-hasflag.c b/src/lib-sieve/plugins/imap4flags/tst-hasflag.c
index 127448a9370e7eecdb2870b86156412b5b97266a..23d7ca75d7f844c308ca1875a419efff5d0a0ebb 100644
--- a/src/lib-sieve/plugins/imap4flags/tst-hasflag.c
+++ b/src/lib-sieve/plugins/imap4flags/tst-hasflag.c
@@ -282,7 +282,7 @@ static int tst_hasflag_operation_execute
 		}
 	}
 
-	if ( (mret=sieve_match_end(mctx)) < 0 ) {
+	if ( (mret=sieve_match_end(&mctx)) < 0 ) {
 		result = FALSE;
 	} else
 		matched = ( mret > 0 || matched ); 	
diff --git a/src/lib-sieve/plugins/regex/mcht-regex.c b/src/lib-sieve/plugins/regex/mcht-regex.c
index be3a137b312c3c85cb46f34416067ad1c9238d80..4c4d416f717a8b12a1fb171367e1b9fb78737e79 100644
--- a/src/lib-sieve/plugins/regex/mcht-regex.c
+++ b/src/lib-sieve/plugins/regex/mcht-regex.c
@@ -178,16 +178,17 @@ struct mcht_regex_context {
 };
 
 static void mcht_regex_match_init
-	(struct sieve_match_context *mctx)
+(struct sieve_match_context *mctx)
 {
-	struct mcht_regex_context *ctx = 
-		t_new(struct mcht_regex_context, 1);
+	pool_t pool = mctx->pool;
+	struct mcht_regex_context *ctx;
 	
-	t_array_init(&ctx->reg_expressions, 4);
+	ctx = p_new(pool, struct mcht_regex_context, 1);
+	p_array_init(&ctx->reg_expressions, pool, 4);
 
 	ctx->value_index = -1;
 	if ( sieve_match_values_are_enabled(mctx->interp) ) {
-		ctx->pmatch = t_new(regmatch_t, MCHT_REGEX_MAX_SUBSTITUTIONS);
+		ctx->pmatch = p_new(pool, regmatch_t, MCHT_REGEX_MAX_SUBSTITUTIONS);
 		ctx->nmatch = MCHT_REGEX_MAX_SUBSTITUTIONS;
 	} else {
 		ctx->pmatch = NULL;
@@ -287,7 +288,7 @@ static int mcht_regex_match
 }
 
 int mcht_regex_match_deinit
-	(struct sieve_match_context *mctx)
+(struct sieve_match_context *mctx)
 {
 	struct mcht_regex_context *ctx = (struct mcht_regex_context *) mctx->data;
 	regex_t *regexps;
diff --git a/src/lib-sieve/plugins/relational/mcht-count.c b/src/lib-sieve/plugins/relational/mcht-count.c
index cf0296e12192d27d263a0cce2bd1079a94005205..61e44776d212af737231966bc905ae45a4ce5c0f 100644
--- a/src/lib-sieve/plugins/relational/mcht-count.c
+++ b/src/lib-sieve/plugins/relational/mcht-count.c
@@ -71,7 +71,7 @@ struct mcht_count_context {
 
 static void mcht_count_match_init(struct sieve_match_context *mctx)
 {
-	struct mcht_count_context *cctx = t_new(struct mcht_count_context, 1);
+	struct mcht_count_context *cctx = p_new(mctx->pool, struct mcht_count_context, 1);
 
 	cctx->count = 0;
 	mctx->data = (void *) cctx;
diff --git a/src/lib-sieve/plugins/variables/tst-string.c b/src/lib-sieve/plugins/variables/tst-string.c
index 08656c27e5f8a18718a287446e7db30daf031836..63179f52427ca325891aacb8d7d9b6c50e30c584 100644
--- a/src/lib-sieve/plugins/variables/tst-string.c
+++ b/src/lib-sieve/plugins/variables/tst-string.c
@@ -227,7 +227,7 @@ static int tst_string_operation_execute
 		matched = ( mret > 0 );				
 	}
 
-	if ( (mret=sieve_match_end(mctx)) < 0 ) 
+	if ( (mret=sieve_match_end(&mctx)) < 0 ) 
 		result = FALSE;
 	else
 		matched = ( mret > 0 || matched ); 	
diff --git a/src/lib-sieve/sieve-match.c b/src/lib-sieve/sieve-match.c
index 0be2a094ff6c367da1edcbaec2b21e150bef89ce..0c841dcab11acc4ae0aea19a6f690e71dd6c8961 100644
--- a/src/lib-sieve/sieve-match.c
+++ b/src/lib-sieve/sieve-match.c
@@ -29,8 +29,13 @@ struct sieve_match_context *sieve_match_begin
 	const struct sieve_match_key_extractor *kextract,
 	struct sieve_coded_stringlist *key_list)
 {
-	struct sieve_match_context *mctx = t_new(struct sieve_match_context, 1);  
+	struct sieve_match_context *mctx;
+	pool_t pool;
 
+	pool = pool_alloconly_create("sieve_match_context", 1024);
+	mctx = p_new(pool, struct sieve_match_context, 1);  
+
+	mctx->pool = pool;
 	mctx->interp = interp;
 	mctx->match_type = mtch;
 	mctx->comparator = cmp;
@@ -59,36 +64,35 @@ int sieve_match_value
 	if ( mtch->is_iterative ) {
 		unsigned int key_index = 0;
 		string_t *key_item = NULL;
+		int ret = 0;
 	
-		while ( (ok=sieve_coded_stringlist_next_item(mctx->key_list, &key_item)) && 
-			key_item != NULL ) 
-		{	
-			int ret;
-			
-			if ( mctx->kextract != NULL && mtch->allow_key_extract ) {
-				const struct sieve_match_key_extractor *kext = mctx->kextract;
-				void *kctx;
+		while ( (ok=sieve_coded_stringlist_next_item(mctx->key_list, &key_item)) 
+			&& key_item != NULL ) 
+		{				
+			T_BEGIN {
+				if ( mctx->kextract != NULL && mtch->allow_key_extract ) {
+					const struct sieve_match_key_extractor *kext = mctx->kextract;
+					void *kctx;
 				
-				if ( (ret=kext->init(&kctx, key_item)) > 0 ) {
-					const char *key;
-					size_t key_size;
+					if ( (ret=kext->init(&kctx, key_item)) > 0 ) {
+						const char *key;
+						size_t key_size;
 					 			
-					while ( (ret=kext->extract_key(kctx, &key, &key_size)) > 0 ) {				
-						ret = mtch->match(mctx, value, val_size, key, key_size, key_index);
+						while ( (ret=kext->extract_key(kctx, &key, &key_size)) > 0 ) {				
+							ret = mtch->match
+								(mctx, value, val_size, key, key_size, key_index);
 						
-						if ( ret != 0 ) break;
-					}
-				}  
-			} else {
-				ret = mtch->match(mctx, value, val_size, str_c(key_item), 
-						str_len(key_item), key_index);
-			}
+							if ( ret != 0 ) break;
+						}
+					}  
+				} else {
+					ret = mtch->match(mctx, value, val_size, str_c(key_item), 
+							str_len(key_item), key_index);
+				}
+			} T_END;
 			
-			if ( ret < 0 ) 
-				return ret;
-
-			if ( ret > 0 )
-				return TRUE;
+			if ( ret != 0 )
+				break;
 	
 			key_index++;
 		}
@@ -96,21 +100,35 @@ int sieve_match_value
 		if ( !ok ) 
 			return -1;
 
+		if ( ret < 0 ) 
+			return ret;
+		if ( ret > 0 )
+			return TRUE;
+
 	} else {
-		return mtch->match(mctx, value, val_size, NULL, 0, -1);
+		bool result;
+
+		T_BEGIN {
+			result = mtch->match(mctx, value, val_size, NULL, 0, -1);
+		} T_END;
+
+		return result;
 	}
 
 	return FALSE;
 }
 
-int sieve_match_end(struct sieve_match_context *mctx)
+int sieve_match_end(struct sieve_match_context **mctx)
 {
-	const struct sieve_match_type *mtch = mctx->match_type;
+	const struct sieve_match_type *mtch = (*mctx)->match_type;
 
 	if ( mtch->match_deinit != NULL ) {
-		return mtch->match_deinit(mctx);
+		return mtch->match_deinit(*mctx);
 	}
 
+    pool_unref(&(*mctx)->pool);
+    *mctx = NULL;
+
 	return FALSE;
 }
 
diff --git a/src/lib-sieve/sieve-match.h b/src/lib-sieve/sieve-match.h
index ea602f9b8e57bbe25efd9f7d3a2551b90c744d53..9f08faf05f68a419119f3c8c1e7a426e166bed36 100644
--- a/src/lib-sieve/sieve-match.h
+++ b/src/lib-sieve/sieve-match.h
@@ -16,6 +16,8 @@ struct sieve_match_key_extractor {
 };
 
 struct sieve_match_context {
+	pool_t pool;
+
 	struct sieve_interpreter *interp;
 	const struct sieve_match_type *match_type;
 	const struct sieve_comparator *comparator;
@@ -38,7 +40,7 @@ struct sieve_match_context *sieve_match_begin
 		struct sieve_coded_stringlist *key_list);
 int sieve_match_value
 	(struct sieve_match_context *mctx, const char *value, size_t val_size);
-int sieve_match_end(struct sieve_match_context *mctx);
+int sieve_match_end(struct sieve_match_context **mctx);
 
 /*
  * Read matching operands
diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c
index c9e4cdd1c0e977c4944960e0cc007579af8c683b..70bb3d0f0b566be7067cf3232318080da82bbba5 100644
--- a/src/lib-sieve/tst-address.c
+++ b/src/lib-sieve/tst-address.c
@@ -278,7 +278,7 @@ static int tst_address_operation_execute
 	
 	/* Finish match */
 
-	if ( (ret=sieve_match_end(mctx)) < 0 )
+	if ( (ret=sieve_match_end(&mctx)) < 0 )
 		result = FALSE;
 	else
 		matched = ( ret > 0 || matched );
diff --git a/src/lib-sieve/tst-header.c b/src/lib-sieve/tst-header.c
index b358d9375f15ddfaa9317569936d15aed18170b6..4243325614e05c1cae233284e7afaed0393e2bd6 100644
--- a/src/lib-sieve/tst-header.c
+++ b/src/lib-sieve/tst-header.c
@@ -233,7 +233,7 @@ static int tst_header_operation_execute
 	}
 
 	/* Finish match */
-	if ( (ret=sieve_match_end(mctx)) < 0 ) 
+	if ( (ret=sieve_match_end(&mctx)) < 0 ) 
 		result = FALSE;
 	else
 		matched = ( ret > 0 || matched );
diff --git a/src/testsuite/tst-test-error.c b/src/testsuite/tst-test-error.c
index 20fdd8cc7d96fb8bbc24d81ff57f722ea9f505ff..b3f4ddda60a1352ad6a3c508a553641137bbb746 100644
--- a/src/testsuite/tst-test-error.c
+++ b/src/testsuite/tst-test-error.c
@@ -289,7 +289,7 @@ static int tst_test_error_operation_execute
 	}
 
 	/* Finish match */
-	if ( (ret=sieve_match_end(mctx)) < 0 )
+	if ( (ret=sieve_match_end(&mctx)) < 0 )
 		result = FALSE;
 	else
 		matched = ( ret > 0 || matched );
diff --git a/src/testsuite/tst-test-result.c b/src/testsuite/tst-test-result.c
index 05e1274872dd8affd87179e9ce0915784ac0d38a..025ae2322c91931e4bc392f27d9e0e23b5700aa7 100644
--- a/src/testsuite/tst-test-result.c
+++ b/src/testsuite/tst-test-result.c
@@ -305,7 +305,7 @@ static int tst_test_result_operation_execute
 	}
 
 	/* Finish match */
-	if ( (ret=sieve_match_end(mctx)) < 0 )
+	if ( (ret=sieve_match_end(&mctx)) < 0 )
 		result = FALSE;
 	else
 		matched = ( ret > 0 || matched );