diff --git a/src/lib-sieve/cmd-discard.c b/src/lib-sieve/cmd-discard.c
index c5a459076d3e038a0b26d97ffa4be18320f9b5b4..5f9ba91bc1cec116628306d9aa97474e8e4ebb93 100644
--- a/src/lib-sieve/cmd-discard.c
+++ b/src/lib-sieve/cmd-discard.c
@@ -81,7 +81,7 @@ static bool cmd_discard_generate
 (const struct sieve_codegen_env *cgenv, 
 	struct sieve_command_context *ctx ATTR_UNUSED) 
 {
-	sieve_operation_emit_code(cgenv->sbin, &cmd_discard_operation, -1);
+	sieve_operation_emit_code(cgenv->sbin, &cmd_discard_operation);
 
 	/* Emit line number */
     sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
diff --git a/src/lib-sieve/cmd-if.c b/src/lib-sieve/cmd-if.c
index 0d0820f604fdf06e9f37e2706a457c249ca375b8..380240c342ed9d31d6b39c8c6b980d86ad0e3714 100644
--- a/src/lib-sieve/cmd-if.c
+++ b/src/lib-sieve/cmd-if.c
@@ -193,7 +193,7 @@ static bool cmd_if_generate
 		 * anyway. 
 		 */
 		if ( !sieve_command_block_exits_unconditionally(ctx) ) {
-			sieve_operation_emit_code(sbin, &sieve_jmp_operation, -1);
+			sieve_operation_emit_code(sbin, &sieve_jmp_operation);
 			ctx_data->exit_jump = sieve_binary_emit_offset(sbin, 0);
 			ctx_data->jump_generated = TRUE;
 		}
diff --git a/src/lib-sieve/cmd-keep.c b/src/lib-sieve/cmd-keep.c
index 3553180330ec1d1eb95763693ee2cc882a71ddbd..0d901da5028fd0be32f9bbfedc781563871f6085 100644
--- a/src/lib-sieve/cmd-keep.c
+++ b/src/lib-sieve/cmd-keep.c
@@ -61,7 +61,7 @@ static bool cmd_keep_generate
 	struct sieve_command_context *ctx ATTR_UNUSED) 
 {
 	/* Emit opcode */
-	sieve_operation_emit_code(cgenv->sbin, &cmd_keep_operation, -1);
+	sieve_operation_emit_code(cgenv->sbin, &cmd_keep_operation);
 
 	/* Emit line number */
     sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c
index 3dd41dc0f541effe9bc6e5bfc6a3a7288deecd90..575d02eeb9e00f7f3eee790ba5920fb4fe144fce 100644
--- a/src/lib-sieve/cmd-redirect.c
+++ b/src/lib-sieve/cmd-redirect.c
@@ -152,7 +152,7 @@ static bool cmd_redirect_validate
 static bool cmd_redirect_generate
 (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
-	sieve_operation_emit_code(cgenv->sbin, &cmd_redirect_operation, -1);
+	sieve_operation_emit_code(cgenv->sbin, &cmd_redirect_operation);
 
 	/* Emit line number */
 	sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
diff --git a/src/lib-sieve/cmd-require.c b/src/lib-sieve/cmd-require.c
index 2bc45d9484e672d6f1e70cf6235418f98ab70d3f..78ff2b206c19f0403a2f032929771a499c177062 100644
--- a/src/lib-sieve/cmd-require.c
+++ b/src/lib-sieve/cmd-require.c
@@ -59,22 +59,22 @@ static bool cmd_require_validate
 	arg = cmd->first_positional;
 	if ( sieve_ast_argument_type(arg) == SAAT_STRING ) {
 		/* Single string */
-		int ext_id = sieve_validator_extension_load
+		const struct sieve_extension *ext = sieve_validator_extension_load
 			(validator, cmd, sieve_ast_argument_strc(arg));	
 
-		if ( ext_id < 0 ) result = FALSE;
-		arg->context = (void *) ext_id;
+		if ( ext == NULL ) result = FALSE;
+		arg->context = (void *) ext;
 
 	} else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) {
 		/* String list */
 		struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg);
 		
 		while ( stritem != NULL ) {
-			int ext_id = sieve_validator_extension_load
+			const struct sieve_extension *ext = sieve_validator_extension_load
 				(validator, cmd, sieve_ast_strlist_strc(stritem));
 
-			if ( ext_id < 0 ) result = FALSE;
-			stritem->context = (void *) ext_id;
+			if ( ext == NULL ) result = FALSE;
+			stritem->context = (void *) ext;
 	
 			stritem = sieve_ast_strlist_next(stritem);
 		}
@@ -101,17 +101,19 @@ static bool cmd_require_generate
 	
 	if ( sieve_ast_argument_type(arg) == SAAT_STRING ) {
 		/* Single string */
-		int ext_id = (int) arg->context;
+		const struct sieve_extension *ext = 
+			(const struct sieve_extension *) arg->context;
 		
-		sieve_generator_link_extension(cgenv->gentr, ext_id);
+		sieve_generator_link_extension(cgenv->gentr, ext);
 	} else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) {
 		/* String list */
 		struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg);
 		
 		while ( stritem != NULL ) {
-			int ext_id = (int) stritem->context;
+			const struct sieve_extension *ext = 
+				(const struct sieve_extension *) stritem->context;
 		
-			sieve_generator_link_extension(cgenv->gentr, ext_id);
+			sieve_generator_link_extension(cgenv->gentr, ext);
 			
 			stritem = sieve_ast_strlist_next(stritem);
 		}
diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c
index 98c14f77b394220aa930fa9e606fe4cd1edd9ec3..eaec8270e152c9d59150fb527f888cf524262810 100644
--- a/src/lib-sieve/ext-envelope.c
+++ b/src/lib-sieve/ext-envelope.c
@@ -165,8 +165,7 @@ static bool tst_envelope_validate
 static bool tst_envelope_generate
 (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
-	(void)sieve_operation_emit_code
-		(cgenv->sbin, &envelope_operation, ext_my_id);
+	(void)sieve_operation_emit_code(cgenv->sbin, &envelope_operation);
 
 	/* Generate arguments */
 	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c
index 68a1ba06d40ec54bd2e8354ee64193507ac8ca82..c11b926bcc4b73342b533ced3345204765d32f05 100644
--- a/src/lib-sieve/ext-fileinto.c
+++ b/src/lib-sieve/ext-fileinto.c
@@ -128,7 +128,7 @@ static bool cmd_fileinto_validate
 static bool cmd_fileinto_generate
 (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
-	sieve_operation_emit_code(cgenv->sbin, &fileinto_operation, ext_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &fileinto_operation);
 
 	/* Emit line number */
     sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c
index 2435305f30804830ce342d18d08579d00d35ec97..ab29f9ef4ef399291e7a2649a27096f9a990867a 100644
--- a/src/lib-sieve/ext-reject.c
+++ b/src/lib-sieve/ext-reject.c
@@ -170,8 +170,7 @@ static bool cmd_reject_validate
 static bool cmd_reject_generate
 (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
-	sieve_operation_emit_code
-		(cgenv->sbin, &reject_operation, ext_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &reject_operation);
 
 	/* Emit line number */
     sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
diff --git a/src/lib-sieve/plugins/body/ext-body-common.c b/src/lib-sieve/plugins/body/ext-body-common.c
index ff169083487d7429c815250b170e004587270a2e..afbeb4f3682f34faa4c0033331bda952c3f9faf6 100644
--- a/src/lib-sieve/plugins/body/ext-body-common.c
+++ b/src/lib-sieve/plugins/body/ext-body-common.c
@@ -241,7 +241,7 @@ static struct ext_body_message_context *ext_body_get_context
 	struct ext_body_message_context *ctx;
 	
 	ctx = (struct ext_body_message_context *)
-		sieve_message_context_extension_get(msgctx, ext_body_my_id);
+		sieve_message_context_extension_get(msgctx, &body_extension);
 	
 	if ( ctx == NULL ) {
 		ctx = p_new(pool, struct ext_body_message_context, 1);	
@@ -251,7 +251,7 @@ static struct ext_body_message_context *ext_body_get_context
 		ctx->tmp_buffer = buffer_create_dynamic(pool, 1024*64);
 		
 		sieve_message_context_extension_set
-			(msgctx, ext_body_my_id, (void *) ctx);
+			(msgctx, &body_extension, (void *) ctx);
 	}
 	
 	return ctx;
diff --git a/src/lib-sieve/plugins/body/tst-body.c b/src/lib-sieve/plugins/body/tst-body.c
index 9d742dd13a9621252a1238d7d8d641c57a13e314..db50c38c0ffed12260c396635f856147110a8639 100644
--- a/src/lib-sieve/plugins/body/tst-body.c
+++ b/src/lib-sieve/plugins/body/tst-body.c
@@ -212,8 +212,7 @@ static bool tst_body_validate
 static bool tst_body_generate
 	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
-	(void)sieve_operation_emit_code
-		(cgenv->sbin, &body_operation, ext_body_my_id);
+	(void)sieve_operation_emit_code(cgenv->sbin, &body_operation);
 
 	/* Generate arguments */
 	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
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 f2e069d32e8c819e4640bf1a5cf391b48cf7aba9..19802006dec2fd205b3c1a3dd685f2947addcea3 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
@@ -83,8 +83,7 @@ const struct sieve_comparator i_ascii_numeric_comparator = {
 
 static bool ext_cmp_i_ascii_numeric_validator_load(struct sieve_validator *validator)
 {
-	sieve_comparator_register
-		(validator, &i_ascii_numeric_comparator, ext_my_id);
+	sieve_comparator_register(validator, &i_ascii_numeric_comparator);
 	return TRUE;
 }
 
diff --git a/src/lib-sieve/plugins/copy/ext-copy.c b/src/lib-sieve/plugins/copy/ext-copy.c
index 9153ce98092d7d00fac3dfb588687be9f325bcaa..87daf27bf155e71438af306605a441771796b9a2 100644
--- a/src/lib-sieve/plugins/copy/ext-copy.c
+++ b/src/lib-sieve/plugins/copy/ext-copy.c
@@ -105,7 +105,7 @@ static bool tag_copy_generate
         return FALSE;
     }
 
-    sieve_opr_side_effect_emit(cgenv->sbin, &copy_side_effect, ext_my_id);
+    sieve_opr_side_effect_emit(cgenv->sbin, &copy_side_effect);
 
     return TRUE;
 }
diff --git a/src/lib-sieve/plugins/imapflags/cmd-addflag.c b/src/lib-sieve/plugins/imapflags/cmd-addflag.c
index 029ca11fc0a9c08ff8ba84ca3ee2e82558424e64..17c11aa02e8cbda99e1fd34d6b09662bd67c3168 100644
--- a/src/lib-sieve/plugins/imapflags/cmd-addflag.c
+++ b/src/lib-sieve/plugins/imapflags/cmd-addflag.c
@@ -50,8 +50,7 @@ const struct sieve_operation addflag_operation = {
 static bool cmd_addflag_generate
 	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
 {
-	sieve_operation_emit_code	
-		(cgenv->sbin, &addflag_operation, ext_imapflags_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &addflag_operation);
 
 	/* Generate arguments */
 	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
diff --git a/src/lib-sieve/plugins/imapflags/cmd-removeflag.c b/src/lib-sieve/plugins/imapflags/cmd-removeflag.c
index 1a2459e523538d4942eb38a66d9dcd59927a52df..1ccb4846d594e74393193e38471cd2b08203426e 100644
--- a/src/lib-sieve/plugins/imapflags/cmd-removeflag.c
+++ b/src/lib-sieve/plugins/imapflags/cmd-removeflag.c
@@ -51,8 +51,7 @@ const struct sieve_operation removeflag_operation = {
 static bool cmd_removeflag_generate
 (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
 {
-	sieve_operation_emit_code
-		(cgenv->sbin, &removeflag_operation, ext_imapflags_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &removeflag_operation);
 
 	/* Generate arguments */
 	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
diff --git a/src/lib-sieve/plugins/imapflags/cmd-setflag.c b/src/lib-sieve/plugins/imapflags/cmd-setflag.c
index cac5d79f2d2854ef30bfcbb25dbfd5cefa85e2f0..74e03c6b86ae93d5d9bc9da793b648436d2ea5a6 100644
--- a/src/lib-sieve/plugins/imapflags/cmd-setflag.c
+++ b/src/lib-sieve/plugins/imapflags/cmd-setflag.c
@@ -49,8 +49,7 @@ const struct sieve_operation setflag_operation = {
 static bool cmd_setflag_generate
 (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
 {
-	sieve_operation_emit_code
-		(cgenv->sbin, &setflag_operation, ext_imapflags_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &setflag_operation);
 
 	/* Generate arguments */
 	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
index b448d5ceafdf0a5b83c77dcfc64d43e87f284211..3ebe325201b5d9978486032a7439a800c533000b 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
@@ -181,7 +181,7 @@ static inline struct ext_imapflags_result_context *
 {
 	struct ext_imapflags_result_context *rctx =
 		(struct ext_imapflags_result_context *) 
-		sieve_result_extension_get_context(result, ext_imapflags_my_id);
+		sieve_result_extension_get_context(result, &imapflags_extension);
 
 	if ( rctx == NULL ) {
 		pool_t pool = sieve_result_pool(result);
@@ -190,7 +190,7 @@ static inline struct ext_imapflags_result_context *
 		rctx->internal_flags = str_new(pool, 32);
 
 		sieve_result_extension_set_context
-			(result, ext_imapflags_my_id, rctx);
+			(result, &imapflags_extension, rctx);
 	}
 
 	return rctx;
diff --git a/src/lib-sieve/plugins/imapflags/tag-flags.c b/src/lib-sieve/plugins/imapflags/tag-flags.c
index 295baf921f5e7e6bdfddb3741c71815e77f4acc3..2b867fe2e00c494907998e7e2d23c6d76a3f78a4 100644
--- a/src/lib-sieve/plugins/imapflags/tag-flags.c
+++ b/src/lib-sieve/plugins/imapflags/tag-flags.c
@@ -110,7 +110,7 @@ static bool tag_flags_generate
 		return FALSE;
 	}
 
-	sieve_opr_side_effect_emit(cgenv->sbin, &flags_side_effect, ext_imapflags_my_id);
+	sieve_opr_side_effect_emit(cgenv->sbin, &flags_side_effect);
 	  
 	param = arg->parameters;
 
diff --git a/src/lib-sieve/plugins/imapflags/tst-hasflag.c b/src/lib-sieve/plugins/imapflags/tst-hasflag.c
index 7e1430368ab75d3b07bee427648f62f43c554bd7..d221bcf4145de050dd5f4afe18e7ab337fddfb66 100644
--- a/src/lib-sieve/plugins/imapflags/tst-hasflag.c
+++ b/src/lib-sieve/plugins/imapflags/tst-hasflag.c
@@ -100,8 +100,7 @@ static bool tst_hasflag_validate
 static bool tst_hasflag_generate
 	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
 {
-	sieve_operation_emit_code
-		(cgenv->sbin, &hasflag_operation, ext_imapflags_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &hasflag_operation);
 
 	/* Generate arguments */
 	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
diff --git a/src/lib-sieve/plugins/include/cmd-include.c b/src/lib-sieve/plugins/include/cmd-include.c
index ccae381801bb1b65be27370ce05fc144886cd372..2f4014fbaf9a3e5bb1f856c8d76b5df87bc4b22c 100644
--- a/src/lib-sieve/plugins/include/cmd-include.c
+++ b/src/lib-sieve/plugins/include/cmd-include.c
@@ -219,8 +219,7 @@ static bool cmd_include_generate
 		(cgenv, cmd, ctx_data->location, ctx_data->script, &block_id) )
  		return FALSE;
  		
- 	sieve_operation_emit_code	
-		(cgenv->sbin, &include_operation, ext_include_my_id);
+ 	sieve_operation_emit_code(cgenv->sbin, &include_operation);
 	sieve_binary_emit_offset(cgenv->sbin, block_id); 
  	 		
 	return TRUE;
diff --git a/src/lib-sieve/plugins/include/cmd-return.c b/src/lib-sieve/plugins/include/cmd-return.c
index 88e47cfc603c3c3e42d3015be6019705ef75e58f..0dc9dc998b1b1785bf3cb76109752b4cabd2686b 100644
--- a/src/lib-sieve/plugins/include/cmd-return.c
+++ b/src/lib-sieve/plugins/include/cmd-return.c
@@ -50,8 +50,7 @@ static bool cmd_return_generate
 (const struct sieve_codegen_env *cgenv, 
 	struct sieve_command_context *ctx ATTR_UNUSED) 
 {
-	sieve_operation_emit_code	
-		(cgenv->sbin, &return_operation, ext_include_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &return_operation);
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/include/ext-include-binary.c b/src/lib-sieve/plugins/include/ext-include-binary.c
index 51d933a84f216df5e3268ff1018fd02c98511e9c..bdef393abcbdbb7698620cea0dcba9f4030b6a64 100644
--- a/src/lib-sieve/plugins/include/ext-include-binary.c
+++ b/src/lib-sieve/plugins/include/ext-include-binary.c
@@ -72,11 +72,11 @@ static inline struct ext_include_binary_context *ext_include_binary_get_context
 (struct sieve_binary *sbin)
 {	
 	struct ext_include_binary_context *ctx = (struct ext_include_binary_context *)
-		sieve_binary_extension_get_context(sbin, ext_include_my_id);
+		sieve_binary_extension_get_context(sbin, &include_extension);
 	
 	if ( ctx == NULL ) {
 		ctx = ext_include_binary_create_context(sbin);
-		sieve_binary_extension_set_context(sbin, ext_include_my_id, ctx);
+		sieve_binary_extension_set_context(sbin, &include_extension, ctx);
 	};
 	
 	return ctx;
@@ -97,7 +97,7 @@ struct ext_include_binary_context *ext_include_binary_init
 	/* Create dependency block */
 	if ( ctx->dependency_block == 0 )
 		ctx->dependency_block = 
-			sieve_binary_extension_create_block(sbin, ext_include_my_id);
+			sieve_binary_extension_create_block(sbin, &include_extension);
 			
 	return ctx;
 }
@@ -169,7 +169,7 @@ static bool ext_include_binary_open(struct sieve_binary *sbin)
 	unsigned int block, prvblk, depcount, i;
 	sieve_size_t offset;
 	
-	block = sieve_binary_extension_get_block(sbin, ext_include_my_id);
+	block = sieve_binary_extension_get_block(sbin, &include_extension);
 	
 	if ( !sieve_binary_block_set_active(sbin, block, &prvblk) )
 		return FALSE; 
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index 318b71eb370594f3d4a102ca85db26f742ea78d0..efc9c8186a5feaddadf889ce339a8357e3aa5c04 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -92,14 +92,14 @@ static inline struct ext_include_generator_context *
 (struct sieve_generator *gentr)
 {
 	return (struct ext_include_generator_context *)
-		sieve_generator_extension_get_context(gentr, ext_include_my_id);
+		sieve_generator_extension_get_context(gentr, &include_extension);
 }
 
 static inline void ext_include_initialize_generator_context
 (struct sieve_generator *gentr, struct ext_include_generator_context *parent, 
 	struct sieve_script *script)
 {
-	sieve_generator_extension_set_context(gentr, ext_include_my_id,
+	sieve_generator_extension_set_context(gentr, &include_extension,
 		ext_include_create_generator_context(gentr, parent, script));
 }
 
@@ -114,7 +114,7 @@ void ext_include_register_generator_context
 		ctx = ext_include_create_generator_context(gentr, NULL, script);
 		
 		sieve_generator_extension_set_context
-			(gentr, ext_include_my_id, (void *) ctx);		
+			(gentr, &include_extension, (void *) ctx);		
 	}
 }
 
@@ -150,7 +150,7 @@ static inline struct ext_include_interpreter_context *
 (struct sieve_interpreter *interp)
 {
 	return (struct ext_include_interpreter_context *)
-		sieve_interpreter_extension_get_context(interp, ext_include_my_id);
+		sieve_interpreter_extension_get_context(interp, &include_extension);
 }
 
 static inline struct ext_include_interpreter_context *
@@ -162,7 +162,7 @@ static inline struct ext_include_interpreter_context *
 	struct ext_include_interpreter_context *ctx = 
 		ext_include_create_interpreter_context(interp, parent, script, block_id);
 		
-	sieve_interpreter_extension_set_context(interp, ext_include_my_id, ctx);
+	sieve_interpreter_extension_set_context(interp, &include_extension, ctx);
 	
 	return ctx;
 }
@@ -179,7 +179,7 @@ void ext_include_interpreter_context_init
 			(interp, NULL, script, SBIN_SYSBLOCK_MAIN_PROGRAM);
 		
 		sieve_interpreter_extension_set_context
-			(interp, ext_include_my_id, (void *) ctx);		
+			(interp, &include_extension, (void *) ctx);		
 	}
 }
 
@@ -321,8 +321,8 @@ bool ext_include_execute_include
 			(subinterp, ctx, NULL, block_id);
 			
 		/* Create variable storage for global variables */
-		varstrg = sieve_ext_variables_get_storage(renv->interp, ext_include_my_id);
-		sieve_ext_variables_set_storage(subinterp, varstrg, ext_include_my_id);
+		varstrg = sieve_ext_variables_get_storage(renv->interp, &include_extension);
+		sieve_ext_variables_set_storage(subinterp, varstrg, &include_extension);
 	
 		/* Activate and start the top-level included script */
 		if ( sieve_binary_block_set_active(renv->sbin, block_id, &this_block_id) ) 			
diff --git a/src/lib-sieve/plugins/include/ext-include-variables.c b/src/lib-sieve/plugins/include/ext-include-variables.c
index 2d89d979e2a6c2fbfb812a36c753707e6b642e52..da749379737d53c7df2f62c7cbc109f964d068b6 100644
--- a/src/lib-sieve/plugins/include/ext-include-variables.c
+++ b/src/lib-sieve/plugins/include/ext-include-variables.c
@@ -31,16 +31,16 @@ struct ext_include_ast_context *ext_include_create_ast_context
 
 	pool_t pool = sieve_ast_pool(ast);
 	ctx = p_new(pool, struct ext_include_ast_context, 1);
-	ctx->import_vars = sieve_variable_scope_create(pool, ext_include_my_id);
+	ctx->import_vars = sieve_variable_scope_create(pool, &include_extension);
 	
 	if ( parent != NULL ) {
 		struct ext_include_ast_context *parent_ctx = 
 			(struct ext_include_ast_context *)
-			sieve_ast_extension_get_context(parent, ext_include_my_id);
+			sieve_ast_extension_get_context(parent, &include_extension);
 		ctx->global_vars = ( parent_ctx == NULL ? NULL : parent_ctx->global_vars );
 	}
 	
-	sieve_ast_extension_set_context(ast, ext_include_my_id, ctx);
+	sieve_ast_extension_set_context(ast, &include_extension, ctx);
 	
 	return ctx;
 }
@@ -49,7 +49,7 @@ static inline struct ext_include_ast_context *
 	ext_include_get_ast_context(struct sieve_ast *ast)
 {
 	struct ext_include_ast_context *ctx = (struct ext_include_ast_context *)
-		sieve_ast_extension_get_context(ast, ext_include_my_id);
+		sieve_ast_extension_get_context(ast, &include_extension);
 		
 	if ( ctx == NULL ) {
 		ctx = ext_include_create_ast_context(ast, NULL);	
@@ -81,7 +81,7 @@ bool ext_include_variable_import_global
 	
 		if ( ctx->global_vars == NULL ) {
 			pool_t pool = sieve_ast_pool(ast);
-			ctx->global_vars = sieve_variable_scope_create(pool, ext_include_my_id);
+			ctx->global_vars = sieve_variable_scope_create(pool, &include_extension);
 		}
 		
 		var = sieve_variable_scope_get_variable(ctx->global_vars, variable, TRUE);
diff --git a/src/lib-sieve/plugins/include/ext-include.c b/src/lib-sieve/plugins/include/ext-include.c
index 47e9bb778c7b6e62b11f46defaece288bd3bd83f..1a51cb4f371e1282c4f23ca4580f3f204d9c9b2e 100644
--- a/src/lib-sieve/plugins/include/ext-include.c
+++ b/src/lib-sieve/plugins/include/ext-include.c
@@ -110,7 +110,7 @@ static bool ext_include_binary_load(struct sieve_binary *sbin)
 	 * opening or saving the binary. The implemententation of these hooks is found
 	 * in ext-include-binary.c
 	 */
-	sieve_binary_extension_set(sbin, ext_include_my_id, &include_binary_ext);
+	sieve_binary_extension_set(sbin, &include_extension, &include_binary_ext);
 	
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/regex/ext-regex.c b/src/lib-sieve/plugins/regex/ext-regex.c
index c62cb95da26baf83bae2f749f9d21cdc853abb90..0606315a8c51ad67d8ad3375daaf276ad8686543 100644
--- a/src/lib-sieve/plugins/regex/ext-regex.c
+++ b/src/lib-sieve/plugins/regex/ext-regex.c
@@ -68,8 +68,7 @@ static bool ext_regex_load(int ext_id)
 
 static bool ext_regex_validator_load(struct sieve_validator *validator)
 {
-	sieve_match_type_register
-		(validator, &regex_match_type, ext_my_id); 
+	sieve_match_type_register(validator, &regex_match_type); 
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/relational/ext-relational.c b/src/lib-sieve/plugins/relational/ext-relational.c
index 6555777b8d95c4a0d111145162a43a4f696b963e..b31ad299cf6d6efa500312979aa41cc07ae035e8 100644
--- a/src/lib-sieve/plugins/relational/ext-relational.c
+++ b/src/lib-sieve/plugins/relational/ext-relational.c
@@ -59,10 +59,8 @@ static bool ext_relational_load(int ext_id)
 
 static bool ext_relational_validator_load(struct sieve_validator *validator)
 {
-	sieve_match_type_register
-		(validator, &value_match_type, ext_relational_my_id); 
-	sieve_match_type_register
-		(validator, &count_match_type, ext_relational_my_id); 
+	sieve_match_type_register(validator, &value_match_type); 
+	sieve_match_type_register(validator, &count_match_type); 
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/subaddress/ext-subaddress.c b/src/lib-sieve/plugins/subaddress/ext-subaddress.c
index d7489640d4f05d29ffdaed7614ecbcac99f1c728..ab1b66ae4338501c501ca69dc3e37c0d5439df4d 100644
--- a/src/lib-sieve/plugins/subaddress/ext-subaddress.c
+++ b/src/lib-sieve/plugins/subaddress/ext-subaddress.c
@@ -112,10 +112,8 @@ static struct sieve_operand subaddress_operand = {
 
 static bool ext_subaddress_validator_load(struct sieve_validator *validator)
 {
-	sieve_address_part_register
-		(validator, &user_address_part, ext_my_id); 
-	sieve_address_part_register
-		(validator, &detail_address_part, ext_my_id); 
+	sieve_address_part_register(validator, &user_address_part); 
+	sieve_address_part_register(validator, &detail_address_part); 
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c
index 3fc7b3497db8b58836754fae97366e7c37737259..a23a4fd0ce7f3039b2c96dc4bc7303e035be9b69 100644
--- a/src/lib-sieve/plugins/vacation/cmd-vacation.c
+++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c
@@ -311,8 +311,7 @@ static bool cmd_vacation_validate
 static bool cmd_vacation_generate
 (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
-	sieve_operation_emit_code
-		(cgenv->sbin, &vacation_operation, ext_vacation_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &vacation_operation);
 
 	/* Emit source line */
 	sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
diff --git a/src/lib-sieve/plugins/variables/cmd-set.c b/src/lib-sieve/plugins/variables/cmd-set.c
index a94d0ed030d78760799b7f56fef0ad80094f2bb3..b7bb521cfe91fe0a2e7ef57286bdd51b504bc4c5 100644
--- a/src/lib-sieve/plugins/variables/cmd-set.c
+++ b/src/lib-sieve/plugins/variables/cmd-set.c
@@ -64,13 +64,8 @@ const struct sieve_operation cmd_set_operation = {
 
 /* Compiler context */
 
-struct cmd_set_modifier_context {
-	const struct sieve_variables_modifier *modifier;
-	int ext_id;
-};
-
 struct cmd_set_context {
-	ARRAY_DEFINE(modifiers, struct cmd_set_modifier_context *);
+	ARRAY_DEFINE(modifiers, const struct sieve_variables_modifier *);
 };
 
 /* 
@@ -104,26 +99,15 @@ const struct sieve_argument modifier_tag = {
  
 static bool tag_modifier_is_instance_of
 (struct sieve_validator *validator ATTR_UNUSED, 
-	struct sieve_command_context *cmdctx,	
+	struct sieve_command_context *cmdctx ATTR_UNUSED,	
 	struct sieve_ast_argument *arg)
 {	
-	int ext_id;
 	const struct sieve_variables_modifier *modf = ext_variables_modifier_find
-		(validator, sieve_ast_argument_tag(arg), &ext_id);
-		
-	if ( modf != NULL ) {
-		pool_t pool = sieve_command_pool(cmdctx);
-		
-		struct cmd_set_modifier_context *ctx = 
-			p_new(pool, struct cmd_set_modifier_context, 1);
-		ctx->modifier = modf;
-		ctx->ext_id = ext_id;
-		
-		arg->context = ctx;
-		return TRUE;
-	}
+		(validator, sieve_ast_argument_tag(arg));
+
+	arg->context = (void *) modf;
 		
-	return FALSE;
+	return ( modf != NULL );
 }
 
 static bool tag_modifier_validate
@@ -132,32 +116,31 @@ static bool tag_modifier_validate
 {
 	unsigned int i;
 	bool inserted;
-	struct cmd_set_modifier_context *mctx = (*arg)->context;
-	const struct sieve_variables_modifier *modf = mctx->modifier;
+	const struct sieve_variables_modifier *modf = 
+		(const struct sieve_variables_modifier *) (*arg)->context;
 	struct cmd_set_context *sctx = (struct cmd_set_context *) cmd->data;
 	
 	inserted = FALSE;
 	for ( i = 0; i < array_count(&sctx->modifiers) && !inserted; i++ ) {
-		struct cmd_set_modifier_context * const *smctx =
+		const struct sieve_variables_modifier * const *smdf =
 			array_idx(&sctx->modifiers, i);
-		const struct sieve_variables_modifier *smdf = (*smctx)->modifier;
 	
-		if ( smdf->precedence == modf->precedence ) {
+		if ( (*smdf)->precedence == modf->precedence ) {
 			sieve_command_validate_error(validator, cmd, 
 				"modifiers :%s and :%s specified for the set command conflict "
 				"having equal precedence", 
-				smdf->object.identifier, modf->object.identifier);
+				(*smdf)->object.identifier, modf->object.identifier);
 			return FALSE;
 		}
 			
-		if ( smdf->precedence < modf->precedence ) {
-			array_insert(&sctx->modifiers, i, &mctx, 1);
+		if ( (*smdf)->precedence < modf->precedence ) {
+			array_insert(&sctx->modifiers, i, &modf, 1);
 			inserted = TRUE;
 		}
 	}
 	
 	if ( !inserted )
-		array_append(&sctx->modifiers, &mctx, 1);
+		array_append(&sctx->modifiers, &modf, 1);
 	
 	/* Added to modifier list; self-destruct to prevent duplicate generation */
 	*arg = sieve_ast_arguments_detach(*arg, 1);
@@ -227,8 +210,7 @@ static bool cmd_set_generate
 	struct cmd_set_context *sctx = (struct cmd_set_context *) ctx->data;
 	unsigned int i;	
 
-	sieve_operation_emit_code
-		(sbin, &cmd_set_operation, ext_variables_my_id); 
+	sieve_operation_emit_code(sbin, &cmd_set_operation); 
 
 	/* Generate arguments */
 	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
@@ -237,10 +219,10 @@ static bool cmd_set_generate
 	/* Generate modifiers (already sorted during validation) */
 	sieve_binary_emit_byte(sbin, array_count(&sctx->modifiers));
 	for ( i = 0; i < array_count(&sctx->modifiers); i++ ) {
-		struct cmd_set_modifier_context * const * mctx =
+		const struct sieve_variables_modifier * const * modf =
 			array_idx(&sctx->modifiers, i);
 			
-		ext_variables_opr_modifier_emit(sbin, (*mctx)->modifier, (*mctx)->ext_id);
+		ext_variables_opr_modifier_emit(sbin, *modf);
 	}
 
 	return TRUE;
diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c
index fe3db98fae6da48713c4dad3e04691308907364b..028b8e08f5f853414aa8334de7dd409bb20da2c2 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-common.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-common.c
@@ -42,20 +42,20 @@ const unsigned int default_set_modifiers_count =
 
 struct sieve_variable_scope {
 	pool_t pool;
-  int ext_id;
+	const struct sieve_extension *ext;
 
 	unsigned int next_index;
 	struct hash_table *variables;
 };
 
 struct sieve_variable_scope *sieve_variable_scope_create
-	(pool_t pool, int ext_id) 
+	(pool_t pool, const struct sieve_extension *ext) 
 {
 	struct sieve_variable_scope *scope;
 	
 	scope = p_new(pool, struct sieve_variable_scope, 1);
 	scope->pool = pool;
-	scope->ext_id = ext_id;
+	scope->ext = ext;
 	scope->variables = hash_create
 		(pool, pool, 0, strcase_hash, (hash_cmp_callback_t *)strcasecmp);
 		
@@ -68,7 +68,7 @@ struct sieve_variable *sieve_variable_scope_declare
 	struct sieve_variable *new_var = p_new(scope->pool, struct sieve_variable, 1);
 	new_var->identifier = identifier;
 	new_var->index = scope->next_index++;
-	new_var->ext_id = scope->ext_id;
+	new_var->ext = scope->ext;
 		
 	hash_insert(scope->variables, (void *) identifier, (void *) new_var);
 	
@@ -170,10 +170,10 @@ ext_variables_validator_context_create(struct sieve_validator *valdtr)
 	
 	ctx = p_new(pool, struct ext_variables_validator_context, 1);
 	ctx->modifiers = sieve_validator_object_registry_create(valdtr);
-	ctx->main_scope = sieve_variable_scope_create(sieve_ast_pool(ast), -1);
+	ctx->main_scope = sieve_variable_scope_create(sieve_ast_pool(ast), NULL);
 
 	sieve_validator_extension_set_context
-		(valdtr, ext_variables_my_id, (void *) ctx);
+		(valdtr, &variables_extension, (void *) ctx);
 
 	return ctx;
 }
@@ -229,7 +229,7 @@ ext_variables_interpreter_context_create(struct sieve_interpreter *interp)
 	p_array_init(&ctx->ext_storages, pool, sieve_extensions_get_count());
 
 	sieve_interpreter_extension_set_context
-		(interp, ext_variables_my_id, (void *) ctx);
+		(interp, &variables_extension, (void *) ctx);
 
 	return ctx;
 }
@@ -249,19 +249,21 @@ static inline struct ext_variables_interpreter_context *
 ext_variables_interpreter_context_get(struct sieve_interpreter *interp)
 {
 	return (struct ext_variables_interpreter_context *)
-		sieve_interpreter_extension_get_context(interp, ext_variables_my_id);
+		sieve_interpreter_extension_get_context(interp, &variables_extension);
 }
 
 struct sieve_variable_storage *sieve_ext_variables_get_storage
-	(struct sieve_interpreter *interp, int ext_id)
+	(struct sieve_interpreter *interp, const struct sieve_extension *ext)
 {
 	struct ext_variables_interpreter_context *ctx = 
 		ext_variables_interpreter_context_get(interp);
 	struct sieve_variable_storage * const *storage;
+	int ext_id;
 		
-	if ( ext_id < 0 )
+	if ( ext == NULL )
 		return ctx->local_storage;
 
+	ext_id = *ext->id;
 	if ( ext_id >= (int) array_count(&ctx->ext_storages) ) {
 		storage = NULL;
 	} else {
@@ -282,15 +284,15 @@ struct sieve_variable_storage *sieve_ext_variables_get_storage
 
 void sieve_ext_variables_set_storage
 (struct sieve_interpreter *interp, struct sieve_variable_storage *storage,
-	int ext_id)
+	const struct sieve_extension *ext)
 {
 	struct ext_variables_interpreter_context *ctx = 
 		ext_variables_interpreter_context_get(interp);
 		
-	if ( ext_id < 0 || storage == NULL )
+	if ( ext == NULL || storage == NULL )
 		return;
 		
-	array_idx_set(&ctx->ext_storages, (unsigned int) ext_id, &storage);
+	array_idx_set(&ctx->ext_storages, (unsigned int) *ext->id, &storage);
 }
 
 
diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.h b/src/lib-sieve/plugins/variables/ext-variables-common.h
index a0f5d45fef339eef615b92e9e1ff78494c07421a..13b6b8132589a45c9a72c84b82726c1f5c296634 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-common.h
+++ b/src/lib-sieve/plugins/variables/ext-variables-common.h
@@ -37,7 +37,7 @@ static inline struct ext_variables_validator_context *
 ext_variables_validator_context_get(struct sieve_validator *valdtr)
 {
 	return (struct ext_variables_validator_context *)
-		sieve_validator_extension_get_context(valdtr, ext_variables_my_id);
+		sieve_validator_extension_get_context(valdtr, &variables_extension);
 }	
 	
 /* Variables */
@@ -61,6 +61,6 @@ struct sieve_variable *ext_variables_validator_get_variable
 (struct sieve_validator *validator, const char *variable, bool declare);
 
 struct sieve_variable_storage *ext_variables_interpreter_get_storage
-	(struct sieve_interpreter *interp, unsigned int ext_id);
+	(struct sieve_interpreter *interp, const struct sieve_extension *ext);
 	
 #endif /* __EXT_VARIABLES_COMMON_H */
diff --git a/src/lib-sieve/plugins/variables/ext-variables-modifiers.c b/src/lib-sieve/plugins/variables/ext-variables-modifiers.c
index 05201732c3ba37ccfa2bf20d33698ac20fe1ee74..72fd58c1c810cf4c9712f438c7c78f8256a5afd6 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-modifiers.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-modifiers.c
@@ -36,25 +36,22 @@ const unsigned int ext_variables_core_modifiers_count =
  */
 
 void sieve_variables_modifier_register
-(struct sieve_validator *valdtr, const struct sieve_variables_modifier *smodf, 
-	int ext_id) 
+(struct sieve_validator *valdtr, const struct sieve_variables_modifier *smodf) 
 {
 	struct ext_variables_validator_context *ctx = 
 		ext_variables_validator_context_get(valdtr);
 	
-	sieve_validator_object_registry_add
-		(ctx->modifiers, &smodf->object, ext_id);
+	sieve_validator_object_registry_add(ctx->modifiers, &smodf->object);
 }
 
 const struct sieve_variables_modifier *ext_variables_modifier_find
-(struct sieve_validator *valdtr, const char *identifier, int *ext_id_r)
+(struct sieve_validator *valdtr, const char *identifier)
 {
 	struct ext_variables_validator_context *ctx = 
 		ext_variables_validator_context_get(valdtr);
 		
 	const struct sieve_object *object = 
-		sieve_validator_object_registry_find
-			(ctx->modifiers, identifier, ext_id_r);
+		sieve_validator_object_registry_find(ctx->modifiers, identifier);
 
 	return (const struct sieve_variables_modifier *) object;
 }
@@ -64,11 +61,10 @@ void ext_variables_register_core_modifiers
 {
 	unsigned int i;
 	
-	/* Register core testsuite objects */
+	/* Register core modifiers*/
 	for ( i = 0; i < ext_variables_core_modifiers_count; i++ ) {
 		sieve_validator_object_registry_add
-			(ctx->modifiers, &(ext_variables_core_modifiers[i]->object), 
-				ext_variables_my_id);
+			(ctx->modifiers, &(ext_variables_core_modifiers[i]->object));
 	}
 }
 
diff --git a/src/lib-sieve/plugins/variables/ext-variables-modifiers.h b/src/lib-sieve/plugins/variables/ext-variables-modifiers.h
index 2af9244c470dfd720efbddbef832bd8c96e78e18..c47db35b8855f016b70a194eb042df715210dbed 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-modifiers.h
+++ b/src/lib-sieve/plugins/variables/ext-variables-modifiers.h
@@ -14,7 +14,7 @@ enum ext_variables_modifier_code {
 };
 
 const struct sieve_variables_modifier *ext_variables_modifier_find
-	(struct sieve_validator *validator, const char *identifier, int *ext_id_r);
+	(struct sieve_validator *validator, const char *identifier);
 
 void ext_variables_register_core_modifiers
 	(struct ext_variables_validator_context *ctx);
@@ -28,10 +28,9 @@ extern const struct sieve_operand_class
 extern const struct sieve_operand modifier_operand;
 
 static inline void ext_variables_opr_modifier_emit
-(struct sieve_binary *sbin, const struct sieve_variables_modifier *modf, 
-	int ext_id)
+(struct sieve_binary *sbin, const struct sieve_variables_modifier *modf)
 { 
-	sieve_opr_object_emit(sbin, &modf->object, ext_id);
+	sieve_opr_object_emit(sbin, &modf->object);
 }
 
 static inline const struct sieve_variables_modifier *
diff --git a/src/lib-sieve/plugins/variables/ext-variables-operands.c b/src/lib-sieve/plugins/variables/ext-variables-operands.c
index dd980935430a5fdc70f999fde4bc59418f5132cd..ed8a3779805c59e5d2d292e6852bda1167162d56 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-operands.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-operands.c
@@ -44,16 +44,17 @@ const struct sieve_operand variable_operand = {
 void ext_variables_opr_variable_emit
 	(struct sieve_binary *sbin, struct sieve_variable *var) 
 {
-	if ( var->ext_id < 0 ) {
+	if ( var->ext == NULL ) {
 		/* Default variable storage */
-		(void) sieve_operand_emit_code(sbin, &variable_operand, ext_variables_my_id);
+		(void) sieve_operand_emit_code(sbin, &variable_operand);
 		(void) sieve_binary_emit_byte(sbin, 0);
 		(void) sieve_binary_emit_integer(sbin, var->index);
 		return;
 	} 
-	
-	(void) sieve_operand_emit_code(sbin, &variable_operand, ext_variables_my_id);
-	(void) sieve_binary_emit_byte(sbin, 1 +	var->ext_id);
+
+	/* FIXME: never directly emit *ext->id !! */
+	(void) sieve_operand_emit_code(sbin, &variable_operand);
+	(void) sieve_binary_emit_byte(sbin, 1 +	*var->ext->id);
 	(void) sieve_binary_emit_integer(sbin, var->index);
 }
 
@@ -68,6 +69,7 @@ static bool opr_variable_dump
 	if ( !sieve_binary_read_byte(denv->sbin, address, &code) ) {
 		return FALSE;
 	} 
+
 	ext_id = code - 1;
 	
 	if ( ext_id >= 0 && (ext = sieve_extension_get_by_id(ext_id)) == NULL ) {
@@ -90,6 +92,7 @@ static bool opr_variable_read_value
 { 
 	unsigned int code;
 	int ext_id;
+	const struct sieve_extension *ext = NULL;
 	struct sieve_variable_storage *storage;
 	sieve_size_t index = 0;
 	
@@ -98,7 +101,10 @@ static bool opr_variable_read_value
 	}
 	ext_id = code - 1;
 	
-	storage = sieve_ext_variables_get_storage(renv->interp, ext_id);
+	if ( ext_id >= 0 ) 
+		ext = sieve_extension_get_by_id(ext_id);
+
+	storage = sieve_ext_variables_get_storage(renv->interp, ext);
 	if ( storage == NULL ) return FALSE;
 	
 	if (sieve_binary_read_integer(renv->sbin, address, &index) ) {
@@ -123,6 +129,7 @@ bool sieve_variable_operand_read_data
 {
 	unsigned int code;
 	int ext_id;
+	const struct sieve_extension *ext = NULL;
 	sieve_size_t idx = 0;
 
 	if ( operand != &variable_operand ) {
@@ -133,8 +140,11 @@ bool sieve_variable_operand_read_data
 		return FALSE;
 	}
 	ext_id = code - 1;
+
+	if ( ext_id >= 0 )
+        ext = sieve_extension_get_by_id(ext_id);
 		
-	*storage = sieve_ext_variables_get_storage(renv->interp, ext_id);
+	*storage = sieve_ext_variables_get_storage(renv->interp, ext);
 	if ( *storage == NULL )	return FALSE;
 	
 	if (sieve_binary_read_integer(renv->sbin, address, &idx) ) {
@@ -181,8 +191,7 @@ const struct sieve_operand match_value_operand = {
 void ext_variables_opr_match_value_emit
 	(struct sieve_binary *sbin, unsigned int index) 
 {
-	(void) sieve_operand_emit_code
-		(sbin, &match_value_operand, ext_variables_my_id);
+	(void) sieve_operand_emit_code(sbin, &match_value_operand);
 	(void) sieve_binary_emit_integer(sbin, index);
 }
 
@@ -245,8 +254,7 @@ const struct sieve_operand variable_string_operand = {
 void ext_variables_opr_variable_string_emit
 	(struct sieve_binary *sbin, unsigned int elements) 
 {
-	(void) sieve_operand_emit_code
-		(sbin, &variable_string_operand, ext_variables_my_id);
+	(void) sieve_operand_emit_code(sbin, &variable_string_operand);
 	(void) sieve_binary_emit_integer(sbin, elements);
 }
 
diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h
index c8bead2eb2673d68d60501ee74afe54d91b95fe8..e554f410ef166fd268455da00f176a6cf26380d5 100644
--- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h
+++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h
@@ -16,13 +16,13 @@
 struct sieve_variable {
 	const char *identifier;
 	unsigned int index;
-	int ext_id;
+	const struct sieve_extension *ext;
 };
 
 struct sieve_variable_scope;
 
 struct sieve_variable_scope *sieve_variable_scope_create
-	(pool_t pool, int ext_id);
+	(pool_t pool, const struct sieve_extension *ext);
 struct sieve_variable *sieve_variable_scope_declare
 	(struct sieve_variable_scope *scope, const char *identifier);
 struct sieve_variable *sieve_variable_scope_import
@@ -57,10 +57,10 @@ struct sieve_variable_scope *sieve_ext_variables_get_main_scope
 	(struct sieve_validator *validator);
 	
 struct sieve_variable_storage *sieve_ext_variables_get_storage
-	(struct sieve_interpreter *interp, int ext_id);
+	(struct sieve_interpreter *interp, const struct sieve_extension *ext);
 void sieve_ext_variables_set_storage
 	(struct sieve_interpreter *interp, struct sieve_variable_storage *storage,
-		int ext_id);	
+		const struct sieve_extension *ext);	
 		
 /* Variable arguments */
 
@@ -100,7 +100,6 @@ struct sieve_variables_modifier {
 #define SIEVE_VARIABLES_DEFINE_MODIFIERS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
 
 void sieve_variables_modifier_register
-(struct sieve_validator *valdtr, const struct sieve_variables_modifier *smodf, 
-	int ext_id);
+(struct sieve_validator *valdtr, const struct sieve_variables_modifier *smodf);
 
 #endif /* __SIEVE_EXT_VARIABLES_H */
diff --git a/src/lib-sieve/plugins/variables/tst-string.c b/src/lib-sieve/plugins/variables/tst-string.c
index c8ed71733618e1e1625db8dcea9ee9887445206c..c08f1be2f83e05d7704f7c2d8496c7b5a56d5ce7 100644
--- a/src/lib-sieve/plugins/variables/tst-string.c
+++ b/src/lib-sieve/plugins/variables/tst-string.c
@@ -108,8 +108,7 @@ static bool tst_string_validate
 static bool tst_string_generate
 	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
-	sieve_operation_emit_code
-		(cgenv->sbin, &tst_string_operation, ext_variables_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &tst_string_operation);
 
  	/* Generate arguments */
 	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h
index edf848a9f76662f5a6abca4e1744b3485c2577bb..2f2c1a726428a0bc3340efdb32028d15e79b051d 100644
--- a/src/lib-sieve/sieve-actions.h
+++ b/src/lib-sieve/sieve-actions.h
@@ -104,9 +104,9 @@ struct sieve_side_effect {
 extern const struct sieve_operand_class sieve_side_effect_operand_class;
 
 static inline void sieve_opr_side_effect_emit
-(struct sieve_binary *sbin, const struct sieve_side_effect *seff, int ext_id)
+(struct sieve_binary *sbin, const struct sieve_side_effect *seff)
 { 
-	sieve_opr_object_emit(sbin, &seff->object, ext_id);
+	sieve_opr_object_emit(sbin, &seff->object);
 }
 
 static inline const struct sieve_side_effect *sieve_opr_side_effect_read
diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c
index d9bccee5de7f7d292d83cae0687cc64ec2c0ed7d..dde4de454895bdd3d27c9a31fba336b32ca7fd3e 100644
--- a/src/lib-sieve/sieve-address-parts.c
+++ b/src/lib-sieve/sieve-address-parts.c
@@ -51,6 +51,8 @@ const struct sieve_extension address_part_extension = {
 	SIEVE_EXT_DEFINE_NO_OPERATIONS,
 	SIEVE_EXT_DEFINE_NO_OPERANDS /* Defined as core operand */
 };
+
+static const struct sieve_extension *ext_this = &address_part_extension;
 	
 static bool addrp_extension_load(int ext_id) 
 {
@@ -64,23 +66,21 @@ static bool addrp_extension_load(int ext_id)
  */
  
 void sieve_address_part_register
-	(struct sieve_validator *validator, 
-	const struct sieve_address_part *addrp, int ext_id) 
+(struct sieve_validator *validator, const struct sieve_address_part *addrp) 
 {
 	struct sieve_validator_object_registry *regs = 
-		sieve_validator_object_registry_get(validator, ext_my_id);
+		sieve_validator_object_registry_get(validator, ext_this);
 	
-	sieve_validator_object_registry_add(regs, &addrp->object, ext_id);
+	sieve_validator_object_registry_add(regs, &addrp->object);
 }
 
 const struct sieve_address_part *sieve_address_part_find
-	(struct sieve_validator *validator, const char *identifier,
-		int *ext_id) 
+(struct sieve_validator *validator, const char *identifier) 
 {
 	struct sieve_validator_object_registry *regs = 
-		sieve_validator_object_registry_get(validator, ext_my_id);
+		sieve_validator_object_registry_get(validator, ext_this);
 	const struct sieve_object *object = 
-		sieve_validator_object_registry_find(regs, identifier, ext_id);
+		sieve_validator_object_registry_find(regs, identifier);
 
   return (const struct sieve_address_part *) object;
 }
@@ -88,13 +88,13 @@ const struct sieve_address_part *sieve_address_part_find
 bool addrp_validator_load(struct sieve_validator *validator)
 {
 	struct sieve_validator_object_registry *regs = 
-		sieve_validator_object_registry_init(validator, ext_my_id);
+		sieve_validator_object_registry_init(validator, ext_this);
 	unsigned int i;
 
 	/* Register core address-parts */
 	for ( i = 0; i < sieve_core_address_parts_count; i++ ) {
 		sieve_validator_object_registry_add
-			(regs, &(sieve_core_address_parts[i]->object), -1);
+			(regs, &(sieve_core_address_parts[i]->object));
 	}
 
 	return TRUE;
@@ -116,17 +116,15 @@ static bool tag_address_part_is_instance_of
 (struct sieve_validator *validator, struct sieve_command_context *cmd,
 	struct sieve_ast_argument *arg)
 {
-	int ext_id;
 	struct sieve_address_part_context *adpctx;
 	const struct sieve_address_part *addrp = sieve_address_part_find
-		(validator, sieve_ast_argument_tag(arg), &ext_id);
+		(validator, sieve_ast_argument_tag(arg));
 
 	if ( addrp == NULL ) return FALSE;
 
 	adpctx = p_new(sieve_command_pool(cmd), struct sieve_address_part_context, 1);
 	adpctx->command_ctx = cmd;
 	adpctx->address_part = addrp;
-	adpctx->ext_id = ext_id;
 
 	/* Store address-part in context */
 	arg->context = (void *) adpctx;
@@ -159,8 +157,7 @@ static bool tag_address_part_generate
 	struct sieve_address_part_context *adpctx =
 		(struct sieve_address_part_context *) arg->context;
 		
-	sieve_opr_address_part_emit
-		(cgenv->sbin, adpctx->address_part, adpctx->ext_id); 
+	sieve_opr_address_part_emit(cgenv->sbin, adpctx->address_part); 
 		
 	return TRUE;
 }
diff --git a/src/lib-sieve/sieve-address-parts.h b/src/lib-sieve/sieve-address-parts.h
index da0217f9e8c67ecdeb3be074e63eaab79cd774a7..395131878bef8fca6b31975efd982c70e3333d6f 100644
--- a/src/lib-sieve/sieve-address-parts.h
+++ b/src/lib-sieve/sieve-address-parts.h
@@ -41,8 +41,6 @@ extern const struct sieve_argument address_part_tag;
 struct sieve_address_part_context {
 	struct sieve_command_context *command_ctx;
 	const struct sieve_address_part *address_part;
-	
-	int ext_id;
 };
 
 void sieve_address_parts_link_tags
@@ -55,10 +53,9 @@ void sieve_address_parts_link_tags
 		
 void sieve_address_part_register
 	(struct sieve_validator *validator, 
-		const struct sieve_address_part *addrp, int ext_id);
+		const struct sieve_address_part *addrp);
 const struct sieve_address_part *sieve_address_part_find
-	(struct sieve_validator *validator, const char *identifier,
-		int *ext_id);
+	(struct sieve_validator *validator, const char *identifier);
 		
 /*
  * Address part operand
@@ -71,9 +68,9 @@ struct sieve_operand_class sieve_address_part_operand_class;
 #define SIEVE_EXT_DEFINE_ADDRESS_PARTS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
 
 static inline void sieve_opr_address_part_emit
-(struct sieve_binary *sbin, const struct sieve_address_part *addrp, int ext_id)
+(struct sieve_binary *sbin, const struct sieve_address_part *addrp)
 { 
-	sieve_opr_object_emit(sbin, &addrp->object, ext_id);
+	sieve_opr_object_emit(sbin, &addrp->object);
 }
 
 static inline const struct sieve_address_part *sieve_opr_address_part_read
diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c
index c3602f3d3e5a7055840ca76d7f2e0b5a9b35bea1..d0d24daeeb6e46698911a7d4a0777d6f89fc355b 100644
--- a/src/lib-sieve/sieve-ast.c
+++ b/src/lib-sieve/sieve-ast.c
@@ -130,14 +130,15 @@ const char *sieve_ast_type_name(enum sieve_ast_type ast_type) {
 /* Extension support */
 
 void sieve_ast_extension_set_context
-	(struct sieve_ast *ast, int ext_id, void *context)
+(struct sieve_ast *ast, const struct sieve_extension *ext, void *context)
 {
-	array_idx_set(&ast->ext_contexts, (unsigned int) ext_id, &context);	
+	array_idx_set(&ast->ext_contexts, (unsigned int) *ext->id, &context);	
 }
 
 const void *sieve_ast_extension_get_context
-	(struct sieve_ast *ast, int ext_id) 
+(struct sieve_ast *ast, const struct sieve_extension *ext) 
 {
+	int ext_id = *ext->id;
 	void * const *ctx;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&ast->ext_contexts) )
diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h
index 108443c34e1e44d8c67e05898ff7bd87c043e204..67eeb579cc4209d662ba0a8e6749f7bc419d8047 100644
--- a/src/lib-sieve/sieve-ast.h
+++ b/src/lib-sieve/sieve-ast.h
@@ -170,9 +170,9 @@ const char *sieve_ast_type_name(enum sieve_ast_type ast_type);
 
 /* extension support */
 void sieve_ast_extension_set_context
-	(struct sieve_ast *ast, int ext_id, void *context);
+	(struct sieve_ast *ast, const struct sieve_extension *ext, void *context);
 const void *sieve_ast_extension_get_context
-	(struct sieve_ast *ast, int ext_id);
+	(struct sieve_ast *ast, const struct sieve_extension *ext);
 
 /* error reporting */
 void sieve_ast_error
diff --git a/src/lib-sieve/sieve-binary-dumper.c b/src/lib-sieve/sieve-binary-dumper.c
index 2c64bae7b7d8e988b0b527eb1497e134429026f2..d0cf208c77e15727f3139980fa0649a7c2311872 100644
--- a/src/lib-sieve/sieve-binary-dumper.c
+++ b/src/lib-sieve/sieve-binary-dumper.c
@@ -93,10 +93,9 @@ void sieve_binary_dumper_run
 		sieve_binary_dump_sectionf(denv, "Required extensions");
 	
 		for ( i = 0; i < count; i++ ) {
-			int ext_id;
 			const struct sieve_extension *ext = sieve_binary_extension_get_by_index
-				(sbin, i, &ext_id);
-			sieve_binary_dumpf(denv, "%d: %s (%d)\n", i, ext->name, ext_id);
+				(sbin, i);
+			sieve_binary_dumpf(denv, "%d: %s (%d)\n", i, ext->name, *ext->id);
 		}
 	}
 	
@@ -115,9 +114,8 @@ void sieve_binary_dumper_run
 	count = sieve_binary_extensions_count(sbin);
 	if ( count > 0 ) {	
 		for ( i = 0; i < count; i++ ) {
-			int ext_id;
 			const struct sieve_extension *ext = sieve_binary_extension_get_by_index
-				(sbin, i, &ext_id);
+				(sbin, i);
 	
 			if ( ext->binary_dump != NULL ) {	
 				if ( !ext->binary_dump(denv) ) break;
diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c
index 336ec9b7c5e287e625835c7f218d2f09a4bfaba6..709bd4205a16bb50fa2bdeb08865a8ef9e77c234 100644
--- a/src/lib-sieve/sieve-binary.c
+++ b/src/lib-sieve/sieve-binary.c
@@ -52,9 +52,9 @@ static struct sieve_binary_block *sieve_binary_load_block
 	(struct sieve_binary *sbin, unsigned int id);
 
 static inline struct sieve_binary_extension_reg *sieve_binary_extension_get_reg
-	(struct sieve_binary *sbin, int ext_id);
+	(struct sieve_binary *sbin, const struct sieve_extension *ext);
 static inline int sieve_binary_extension_register
-	(struct sieve_binary *sbin, int ext_id, 
+	(struct sieve_binary *sbin, const struct sieve_extension *ext, 
 		struct sieve_binary_extension_reg **reg);
 
 static inline sieve_size_t sieve_binary_emit_dynamic_data
@@ -70,9 +70,6 @@ struct sieve_binary_extension_reg {
 	/* The identifier of the extension within this binary */
 	int index;
 	
-	/* Global extension id */
-	int ext_id;
-	
 	/* Global extension object */
 	const struct sieve_extension *extension; 
 	
@@ -94,7 +91,6 @@ struct sieve_binary_extension_reg {
 struct sieve_binary_block {
 	buffer_t *buffer;
 	int ext_index;
-	int ext_id;
 	
 	uoff_t offset;
 };
@@ -979,19 +975,19 @@ static bool _sieve_binary_load_extensions(struct sieve_binary *sbin)
 	for ( i = 0; result && i < count; i++ ) {
 		T_BEGIN {
 			string_t *extension;
-			int ext_id;
+			const struct sieve_extension *ext;
 			
 			if ( sieve_binary_read_string(sbin, &offset, &extension) ) { 
-				ext_id = sieve_extension_get_by_name(str_c(extension), NULL);	
+				ext = sieve_extension_get_by_name(str_c(extension));	
 			
-				if ( ext_id < 0 ) { 
+				if ( ext == NULL ) { 
 					sieve_sys_error("loaded binary %s requires unknown extension '%s'", 
 						sbin->path, str_c(extension));
 					result = FALSE;					
 				} else {
 					struct sieve_binary_extension_reg *ereg = NULL;
 					
-					(void) sieve_binary_extension_register(sbin, ext_id, &ereg);
+					(void) sieve_binary_extension_register(sbin, ext, &ereg);
 					if ( !sieve_binary_read_integer(sbin, &offset, &ereg->block_id) )
 						result = FALSE;
 				}
@@ -1208,8 +1204,10 @@ void sieve_binary_activate(struct sieve_binary *sbin)
  */
 
 static inline struct sieve_binary_extension_reg *sieve_binary_extension_get_reg 
-(struct sieve_binary *sbin, int ext_id) 
+(struct sieve_binary *sbin, const struct sieve_extension *ext) 
 {
+	int ext_id = *ext->id;
+
 	if ( ext_id >= 0 && ext_id < (int) array_count(&sbin->extension_index) ) {
 		struct sieve_binary_extension_reg * const *ereg = 
 			array_idx(&sbin->extension_index, (unsigned int) ext_id);
@@ -1222,14 +1220,14 @@ static inline struct sieve_binary_extension_reg *sieve_binary_extension_get_reg
 
 static inline struct sieve_binary_extension_reg *
 	sieve_binary_extension_create_reg
-(struct sieve_binary *sbin, const struct sieve_extension *ext, int ext_id)
+(struct sieve_binary *sbin, const struct sieve_extension *ext)
 {
+	int ext_id = *ext->id;
 	int index = array_count(&sbin->extensions);
 	struct sieve_binary_extension_reg *ereg;
 
 	ereg = p_new(sbin->pool, struct sieve_binary_extension_reg, 1);
 	ereg->index = index;
-	ereg->ext_id = ext_id;
 	ereg->extension = ext;
 	
 	array_idx_set(&sbin->extensions, (unsigned int) index, &ereg);
@@ -1239,25 +1237,24 @@ static inline struct sieve_binary_extension_reg *
 }
 
 void sieve_binary_extension_set_context
-	(struct sieve_binary *sbin, int ext_id, void *context)
+(struct sieve_binary *sbin, const struct sieve_extension *ext, void *context)
 {
 	struct sieve_binary_extension_reg *ereg = 
-		sieve_binary_extension_get_reg(sbin, ext_id);
+		sieve_binary_extension_get_reg(sbin, ext);
 	
 	if ( ereg == NULL ) {
 		/* Failsafe, this shouldn't happen */
-		ereg = sieve_binary_extension_create_reg(sbin, 
-		  sieve_extension_get_by_id(ext_id), ext_id);
+		ereg = sieve_binary_extension_create_reg(sbin, ext);
 	}
 	
 	ereg->context = context;
 }
 
 const void *sieve_binary_extension_get_context
-	(struct sieve_binary *sbin, int ext_id) 
+	(struct sieve_binary *sbin, const struct sieve_extension *ext) 
 {
 	struct sieve_binary_extension_reg *ereg = 
-		sieve_binary_extension_get_reg(sbin, ext_id);
+		sieve_binary_extension_get_reg(sbin, ext);
 
 	if ( ereg != NULL ) {
 		return ereg->context;
@@ -1267,33 +1264,31 @@ const void *sieve_binary_extension_get_context
 }
 
 void sieve_binary_extension_set
-(struct sieve_binary *sbin, int ext_id, 
+(struct sieve_binary *sbin, const struct sieve_extension *ext, 
 	const struct sieve_binary_extension *bext)
 {
 	struct sieve_binary_extension_reg *ereg = 
-		sieve_binary_extension_get_reg(sbin, ext_id);
+		sieve_binary_extension_get_reg(sbin, ext);
 	
 	if ( ereg == NULL ) {
 		/* Failsafe, this shouldn't happen */
-		ereg = sieve_binary_extension_create_reg(sbin, 
-		  sieve_extension_get_by_id(ext_id), ext_id);
+		ereg = sieve_binary_extension_create_reg(sbin, ext);
 	}
 	
 	ereg->binext = bext;
 }
 
 unsigned int sieve_binary_extension_create_block
-(struct sieve_binary *sbin, int ext_id)
+(struct sieve_binary *sbin, const struct sieve_extension *ext)
 {
 	struct sieve_binary_block *block;	
 	unsigned int block_id;
 	struct sieve_binary_extension_reg *ereg = 
-		sieve_binary_extension_get_reg(sbin, ext_id);
+		sieve_binary_extension_get_reg(sbin, ext);
 	
 	if ( ereg == NULL ) {
 		/* Failsafe, this shouldn't happen */
-		ereg = sieve_binary_extension_create_reg(sbin, 
-		  sieve_extension_get_by_id(ext_id), ext_id);
+		ereg = sieve_binary_extension_create_reg(sbin, ext);
 	}
 	
 	block = p_new(sbin->pool, struct sieve_binary_block, 1);
@@ -1303,16 +1298,16 @@ unsigned int sieve_binary_extension_create_block
 	
 	if ( ereg->block_id < SBIN_SYSBLOCK_LAST )
 		ereg->block_id = block_id;
-	block->ext_id = ereg->index;
+	block->ext_index = ereg->index;
 	
 	return block_id;
 }
 
 unsigned int sieve_binary_extension_get_block
-(struct sieve_binary *sbin, int ext_id)
+(struct sieve_binary *sbin, const struct sieve_extension *ext)
 {
 	struct sieve_binary_extension_reg *ereg = 
-		sieve_binary_extension_get_reg(sbin, ext_id);
+		sieve_binary_extension_get_reg(sbin, ext);
 		
 	if ( ereg == NULL ) return 0;
 	
@@ -1320,17 +1315,16 @@ unsigned int sieve_binary_extension_get_block
 }
 
 static inline int sieve_binary_extension_register
-(struct sieve_binary *sbin, int ext_id, struct sieve_binary_extension_reg **reg) 
+(struct sieve_binary *sbin, const struct sieve_extension *ext, 
+	struct sieve_binary_extension_reg **reg_r) 
 {
-	const struct sieve_extension *ext = sieve_extension_get_by_id(ext_id);
-	
-	if ( ext != NULL && sieve_binary_extension_get_index(sbin, ext_id) == -1 ) {
+	if ( sieve_binary_extension_get_index(sbin, ext) == -1 ) {
 		struct sieve_binary_extension_reg *ereg = 
-			sieve_binary_extension_create_reg(sbin, ext, ext_id);
+			sieve_binary_extension_create_reg(sbin, ext);
 		
 		array_append(&sbin->linked_extensions, &ereg, 1);
 		
-		if ( reg != NULL ) *reg = ereg;
+		if ( reg_r != NULL ) *reg_r = ereg;
 		return ereg->index;
 	}
 	
@@ -1338,39 +1332,32 @@ static inline int sieve_binary_extension_register
 }
 
 int sieve_binary_extension_link
-	(struct sieve_binary *sbin, int ext_id) 
+	(struct sieve_binary *sbin, const struct sieve_extension *ext) 
 {	
-	return sieve_binary_extension_register(sbin, ext_id, NULL);
+	return sieve_binary_extension_register(sbin, ext, NULL);
 }
 
 const struct sieve_extension *sieve_binary_extension_get_by_index
-	(struct sieve_binary *sbin, int index, int *ext_id) 
+	(struct sieve_binary *sbin, int index) 
 {
 	struct sieve_binary_extension_reg * const *ext;
 	
 	if ( index < (int) array_count(&sbin->extensions) ) {
 		ext = array_idx(&sbin->extensions, (unsigned int) index);
 		
-		if ( ext_id != NULL ) *ext_id = (*ext)->ext_id;
-		
 		return (*ext)->extension;
 	}
 	
-	if ( ext_id != NULL ) *ext_id = -1;
-	
 	return NULL;
 }
 
 int sieve_binary_extension_get_index
-	(struct sieve_binary *sbin, int ext_id) 
+	(struct sieve_binary *sbin, const struct sieve_extension *ext) 
 {
 	struct sieve_binary_extension_reg *ereg =
-		sieve_binary_extension_get_reg(sbin, ext_id);
+		sieve_binary_extension_get_reg(sbin, ext);
 	
-	if ( ereg != NULL )
-		return ereg->index;
-			
-	return -1;
+	return ( ereg != NULL ? ereg->index : -1 );
 }
 
 int sieve_binary_extensions_count(struct sieve_binary *sbin) 
@@ -1617,56 +1604,4 @@ bool sieve_binary_read_string
 	return TRUE;
 }
 
-/* 
- * Binary registry 
- */
-
-struct sieve_binary_registry {
-	ARRAY_DEFINE(objects, const void *); 
-};
-
-static inline struct sieve_binary_registry *
-	get_binary_registry(struct sieve_binary *sbin, int ext_id)
-{
-	return (struct sieve_binary_registry *) 
-		sieve_binary_extension_get_context(sbin, ext_id);
-}
-
-const void *sieve_binary_registry_get_object
-	(struct sieve_binary *sbin, int ext_id, int id)
-{
-	struct sieve_binary_registry *reg = get_binary_registry(sbin, ext_id);
-	
-	if ( (reg != NULL) && (id > 0) && 
-		(id < (int) array_count(&reg->objects)) ) {
-		const void * const *obj;
-
-		obj = array_idx(&reg->objects, (unsigned int) id);
-
-		return *obj;
-	}
-	
-	return NULL;
-}
-
-void sieve_binary_registry_set_object
-	(struct sieve_binary *sbin, int ext_id, int id, const void *object)
-{
-	struct sieve_binary_registry *reg = get_binary_registry(sbin, ext_id);
-
-	array_idx_set(&reg->objects, (unsigned int) id, &object);
-}
-
-void sieve_binary_registry_init(struct sieve_binary *sbin, int ext_id)
-{
-	pool_t pool = sieve_binary_pool(sbin);
-		
-	struct sieve_binary_registry *reg = 
-		p_new(pool, struct sieve_binary_registry, 1);
-	
-	/* Setup match-type registry */
-	p_array_init(&reg->objects, pool, 4);
-
-	sieve_binary_extension_set_context(sbin, ext_id, (void *) reg);
-}
 
diff --git a/src/lib-sieve/sieve-binary.h b/src/lib-sieve/sieve-binary.h
index 6b8067ca7ee1a3d864e95311b4a00c5e360e3edb..37b730dbd194083b1b334419d4501061256bdd91 100644
--- a/src/lib-sieve/sieve-binary.h
+++ b/src/lib-sieve/sieve-binary.h
@@ -62,25 +62,25 @@ struct sieve_binary_extension {
 };
  
 void sieve_binary_extension_set_context
-	(struct sieve_binary *sbin, int ext_id, void *context);
+	(struct sieve_binary *sbin, const struct sieve_extension *ext, void *context);
 const void *sieve_binary_extension_get_context
-	(struct sieve_binary *sbin, int ext_id);
+	(struct sieve_binary *sbin, const struct sieve_extension *ext);
 	
 void sieve_binary_extension_set
-	(struct sieve_binary *sbin, int ext_id, 
+	(struct sieve_binary *sbin, const struct sieve_extension *ext, 
 		const struct sieve_binary_extension *bext);
 
 unsigned int sieve_binary_extension_create_block
-	(struct sieve_binary *sbin, int ext_id);
+	(struct sieve_binary *sbin, const struct sieve_extension *ext);
 unsigned int sieve_binary_extension_get_block
-(struct sieve_binary *sbin, int ext_id);
+(struct sieve_binary *sbin, const struct sieve_extension *ext);
 
 int sieve_binary_extension_link
-	(struct sieve_binary *sbin, int ext_id);
+	(struct sieve_binary *sbin, const struct sieve_extension *ext);
 const struct sieve_extension *sieve_binary_extension_get_by_index
-	(struct sieve_binary *sbin, int index, int *ext_id);
+	(struct sieve_binary *sbin, int index);
 int sieve_binary_extension_get_index
-	(struct sieve_binary *sbin, int ext_id);
+	(struct sieve_binary *sbin, const struct sieve_extension *ext);
 int sieve_binary_extensions_count(struct sieve_binary *sbin);
 
 	
@@ -143,14 +143,4 @@ bool sieve_binary_read_integer
 bool sieve_binary_read_string
   (struct sieve_binary *binary, sieve_size_t *address, string_t **str);
 
-/* 
- * Default registry context (used at various occasions)
- */
- 
-const void *sieve_binary_registry_get_object
-	(struct sieve_binary *sbin, int ext_id, int id);
-void sieve_binary_registry_set_object
-	(struct sieve_binary *sbin, int ext_id, int id, const void *object);
-void sieve_binary_registry_init(struct sieve_binary *sbin, int ext_id);
-
 #endif
diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c
index af0e1cae0b54da54dfd82de16cbc30a5d1b95d6a..e6407e4b7e3c768415b65a9ddd12b8f6ae3ee2d2 100644
--- a/src/lib-sieve/sieve-code.c
+++ b/src/lib-sieve/sieve-code.c
@@ -215,23 +215,19 @@ static struct sieve_extension_obj_registry oprd_default_reg =
  */
 
 sieve_size_t sieve_operand_emit_code
-	(struct sieve_binary *sbin, const struct sieve_operand *opr, int ext_id)
+	(struct sieve_binary *sbin, const struct sieve_operand *opr)
 {
-	/* A sanity check on the emitted operand */
-	i_assert( !((opr->extension != NULL) && (ext_id < 0)) );
-	
 	return sieve_extension_emit_obj
-		(sbin, &oprd_default_reg, opr, operands, ext_id);
+		(sbin, &oprd_default_reg, opr, operands, opr->extension);
 }
 
 static const struct sieve_extension_obj_registry *
 	sieve_operand_registry_get
 (struct sieve_binary *sbin, unsigned int ext_index)
 {
-	int ext_id = -1; 
 	const struct sieve_extension *ext;
 	
-	if ( (ext=sieve_binary_extension_get_by_index(sbin, ext_index, &ext_id)) 
+	if ( (ext=sieve_binary_extension_get_by_index(sbin, ext_index)) 
 		== NULL )
 		return NULL;
 		
@@ -351,7 +347,7 @@ const struct sieve_operand stringlist_operand =	{
 
 void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_size_t number) 
 {
-	(void) sieve_operand_emit_code(sbin, &number_operand, -1);
+	(void) sieve_operand_emit_code(sbin, &number_operand);
 	(void) sieve_binary_emit_integer(sbin, number);
 }
 
@@ -435,7 +431,7 @@ static bool opr_number_read
 
 void sieve_opr_string_emit(struct sieve_binary *sbin, string_t *str)
 {
-	(void) sieve_operand_emit_code(sbin, &string_operand, -1);
+	(void) sieve_operand_emit_code(sbin, &string_operand);
 	(void) sieve_binary_emit_string(sbin, str);
 }
 
@@ -531,7 +527,7 @@ void sieve_opr_stringlist_emit_start
 	sieve_size_t *end_offset = t_new(sieve_size_t, 1);
 
 	/* Emit byte identifying the type of operand */	  
-	(void) sieve_operand_emit_code(sbin, &stringlist_operand, -1);
+	(void) sieve_operand_emit_code(sbin, &stringlist_operand);
   
 	/* Give the interpreter an easy way to skip over this string list */
 	*end_offset = sieve_binary_emit_offset(sbin, 0);
@@ -760,23 +756,19 @@ static struct sieve_extension_obj_registry oprt_default_reg =
 /* Operation functions */
 
 sieve_size_t sieve_operation_emit_code
-	(struct sieve_binary *sbin, const struct sieve_operation *op, int ext_id)
+	(struct sieve_binary *sbin, const struct sieve_operation *op)
 {
-	/* A sanity check on the emitted operation */
-	i_assert( !((op->extension != NULL) && (ext_id < 0)) );
-		
 	return sieve_extension_emit_obj
-		(sbin, &oprt_default_reg, op, operations, ext_id);
+		(sbin, &oprt_default_reg, op, operations, op->extension);
 }
 
 static const struct sieve_extension_obj_registry *
 	sieve_operation_registry_get
 (struct sieve_binary *sbin, unsigned int ext_index)
 {
-	int ext_id = -1; 
 	const struct sieve_extension *ext;
 	
-	if ( (ext=sieve_binary_extension_get_by_index(sbin, ext_index, &ext_id)) 
+	if ( (ext=sieve_binary_extension_get_by_index(sbin, ext_index)) 
 		== NULL )
 		return NULL;
 		
diff --git a/src/lib-sieve/sieve-code.h b/src/lib-sieve/sieve-code.h
index f6b506d1b31d1c2bfa5c51dd7a0ee6c09452c6b7..ccd57d2aba834d3a899a3494544c79d789f400fe 100644
--- a/src/lib-sieve/sieve-code.h
+++ b/src/lib-sieve/sieve-code.h
@@ -100,7 +100,7 @@ extern const struct sieve_operand *sieve_operands[];
 extern const unsigned int sieve_operand_count;
 
 sieve_size_t sieve_operand_emit_code
-	(struct sieve_binary *sbin, const struct sieve_operand *opr, int ext_id);
+	(struct sieve_binary *sbin, const struct sieve_operand *opr);
 const struct sieve_operand *sieve_operand_read
 	(struct sieve_binary *sbin, sieve_size_t *address);
 
@@ -215,7 +215,7 @@ extern const struct sieve_operation sieve_jmptrue_operation;
 extern const struct sieve_operation sieve_jmpfalse_operation; 
 
 sieve_size_t sieve_operation_emit_code
-	(struct sieve_binary *sbin, const struct sieve_operation *op, int ext_id);	
+	(struct sieve_binary *sbin, const struct sieve_operation *op);	
 const struct sieve_operation *sieve_operation_read
 	(struct sieve_binary *sbin, sieve_size_t *address);
 const char *sieve_operation_read_string
diff --git a/src/lib-sieve/sieve-commands.c b/src/lib-sieve/sieve-commands.c
index 872d9ac4658eda127dfa199a52332b6fd2afb9af..22dc948c3d7ad90441233f5003a5dda6bc5d9397 100644
--- a/src/lib-sieve/sieve-commands.c
+++ b/src/lib-sieve/sieve-commands.c
@@ -343,7 +343,7 @@ static bool cmd_stop_generate
 (const struct sieve_codegen_env *cgenv, 
 	struct sieve_command_context *ctx ATTR_UNUSED) 
 {
-	sieve_operation_emit_code(cgenv->sbin, &cmd_stop_operation, -1);
+	sieve_operation_emit_code(cgenv->sbin, &cmd_stop_operation);
 	return TRUE;
 }
 
@@ -353,7 +353,7 @@ static bool tst_false_generate
 	struct sieve_jumplist *jumps, bool jump_true)
 {
 	if ( !jump_true ) {
-		sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation, -1);
+		sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation);
 		sieve_jumplist_add(jumps, sieve_binary_emit_offset(cgenv->sbin, 0));
 	}
 	
@@ -366,7 +366,7 @@ static bool tst_true_generate
 	struct sieve_jumplist *jumps, bool jump_true)
 {
 	if ( jump_true ) {
-		sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation, -1);
+		sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation);
 		sieve_jumplist_add(jumps, sieve_binary_emit_offset(cgenv->sbin, 0));
 	}
 	
diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c
index 1affea88a8cdb5294b6d2a239f563e7b7f7e9c89..c546a242747e21461a5d05c43508cf6e8f98ef3f 100644
--- a/src/lib-sieve/sieve-comparators.c
+++ b/src/lib-sieve/sieve-comparators.c
@@ -36,7 +36,7 @@ const unsigned int sieve_core_comparators_count =
  */
  
 static void sieve_opr_comparator_emit
-	(struct sieve_binary *sbin, const struct sieve_comparator *cmp, int ext_id);
+	(struct sieve_binary *sbin, const struct sieve_comparator *cmp);
 
 /* 
  * Comparator 'extension' 
@@ -56,6 +56,8 @@ const struct sieve_extension comparator_extension = {
 	SIEVE_EXT_DEFINE_NO_OPERATIONS,
 	SIEVE_EXT_DEFINE_NO_OPERANDS    /* Defined as core operand */
 };
+
+static const struct sieve_extension *ext_this = &comparator_extension;
 	
 static bool cmp_extension_load(int ext_id) 
 {
@@ -69,22 +71,21 @@ static bool cmp_extension_load(int ext_id)
  */
  
 void sieve_comparator_register
-(struct sieve_validator *validator, const struct sieve_comparator *cmp, 
-	int ext_id) 
+(struct sieve_validator *validator, const struct sieve_comparator *cmp) 
 {
 	struct sieve_validator_object_registry *regs = 
-		sieve_validator_object_registry_get(validator, ext_my_id);
+		sieve_validator_object_registry_get(validator, ext_this);
 	
-	sieve_validator_object_registry_add(regs, &cmp->object, ext_id);
+	sieve_validator_object_registry_add(regs, &cmp->object);
 }
 
 const struct sieve_comparator *sieve_comparator_find
-(struct sieve_validator *validator, const char *identifier, int *ext_id) 
+(struct sieve_validator *validator, const char *identifier) 
 {
 	struct sieve_validator_object_registry *regs = 
-		sieve_validator_object_registry_get(validator, ext_my_id);
+		sieve_validator_object_registry_get(validator, ext_this);
 	const struct sieve_object *object = 
-		sieve_validator_object_registry_find(regs, identifier, ext_id);
+		sieve_validator_object_registry_find(regs, identifier);
 
   return (const struct sieve_comparator *) object;
 }
@@ -92,13 +93,13 @@ const struct sieve_comparator *sieve_comparator_find
 bool cmp_validator_load(struct sieve_validator *validator)
 {
 	struct sieve_validator_object_registry *regs = 
-		sieve_validator_object_registry_init(validator, ext_my_id);
+		sieve_validator_object_registry_init(validator, ext_this);
 	unsigned int i;
 		
 	/* Register core comparators */
 	for ( i = 0; i < sieve_core_comparators_count; i++ ) {
 		sieve_validator_object_registry_add
-			(regs, &(sieve_core_comparators[i]->object), -1);
+			(regs, &(sieve_core_comparators[i]->object));
 	}
 
 	return TRUE;
@@ -113,8 +114,6 @@ bool cmp_validator_load(struct sieve_validator *validator)
 struct sieve_comparator_context {
 	struct sieve_command_context *command_ctx;
 	const struct sieve_comparator *comparator;
-	
-	int ext_id;
 };
  
 /* Comparator argument */
@@ -138,7 +137,6 @@ static bool tag_comparator_validate
 	(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
 	struct sieve_command_context *cmd)
 {
-	int ext_id;
 	struct sieve_comparator_context *cmpctx;
 	struct sieve_ast_argument *tag = *arg;
 	const struct sieve_comparator *cmp;
@@ -157,8 +155,7 @@ static bool tag_comparator_validate
 	}
 	
 	/* Get comparator from registry */
-	cmp = sieve_comparator_find
-		(validator, sieve_ast_argument_strc(*arg), &ext_id);
+	cmp = sieve_comparator_find(validator, sieve_ast_argument_strc(*arg));
 	
 	if ( cmp == NULL ) {
 		sieve_command_validate_error(validator, cmd, 
@@ -176,7 +173,6 @@ static bool tag_comparator_validate
 	cmpctx = p_new(sieve_command_pool(cmd), struct sieve_comparator_context, 1);
 	cmpctx->command_ctx = cmd;
 	cmpctx->comparator = cmp;
-	cmpctx->ext_id = ext_id;
 
 	/* Store comparator in context */
 	tag->context = (void *) cmpctx;
@@ -192,7 +188,7 @@ static bool tag_comparator_generate
 		(struct sieve_comparator_context *) arg->context;
 	const struct sieve_comparator *cmp = cmpctx->comparator;
 	
-	sieve_opr_comparator_emit(cgenv->sbin, cmp, cmpctx->ext_id);
+	sieve_opr_comparator_emit(cgenv->sbin, cmp);
 		
 	return TRUE;
 }
diff --git a/src/lib-sieve/sieve-comparators.h b/src/lib-sieve/sieve-comparators.h
index d2f3f604fddb5f9c2042238897e80d4d3523dc9a..76fa69beb81cb2d6826156feeba57bea32577e3d 100644
--- a/src/lib-sieve/sieve-comparators.h
+++ b/src/lib-sieve/sieve-comparators.h
@@ -72,11 +72,9 @@ const struct sieve_comparator *sieve_comparator_tag_get
 	(struct sieve_ast_argument *tag);
 
 void sieve_comparator_register
-	(struct sieve_validator *validator, 
-	const struct sieve_comparator *cmp, int ext_id); 
+	(struct sieve_validator *validator, const struct sieve_comparator *cmp); 
 const struct sieve_comparator *sieve_comparator_find
-	(struct sieve_validator *validator, const char *identifier,
-		int *ext_id);
+	(struct sieve_validator *validator, const char *identifier);
 		
 /*
  * Comparator operand
@@ -89,9 +87,9 @@ extern const struct sieve_operand_class sieve_comparator_operand_class;
 extern const struct sieve_operand comparator_operand;
 
 static inline void sieve_opr_comparator_emit
-(struct sieve_binary *sbin, const struct sieve_comparator *cmp, int ext_id)
+(struct sieve_binary *sbin, const struct sieve_comparator *cmp)
 { 
-	sieve_opr_object_emit(sbin, &cmp->object, ext_id);
+	sieve_opr_object_emit(sbin, &cmp->object);
 }
 
 static inline const struct sieve_comparator *sieve_opr_comparator_read
diff --git a/src/lib-sieve/sieve-extensions-private.h b/src/lib-sieve/sieve-extensions-private.h
index 3a6914658666ecebf0bd402cf5bc419dd23a0cf6..bf47957f9ac8a8afc59be96bfdf9ef42d3433830 100644
--- a/src/lib-sieve/sieve-extensions-private.h
+++ b/src/lib-sieve/sieve-extensions-private.h
@@ -29,12 +29,12 @@ static inline sieve_size_t _sieve_extension_emit_obj
 (struct sieve_binary *sbin, 
 	const struct sieve_extension_obj_registry *defreg,
 	const struct sieve_extension_obj_registry *reg,
-	unsigned int obj_code, int ext_id) 
+	unsigned int obj_code, const struct sieve_extension *ext) 
 { 
-	if ( ext_id >= 0 ) {
+	if ( ext != NULL ) {
 		sieve_size_t address; 
 		unsigned char code = defreg->count +
-			sieve_binary_extension_get_index(sbin, ext_id);
+			sieve_binary_extension_get_index(sbin, ext);
 
 		address = sieve_binary_emit_byte(sbin, code);
 		
@@ -46,9 +46,9 @@ static inline sieve_size_t _sieve_extension_emit_obj
 
 	return sieve_binary_emit_byte(sbin, obj_code);
 }
-#define sieve_extension_emit_obj(sbin, defreg, obj, reg, ext_id)\
+#define sieve_extension_emit_obj(sbin, defreg, obj, reg, ext)\
 	_sieve_extension_emit_obj\
-		(sbin, defreg, &obj->extension->reg, obj->code, ext_id)
+		(sbin, defreg, &obj->extension->reg, obj->code, ext)
 
 static inline const void *_sieve_extension_read_obj
 (struct sieve_binary *sbin, sieve_size_t *address, 
diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c
index 543f382b2a0e175649b848ce0635ad759727e81a..d45b5e55ae0d6ca69b21f1f26bbd00c873196b26 100644
--- a/src/lib-sieve/sieve-extensions.c
+++ b/src/lib-sieve/sieve-extensions.c
@@ -161,38 +161,20 @@ const struct sieve_extension *sieve_extension_get_by_id(unsigned int ext_id)
 	return NULL;
 }
 
-int sieve_extension_get_by_name(const char *name, const struct sieve_extension **ext) 
+const struct sieve_extension *sieve_extension_get_by_name(const char *name) 
 {
   struct sieve_extension_registration *ereg;
 	
-	if ( ext != NULL )
-		*ext = NULL;
-		
 	if ( *name == '@' )
-		return -1;	
+		return NULL;	
 		
 	ereg = (struct sieve_extension_registration *) 
 		hash_lookup(extension_index, name);
 
 	if ( ereg == NULL )
-		return -1;
+		return NULL;
 		
-	if ( ext != NULL )    
-		*ext = ereg->extension;
-	
-	return ereg->id;
-}
-
-int sieve_extension_get_id(const struct sieve_extension *extension) 
-{
-	struct sieve_extension_registration *ereg = 
-		(struct sieve_extension_registration *) 
-			hash_lookup(extension_index, extension->name);
-
-	if ( ereg == NULL )
-		return -1;
-		    
-	return ereg->id;
+	return ereg->extension;
 }
 
 static bool _list_extension(const struct sieve_extension *ext)
diff --git a/src/lib-sieve/sieve-extensions.h b/src/lib-sieve/sieve-extensions.h
index 20d065845b9251a80883882b37ffa52da6a71e42..df13517ec853efcd6298d6f63bb4af27a1dee229 100644
--- a/src/lib-sieve/sieve-extensions.h
+++ b/src/lib-sieve/sieve-extensions.h
@@ -71,8 +71,7 @@ void sieve_extensions_deinit(void);
 int sieve_extension_register(const struct sieve_extension *extension);
 int sieve_extensions_get_count(void);
 const struct sieve_extension *sieve_extension_get_by_id(unsigned int ext_id);
-int sieve_extension_get_by_name(const char *name, const struct sieve_extension **ext);
-int sieve_extension_get_id(const struct sieve_extension *extension);
+const struct sieve_extension *sieve_extension_get_by_name(const char *name);
 
 const char *sieve_extensions_get_string(void);
 
diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c
index 067029342f9073eae34ddb285e6ac6c23329eaac..799f861216f3e9db8f5fc9b77f90d60b3ff47b95 100644
--- a/src/lib-sieve/sieve-generator.c
+++ b/src/lib-sieve/sieve-generator.c
@@ -156,14 +156,9 @@ void sieve_generator_critical
 /* Extension support */
 
 bool sieve_generator_link_extension
-	(struct sieve_generator *gentr, int ext_id) 
+(struct sieve_generator *gentr, const struct sieve_extension *ext) 
 {
-	const struct sieve_extension *ext = sieve_extension_get_by_id(ext_id);
-	
-	(void)sieve_binary_extension_link(gentr->genenv.sbin, ext_id);
-	
-	if ( ext == NULL ) 
-		return FALSE;
+	(void)sieve_binary_extension_link(gentr->genenv.sbin, ext);
 	
 	if ( ext->generator_load != NULL )
 		return ext->generator_load(gentr);
@@ -172,14 +167,15 @@ bool sieve_generator_link_extension
 }
 
 void sieve_generator_extension_set_context
-	(struct sieve_generator *gentr, int ext_id, void *context)
+(struct sieve_generator *gentr, const struct sieve_extension *ext, void *context)
 {
-	array_idx_set(&gentr->ext_contexts, (unsigned int) ext_id, &context);	
+	array_idx_set(&gentr->ext_contexts, (unsigned int) *ext->id, &context);	
 }
 
 const void *sieve_generator_extension_get_context
-	(struct sieve_generator *gentr, int ext_id) 
+(struct sieve_generator *gentr, const struct sieve_extension *ext) 
 {
+	int ext_id = *ext->id;
 	void * const *ctx;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&gentr->ext_contexts) )
@@ -309,9 +305,9 @@ bool sieve_generate_test
 		if ( tst_node->context->command->generate(cgenv, tst_node->context) ) {
 			
 			if ( jump_true ) 
-				sieve_operation_emit_code(cgenv->sbin, &sieve_jmptrue_operation, -1);
+				sieve_operation_emit_code(cgenv->sbin, &sieve_jmptrue_operation);
 			else
-				sieve_operation_emit_code(cgenv->sbin, &sieve_jmpfalse_operation, -1);
+				sieve_operation_emit_code(cgenv->sbin, &sieve_jmpfalse_operation);
 			sieve_jumplist_add(jlist, sieve_binary_emit_offset(cgenv->sbin, 0));
 						
 			return TRUE;
diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h
index 30be429aa99454204abd79b704081a94c2a3c4c8..c53fd4b3c44c42ef0cb5d95016ee483fda5086b4 100644
--- a/src/lib-sieve/sieve-generator.h
+++ b/src/lib-sieve/sieve-generator.h
@@ -35,12 +35,13 @@ void sieve_generator_critical
 /* Extension support */
 
 bool sieve_generator_link_extension
-	(struct sieve_generator *gentr, int ext_id);
+	(struct sieve_generator *gentr, const struct sieve_extension *ext);
 
 void sieve_generator_extension_set_context
-	(struct sieve_generator *gentr, int ext_id, void *context);
+	(struct sieve_generator *gentr, const struct sieve_extension *ext, 
+		void *context);
 const void *sieve_generator_extension_get_context
-	(struct sieve_generator *gentr, int ext_id);
+	(struct sieve_generator *gentr, const struct sieve_extension *ext);
     		
 /* Jump list */
 
diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c
index a41eb1ae514b955d934ff4fe89d37dae75dd7194..042223d362f9c577ea04f113feda741bf556d035 100644
--- a/src/lib-sieve/sieve-interpreter.c
+++ b/src/lib-sieve/sieve-interpreter.c
@@ -86,7 +86,7 @@ struct sieve_interpreter *sieve_interpreter_create
 	/* Load other extensions listed in the binary */
 	for ( idx = 0; idx < sieve_binary_extensions_count(sbin); idx++ ) {
 		const struct sieve_extension *ext = 
-			sieve_binary_extension_get_by_index(sbin, idx, NULL);
+			sieve_binary_extension_get_by_index(sbin, idx);
 		
 		if ( ext->interpreter_load != NULL )
 			ext->interpreter_load(interp);
@@ -200,14 +200,16 @@ void _sieve_runtime_trace
 /* Extension support */
 
 void sieve_interpreter_extension_set_context
-	(struct sieve_interpreter *interpreter, int ext_id, void *context)
+(struct sieve_interpreter *interpreter, const struct sieve_extension *ext, 
+	void *context)
 {
-	array_idx_set(&interpreter->ext_contexts, (unsigned int) ext_id, &context);	
+	array_idx_set(&interpreter->ext_contexts, (unsigned int) *ext->id, &context);	
 }
 
 const void *sieve_interpreter_extension_get_context
-	(struct sieve_interpreter *interpreter, int ext_id) 
+(struct sieve_interpreter *interpreter, const struct sieve_extension *ext) 
 {
+	int ext_id = *ext->id;
 	void * const *ctx;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&interpreter->ext_contexts) )
@@ -391,7 +393,7 @@ int sieve_interpreter_start
 	/* Load other extensions listed in the binary */
 	for ( idx = 0; idx < sieve_binary_extensions_count(sbin); idx++ ) {
 		const struct sieve_extension *ext = 
-			sieve_binary_extension_get_by_index(sbin, idx, NULL);
+			sieve_binary_extension_get_by_index(sbin, idx);
 		
 		if ( ext->runtime_load != NULL )
 			ext->runtime_load(&interp->runenv);
diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h
index 259c89891822ad0c71bb139f1de70c4632cc33bf..83b44becdd299205148c4567e3d0415624ee1c92 100644
--- a/src/lib-sieve/sieve-interpreter.h
+++ b/src/lib-sieve/sieve-interpreter.h
@@ -93,10 +93,12 @@ void _sieve_runtime_trace
 /* Extension support */
 
 void sieve_interpreter_extension_set_context
-	(struct sieve_interpreter *interp, int ext_id, void *context);
+	(struct sieve_interpreter *interp, const struct sieve_extension *ext,
+		void *context);
 const void *sieve_interpreter_extension_get_context
-	(struct sieve_interpreter *interp, int ext_id);
-	/* Opcodes and operands */
+	(struct sieve_interpreter *interp, const struct sieve_extension *ext);
+
+/* Opcodes and operands */
 	
 bool sieve_interpreter_handle_optional_operands
 	(const struct sieve_runtime_env *renv, sieve_size_t *address,
diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c
index 4e6ad7fdce9e7726eb3507da269c34dd1c392038..eacd617fae22c69c428ae1f9b4f9d4db3cae3b16 100644
--- a/src/lib-sieve/sieve-match-types.c
+++ b/src/lib-sieve/sieve-match-types.c
@@ -31,13 +31,6 @@ const struct sieve_match_type *sieve_core_match_types[] = {
 const unsigned int sieve_core_match_types_count = 
 	N_ELEMENTS(sieve_core_match_types);
 
-/* 
- * Forward declarations 
- */
-  
-static void sieve_opr_match_type_emit
-	(struct sieve_binary *sbin, const struct sieve_match_type *mtch, int ext_id);
-
 /* 
  * Match-type 'extension' 
  */
@@ -56,6 +49,8 @@ const struct sieve_extension match_type_extension = {
 	SIEVE_EXT_DEFINE_NO_OPERATIONS,
 	SIEVE_EXT_DEFINE_NO_OPERANDS
 };
+
+static const struct sieve_extension *ext_this = &match_type_extension;
 	
 static bool mtch_extension_load(int ext_id) 
 {
@@ -69,22 +64,21 @@ static bool mtch_extension_load(int ext_id)
  */
  
 void sieve_match_type_register
-(struct sieve_validator *validator, const struct sieve_match_type *mtch, 
-	int ext_id) 
+(struct sieve_validator *validator, const struct sieve_match_type *mtch) 
 {
 	struct sieve_validator_object_registry *regs = 
-		sieve_validator_object_registry_get(validator, ext_my_id);
+		sieve_validator_object_registry_get(validator, ext_this);
 	
-	sieve_validator_object_registry_add(regs, &mtch->object, ext_id);
+	sieve_validator_object_registry_add(regs, &mtch->object);
 }
 
 const struct sieve_match_type *sieve_match_type_find
-(struct sieve_validator *validator, const char *identifier, int *ext_id) 
+(struct sieve_validator *validator, const char *identifier) 
 {
 	struct sieve_validator_object_registry *regs = 
-		sieve_validator_object_registry_get(validator, ext_my_id);
+		sieve_validator_object_registry_get(validator, ext_this);
 	const struct sieve_object *object = 
-		sieve_validator_object_registry_find(regs, identifier, ext_id);
+		sieve_validator_object_registry_find(regs, identifier);
 
   return (const struct sieve_match_type *) object;
 }
@@ -92,13 +86,13 @@ const struct sieve_match_type *sieve_match_type_find
 bool mtch_validator_load(struct sieve_validator *validator)
 {
 	struct sieve_validator_object_registry *regs = 
-		sieve_validator_object_registry_init(validator, ext_my_id);
+		sieve_validator_object_registry_init(validator, ext_this);
 	unsigned int i;
 
 	/* Register core match-types */
 	for ( i = 0; i < sieve_core_match_types_count; i++ ) {
 		sieve_validator_object_registry_add
-			(regs, &(sieve_core_match_types[i]->object), -1);
+			(regs, &(sieve_core_match_types[i]->object));
 	}
 
 	return TRUE;
@@ -117,7 +111,7 @@ static inline struct mtch_interpreter_context *
 get_interpreter_context(struct sieve_interpreter *interp)
 {
 	return (struct mtch_interpreter_context *)
-		sieve_interpreter_extension_get_context(interp, ext_my_id);
+		sieve_interpreter_extension_get_context(interp, ext_this);
 }
 
 static struct mtch_interpreter_context *
@@ -129,7 +123,7 @@ mtch_interpreter_context_init(struct sieve_interpreter *interp)
 	ctx = p_new(pool, struct mtch_interpreter_context, 1);
 
 	sieve_interpreter_extension_set_context
-		(interp, ext_my_id, (void *) ctx);
+		(interp, ext_this, (void *) ctx);
 
 	return ctx;
 }
@@ -283,17 +277,15 @@ static bool tag_match_type_is_instance_of
 (struct sieve_validator *validator, struct sieve_command_context *cmd, 
 	struct sieve_ast_argument *arg)
 {
-	int ext_id;
 	struct sieve_match_type_context *mtctx;
 	const struct sieve_match_type *mtch = 
-		sieve_match_type_find(validator, sieve_ast_argument_tag(arg), &ext_id);
+		sieve_match_type_find(validator, sieve_ast_argument_tag(arg));
 		
 	if ( mtch == NULL ) return FALSE;	
 		
 	/* Create context */
 	mtctx = p_new(sieve_command_pool(cmd), struct sieve_match_type_context, 1);
 	mtctx->match_type = mtch;
-	mtctx->ext_id = ext_id;
 	mtctx->command_ctx = cmd;
 	
 	arg->context = (void *) mtctx;
@@ -334,8 +326,7 @@ static bool tag_match_type_generate
 	struct sieve_match_type_context *mtctx =
 		(struct sieve_match_type_context *) arg->context;
 	
-	(void) sieve_opr_match_type_emit
-		(cgenv->sbin, mtctx->match_type, mtctx->ext_id);
+	(void) sieve_opr_match_type_emit(cgenv->sbin, mtctx->match_type);
 			
 	return TRUE;
 }
diff --git a/src/lib-sieve/sieve-match-types.h b/src/lib-sieve/sieve-match-types.h
index a8fd2ac8ad8509400e71a7c36c0d25a84915eae8..069eebca761b157afeef8b054ebbf5305b9135c2 100644
--- a/src/lib-sieve/sieve-match-types.h
+++ b/src/lib-sieve/sieve-match-types.h
@@ -63,8 +63,6 @@ struct sieve_match_type_context {
 	struct sieve_command_context *command_ctx;
 	const struct sieve_match_type *match_type;
 	
-	int ext_id;
-	
 	/* Context data could be used in the future to pass data between validator and
 	 * generator in match types that use extra parameters. Currently not 
 	 * necessary, not even for the relational extension.
@@ -103,10 +101,9 @@ bool sieve_match_type_validate
 		
 void sieve_match_type_register
 	(struct sieve_validator *validator, 
-	const struct sieve_match_type *addrp, int ext_id);
+	const struct sieve_match_type *addrp);
 const struct sieve_match_type *sieve_match_type_find
-	(struct sieve_validator *validator, const char *identifier,
-		int *ext_id);
+	(struct sieve_validator *validator, const char *identifier);
 
 extern const struct sieve_argument match_type_tag;
 
@@ -128,9 +125,9 @@ static inline bool sieve_operand_is_match_type
 }
 
 static inline void sieve_opr_match_type_emit
-(struct sieve_binary *sbin, const struct sieve_match_type *mtch, int ext_id)
+(struct sieve_binary *sbin, const struct sieve_match_type *mtch)
 { 
-	sieve_opr_object_emit(sbin, &mtch->object, ext_id);
+	sieve_opr_object_emit(sbin, &mtch->object);
 }
 
 static inline const struct sieve_match_type *sieve_opr_match_type_read
diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c
index 57bc9aa63fb4bd182a160ccb119991a4c215c4a3..bc623222f3c7a893f63e0fa84410c55a9c6f7872 100644
--- a/src/lib-sieve/sieve-message.c
+++ b/src/lib-sieve/sieve-message.c
@@ -4,6 +4,7 @@
 
 #include "sieve-common.h"
 #include "sieve-message.h"
+#include "sieve-extensions.h"
 
 /* 
  * Message context 
@@ -50,14 +51,16 @@ void sieve_message_context_unref(struct sieve_message_context **msgctx)
 }
 
 void sieve_message_context_extension_set
-	(struct sieve_message_context *msgctx, int ext_id, void *context)
+(struct sieve_message_context *msgctx, const struct sieve_extension *ext, 
+	void *context)
 {
-	array_idx_set(&msgctx->ext_contexts, (unsigned int) ext_id, &context);	
+	array_idx_set(&msgctx->ext_contexts, (unsigned int) *ext->id, &context);	
 }
 
 const void *sieve_message_context_extension_get
-	(struct sieve_message_context *msgctx, int ext_id) 
+(struct sieve_message_context *msgctx, const struct sieve_extension *ext) 
 {
+	int ext_id = *ext->id;
 	void * const *ctx;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&msgctx->ext_contexts) )
diff --git a/src/lib-sieve/sieve-message.h b/src/lib-sieve/sieve-message.h
index 33fd667d7ad73f8884516db6892b7f86bbec9ff8..4e6e848bf56c1476de21ab4a0ab702fd27c6d934 100644
--- a/src/lib-sieve/sieve-message.h
+++ b/src/lib-sieve/sieve-message.h
@@ -10,9 +10,10 @@ void sieve_message_context_ref(struct sieve_message_context *msgctx);
 void sieve_message_context_unref(struct sieve_message_context **msgctx);
 
 void sieve_message_context_extension_set
-	(struct sieve_message_context *msgctx, int ext_id, void *context);
+	(struct sieve_message_context *msgctx, const struct sieve_extension *ext, 
+		void *context);
 const void *sieve_message_context_extension_get
-	(struct sieve_message_context *msgctx, int ext_id);
+	(struct sieve_message_context *msgctx, const struct sieve_extension *ext);
 pool_t sieve_message_context_pool
 	(struct sieve_message_context *msgctx);
 	
diff --git a/src/lib-sieve/sieve-objects.c b/src/lib-sieve/sieve-objects.c
index 1358a577e4b5d6580933337bc5a125787d44a732..a797d672d803b3b30c6b5c017f12da3c890c6131 100644
--- a/src/lib-sieve/sieve-objects.c
+++ b/src/lib-sieve/sieve-objects.c
@@ -8,12 +8,12 @@
 #include "sieve-objects.h"
 
 void sieve_opr_object_emit
-(struct sieve_binary *sbin, const struct sieve_object *obj, int ext_id)
+(struct sieve_binary *sbin, const struct sieve_object *obj)
 {
 	struct sieve_extension_obj_registry *reg = 
 		(struct sieve_extension_obj_registry *) obj->operand->interface;
 		 
-	(void) sieve_operand_emit_code(sbin, obj->operand, ext_id);
+	(void) sieve_operand_emit_code(sbin, obj->operand);
 	
 	if ( reg->count > 1 ) {	
 		(void) sieve_binary_emit_byte(sbin, obj->code);
diff --git a/src/lib-sieve/sieve-objects.h b/src/lib-sieve/sieve-objects.h
index 86858aa030fe1069ed9014e7a2d9308c4f7641f6..538fa0d64ccd29eb2d37eb1045cad4b03daae3b7 100644
--- a/src/lib-sieve/sieve-objects.h
+++ b/src/lib-sieve/sieve-objects.h
@@ -11,7 +11,7 @@ struct sieve_object {
 	{ identifier, operand, code }
 
 void sieve_opr_object_emit
-	(struct sieve_binary *sbin, const struct sieve_object *obj, int ext_id);
+	(struct sieve_binary *sbin, const struct sieve_object *obj);
 
 const struct sieve_object *sieve_opr_object_read_data
 	(struct sieve_binary *sbin, const struct sieve_operand *operand,
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index 79bb140be0a7a1110efe99021f5faafb377c42ab..47cf75f251f7102fd60556c41f2420089854239e 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -117,14 +117,15 @@ pool_t sieve_result_pool(struct sieve_result *result)
 }
 
 void sieve_result_extension_set_context
-	(struct sieve_result *result, int ext_id, void *context)
+(struct sieve_result *result, const struct sieve_extension *ext, void *context)
 {
-	array_idx_set(&result->ext_contexts, (unsigned int) ext_id, &context);	
+	array_idx_set(&result->ext_contexts, (unsigned int) *ext->id, &context);	
 }
 
 const void *sieve_result_extension_get_context
-	(struct sieve_result *result, int ext_id) 
+(struct sieve_result *result, const struct sieve_extension *ext) 
 {
+	int ext_id = *ext->id;
 	void * const *ctx;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&result->ext_contexts) )
diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h
index 529a1200f24e29a7520b5eca17b9902930f61c6c..79f016e3e92c1d7fd0ad207cb9ae3085fa835751 100644
--- a/src/lib-sieve/sieve-result.h
+++ b/src/lib-sieve/sieve-result.h
@@ -14,9 +14,10 @@ void sieve_result_unref(struct sieve_result **result);
 pool_t sieve_result_pool(struct sieve_result *result);
 
 void sieve_result_extension_set_context
-	(struct sieve_result *result, int ext_id, void *context);
+	(struct sieve_result *result, const struct sieve_extension *ext,
+		void *context);
 const void *sieve_result_extension_get_context
-	(struct sieve_result *result, int ext_id); 
+	(struct sieve_result *result, const struct sieve_extension *ext); 
 
 /* Printing */
 
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index dc7eb66d255468f637831786f48ef77049199cbc..63f435239f373c3b9dc769c21b6c4836bfd00f75 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -412,37 +412,37 @@ static const struct sieve_argument *sieve_validator_find_tag
 
 /* Extension support */
 
-int sieve_validator_extension_load
+const struct sieve_extension *sieve_validator_extension_load
 	(struct sieve_validator *validator, struct sieve_command_context *cmd, 
 		const char *ext_name) 
 {
-	const struct sieve_extension *ext;
-	int ext_id = sieve_extension_get_by_name(ext_name, &ext); 
+	const struct sieve_extension *ext = sieve_extension_get_by_name(ext_name); 
 	
-	if ( ext_id < 0 ) {
+	if ( ext == NULL ) {
 		sieve_command_validate_error(validator, cmd, 
 			"unsupported sieve capability '%s'", ext_name);
-		return -1;
+		return NULL;
 	}
 
 	if ( ext->validator_load != NULL && !ext->validator_load(validator) ) {
 		sieve_command_validate_error(validator, cmd, 
 			"failed to load sieve capability '%s'", ext->name);
-		return -1;
+		return NULL;
 	}
 	
-	return ext_id;
+	return ext;
 }
 
 void sieve_validator_extension_set_context
-	(struct sieve_validator *validator, int ext_id, void *context)
+(struct sieve_validator *validator, const struct sieve_extension *ext, void *context)
 {
-	array_idx_set(&validator->ext_contexts, (unsigned int) ext_id, &context);	
+	array_idx_set(&validator->ext_contexts, (unsigned int) *ext->id, &context);	
 }
 
 const void *sieve_validator_extension_get_context
-	(struct sieve_validator *validator, int ext_id) 
+(struct sieve_validator *validator, const struct sieve_extension *ext) 
 {
+	int ext_id = *ext->id;
 	void * const *ctx;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&validator->ext_contexts) )
@@ -951,49 +951,30 @@ bool sieve_validator_run(struct sieve_validator *validator) {
  * Validator object registry
  */
 
-struct sieve_validator_object_reg {
-	const struct sieve_object *object;
-	int ext_id;
-};
- 
 struct sieve_validator_object_registry {
 	struct sieve_validator *validator;
 	struct hash_table *registrations;
 };
 
 struct sieve_validator_object_registry *sieve_validator_object_registry_get
-(struct sieve_validator *validator, int ext_id)
+(struct sieve_validator *validator, const struct sieve_extension *ext)
 {
 	return (struct sieve_validator_object_registry *) 
-		sieve_validator_extension_get_context(validator, ext_id);
+		sieve_validator_extension_get_context(validator, ext);
 }
 
 void sieve_validator_object_registry_add
-(struct sieve_validator_object_registry *regs,
-	const struct sieve_object *object, int ext_id) 
+(struct sieve_validator_object_registry *regs, 
+	const struct sieve_object *object) 
 {
-	struct sieve_validator_object_reg *reg;
-	
-	reg = p_new(regs->validator->pool, struct sieve_validator_object_reg, 1);
-	reg->object = object;
-	reg->ext_id = ext_id;
-	
 	hash_insert
-		(regs->registrations, (void *) object->identifier, (void *) reg);
+		(regs->registrations, (void *) object->identifier, (void *) object);
 }
 
 const struct sieve_object *sieve_validator_object_registry_find
-(struct sieve_validator_object_registry *regs, const char *identifier,
-		int *ext_id) 
+(struct sieve_validator_object_registry *regs, const char *identifier) 
 {
-	struct sieve_validator_object_reg *reg =(struct sieve_validator_object_reg *) 
-		hash_lookup(regs->registrations, identifier);
-			
-	if ( reg == NULL ) return NULL;
-
-	if ( ext_id != NULL ) *ext_id = reg->ext_id;
-
-  return reg->object;
+	return (const struct sieve_object *) hash_lookup(regs->registrations, identifier);
 }
 
 struct sieve_validator_object_registry *sieve_validator_object_registry_create
@@ -1012,12 +993,12 @@ struct sieve_validator_object_registry *sieve_validator_object_registry_create
 }
 
 struct sieve_validator_object_registry *sieve_validator_object_registry_init
-(struct sieve_validator *validator, int ext_id)
+(struct sieve_validator *validator, const struct sieve_extension *ext)
 {
 	struct sieve_validator_object_registry *regs = 
 		sieve_validator_object_registry_create(validator);
 	
-	sieve_validator_extension_set_context(validator, ext_id, regs);
+	sieve_validator_extension_set_context(validator, ext, regs);
 	return regs;
 }
 
diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h
index ff3595c2a5e0307b2cfd95cd8110a1962241d9b6..16b825f21c8dd4eb6b6e7fee44abaf1de77e756c 100644
--- a/src/lib-sieve/sieve-validator.h
+++ b/src/lib-sieve/sieve-validator.h
@@ -85,14 +85,15 @@ bool sieve_validator_argument_activate_super
 	struct sieve_ast_argument *arg, bool constant);
 
 /* Extensions */
-int sieve_validator_extension_load
+const struct sieve_extension *sieve_validator_extension_load
 	(struct sieve_validator *validator, struct sieve_command_context *cmd, 
 		const char *ext_name); 
 
 void sieve_validator_extension_set_context
-	(struct sieve_validator *validator, int ext_id, void *context);
+	(struct sieve_validator *validator, const struct sieve_extension *ext, 
+		void *context);
 const void *sieve_validator_extension_get_context
-	(struct sieve_validator *validator, int ext_id);
+	(struct sieve_validator *validator, const struct sieve_extension *ext);
 
 /*
  * Validator object registry
@@ -101,16 +102,15 @@ const void *sieve_validator_extension_get_context
 struct sieve_validator_object_registry;
 
 struct sieve_validator_object_registry *sieve_validator_object_registry_get
-	(struct sieve_validator *validator, int ext_id);
+	(struct sieve_validator *validator, const struct sieve_extension *ext);
 void sieve_validator_object_registry_add
 	(struct sieve_validator_object_registry *regs,
-		const struct sieve_object *object, int ext_id);
+		const struct sieve_object *object);
 const struct sieve_object *sieve_validator_object_registry_find
-	(struct sieve_validator_object_registry *regs, const char *identifier,
-		int *ext_id);
+	(struct sieve_validator_object_registry *regs, const char *identifier);
 struct sieve_validator_object_registry *sieve_validator_object_registry_create
 	(struct sieve_validator *validator);
 struct sieve_validator_object_registry *sieve_validator_object_registry_init
-	(struct sieve_validator *validator, int ext_id);
+	(struct sieve_validator *validator, const struct sieve_extension *ext);
 
 #endif /* __SIEVE_VALIDATOR_H */
diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c
index dfc644beb238bc5b35d807c0d8c99f30f9fa2e4e..62206614a2b083e45091674182e3056a3ec25b67 100644
--- a/src/lib-sieve/tst-address.c
+++ b/src/lib-sieve/tst-address.c
@@ -114,7 +114,7 @@ static bool tst_address_validate
 static bool tst_address_generate
 (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
-	sieve_operation_emit_code(cgenv->sbin, &tst_address_operation, -1);
+	sieve_operation_emit_code(cgenv->sbin, &tst_address_operation);
 	
 	/* Generate arguments */  	
 	return sieve_generate_arguments(cgenv, ctx, NULL);
diff --git a/src/lib-sieve/tst-allof.c b/src/lib-sieve/tst-allof.c
index 81cd9feffb0f4bb00136ba9585b1ad0944e4b3eb..7f9d16b9b5ad2079909d17970102230236f9da03 100644
--- a/src/lib-sieve/tst-allof.c
+++ b/src/lib-sieve/tst-allof.c
@@ -69,7 +69,7 @@ static bool tst_allof_generate
 	
 		if ( jump_true ) {
 			/* All tests succeeded, jump to case TRUE */
-			sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation, -1);
+			sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation);
 			sieve_jumplist_add(jumps, sieve_binary_emit_offset(sbin, 0));
 			
 			/* All false exits jump here */
diff --git a/src/lib-sieve/tst-anyof.c b/src/lib-sieve/tst-anyof.c
index a053cc1b9add652287aa571397d4fec0c5358c31..9a21602a57ccf00ff52233850b17c6ca88aa11e2 100644
--- a/src/lib-sieve/tst-anyof.c
+++ b/src/lib-sieve/tst-anyof.c
@@ -67,7 +67,7 @@ static bool tst_anyof_generate
 	
 		if ( !jump_true ) {
 			/* All tests failed, jump to case FALSE */
-			sieve_operation_emit_code(sbin, &sieve_jmp_operation, -1);
+			sieve_operation_emit_code(sbin, &sieve_jmp_operation);
 			sieve_jumplist_add(jumps, sieve_binary_emit_offset(sbin, 0));
 			
 			/* All true exits jump here */
diff --git a/src/lib-sieve/tst-exists.c b/src/lib-sieve/tst-exists.c
index 741db6037043273ad62504b400d79a633960139b..ca1f47beccf6d22e53c5b386296823e0e963faf8 100644
--- a/src/lib-sieve/tst-exists.c
+++ b/src/lib-sieve/tst-exists.c
@@ -75,7 +75,7 @@ static bool tst_exists_validate
 static bool tst_exists_generate
 (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
-	sieve_operation_emit_code(cgenv->sbin, &tst_exists_operation, -1);
+	sieve_operation_emit_code(cgenv->sbin, &tst_exists_operation);
 
  	/* Generate arguments */
     return sieve_generate_arguments(cgenv, ctx, NULL);
diff --git a/src/lib-sieve/tst-header.c b/src/lib-sieve/tst-header.c
index acb829468d6d210c1210374d89b551700e2ebadc..e881f7306ff795de82a5f6aa88120cc234d9fbb6 100644
--- a/src/lib-sieve/tst-header.c
+++ b/src/lib-sieve/tst-header.c
@@ -116,7 +116,7 @@ static bool tst_header_validate
 static bool tst_header_generate
 	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
-	sieve_operation_emit_code(cgenv->sbin, &tst_header_operation, -1);
+	sieve_operation_emit_code(cgenv->sbin, &tst_header_operation);
 
  	/* Generate arguments */
 	return sieve_generate_arguments(cgenv, ctx, NULL);
diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c
index be632b549fca2f7b4cacb1d17853dd187dfc3f2c..f6d563dc5d246bb3ee9cc438f1889b403e51b65d 100644
--- a/src/lib-sieve/tst-size.c
+++ b/src/lib-sieve/tst-size.c
@@ -193,9 +193,9 @@ bool tst_size_generate
 	struct tst_size_context_data *ctx_data = (struct tst_size_context_data *) ctx->data;
 
 	if ( ctx_data->type == SIZE_OVER ) 
-		sieve_operation_emit_code(cgenv->sbin, &tst_size_over_operation, -1);
+		sieve_operation_emit_code(cgenv->sbin, &tst_size_over_operation);
 	else
-		sieve_operation_emit_code(cgenv->sbin, &tst_size_under_operation, -1);
+		sieve_operation_emit_code(cgenv->sbin, &tst_size_under_operation);
 
  	/* Generate arguments */
     if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
diff --git a/src/testsuite/cmd-test-fail.c b/src/testsuite/cmd-test-fail.c
index 22f6b99d88943cd4e33db6faa53bf6a67467f188..f3a9994cb1e4d24b6c3476887306dbbe86a0e5a2 100644
--- a/src/testsuite/cmd-test-fail.c
+++ b/src/testsuite/cmd-test-fail.c
@@ -69,7 +69,7 @@ static inline struct testsuite_generator_context *
 	_get_generator_context(struct sieve_generator *gentr)
 {
 	return (struct testsuite_generator_context *) 
-		sieve_generator_extension_get_context(gentr, ext_testsuite_my_id);
+		sieve_generator_extension_get_context(gentr, &testsuite_extension);
 }
 
 static bool cmd_test_fail_generate
@@ -78,8 +78,7 @@ static bool cmd_test_fail_generate
 	struct testsuite_generator_context *genctx = 
 		_get_generator_context(cgenv->gentr);
 	
-	sieve_operation_emit_code(cgenv->sbin, &test_fail_operation, 
-		ext_testsuite_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &test_fail_operation);
 
 	/* Generate arguments */
 	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
diff --git a/src/testsuite/cmd-test-set.c b/src/testsuite/cmd-test-set.c
index f808dcfe12a4ec38e3584fe67640e06b492a8693..d6ffcd22c0688c3b0b865c2bab1faa8f48899b73 100644
--- a/src/testsuite/cmd-test-set.c
+++ b/src/testsuite/cmd-test-set.c
@@ -95,8 +95,7 @@ static bool cmd_test_set_validate
 static bool cmd_test_set_generate
 	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
-	sieve_operation_emit_code(cgenv->sbin, &test_set_operation, 
-		ext_testsuite_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &test_set_operation);
 
 	/* Generate arguments */
 	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
diff --git a/src/testsuite/cmd-test.c b/src/testsuite/cmd-test.c
index 6d812d171a5cb3141c796147f5bcdf9ba2d29de1..078c1535468f8ca5a8b840d8e3ca4518c173bc2f 100644
--- a/src/testsuite/cmd-test.c
+++ b/src/testsuite/cmd-test.c
@@ -88,7 +88,7 @@ static inline struct testsuite_generator_context *
 	_get_generator_context(struct sieve_generator *gentr)
 {
 	return (struct testsuite_generator_context *) 
-		sieve_generator_extension_get_context(gentr, ext_testsuite_my_id);
+		sieve_generator_extension_get_context(gentr, &testsuite_extension);
 }
 
 static bool cmd_test_generate
@@ -97,8 +97,7 @@ static bool cmd_test_generate
 	struct testsuite_generator_context *genctx = 
 		_get_generator_context(cgenv->gentr);
 	
-	sieve_operation_emit_code(cgenv->sbin, &test_operation, 
-		ext_testsuite_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &test_operation);
 
 	/* Generate arguments */
 	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
@@ -110,8 +109,7 @@ static bool cmd_test_generate
 	/* Test body */
 	sieve_generate_block(cgenv, ctx->ast_node);
 	
-	sieve_operation_emit_code(cgenv->sbin, &test_finish_operation, 
-		ext_testsuite_my_id);
+	sieve_operation_emit_code(cgenv->sbin, &test_finish_operation);
 	
 	/* Resolve exit jumps to this point */
 	sieve_jumplist_resolve(genctx->exit_jumps); 
diff --git a/src/testsuite/testsuite-common.c b/src/testsuite/testsuite-common.c
index 2d81258e6133da2b968eb16e3582f8220173c5ef..ac695462b04cc68f3ab1c20d997ac9ec6138a830 100644
--- a/src/testsuite/testsuite-common.c
+++ b/src/testsuite/testsuite-common.c
@@ -158,7 +158,7 @@ bool testsuite_validator_context_initialize(struct sieve_validator *valdtr)
 	ctx->object_registrations = sieve_validator_object_registry_create(valdtr);
 	testsuite_register_core_objects(ctx);
 	
-	sieve_validator_extension_set_context(valdtr, ext_testsuite_my_id, ctx);
+	sieve_validator_extension_set_context(valdtr, &testsuite_extension, ctx);
 
 	return TRUE;
 }
@@ -167,7 +167,7 @@ struct testsuite_validator_context *testsuite_validator_context_get
 (struct sieve_validator *valdtr)
 {
 	return (struct testsuite_validator_context *)
-		sieve_validator_extension_get_context(valdtr, ext_testsuite_my_id);
+		sieve_validator_extension_get_context(valdtr, &testsuite_extension);
 }
 
 /* 
@@ -184,7 +184,7 @@ bool testsuite_generator_context_initialize(struct sieve_generator *gentr)
 	/* Setup exit jumplist */
 	ctx->exit_jumps = sieve_jumplist_create(pool, sbin);
 	
-	sieve_generator_extension_set_context(gentr, ext_testsuite_my_id, ctx);
+	sieve_generator_extension_set_context(gentr, &testsuite_extension, ctx);
 
 	return TRUE;
 }
diff --git a/src/testsuite/testsuite-objects.c b/src/testsuite/testsuite-objects.c
index 3f2420f15654c8ed505c806779dacf4755ea31e9..6d0fb39599112aa868e4b4e7f7c90d681c8db50a 100644
--- a/src/testsuite/testsuite-objects.c
+++ b/src/testsuite/testsuite-objects.c
@@ -38,26 +38,25 @@ const unsigned int testsuite_core_objects_count =
  */
  
 void testsuite_object_register
-(struct sieve_validator *valdtr, const struct testsuite_object *tobj, 
-	int ext_id) 
+(struct sieve_validator *valdtr, const struct testsuite_object *tobj) 
 {
 	struct testsuite_validator_context *ctx = testsuite_validator_context_get
 		(valdtr);
 	
 	sieve_validator_object_registry_add
-		(ctx->object_registrations, &tobj->object, ext_id);
+		(ctx->object_registrations, &tobj->object);
 }
 
 const struct testsuite_object *testsuite_object_find
-(struct sieve_validator *valdtr, const char *identifier, int *ext_id) 
+(struct sieve_validator *valdtr, const char *identifier) 
 {
 	struct testsuite_validator_context *ctx = testsuite_validator_context_get
 		(valdtr);
 	const struct sieve_object *object = 
 		sieve_validator_object_registry_find
-			(ctx->object_registrations, identifier, ext_id);
+			(ctx->object_registrations, identifier);
 
-  return (const struct testsuite_object *) object;
+	return (const struct testsuite_object *) object;
 }
 
 void testsuite_register_core_objects
@@ -68,8 +67,7 @@ void testsuite_register_core_objects
 	/* Register core testsuite objects */
 	for ( i = 0; i < testsuite_core_objects_count; i++ ) {
 		sieve_validator_object_registry_add
-			(ctx->object_registrations, &(testsuite_core_objects[i]->object), 
-				ext_testsuite_my_id);
+			(ctx->object_registrations, &(testsuite_core_objects[i]->object));
 	}
 }
  
@@ -92,10 +90,10 @@ const struct sieve_operand testsuite_object_operand = {
 };
 
 static void testsuite_object_emit
-(struct sieve_binary *sbin, const struct testsuite_object *obj, int ext_id,
+(struct sieve_binary *sbin, const struct testsuite_object *obj,
 	int member_id)
 { 
-	sieve_opr_object_emit(sbin, &obj->object, ext_id);
+	sieve_opr_object_emit(sbin, &obj->object);
 	
 	if ( obj->get_member_id != NULL ) {
 		(void) sieve_binary_emit_byte(sbin, (unsigned char) member_id);
@@ -180,7 +178,6 @@ const struct sieve_argument testsuite_object_argument = {
  
 struct testsuite_object_argctx {
 	const struct testsuite_object *object;
-	int ext_id;
 	int member;
 };
 
@@ -190,7 +187,7 @@ bool testsuite_object_argument_activate
 {
 	const char *objname = sieve_ast_argument_strc(arg);
 	const struct testsuite_object *object;
-	int ext_id, member_id;
+	int member_id;
 	const char *member;
 	struct testsuite_object_argctx *ctx;
 	
@@ -204,7 +201,7 @@ bool testsuite_object_argument_activate
 	
 	/* Find the object */
 	
-	object = testsuite_object_find(valdtr, objname, &ext_id);
+	object = testsuite_object_find(valdtr, objname);
 	if ( object == NULL ) {
 		sieve_command_validate_error(valdtr, cmd, 
 			"unknown testsuite object '%s'", objname);
@@ -227,7 +224,6 @@ bool testsuite_object_argument_activate
 	
 	ctx = p_new(sieve_command_pool(cmd), struct testsuite_object_argctx, 1);
 	ctx->object = object;
-	ctx->ext_id = ext_id;
 	ctx->member = member_id;
 	
 	arg->argument = &testsuite_object_argument;
@@ -243,7 +239,7 @@ static bool arg_testsuite_object_generate
 	struct testsuite_object_argctx *ctx = 
 		(struct testsuite_object_argctx *) arg->context;
 	
-	testsuite_object_emit(cgenv->sbin, ctx->object, ctx->ext_id, ctx->member);
+	testsuite_object_emit(cgenv->sbin, ctx->object, ctx->member);
 		
 	return TRUE;
 }
diff --git a/src/testsuite/testsuite-objects.h b/src/testsuite/testsuite-objects.h
index b86fcf5c1993f2da9d31b2ee9dc73a1ecb1041a3..999a0c7fc6619e9e7f725f66d860923ebfdf2aa2 100644
--- a/src/testsuite/testsuite-objects.h
+++ b/src/testsuite/testsuite-objects.h
@@ -28,10 +28,9 @@ struct testsuite_object {
 /* Testsuite object registration */
 
 const struct testsuite_object *testsuite_object_find
-	(struct sieve_validator *valdtr, const char *identifier, int *ext_id);
+	(struct sieve_validator *valdtr, const char *identifier);
 void testsuite_object_register
-	(struct sieve_validator *valdtr, const struct testsuite_object *tobj, 
-		int ext_id);		
+	(struct sieve_validator *valdtr, const struct testsuite_object *tobj);		
 void testsuite_register_core_objects
 	(struct testsuite_validator_context *ctx);