diff --git a/src/lib-sieve/plugins/body/ext-body-common.h b/src/lib-sieve/plugins/body/ext-body-common.h
index 66b4175771d42c89875ff7eabb1f50c8ffc3e680..67ebbc4b6eab8ea5154cc56c408c6361fade9aa4 100644
--- a/src/lib-sieve/plugins/body/ext-body-common.h
+++ b/src/lib-sieve/plugins/body/ext-body-common.h
@@ -1,9 +1,31 @@
+/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file
+ */
+ 
 #ifndef __EXT_BODY_COMMON_H
 #define __EXT_BODY_COMMON_H
 
-extern int ext_body_my_id;
+/*
+ * Extension
+ */
+ 
 extern const struct sieve_extension body_extension;
 
+/* 
+ * Commands
+ */
+
+extern const struct sieve_command body_test;
+ 
+/*
+ * Operations
+ */
+
+extern const struct sieve_operation body_operation;
+
+/*
+ * Message body part extraction
+ */
+
 struct ext_body_part {
 	const char *content;
 	unsigned long size;
diff --git a/src/lib-sieve/plugins/body/ext-body.c b/src/lib-sieve/plugins/body/ext-body.c
index dc8e8192da8526011098a3ec0980b5e3b8e2f367..2c5d6cce8b6db50202c673f1fc3db1546c5c9525 100644
--- a/src/lib-sieve/plugins/body/ext-body.c
+++ b/src/lib-sieve/plugins/body/ext-body.c
@@ -1,7 +1,10 @@
+/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file
+ */
+
 /* Extension body 
  * ------------------
  *
- * Authors: Stephan Bosch
+ * Authors: Stephan Bosch, original CMUSieve implementation by Timo Sirainen
  * Specification: RFC 5173
  * Implementation: full, but text body-transform implementation is simple
  * Status: experimental, largely untested
@@ -42,19 +45,7 @@
 #include "ext-body-common.h"
 
 /* 
- * Commands
- */
-
-extern const struct sieve_command body_test;
- 
-/*
- * Operations
- */
-
-extern const struct sieve_operation body_operation;
-
-/* 
- * Extension definitions 
+ * Extension 
  */
 
 int ext_body_my_id;
@@ -78,8 +69,6 @@ static bool ext_body_load(int ext_id)
 	return TRUE;
 }
 
-/* Load extension into validator */
-
 static bool ext_body_validator_load(struct sieve_validator *validator)
 {
 	/* Register new test */
diff --git a/src/lib-sieve/plugins/body/tst-body.c b/src/lib-sieve/plugins/body/tst-body.c
index 5ea705450f64e317cb23b4ed214bca91eebe0972..4730ba5b23429cc0b8af0a50dab2650f26c8d45e 100644
--- a/src/lib-sieve/plugins/body/tst-body.c
+++ b/src/lib-sieve/plugins/body/tst-body.c
@@ -1,3 +1,6 @@
+/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file
+ */
+ 
 #include "sieve-extensions.h"
 #include "sieve-commands.h"
 #include "sieve-code.h"
@@ -50,7 +53,9 @@ const struct sieve_command body_test = {
 	NULL 
 };
 
-/* Body operation */
+/* 
+ * Body operation 
+ */
 
 static bool ext_body_operation_dump
 	(const struct sieve_operation *op, 
@@ -76,15 +81,19 @@ enum tst_body_optional {
 };
 
 /* 
- * Custom command tags 
+ * Tagged arguments 
  */
 
+/* Forward declarations */
+
 static bool tag_body_transform_validate
 	(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
 		struct sieve_command_context *cmd);
 static bool tag_body_transform_generate	
 	(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
 		struct sieve_command_context *cmd);
+
+/* Argument objects */
  
 static const struct sieve_argument body_raw_tag = { 
 	"raw", 
@@ -109,6 +118,8 @@ static const struct sieve_argument body_text_tag = {
 	NULL, 
 	tag_body_transform_generate
 };
+
+/* Argument implementation */
  
 static bool tag_body_transform_validate
 (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
@@ -221,10 +232,7 @@ static bool tst_body_generate
 	(void)sieve_operation_emit_code(cgenv->sbin, &body_operation);
 
 	/* Generate arguments */
-	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
-		return FALSE;
-
-	return TRUE;
+	return sieve_generate_arguments(cgenv, ctx, NULL);
 }
 
 static bool tag_body_transform_generate
@@ -313,6 +321,7 @@ static int ext_body_operation_execute
 	struct sieve_match_context *mctx;
 	const char * const *content_types = _no_content_types;
 	struct ext_body_part *body_parts;
+	bool mvalues_active;
 	bool matched;
 
 	/*
@@ -362,22 +371,28 @@ static int ext_body_operation_execute
 		sieve_runtime_trace_error(renv, "invalid content-type-list operand");
 		return SIEVE_EXEC_BIN_CORRUPT;
 	}
+	
+	/*
+	 * Perform operation
+	 */
 
+	sieve_runtime_trace(renv, "BODY action");
+	
+	/* Extract requested parts */
+	
 	if ( !ext_body_get_content
 		(renv, content_types, transform != TST_BODY_TRANSFORM_RAW, &body_parts) ) {
 		return SIEVE_EXEC_FAILURE;
 	}
 
-	/*
-	 * Perform operation
-	 */
+	/* Disable match values processing as required by RFC */
+		
+	mvalues_active = sieve_match_values_set_enabled(renv->interp, FALSE);
 
-	sieve_runtime_trace(renv, "BODY action");
+	/* Iterate through all requested body parts to match */
 
+	matched = FALSE;	
 	mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); 	
-
-	/* Iterate through all requested body parts to match */
-	matched = FALSE;
 	while ( !matched && body_parts->content != NULL ) {
 		if ( (mret=sieve_match_value(mctx, body_parts->content, body_parts->size)) 	
 			< 0) 
@@ -397,7 +412,12 @@ static int ext_body_operation_execute
 	} else	
 		matched = ( mret > 0 || matched ); 	
 	
+	/* Restore match values processing */ 
+	
+	(void)sieve_match_values_set_enabled(renv->interp, mvalues_active);
+	
 	/* Set test result */	
+	
 	if ( ret == SIEVE_EXEC_OK )
 		sieve_interpreter_set_test_result(renv->interp, matched);
 
diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c
index be1af4c64efe6d3b71534eb86bc457744e95699c..f010855b16c4f2033e91ce72d870f316ff47d267 100644
--- a/src/lib-sieve/sieve-match-types.c
+++ b/src/lib-sieve/sieve-match-types.c
@@ -167,16 +167,19 @@ mtch_interpreter_context_init(struct sieve_interpreter *interp)
 bool sieve_match_values_set_enabled
 (struct sieve_interpreter *interp, bool enable)
 {
-	bool previous;
 	struct mtch_interpreter_context *ctx = get_interpreter_context(interp);
 	
 	if ( ctx == NULL && enable ) 
 		ctx = mtch_interpreter_context_init(interp);
 	
-	previous = ctx->match_values_enabled;
-	ctx->match_values_enabled = enable;
+	if ( ctx != NULL ) {
+		bool previous = ctx->match_values_enabled;
+		
+		ctx->match_values_enabled = enable;
+		return previous;
+	}
 	
-	return previous;
+	return FALSE;
 }
 
 bool sieve_match_values_are_enabled