diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c
index ac962a720f4b90edf70c507fcad9cbe8bf9b4d7e..5d26cbfbdc3520fe32039a9573ec8f403abcc58c 100644
--- a/src/lib-sieve/ext-envelope.c
+++ b/src/lib-sieve/ext-envelope.c
@@ -167,7 +167,7 @@ static bool ext_envelope_opcode_dump
 	printf("ENVELOPE\n");
 
 	/* Handle any optional arguments */
-	if ( !sieve_addrmatch_default_dump_optionals(renv, address) )
+	if ( !sieve_addrmatch_default_dump_optionals(renv->sbin, address) )
 		return FALSE;
 
 	return
@@ -216,7 +216,7 @@ static bool ext_envelope_opcode_execute
 	printf("?? ENVELOPE\n");
 
 	if ( !sieve_addrmatch_default_get_optionals
-		(renv, address, &addrp, &mtch, &cmp) )
+		(renv->sbin, address, &addrp, &mtch, &cmp) )
 		return FALSE; 
 
 	t_push();
diff --git a/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c b/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c
index a8944b3d1befaf5dcdea2846807302fdfb4fbe0b..360cadb92899d80cb86c3f198456bf31736a0fb0 100644
--- a/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c
+++ b/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c
@@ -23,8 +23,7 @@
 
 static bool ext_cmp_i_ascii_numeric_load(int ext_id);
 static bool ext_cmp_i_ascii_numeric_validator_load(struct sieve_validator *validator);
-static bool ext_cmp_i_ascii_numeric_interpreter_load
-	(struct sieve_interpreter *interpreter);
+static bool ext_cmp_i_ascii_numeric_binary_load(struct sieve_binary *sbin);
 
 /* Extension definitions */
 
@@ -34,8 +33,9 @@ const struct sieve_extension comparator_i_ascii_numeric_extension = {
 	"comparator-i;ascii-numeric", 
 	ext_cmp_i_ascii_numeric_load,
 	ext_cmp_i_ascii_numeric_validator_load,
-	NULL, NULL,
-	ext_cmp_i_ascii_numeric_interpreter_load,  
+	NULL, 
+	ext_cmp_i_ascii_numeric_binary_load,  
+	NULL,
 	SIEVE_EXT_DEFINE_NO_OPCODES, 
 	NULL
 };
@@ -83,13 +83,12 @@ static bool ext_cmp_i_ascii_numeric_validator_load(struct sieve_validator *valid
 	return TRUE;
 }
 
-/* Load extension into interpreter */
+/* Load extension into binary */
 
-static bool ext_cmp_i_ascii_numeric_interpreter_load
-	(struct sieve_interpreter *interpreter)
+static bool ext_cmp_i_ascii_numeric_binary_load(struct sieve_binary *sbin)
 {
 	sieve_comparator_extension_set
-		(interpreter, ext_my_id, &i_ascii_numeric_comparator_ext);
+		(sbin, ext_my_id, &i_ascii_numeric_comparator_ext);
 	return TRUE;
 }
 
diff --git a/src/lib-sieve/plugins/imapflags/tst-hasflag.c b/src/lib-sieve/plugins/imapflags/tst-hasflag.c
index 79a4f79859ce5beb0f9e61d05c3ca7e8591f8535..bef34f518418fb6865d95070f4bb803823b2c4a5 100644
--- a/src/lib-sieve/plugins/imapflags/tst-hasflag.c
+++ b/src/lib-sieve/plugins/imapflags/tst-hasflag.c
@@ -174,10 +174,10 @@ static bool tst_hasflag_opcode_dump
 		while ( (opt_code=sieve_operand_optional_read(renv->sbin, address)) ) {
 			switch ( opt_code ) {
 			case OPT_COMPARATOR:
-				sieve_opr_comparator_dump(renv, address);
+				sieve_opr_comparator_dump(renv->sbin, address);
 				break;
 			case OPT_MATCH_TYPE:
-				sieve_opr_match_type_dump(renv, address);
+				sieve_opr_match_type_dump(renv->sbin, address);
 				break;
 			default: 
 				return FALSE;
@@ -213,10 +213,10 @@ static bool tst_hasflag_opcode_execute
 		while ( (opt_code=sieve_operand_optional_read(renv->sbin, address)) ) {
 			switch ( opt_code ) {
 			case OPT_COMPARATOR:
-				cmp = sieve_opr_comparator_read(renv, address);
+				cmp = sieve_opr_comparator_read(renv->sbin, address);
 				break;
 			case OPT_MATCH_TYPE:
-				mtch = sieve_opr_match_type_read(renv, address);
+				mtch = sieve_opr_match_type_read(renv->sbin, address);
 				break;
 			default:
 				return FALSE;
diff --git a/src/lib-sieve/plugins/regex/ext-regex.c b/src/lib-sieve/plugins/regex/ext-regex.c
index 3e66ba9914b650ec3f53d3f04f664a8cef94a193..e1d13144c89dbcc178c24957abc06dfcb8be8158 100644
--- a/src/lib-sieve/plugins/regex/ext-regex.c
+++ b/src/lib-sieve/plugins/regex/ext-regex.c
@@ -39,8 +39,7 @@
 
 static bool ext_regex_load(int ext_id);
 static bool ext_regex_validator_load(struct sieve_validator *validator);
-static bool ext_regex_interpreter_load
-	(struct sieve_interpreter *interpreter);
+static bool ext_regex_binary_load(struct sieve_binary *sbin);
 
 void mtch_regex_match_init(struct sieve_match_context *mctx);
 static bool mtch_regex_match
@@ -56,8 +55,9 @@ const struct sieve_extension regex_extension = {
 	"regex", 
 	ext_regex_load,
 	ext_regex_validator_load,
-	NULL, NULL,
-	ext_regex_interpreter_load,  
+	NULL, 
+	ext_regex_binary_load,
+	NULL,  
 	SIEVE_EXT_DEFINE_NO_OPCODES, 
 	NULL
 };
@@ -292,13 +292,12 @@ static bool ext_regex_validator_load(struct sieve_validator *validator)
 	return TRUE;
 }
 
-/* Load extension into interpreter */
+/* Load extension into binary */
 
-static bool ext_regex_interpreter_load
-	(struct sieve_interpreter *interpreter)
+static bool ext_regex_binary_load(struct sieve_binary *sbin)
 {
 	sieve_match_type_extension_set
-		(interpreter, ext_my_id, &regex_match_extension);
+		(sbin, ext_my_id, &regex_match_extension);
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/relational/ext-relational.c b/src/lib-sieve/plugins/relational/ext-relational.c
index 4860009a0bb1a2e076e0756da916c58922621777..cd748dfaa076cfc6f3ef7b241d91ddfbe80b93d5 100644
--- a/src/lib-sieve/plugins/relational/ext-relational.c
+++ b/src/lib-sieve/plugins/relational/ext-relational.c
@@ -35,8 +35,7 @@
 
 static bool ext_relational_load(int ext_id);
 static bool ext_relational_validator_load(struct sieve_validator *validator);
-static bool ext_relational_interpreter_load
-	(struct sieve_interpreter *interpreter);
+static bool ext_relational_binary_load(struct sieve_binary *sbin);
 
 /* Types */
 
@@ -70,8 +69,9 @@ const struct sieve_extension relational_extension = {
 	"relational", 
 	ext_relational_load,
 	ext_relational_validator_load,
-	NULL, NULL,
-	ext_relational_interpreter_load,  
+	NULL, 
+	ext_relational_binary_load,  
+	NULL,
 	SIEVE_EXT_DEFINE_NO_OPCODES, 
 	NULL
 };
@@ -362,13 +362,12 @@ static bool ext_relational_validator_load(struct sieve_validator *validator)
 	return TRUE;
 }
 
-/* Load extension into interpreter */
+/* Load extension into binary */
 
-static bool ext_relational_interpreter_load
-	(struct sieve_interpreter *interpreter)
+static bool ext_relational_binary_load(struct sieve_binary *sbin)
 {
 	sieve_match_type_extension_set
-		(interpreter, ext_my_id, &relational_match_extension);
+		(sbin, ext_my_id, &relational_match_extension);
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/relational/relational.sieve b/src/lib-sieve/plugins/relational/relational.sieve
index 22f655dad41acbd165e7adb8657c2b1d0852706d..a125a7c25a4992b5b85c73a577603ac79c53b155 100644
--- a/src/lib-sieve/plugins/relational/relational.sieve
+++ b/src/lib-sieve/plugins/relational/relational.sieve
@@ -1,4 +1,4 @@
-require ["comparator-i;ascii-numeric", "relational", "fileinto"];
+require ["relational", "comparator-i;ascii-numeric", "fileinto"];
 
 if header :value "eq" :comparator "i;ascii-numeric" "x-spam-score" "2" {
 	fileinto "INBOX.fail";
diff --git a/src/lib-sieve/plugins/subaddress/ext-subaddress.c b/src/lib-sieve/plugins/subaddress/ext-subaddress.c
index cdb73012d47470203025774ad6cfabce57a5787b..d706d65d2d7960c40b73d39d211fc373ba3c3bd8 100644
--- a/src/lib-sieve/plugins/subaddress/ext-subaddress.c
+++ b/src/lib-sieve/plugins/subaddress/ext-subaddress.c
@@ -31,8 +31,7 @@
 
 static bool ext_subaddress_load(int ext_id);
 static bool ext_subaddress_validator_load(struct sieve_validator *validator);
-static bool ext_subaddress_interpreter_load
-	(struct sieve_interpreter *interpreter);
+static bool ext_subaddress_binary_load(struct sieve_binary *sbin);
 
 /* Extension definitions */
 
@@ -42,8 +41,9 @@ const struct sieve_extension subaddress_extension = {
 	"subaddress", 
 	ext_subaddress_load,
 	ext_subaddress_validator_load,
-	NULL, NULL,
-	ext_subaddress_interpreter_load,  
+	NULL, 
+	ext_subaddress_binary_load,
+	NULL,  
 	SIEVE_EXT_DEFINE_NO_OPCODES, 
 	NULL
 };
@@ -135,13 +135,12 @@ static bool ext_subaddress_validator_load(struct sieve_validator *validator)
 	return TRUE;
 }
 
-/* Load extension into interpreter */
+/* Load extension into binary */
 
-static bool ext_subaddress_interpreter_load
-	(struct sieve_interpreter *interpreter)
+static bool ext_subaddress_binary_load(struct sieve_binary *sbin)
 {
 	sieve_address_part_extension_set
-		(interpreter, ext_my_id, &subaddress_addrp_extension);
+		(sbin, ext_my_id, &subaddress_addrp_extension);
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c
index bc347ab665486f502de546980e00a9bb7458729b..557bc9c6f4cbce68e14dc58ede7b7b020fe88682 100644
--- a/src/lib-sieve/sieve-address-parts.c
+++ b/src/lib-sieve/sieve-address-parts.c
@@ -37,14 +37,15 @@ static int ext_my_id = -1;
 
 static bool addrp_extension_load(int ext_id);
 static bool addrp_validator_load(struct sieve_validator *validator);
-static bool addrp_interpreter_load(struct sieve_interpreter *interp);
+static bool addrp_binary_load(struct sieve_binary *sbin);
 
 const struct sieve_extension address_part_extension = {
 	"@address-parts",
 	addrp_extension_load,
 	addrp_validator_load,
-	NULL, NULL,
-	addrp_interpreter_load,
+	NULL, 
+	addrp_binary_load,
+	NULL,
 	SIEVE_EXT_DEFINE_NO_OPCODES,
 	NULL
 };
@@ -151,30 +152,32 @@ void sieve_address_parts_link_tags
 }
 
 /*
- * Interpreter context:
+ * Binary context:
  *
  * FIXME: This code will be duplicated across all extensions that introduce 
- * a registry of some kind in the interpreter. 
+ * a registry of some kind in the binary. 
  */
 
-struct addrp_interpreter_context {
+struct addrp_binary_context {
 	ARRAY_DEFINE(addrp_extensions, 
 		const struct sieve_address_part_extension *); 
 };
 
-static inline struct addrp_interpreter_context *
-	get_interpreter_context(struct sieve_interpreter *interpreter)
+static inline struct addrp_binary_context *
+	get_binary_context(struct sieve_binary *sbin)
 {
-	return (struct addrp_interpreter_context *) 
-		sieve_interpreter_extension_get_context(interpreter, ext_my_id);
+	return (struct addrp_binary_context *) 
+		sieve_binary_extension_get_context(sbin, ext_my_id);
 }
 
-static const struct sieve_address_part_extension *sieve_address_part_extension_get
-	(struct sieve_interpreter *interpreter, int ext_id)
+static const struct sieve_address_part_extension *
+sieve_address_part_extension_get
+	(struct sieve_binary *sbin, int ext_id)
 {
-	struct addrp_interpreter_context *ctx = get_interpreter_context(interpreter);
+	struct addrp_binary_context *ctx = get_binary_context(sbin);
 	
-	if ( (ctx != NULL) && (ext_id > 0) && (ext_id < (int) array_count(&ctx->addrp_extensions)) ) {
+	if ( (ctx != NULL) && (ext_id > 0) && 
+		(ext_id < (int) array_count(&ctx->addrp_extensions)) ) {
 		const struct sieve_address_part_extension * const *ext;
 
 		ext = array_idx(&ctx->addrp_extensions, (unsigned int) ext_id);
@@ -186,25 +189,26 @@ static const struct sieve_address_part_extension *sieve_address_part_extension_g
 }
 
 void sieve_address_part_extension_set
-	(struct sieve_interpreter *interpreter, int ext_id,
+	(struct sieve_binary *sbin, int ext_id,
 		const struct sieve_address_part_extension *ext)
 {
-	struct addrp_interpreter_context *ctx = get_interpreter_context(interpreter);
+	struct addrp_binary_context *ctx = get_binary_context(sbin);
 
 	array_idx_set(&ctx->addrp_extensions, (unsigned int) ext_id, &ext);
 }
 
-static bool addrp_interpreter_load(struct sieve_interpreter *interpreter)
+static bool addrp_binary_load(struct sieve_binary *sbin)
 {
-	pool_t pool = sieve_interpreter_pool(interpreter);
+	pool_t pool = sieve_binary_pool(sbin);
 	
-	struct addrp_interpreter_context *ctx = 
-		p_new(pool, struct addrp_interpreter_context, 1);
+	struct addrp_binary_context *ctx = 
+		p_new(pool, struct addrp_binary_context, 1);
 	
 	/* Setup comparator registry */
 	p_array_init(&ctx->addrp_extensions, pool, 4);
 
-	sieve_interpreter_extension_set_context(interpreter, ext_my_id, ctx);
+	sieve_binary_extension_set_context
+		(sbin, ext_my_id, ctx);
 	
 	return TRUE;
 }
@@ -288,15 +292,15 @@ static void opr_address_part_emit_ext
 }
 
 const struct sieve_address_part *sieve_opr_address_part_read
-(const struct sieve_runtime_env *renv, sieve_size_t *address)
+(struct sieve_binary *sbin, sieve_size_t *address)
 {
 	unsigned int addrp_code;
-	const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
+	const struct sieve_operand *operand = sieve_operand_read(sbin, address);
 	
 	if ( operand == NULL || operand->class != &address_part_class ) 
 		return NULL;
 	
-	if ( sieve_binary_read_byte(renv->sbin, address, &addrp_code) ) {
+	if ( sieve_binary_read_byte(sbin, address, &addrp_code) ) {
 		if ( addrp_code < SIEVE_ADDRESS_PART_CUSTOM ) {
 			if ( addrp_code < sieve_core_address_parts_count )
 				return sieve_core_address_parts[addrp_code];
@@ -306,18 +310,18 @@ const struct sieve_address_part *sieve_opr_address_part_read
 			int ext_id = -1;
 			const struct sieve_address_part_extension *ap_ext;
 
-			if ( sieve_binary_extension_get_by_index(renv->sbin,
+			if ( sieve_binary_extension_get_by_index(sbin,
 				addrp_code - SIEVE_ADDRESS_PART_CUSTOM, &ext_id) == NULL )
 				return NULL; 
 
-			ap_ext = sieve_address_part_extension_get(renv->interp, ext_id); 
+			ap_ext = sieve_address_part_extension_get(sbin, ext_id); 
  
 			if ( ap_ext != NULL ) {  	
 				unsigned int code;
 				if ( ap_ext->address_part != NULL )
 					return ap_ext->address_part;
 		  	
-				if ( sieve_binary_read_byte(renv->sbin, address, &code) &&
+				if ( sieve_binary_read_byte(sbin, address, &code) &&
 					ap_ext->get_part != NULL )
 				return ap_ext->get_part(code);
 			} else {
@@ -330,11 +334,11 @@ const struct sieve_address_part *sieve_opr_address_part_read
 }
 
 bool sieve_opr_address_part_dump
-(const struct sieve_runtime_env *renv, sieve_size_t *address)
+(struct sieve_binary *sbin, sieve_size_t *address)
 {
 	sieve_size_t pc = *address;
 	const struct sieve_address_part *addrp = 
-		sieve_opr_address_part_read(renv, address);
+		sieve_opr_address_part_read(sbin, address);
 	
 	if ( addrp == NULL )
 		return FALSE;
@@ -407,23 +411,23 @@ bool sieve_address_match
  */
  
 bool sieve_addrmatch_default_dump_optionals
-(const struct sieve_runtime_env *renv, sieve_size_t *address) 
+(struct sieve_binary *sbin, sieve_size_t *address) 
 {
 	unsigned int opt_code;
 	
-	if ( sieve_operand_optional_present(renv->sbin, address) ) {
-		while ( (opt_code=sieve_operand_optional_read(renv->sbin, address)) ) {
+	if ( sieve_operand_optional_present(sbin, address) ) {
+		while ( (opt_code=sieve_operand_optional_read(sbin, address)) ) {
 			switch ( opt_code ) {
 			case SIEVE_AM_OPT_COMPARATOR:
-				if ( !sieve_opr_comparator_dump(renv, address) )
+				if ( !sieve_opr_comparator_dump(sbin, address) )
 					return FALSE;
 				break;
 			case SIEVE_AM_OPT_MATCH_TYPE:
-				if ( !sieve_opr_match_type_dump(renv, address) )
+				if ( !sieve_opr_match_type_dump(sbin, address) )
 					return FALSE;
 				break;
 			case SIEVE_AM_OPT_ADDRESS_PART:
-				if ( !sieve_opr_address_part_dump(renv, address) )
+				if ( !sieve_opr_address_part_dump(sbin, address) )
 					return FALSE;
 				break;
 			default:
@@ -436,25 +440,25 @@ bool sieve_addrmatch_default_dump_optionals
 }
 
 bool sieve_addrmatch_default_get_optionals
-(const struct sieve_runtime_env *renv, sieve_size_t *address, 
+(struct sieve_binary *sbin, sieve_size_t *address, 
 	const struct sieve_address_part **addrp, const struct sieve_match_type **mtch, 
 	const struct sieve_comparator **cmp) 
 {
 	unsigned int opt_code;
 	
-	if ( sieve_operand_optional_present(renv->sbin, address) ) {
-		while ( (opt_code=sieve_operand_optional_read(renv->sbin, address)) ) {
+	if ( sieve_operand_optional_present(sbin, address) ) {
+		while ( (opt_code=sieve_operand_optional_read(sbin, address)) ) {
 			switch ( opt_code ) {
 			case SIEVE_AM_OPT_COMPARATOR:
-				if ( (*cmp = sieve_opr_comparator_read(renv, address)) == NULL )
+				if ( (*cmp = sieve_opr_comparator_read(sbin, address)) == NULL )
 					return FALSE;
 				break;
 			case SIEVE_AM_OPT_MATCH_TYPE:
-				if ( (*mtch = sieve_opr_match_type_read(renv, address)) == NULL )
+				if ( (*mtch = sieve_opr_match_type_read(sbin, address)) == NULL )
 					return FALSE;
 				break;
 			case SIEVE_AM_OPT_ADDRESS_PART:
-				if ( (*addrp = sieve_opr_address_part_read(renv, address)) == NULL )
+				if ( (*addrp = sieve_opr_address_part_read(sbin, address)) == NULL )
 					return FALSE;
 				break;
 			default:
diff --git a/src/lib-sieve/sieve-address-parts.h b/src/lib-sieve/sieve-address-parts.h
index 253bc51e4442a14b2b06d72b02a91f28e1a3893e..5c2b4d00e2d58d1e1149a840292d56d4707fc3aa 100644
--- a/src/lib-sieve/sieve-address-parts.h
+++ b/src/lib-sieve/sieve-address-parts.h
@@ -47,8 +47,9 @@ void sieve_address_part_register
 const struct sieve_address_part *sieve_address_part_find
 	(struct sieve_validator *validator, const char *identifier,
 		int *ext_id);
+		
 void sieve_address_part_extension_set
-	(struct sieve_interpreter *interpreter, int ext_id,
+	(struct sieve_binary *sbin, int ext_id,
 		const struct sieve_address_part_extension *ext);
 
 extern const struct sieve_argument address_part_tag;
@@ -61,9 +62,9 @@ extern const struct sieve_address_part *sieve_core_address_parts[];
 extern const unsigned int sieve_core_address_parts_count;
 
 const struct sieve_address_part *sieve_opr_address_part_read
- 	(const struct sieve_runtime_env *renv, sieve_size_t *address);
+ 	(struct sieve_binary *sbin, sieve_size_t *address);
 bool sieve_opr_address_part_dump
-	(const struct sieve_runtime_env *renv, sieve_size_t *address);
+	(struct sieve_binary *sbin, sieve_size_t *address);
 
 /* Match utility */
 
@@ -79,9 +80,9 @@ enum sieve_addrmatch_opt_operand {
 };
 
 bool sieve_addrmatch_default_dump_optionals
-	(const struct sieve_runtime_env *renv, sieve_size_t *address);
+	(struct sieve_binary *sbin, sieve_size_t *address);
 bool sieve_addrmatch_default_get_optionals
-	(const struct sieve_runtime_env *renv, sieve_size_t *address, 
+	(struct sieve_binary *sbin, sieve_size_t *address, 
 		const struct sieve_address_part **addp, 
 		const struct sieve_match_type **mtch, const struct sieve_comparator **cmp);
 
diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c
index 9420032f15ddfecab70481da17780e524bb4833c..5d06b2a3c765da9c9a7056e529fcc6aa9cbbc822 100644
--- a/src/lib-sieve/sieve-binary.c
+++ b/src/lib-sieve/sieve-binary.c
@@ -66,6 +66,11 @@ inline sieve_size_t sieve_binary_get_code_size(struct sieve_binary *sbin)
 	return buffer_get_used_size(sbin->data);
 }
 
+inline pool_t sieve_binary_pool(struct sieve_binary *sbin)
+{
+	return sbin->pool;
+}
+
 void sieve_binary_load(struct sieve_binary *sbin)
 {
 	unsigned int i;
@@ -73,6 +78,15 @@ void sieve_binary_load(struct sieve_binary *sbin)
 	/* Currently only memory binary support */
 	sbin->code = buffer_get_data(sbin->data, &(sbin->code_size));			
 	
+	/* Pre-load core language features implemented as 'extensions' */
+	for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) {
+		const struct sieve_extension *ext = sieve_preloaded_extensions[i];
+		
+		if ( ext->binary_load != NULL )
+			(void)ext->binary_load(sbin);		
+	}
+	
+	/* Load other extensions into binary */
 	for ( i = 0; i < array_count(&sbin->extensions); i++ ) {
 		struct sieve_binary_extension * const *aext = 
 			array_idx(&sbin->extensions, i);
diff --git a/src/lib-sieve/sieve-binary.h b/src/lib-sieve/sieve-binary.h
index 0dff155c14a83a68b837dea36b5c6717bde0f899..b9818b62a632d5fe260b6ca57fccc214654e5453 100644
--- a/src/lib-sieve/sieve-binary.h
+++ b/src/lib-sieve/sieve-binary.h
@@ -12,6 +12,7 @@ struct sieve_binary *sieve_binary_create_new(void);
 void sieve_binary_ref(struct sieve_binary *sbin);
 void sieve_binary_unref(struct sieve_binary **sbin);
 
+inline pool_t sieve_binary_pool(struct sieve_binary *sbin);
 void sieve_binary_load(struct sieve_binary *sbin);
 
 /* 
diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c
index 321553fa6c796f0cad75aa5298f99ba2b1647c70..5eecf10bde3d4cdd2f3180408b920dc77e22c466 100644
--- a/src/lib-sieve/sieve-comparators.c
+++ b/src/lib-sieve/sieve-comparators.c
@@ -52,14 +52,15 @@ static int ext_my_id = -1;
 
 static bool cmp_extension_load(int ext_id);
 static bool cmp_validator_load(struct sieve_validator *validator);
-static bool cmp_interpreter_load(struct sieve_interpreter *interp);
+static bool cmp_binary_load(struct sieve_binary *sbin);
 
 const struct sieve_extension comparator_extension = {
 	"@comparators",
 	cmp_extension_load,
 	cmp_validator_load,
-	NULL, NULL,
-	cmp_interpreter_load,
+	NULL, 
+	cmp_binary_load,
+	NULL,
 	SIEVE_EXT_DEFINE_NO_OPCODES,
 	NULL
 };
@@ -161,22 +162,22 @@ bool cmp_validator_load(struct sieve_validator *validator)
  * Interpreter context:
  */
 
-struct cmp_interpreter_context {
+struct cmp_binary_context {
 	ARRAY_DEFINE(cmp_extensions, 
 		const struct sieve_comparator_extension *); 
 };
 
-static inline struct cmp_interpreter_context *
-	get_interpreter_context(struct sieve_interpreter *interpreter)
+static inline struct cmp_binary_context *
+	get_binary_context(struct sieve_binary *sbin)
 {
-	return (struct cmp_interpreter_context *) 
-		sieve_interpreter_extension_get_context(interpreter, ext_my_id);
+	return (struct cmp_binary_context *) 
+		sieve_binary_extension_get_context(sbin, ext_my_id);
 }
 
 static const struct sieve_comparator_extension *sieve_comparator_extension_get
-	(struct sieve_interpreter *interpreter, int ext_id)
+	(struct sieve_binary *sbin, int ext_id)
 {
-	struct cmp_interpreter_context *ctx = get_interpreter_context(interpreter);
+	struct cmp_binary_context *ctx = get_binary_context(sbin);
 	
 	if ( ext_id > 0 && ext_id < (int) array_count(&ctx->cmp_extensions) ) {
 		const struct sieve_comparator_extension * const *ext;
@@ -190,25 +191,25 @@ static const struct sieve_comparator_extension *sieve_comparator_extension_get
 }
 
 void sieve_comparator_extension_set
-	(struct sieve_interpreter *interpreter, int ext_id,
+	(struct sieve_binary *sbin, int ext_id,
 		const struct sieve_comparator_extension *ext)
 {
-	struct cmp_interpreter_context *ctx = get_interpreter_context(interpreter);
+	struct cmp_binary_context *ctx = get_binary_context(sbin);
 
 	array_idx_set(&ctx->cmp_extensions, (unsigned int) ext_id, &ext);
 }
 
-static bool cmp_interpreter_load(struct sieve_interpreter *interpreter)
+static bool cmp_binary_load(struct sieve_binary *sbin)
 {
-	pool_t pool = sieve_interpreter_pool(interpreter);
+	pool_t pool = sieve_binary_pool(sbin);
 	
-	struct cmp_interpreter_context *ctx = 
-		p_new(pool, struct cmp_interpreter_context, 1);
+	struct cmp_binary_context *ctx = 
+		p_new(pool, struct cmp_binary_context, 1);
 	
 	/* Setup comparator registry */
 	p_array_init(&ctx->cmp_extensions, pool, 4);
 
-	sieve_interpreter_extension_set_context(interpreter, ext_my_id, ctx);
+	sieve_binary_extension_set_context(sbin, ext_my_id, ctx);
 	
 	return TRUE;
 }
@@ -326,15 +327,15 @@ static void opr_comparator_emit_ext
 }
 
 const struct sieve_comparator *sieve_opr_comparator_read
-  (const struct sieve_runtime_env *renv, sieve_size_t *address)
+  (struct sieve_binary *sbin, sieve_size_t *address)
 {
 	unsigned int cmp_code;
-	const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
+	const struct sieve_operand *operand = sieve_operand_read(sbin, address);
 	
 	if ( operand == NULL || operand->class != &comparator_class ) 
 		return NULL;
 	
-	if ( sieve_binary_read_byte(renv->sbin, address, &cmp_code) ) {
+	if ( sieve_binary_read_byte(sbin, address, &cmp_code) ) {
 		if ( cmp_code < SIEVE_COMPARATOR_CUSTOM ) {
 			if ( cmp_code < sieve_core_comparators_count )
 				return sieve_core_comparators[cmp_code];
@@ -344,18 +345,18 @@ const struct sieve_comparator *sieve_opr_comparator_read
 			int ext_id = -1;
 			const struct sieve_comparator_extension *cmp_ext;
 
-			if ( sieve_binary_extension_get_by_index(renv->sbin,
+			if ( sieve_binary_extension_get_by_index(sbin,
 				cmp_code - SIEVE_COMPARATOR_CUSTOM, &ext_id) == NULL )
 				return NULL; 
 
-			cmp_ext = sieve_comparator_extension_get(renv->interp, ext_id); 
+			cmp_ext = sieve_comparator_extension_get(sbin, ext_id); 
  
 			if ( cmp_ext != NULL ) {  	
 				unsigned int code;
 				if ( cmp_ext->comparator != NULL )
 					return cmp_ext->comparator;
 		  	
-				if ( sieve_binary_read_byte(renv->sbin, address, &code) &&
+				if ( sieve_binary_read_byte(sbin, address, &code) &&
 					cmp_ext->get_comparator != NULL )
 					return cmp_ext->get_comparator(code);
 			} else {
@@ -368,11 +369,11 @@ const struct sieve_comparator *sieve_opr_comparator_read
 }
 
 bool sieve_opr_comparator_dump
-	(const struct sieve_runtime_env *renv, sieve_size_t *address)
+	(struct sieve_binary *sbin, sieve_size_t *address)
 {
 	sieve_size_t pc = *address;
 	const struct sieve_comparator *cmp = 
-		sieve_opr_comparator_read(renv, address);
+		sieve_opr_comparator_read(sbin, address);
 	
 	if ( cmp == NULL )
 		return FALSE;
diff --git a/src/lib-sieve/sieve-comparators.h b/src/lib-sieve/sieve-comparators.h
index 51a4bfedc8e5022cbe21e82e3131531593365f0a..66601ee74fddda938dc67f03dec404f3383cb8b9 100644
--- a/src/lib-sieve/sieve-comparators.h
+++ b/src/lib-sieve/sieve-comparators.h
@@ -71,12 +71,12 @@ const struct sieve_comparator *sieve_comparator_find
 		int *ext_id);
 
 const struct sieve_comparator *sieve_opr_comparator_read
-	(const struct sieve_runtime_env *renv, sieve_size_t *address);
+	(struct sieve_binary *sbin, sieve_size_t *address);
 bool sieve_opr_comparator_dump
-	(const struct sieve_runtime_env *renv, sieve_size_t *address);
+	(struct sieve_binary *sbin, sieve_size_t *address);
 
 void sieve_comparator_extension_set
-	(struct sieve_interpreter *interpreter, int ext_id,
+	(struct sieve_binary *sbin, int ext_id,
 		const struct sieve_comparator_extension *ext);
 
 #endif /* __SIEVE_COMPARATORS_H */
diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c
index 19e0e9c261de3223395cd0b820ced8f73e91b03d..9c260c4faaa5f2db185bfa5113c63b47892036f8 100644
--- a/src/lib-sieve/sieve-match-types.c
+++ b/src/lib-sieve/sieve-match-types.c
@@ -36,14 +36,15 @@ static int ext_my_id = -1;
 
 static bool mtch_extension_load(int ext_id);
 static bool mtch_validator_load(struct sieve_validator *validator);
-static bool mtch_interpreter_load(struct sieve_interpreter *interp);
+static bool mtch_binary_load(struct sieve_binary *sbin);
 
 const struct sieve_extension match_type_extension = {
 	"@match-types",
 	mtch_extension_load,
 	mtch_validator_load,
-	NULL, NULL,
-	mtch_interpreter_load,
+	NULL,
+	mtch_binary_load,
+	NULL,
 	SIEVE_EXT_DEFINE_NO_OPCODES,
 	NULL
 };
@@ -153,27 +154,28 @@ void sieve_match_types_link_tags
  * Interpreter context:
  *
  * FIXME: This code will be duplicated across all extensions that introduce 
- * a registry of some kind in the interpreter. 
+ * a registry of some kind in the binary. 
  */
 
-struct mtch_interpreter_context {
+struct mtch_binary_context {
 	ARRAY_DEFINE(mtch_extensions, 
 		const struct sieve_match_type_extension *); 
 };
 
-static inline struct mtch_interpreter_context *
-	get_interpreter_context(struct sieve_interpreter *interpreter)
+static inline struct mtch_binary_context *
+	get_binary_context(struct sieve_binary *sbin)
 {
-	return (struct mtch_interpreter_context *) 
-		sieve_interpreter_extension_get_context(interpreter, ext_my_id);
+	return (struct mtch_binary_context *) 
+		sieve_binary_extension_get_context(sbin, ext_my_id);
 }
 
 static const struct sieve_match_type_extension *sieve_match_type_extension_get
-	(struct sieve_interpreter *interpreter, int ext_id)
+	(struct sieve_binary *sbin, int ext_id)
 {
-	struct mtch_interpreter_context *ctx = get_interpreter_context(interpreter);
+	struct mtch_binary_context *ctx = get_binary_context(sbin);
 	
-	if ( (ctx != NULL) && (ext_id > 0) && (ext_id < (int) array_count(&ctx->mtch_extensions)) ) {
+	if ( (ctx != NULL) && (ext_id > 0) && 
+		(ext_id < (int) array_count(&ctx->mtch_extensions)) ) {
 		const struct sieve_match_type_extension * const *ext;
 
 		ext = array_idx(&ctx->mtch_extensions, (unsigned int) ext_id);
@@ -185,25 +187,26 @@ static const struct sieve_match_type_extension *sieve_match_type_extension_get
 }
 
 void sieve_match_type_extension_set
-	(struct sieve_interpreter *interpreter, int ext_id,
+	(struct sieve_binary *sbin, int ext_id,
 		const struct sieve_match_type_extension *ext)
 {
-	struct mtch_interpreter_context *ctx = get_interpreter_context(interpreter);
+	struct mtch_binary_context *ctx = get_binary_context(sbin);
 
 	array_idx_set(&ctx->mtch_extensions, (unsigned int) ext_id, &ext);
 }
 
-static bool mtch_interpreter_load(struct sieve_interpreter *interpreter)
+static bool mtch_binary_load(struct sieve_binary *sbin)
 {
-	pool_t pool = sieve_interpreter_pool(interpreter);
+	pool_t pool = sieve_binary_pool(sbin);
 	
-	struct mtch_interpreter_context *ctx = 
-		p_new(pool, struct mtch_interpreter_context, 1);
+	printf("BINARY MATCH-TYPES LOADED\n");
+	struct mtch_binary_context *ctx = 
+		p_new(pool, struct mtch_binary_context, 1);
 	
-	/* Setup comparator registry */
+	/* Setup match-type registry */
 	p_array_init(&ctx->mtch_extensions, pool, 4);
 
-	sieve_interpreter_extension_set_context(interpreter, ext_my_id, ctx);
+	sieve_binary_extension_set_context(sbin, ext_my_id, ctx);
 	
 	return TRUE;
 }
@@ -338,15 +341,15 @@ static void opr_match_type_emit_ext
 }
 
 const struct sieve_match_type *sieve_opr_match_type_read
-  (const struct sieve_runtime_env *renv, sieve_size_t *address)
+  (struct sieve_binary *sbin, sieve_size_t *address)
 {
 	unsigned int mtch_code;
-	const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
+	const struct sieve_operand *operand = sieve_operand_read(sbin, address);
 	
 	if ( operand == NULL || operand->class != &match_type_class ) 
 		return NULL;
 	
-	if ( sieve_binary_read_byte(renv->sbin, address, &mtch_code) ) {
+	if ( sieve_binary_read_byte(sbin, address, &mtch_code) ) {
 		if ( mtch_code < SIEVE_MATCH_TYPE_CUSTOM ) {
 			if ( mtch_code < sieve_core_match_types_count )
 				return sieve_core_match_types[mtch_code];
@@ -356,18 +359,18 @@ const struct sieve_match_type *sieve_opr_match_type_read
 			int ext_id = -1;
 			const struct sieve_match_type_extension *mtch_ext;
 
-			if ( sieve_binary_extension_get_by_index(renv->sbin,
+			if ( sieve_binary_extension_get_by_index(sbin,
 				mtch_code - SIEVE_MATCH_TYPE_CUSTOM, &ext_id) == NULL )
 				return NULL; 
 
-			mtch_ext = sieve_match_type_extension_get(renv->interp, ext_id); 
+			mtch_ext = sieve_match_type_extension_get(sbin, ext_id); 
  
 			if ( mtch_ext != NULL ) {  	
 				unsigned int code;
 				if ( mtch_ext->match_type != NULL )
 					return mtch_ext->match_type;
 		  	
-				if ( sieve_binary_read_byte(renv->sbin, address, &code) &&
+				if ( sieve_binary_read_byte(sbin, address, &code) &&
 					mtch_ext->get_match != NULL )
 					return mtch_ext->get_match(code);
 			} else {
@@ -380,11 +383,11 @@ const struct sieve_match_type *sieve_opr_match_type_read
 }
 
 bool sieve_opr_match_type_dump
-(const struct sieve_runtime_env *renv, sieve_size_t *address)
+(struct sieve_binary *sbin, sieve_size_t *address)
 {
 	sieve_size_t pc = *address;
 	const struct sieve_match_type *mtch = 
-		sieve_opr_match_type_read(renv, address);
+		sieve_opr_match_type_read(sbin, address);
 	
 	if ( mtch == NULL )
 		return FALSE;
diff --git a/src/lib-sieve/sieve-match-types.h b/src/lib-sieve/sieve-match-types.h
index d3eee1a81e3cec7174a55fa95176f751bb8eee4e..d60694ba2242b1ddc211681b167b747f0876545e 100644
--- a/src/lib-sieve/sieve-match-types.h
+++ b/src/lib-sieve/sieve-match-types.h
@@ -89,7 +89,7 @@ const struct sieve_match_type *sieve_match_type_find
 	(struct sieve_validator *validator, const char *identifier,
 		int *ext_id);
 void sieve_match_type_extension_set
-	(struct sieve_interpreter *interpreter, int ext_id,
+	(struct sieve_binary *sbin, int ext_id,
 		const struct sieve_match_type_extension *ext);
 
 extern const struct sieve_argument match_type_tag;
@@ -102,9 +102,9 @@ extern const struct sieve_match_type *sieve_core_match_types[];
 extern const unsigned int sieve_core_match_types_count;
 
 const struct sieve_match_type *sieve_opr_match_type_read
-	(const struct sieve_runtime_env *renv, sieve_size_t *address);
+	(struct sieve_binary *sbin, sieve_size_t *address);
 bool sieve_opr_match_type_dump
-	(const struct sieve_runtime_env *renv, sieve_size_t *address);
+	(struct sieve_binary *sbin, sieve_size_t *address);
 		
 /* Match Utility */
 
diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c
index 8c36d3df60631876906bcf0efcb78f5a060f49cb..5a28c922091290429d1f8019af2efdb7877fb856 100644
--- a/src/lib-sieve/tst-address.c
+++ b/src/lib-sieve/tst-address.c
@@ -116,7 +116,7 @@ static bool tst_address_opcode_dump
 	printf("ADDRESS\n");
 
 	//* Handle any optional arguments */
-	if ( !sieve_addrmatch_default_dump_optionals(renv, address) )
+	if ( !sieve_addrmatch_default_dump_optionals(renv->sbin, address) )
 		return FALSE;
 
 	return
@@ -142,7 +142,7 @@ static bool tst_address_opcode_execute
 	printf("?? ADDRESS\n");
 
 	if ( !sieve_addrmatch_default_get_optionals
-		(renv, address, &addrp, &mtch, &cmp) )
+		(renv->sbin, address, &addrp, &mtch, &cmp) )
 		return FALSE; 
 
 	t_push();
diff --git a/src/lib-sieve/tst-header.c b/src/lib-sieve/tst-header.c
index eddfb9bf731f757b6e96e9a1a92f45ba2c0cf4c2..02ade4a972c84cc725f2861f081359999454eaa1 100644
--- a/src/lib-sieve/tst-header.c
+++ b/src/lib-sieve/tst-header.c
@@ -126,10 +126,10 @@ static bool tst_header_opcode_dump
 		while ( (opt_code=sieve_operand_optional_read(renv->sbin, address)) ) {
 			switch ( opt_code ) {
 			case OPT_COMPARATOR:
-				sieve_opr_comparator_dump(renv, address);
+				sieve_opr_comparator_dump(renv->sbin, address);
 				break;
 			case OPT_MATCH_TYPE:
-				sieve_opr_match_type_dump(renv, address);
+				sieve_opr_match_type_dump(renv->sbin, address);
 				break;
 			default: 
 				return FALSE;
@@ -164,10 +164,10 @@ static bool tst_header_opcode_execute
 		while ( (opt_code=sieve_operand_optional_read(renv->sbin, address)) ) {
 			switch ( opt_code ) {
 			case OPT_COMPARATOR:
-				cmp = sieve_opr_comparator_read(renv, address);
+				cmp = sieve_opr_comparator_read(renv->sbin, address);
 				break;
 			case OPT_MATCH_TYPE:
-				mtch = sieve_opr_match_type_read(renv, address);
+				mtch = sieve_opr_match_type_read(renv->sbin, address);
 				break;
 			default:
 				return FALSE;