diff --git a/src/lib-sieve/plugins/include/cmd-include.c b/src/lib-sieve/plugins/include/cmd-include.c
index 40ae8c8ed1a53e1c5b9462cd261b08f5f078a659..c3cb1569c97f27564d144fb624a013c2025d78ca 100644
--- a/src/lib-sieve/plugins/include/cmd-include.c
+++ b/src/lib-sieve/plugins/include/cmd-include.c
@@ -68,8 +68,8 @@ const struct sieve_opcode include_opcode = {
 struct cmd_include_context_data {
 	enum { LOCATION_PERSONAL, LOCATION_GLOBAL } location;
 	bool location_assigned;
-	struct sieve_script *script;
-	struct sieve_ast *ast;
+	const char *script_name;
+	const char *script_path;
 };   
 
 /* Tags */
@@ -158,12 +158,11 @@ static bool cmd_include_pre_validate
 static bool cmd_include_validate(struct sieve_validator *validator, 
 	struct sieve_command_context *cmd) 
 { 	
+	pool_t pool = sieve_command_pool(cmd);
 	struct sieve_ast_argument *arg = cmd->first_positional;
 	struct cmd_include_context_data *ctx_data = 
 		(struct cmd_include_context_data *) cmd->data;
-	const char *script_name, *script_path;
-	struct sieve_ast *ast;
-
+	
 	if ( !sieve_validate_positional_argument
 		(validator, cmd, arg, "value", 1, SAAT_STRING) ) {
 		return FALSE;
@@ -171,27 +170,20 @@ static bool cmd_include_validate(struct sieve_validator *validator,
 	
 	/* Get script path */
 
-	script_name = sieve_ast_argument_strc(arg);
+	ctx_data->script_name = sieve_ast_argument_strc(arg);
 	
 	/* FIXME: Hardcoded */
 #define HARDCODED_DIR "src/lib-sieve/plugins/include/"
 	if ( ctx_data->location == LOCATION_PERSONAL )
-		script_path = t_strconcat
-  		(HARDCODED_DIR, script_name, ".sieve", NULL);
+		ctx_data->script_path = p_strconcat
+  		(pool, HARDCODED_DIR, ctx_data->script_name, ".sieve", NULL);
 	else if ( ctx_data->location == LOCATION_GLOBAL )
-		script_path = t_strconcat
-  		(HARDCODED_DIR, script_name, ".sieve", NULL);
+		ctx_data->script_path = p_strconcat
+  		(pool, HARDCODED_DIR, ctx_data->script_name, ".sieve", NULL);
 	else 
 		return FALSE;
-
-	/* Validate */
-	if ( !ext_include_validate_include
-		(validator, cmd, script_path, script_name, &ast) ) {
- 		return FALSE;
- 	}
- 	 	
- 	ctx_data->ast = ast;
-	sieve_validator_argument_activate(validator, arg);	
+		
+	arg = sieve_ast_arguments_detach(arg, 1);
 	
 	return TRUE;
 }
@@ -201,8 +193,17 @@ static bool cmd_include_validate(struct sieve_validator *validator,
  */
  
 static bool cmd_include_generate
-	(struct sieve_generator *generator,	struct sieve_command_context *ctx) 
+	(struct sieve_generator *generator,	struct sieve_command_context *cmd) 
 {
+	struct cmd_include_context_data *ctx_data = 
+		(struct cmd_include_context_data *) cmd->data;
+
+	/* Generate */
+	if ( !ext_include_generate_include
+		(generator, cmd, ctx_data->script_path, ctx_data->script_name) ) {
+ 		return FALSE;
+ 	}
+ 	 		
 	return TRUE;
 }
 
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index ed10681ad8bdf8fa4aa72041a9fde496cfb6b490..059c5051c85cef86e34bcf718b7700d18616181d 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -3,42 +3,41 @@
 #include "sieve-script.h"
 #include "sieve-ast.h"
 #include "sieve-commands.h"
-#include "sieve-parser.h"
-#include "sieve-validator.h"
+#include "sieve-generator.h"
 
 #include "ext-include-common.h"
 
-/* Validator context management */
+/* Generator context management */
 
 static struct ext_include_main_context *ext_include_create_main_context
-(struct sieve_validator *validator)
+(struct sieve_generator *gentr)
 {
-	pool_t pool = sieve_validator_pool(validator);
+	pool_t pool = sieve_generator_pool(gentr);
 	
 	struct ext_include_main_context *ctx = 
 		p_new(pool, struct ext_include_main_context, 1);
 	
-	ctx->validator = validator;
+	ctx->generator = gentr;
 	ctx->included_scripts = hash_create
 		(pool, pool, 0, str_hash, (hash_cmp_callback_t *)strcmp);
 	
 	return ctx;
 }
 
-static struct ext_include_validator_context *
-	ext_include_create_validator_context
-(struct sieve_validator *validator, 
-	struct ext_include_validator_context *parent, struct sieve_script *script)
+static struct ext_include_generator_context *
+	ext_include_create_generator_context
+(struct sieve_generator *gentr, struct ext_include_generator_context *parent, 
+	struct sieve_script *script)
 {	
-	struct ext_include_validator_context *ctx;
+	struct ext_include_generator_context *ctx;
 
-	pool_t pool = sieve_validator_pool(validator);
-	ctx = p_new(pool, struct ext_include_validator_context, 1);
+	pool_t pool = sieve_generator_pool(gentr);
+	ctx = p_new(pool, struct ext_include_generator_context, 1);
 	ctx->parent = parent;
 	ctx->script = script;
 	if ( parent == NULL ) {
 		ctx->nesting_level = 0;
-		ctx->main = ext_include_create_main_context(validator);
+		ctx->main = ext_include_create_main_context(gentr);
 	} else {
 		ctx->nesting_level = parent->nesting_level + 1;
 		ctx->main = parent->main;
@@ -47,40 +46,38 @@ static struct ext_include_validator_context *
 	return ctx;
 }
 
-inline struct ext_include_validator_context *
-	ext_include_get_validator_context
-(struct sieve_validator *validator)
+inline struct ext_include_generator_context *ext_include_get_generator_context
+(struct sieve_generator *gentr)
 {
-	return (struct ext_include_validator_context *)
-		sieve_validator_extension_get_context(validator, ext_include_my_id);
+	return (struct ext_include_generator_context *)
+		sieve_generator_extension_get_context(gentr, ext_include_my_id);
 }
 
-void ext_include_register_validator_context
-(struct sieve_validator *validator, struct sieve_script *script)
+void ext_include_register_generator_context(struct sieve_generator *gentr)
 {
-	struct ext_include_validator_context *ctx = 
-		ext_include_get_validator_context(validator);
+	struct ext_include_generator_context *ctx = 
+		ext_include_get_generator_context(gentr);
+	struct sieve_script *script = sieve_generator_script(gentr);
 	
 	if ( ctx == NULL ) {
-		ctx = ext_include_create_validator_context(validator, NULL, script);
+		ctx = ext_include_create_generator_context(gentr, NULL, script);
 		
-		sieve_validator_extension_set_context
-			(validator, ext_include_my_id, (void *) ctx);		
+		sieve_generator_extension_set_context
+			(gentr, ext_include_my_id, (void *) ctx);		
 	}
 }
 
-bool ext_include_validate_include
-(struct sieve_validator *validator, struct sieve_command_context *cmd,
-	const char *script_path, const char *script_name, struct sieve_ast **ast_r)
+bool ext_include_generate_include
+(struct sieve_generator *gentr, struct sieve_command_context *cmd,
+	const char *script_path, const char *script_name)
 {
 	bool result = TRUE;
 	struct sieve_script *script;
-	struct sieve_validator *subvalid; 
-	struct ext_include_validator_context *parent =
-		ext_include_get_validator_context(validator);
-	struct ext_include_validator_context *ctx;
-	struct sieve_error_handler *ehandler = 
-		sieve_validator_get_error_handler(validator);
+	struct sieve_ast *ast;
+	struct ext_include_generator_context *parent =
+		ext_include_get_generator_context(gentr);
+	struct ext_include_generator_context *ctx;
+	struct sieve_error_handler *ehandler = sieve_generator_error_handler(gentr);
 		
 	/* Do not include more scripts when errors have occured already. */
 	if ( sieve_get_errors(ehandler) > 0 )
@@ -91,15 +88,12 @@ bool ext_include_validate_include
 		== NULL )
 		return FALSE;
 	
-	*ast_r = NULL;
-	
 	/* Check for circular include */
 	
 	ctx = parent;
 	while ( ctx != NULL ) {
 		if ( sieve_script_equals(ctx->script, script) ) {
-			sieve_command_validate_error
-				(validator, cmd, "circular include");
+			sieve_command_generate_error(gentr, cmd, "circular include");
 				
 			sieve_script_unref(&script);
 			return FALSE;
@@ -107,34 +101,24 @@ bool ext_include_validate_include
 		
 		ctx = ctx->parent;
 	}	
-			
-	/* Parse script */
-	
-	if ( (*ast_r = sieve_parse(script, ehandler)) == NULL ) {
- 		sieve_command_validate_error
- 			(validator, cmd, "parse failed for included script '%s'", script_name);
-		sieve_script_unref(&script);
-		return FALSE;
+  	
+	/* Parse */
+	if ( (ast = sieve_parse(script, ehandler)) == NULL ) {
+ 		sieve_command_generate_error(gentr, cmd, 
+ 			"failed to parse included script '%s'", script_name);
+		return NULL;
 	}
-	
-	/* AST now holds a reference, so we can drop it already */
-	sieve_script_unref(&script);
-	
-	/* Validate script */
 
-	subvalid = sieve_validator_create(*ast_r, ehandler);	
-	ctx = ext_include_create_validator_context(subvalid, parent, script);
-	sieve_validator_extension_set_context(subvalid, ext_include_my_id, ctx);		
-		
-	if ( !sieve_validator_run(subvalid) || sieve_get_errors(ehandler) > 0 ) {
-		sieve_command_validate_error
-			(validator, cmd, "validation failed for included script '%s'", 
-				script_name);
-		sieve_ast_unref(ast_r);
-		result = FALSE;
-	}
+	/* Validate */
+	if ( !sieve_validate(ast, ehandler) ) {
+		sieve_command_generate_error(gentr, cmd, 
+			"failed to validate included script '%s'", script_name);
 		
-	sieve_validator_free(&subvalid);	
+ 		sieve_ast_unref(&ast);
+ 		return NULL;
+ 	}
+ 	
+	sieve_ast_unref(&ast); 	 	
 		
 	return result;
 }
diff --git a/src/lib-sieve/plugins/include/ext-include-common.h b/src/lib-sieve/plugins/include/ext-include-common.h
index b4f1d51c2e6d147974fbd2f8fa2f3c4fcb3e5ef4..958e25fd42b8b1d63fa7905e5cb5ff370fd7761d 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.h
+++ b/src/lib-sieve/plugins/include/ext-include-common.h
@@ -12,24 +12,24 @@ extern int ext_include_my_id;
 extern const struct sieve_extension include_extension;
 
 struct ext_include_main_context {
-	struct sieve_validator *validator;
+	struct sieve_generator *generator;
 	struct hash_table *included_scripts;
 };
 
-struct ext_include_validator_context {
+struct ext_include_generator_context {
 	unsigned int nesting_level;
 	struct sieve_script *script;
 	struct ext_include_main_context *main;
-	struct ext_include_validator_context *parent;
+	struct ext_include_generator_context *parent;
 };
 
-inline struct ext_include_validator_context *ext_include_get_validator_context
-	(struct sieve_validator *validator);
-void ext_include_register_validator_context
-	(struct sieve_validator *validator, struct sieve_script *script);
+inline struct ext_include_generator_context *ext_include_get_generator_context
+	(struct sieve_generator *gentr);
+void ext_include_register_generator_context
+	(struct sieve_generator *gentr);
 
-bool ext_include_validate_include
-	(struct sieve_validator *validator, struct sieve_command_context *cmd,
-		const char *script_path, const char *script_name, struct sieve_ast **ast_r);
+bool ext_include_generate_include
+	(struct sieve_generator *gentr, struct sieve_command_context *cmd,
+		const char *script_path, const char *script_name);
 
 #endif /* __EXT_INCLUDE_COMMON_H */
diff --git a/src/lib-sieve/plugins/include/ext-include.c b/src/lib-sieve/plugins/include/ext-include.c
index 6e3b02efb1f8533a48b2320355c1db6d246529b7..ea1156cdf715ba5edeb6a3c42f8c406d336b574e 100644
--- a/src/lib-sieve/plugins/include/ext-include.c
+++ b/src/lib-sieve/plugins/include/ext-include.c
@@ -24,6 +24,7 @@
 
 static bool ext_include_load(int ext_id);
 static bool ext_include_validator_load(struct sieve_validator *validator);
+static bool ext_include_generator_load(struct sieve_generator *gentr);
 
 /* Commands */
 
@@ -46,7 +47,8 @@ const struct sieve_extension include_extension = {
 	"include", 
 	ext_include_load,
 	ext_include_validator_load, 
-	NULL, NULL, NULL, 
+	ext_include_generator_load,
+	NULL, NULL, 
 	SIEVE_EXT_DEFINE_OPCODES(ext_include_opcodes),
 	NULL
 };
@@ -65,9 +67,15 @@ static bool ext_include_validator_load(struct sieve_validator *validator)
 	/* Register new commands */
 	sieve_validator_register_command(validator, &cmd_include);
 	sieve_validator_register_command(validator, &cmd_return);
-	
-	ext_include_register_validator_context(validator,
-		sieve_validator_get_script(validator));
+
+	return TRUE;
+}	
+
+/* Load extension into generator */
+
+static bool ext_include_generator_load(struct sieve_generator *gentr)
+{
+	ext_include_register_generator_context(gentr);
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/include/included1.sieve b/src/lib-sieve/plugins/include/included1.sieve
index 41e84c2dd55cd8cad0014048576bca7a2e9f35c4..a544e2742d7b0a2a311b9a6f10410079ecf94384 100644
--- a/src/lib-sieve/plugins/include/included1.sieve
+++ b/src/lib-sieve/plugins/include/included1.sieve
@@ -1,3 +1,3 @@
 require "fileinto";
 
-fileinto "INBOX.frop";
+fileinto "INBOX.frop"
diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c
index 1a59e6ec555255e465be5698f7166a8de26e5748..500a0717f1f6a0e0ce17663831a4a493021c04d3 100644
--- a/src/lib-sieve/sieve-ast.c
+++ b/src/lib-sieve/sieve-ast.c
@@ -88,6 +88,20 @@ const char *sieve_ast_type_name(enum sieve_ast_type ast_type) {
 	}
 }
 
+/* AST-based error reporting */
+
+void sieve_ast_error
+(struct sieve_error_handler *ehandler, sieve_error_vfunc_t vfunc, 
+	struct sieve_ast_node *node, const char *fmt, va_list args) 
+{ 
+	struct sieve_script *script = node->ast->script;
+	
+	T_FRAME(vfunc(ehandler, 
+		t_strdup_printf("%s:%d", sieve_script_name(script),
+			sieve_ast_node_line(node)), fmt, args)); 
+}
+ 
+
 /* Very simplistic linked list implementation
  */
 #define __LIST_CREATE(pool, type) { \
diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h
index 83a5259ed797e07f9ea6088ace65ca9537d81266..4268bb8fed504cabdcab84dcaab4051984561933 100644
--- a/src/lib-sieve/sieve-ast.h
+++ b/src/lib-sieve/sieve-ast.h
@@ -163,6 +163,11 @@ inline pool_t sieve_ast_pool(struct sieve_ast *ast);
 inline struct sieve_script *sieve_ast_script(struct sieve_ast *ast);
 
 const char *sieve_ast_type_name(enum sieve_ast_type ast_type);
+
+/* error reporting */
+void sieve_ast_error
+(struct sieve_error_handler *ehandler, sieve_error_vfunc_t vfunc, 
+	struct sieve_ast_node *node, const char *fmt, va_list args);
 	
 /* sieve_ast_argument */
 struct sieve_ast_argument *sieve_ast_argument_string_create
diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c
index 4c3d0b6ec4304682d1333a8a0f8d3745559d13d2..e20441e26353cd0ed1934983542a350197aec15b 100644
--- a/src/lib-sieve/sieve-binary.c
+++ b/src/lib-sieve/sieve-binary.c
@@ -41,6 +41,8 @@ struct sieve_binary_extension {
 struct sieve_binary {
 	pool_t pool;
 	
+	struct sieve_script *script;
+	
 	/* When the binary is loaded into memory or when it is being constructed by
 	 * the generator, extensions will be associated to the binary. The extensions
 	 * array is a sequential lit of all used extensions. The extension_index 
@@ -73,7 +75,7 @@ struct sieve_binary {
 	size_t code_size;
 };
 
-static struct sieve_binary *sieve_binary_create(void) 
+static struct sieve_binary *sieve_binary_create(struct sieve_script *script) 
 {
 	pool_t pool;
 	struct sieve_binary *sbin;
@@ -81,6 +83,7 @@ static struct sieve_binary *sieve_binary_create(void)
 	pool = pool_alloconly_create("sieve_binary", 4096);	
 	sbin = p_new(pool, struct sieve_binary, 1);
 	sbin->pool = pool;
+	sbin->script = script;
 	
 	p_array_init(&sbin->extensions, pool, 5);
 	p_array_init(&sbin->extension_index, pool, sieve_extensions_get_count());
@@ -90,9 +93,9 @@ static struct sieve_binary *sieve_binary_create(void)
 	return sbin;
 }
 
-struct sieve_binary *sieve_binary_create_new(void) 
+struct sieve_binary *sieve_binary_create_new(struct sieve_script *script) 
 {
-	struct sieve_binary *sbin = sieve_binary_create();
+	struct sieve_binary *sbin = sieve_binary_create(script);
 	
 	sbin->code_buffer = buffer_create_dynamic(sbin->pool, 256);
 	sbin->data = sbin->code_buffer;	
@@ -123,6 +126,11 @@ inline pool_t sieve_binary_pool(struct sieve_binary *sbin)
 	return sbin->pool;
 }
 
+inline struct sieve_script *sieve_binary_script(struct sieve_binary *sbin)
+{
+	return sbin->script;
+}
+
 static inline void sieve_binary_set_active_block
 	(struct sieve_binary *sbin, buffer_t *buffer)
 {
@@ -431,7 +439,8 @@ static bool _sieve_binary_load(struct sieve_binary *sbin)
 	return TRUE;
 }
 
-struct sieve_binary *sieve_binary_load(const char *path)
+struct sieve_binary *sieve_binary_load
+	(const char *path, struct sieve_script *script)
 {
 	int fd;
 	struct stat st;
@@ -455,7 +464,7 @@ struct sieve_binary *sieve_binary_load(const char *path)
 	}
 	
 	/* Create binary object */
-	sbin = sieve_binary_create();
+	sbin = sieve_binary_create(script);
 	sbin->path = p_strdup(sbin->pool, path);
 	
 	/* Allocate memory buffer
@@ -493,7 +502,8 @@ struct sieve_binary *sieve_binary_load(const char *path)
 		sbin = NULL;
 	}
 	
-	sieve_binary_activate(sbin);
+	if ( sbin != NULL )
+		sieve_binary_activate(sbin);
 
 	return sbin;
 }
diff --git a/src/lib-sieve/sieve-binary.h b/src/lib-sieve/sieve-binary.h
index be7bd9257ce201435e1215e0e6f829493eb6048e..fd3bc54d6250a088c609c546efb019896e408cd5 100644
--- a/src/lib-sieve/sieve-binary.h
+++ b/src/lib-sieve/sieve-binary.h
@@ -8,17 +8,19 @@
 
 struct sieve_binary;
 
-struct sieve_binary *sieve_binary_create_new(void);
+struct sieve_binary *sieve_binary_create_new(struct sieve_script *script);
 void sieve_binary_ref(struct sieve_binary *sbin);
 void sieve_binary_unref(struct sieve_binary **sbin);
 
 inline pool_t sieve_binary_pool(struct sieve_binary *sbin);
+inline struct sieve_script *sieve_binary_script(struct sieve_binary *sbin);
 
 void sieve_binary_activate(struct sieve_binary *sbin);
 
 bool sieve_binary_save
 	(struct sieve_binary *sbin, const char *path);
-struct sieve_binary *sieve_binary_load(const char *path);
+struct sieve_binary *sieve_binary_load
+	(const char *path, struct sieve_script *script);
 
 /* 
  * Extension support 
diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h
index 1bfd5bfce5402b64ee7a0a167ae3fbcc6fe1aca7..8736904dc2238cd27b684ad20eca559f998efcab 100644
--- a/src/lib-sieve/sieve-commands.h
+++ b/src/lib-sieve/sieve-commands.h
@@ -90,6 +90,11 @@ const char *sieve_command_type_name(const struct sieve_command *command);
 #define sieve_command_validate_critical(validator, context, ...) \
 	sieve_validator_critical(validator, (context)->ast_node, __VA_ARGS__)
 
+#define sieve_command_generate_error(gentr, context, ...) \
+	sieve_generator_error(gentr, (context)->ast_node, __VA_ARGS__)
+#define sieve_command_generate_critical(gentr, context, ...) \
+	sieve_generator_critical(gentr, (context)->ast_node, __VA_ARGS__)
+
 #define sieve_command_pool(context) \
 	sieve_ast_node_pool((context)->ast_node)
 
diff --git a/src/lib-sieve/sieve-error.h b/src/lib-sieve/sieve-error.h
index 37ab8d23ef538e801e8bb5d404aa214245e75d42..00d395f84b10fbf5872f7ff4cbb8fae3ee6dfdc8 100644
--- a/src/lib-sieve/sieve-error.h
+++ b/src/lib-sieve/sieve-error.h
@@ -8,6 +8,10 @@
 
 struct sieve_error_handler;
 
+typedef void (*sieve_error_vfunc_t)
+	(struct sieve_error_handler *ehandler, const char *location, 
+		const char *fmt, va_list args);
+
 /* For these functions it is the responsibility of the caller to
  * manage the datastack.
  */
diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c
index b09ca2b738a01284f4b3cb090f0f1275a9931777..7d38eef0886383bec83a6c2e724a99cb0dccf852 100644
--- a/src/lib-sieve/sieve-generator.c
+++ b/src/lib-sieve/sieve-generator.c
@@ -41,27 +41,47 @@ void sieve_jumplist_resolve(struct sieve_jumplist *jlist)
 struct sieve_generator {
 	pool_t pool;
 	
+	struct sieve_error_handler *ehandler;
+	
 	struct sieve_ast *ast;
+	struct sieve_script *script;
 	
 	struct sieve_binary *binary;
+	
+	ARRAY_DEFINE(ext_contexts, void *);
 };
 
-struct sieve_generator *sieve_generator_create(struct sieve_ast *ast) 
+struct sieve_generator *sieve_generator_create
+	(struct sieve_ast *ast, struct sieve_error_handler *ehandler) 
 {
 	pool_t pool;
-	struct sieve_generator *generator;
+	struct sieve_generator *gentr;
 	
 	pool = pool_alloconly_create("sieve_generator", 4096);	
-	generator = p_new(pool, struct sieve_generator, 1);
-	generator->pool = pool;
+	gentr = p_new(pool, struct sieve_generator, 1);
+	gentr->pool = pool;
+	gentr->ehandler = ehandler;
 	
-	generator->ast = ast;	
+	gentr->ast = ast;	
+	gentr->script = sieve_ast_script(ast);
 	sieve_ast_ref(ast);
 
-	generator->binary = sieve_binary_create_new();
-	sieve_binary_ref(generator->binary);
+	/* Setup storage for extension contexts */		
+	array_create(&gentr->ext_contexts, pool, sizeof(void *), 
+		sieve_extensions_get_count());
+
+	gentr->binary = sieve_binary_create_new(sieve_ast_script(ast));
+	sieve_binary_ref(gentr->binary);
 	
-	return generator;
+	/* Pre-load core language features implemented as 'extensions' (none) */
+	/*for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) {
+		const struct sieve_extension *ext = sieve_preloaded_extensions[i];
+		
+		if ( ext->generator_load != NULL )
+			(void)ext->generator_load(gentr);		
+	}*/
+	
+	return gentr;
 }
 
 void sieve_generator_free(struct sieve_generator *generator) 
@@ -71,10 +91,82 @@ void sieve_generator_free(struct sieve_generator *generator)
 	pool_unref(&(generator->pool));
 }
 
-inline void sieve_generator_link_extension
-	(struct sieve_generator *generator, int ext_id) 
+inline struct sieve_script *sieve_generator_get_script
+	(struct sieve_generator *gentr)
+{
+	return gentr->script;
+}
+
+/* Error handling */
+
+void sieve_generator_warning
+(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+	const char *fmt, ...) 
+{ 
+	va_list args;
+	
+	va_start(args, fmt);
+	sieve_ast_error(gentr->ehandler, sieve_vwarning, node, fmt, args);
+	va_end(args);
+}
+ 
+void sieve_generator_error
+(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+	const char *fmt, ...) 
+{
+	va_list args;
+	
+	va_start(args, fmt);
+	sieve_ast_error(gentr->ehandler, sieve_verror, node, fmt, args);
+	va_end(args);
+}
+
+void sieve_generator_critical
+(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+	const char *fmt, ...) 
+{
+	va_list args;
+	
+	va_start(args, fmt);
+	sieve_ast_error(gentr->ehandler, sieve_vcritical, node, fmt, args);
+	va_end(args);
+}
+
+/* Extension support */
+
+bool sieve_generator_link_extension
+	(struct sieve_generator *gentr, int ext_id) 
+{
+	const struct sieve_extension *ext = sieve_extension_get_by_id(ext_id);
+	
+	(void)sieve_binary_extension_link(gentr->binary, ext_id);
+	
+	if ( ext == NULL ) 
+		return FALSE;
+	
+	if ( ext->generator_load != NULL )
+		return ext->generator_load(gentr);
+	
+	return TRUE;
+}
+
+inline void sieve_generator_extension_set_context
+	(struct sieve_generator *gentr, int ext_id, void *context)
 {
-	(void)sieve_binary_extension_link(generator->binary, ext_id);
+	array_idx_set(&gentr->ext_contexts, (unsigned int) ext_id, &context);	
+}
+
+inline const void *sieve_generator_extension_get_context
+	(struct sieve_generator *gentr, int ext_id) 
+{
+	void * const *ctx;
+
+	if  ( ext_id < 0 || ext_id >= (int) array_count(&gentr->ext_contexts) )
+		return NULL;
+	
+	ctx = array_idx(&gentr->ext_contexts, (unsigned int) ext_id);		
+
+	return *ctx;
 }
 
 /* Binary access */
@@ -201,17 +293,18 @@ static bool sieve_generate_command
 bool sieve_generate_block
 	(struct sieve_generator *generator, struct sieve_ast_node *block) 
 {
+	bool result = TRUE;
 	struct sieve_ast_node *command;
 
 	T_FRAME(	
 		command = sieve_ast_command_first(block);
-		while ( command != NULL ) {	
-			sieve_generate_command(generator, command);	
+		while ( result && command != NULL ) {	
+			result = sieve_generate_command(generator, command);	
 			command = sieve_ast_command_next(command);
 		}		
 	);
 	
-	return TRUE;
+	return result;
 }
 
 struct sieve_binary *sieve_generator_run(struct sieve_generator *generator) {	
@@ -223,4 +316,24 @@ struct sieve_binary *sieve_generator_run(struct sieve_generator *generator) {
 	return NULL;
 }
 
+/* Accessors */
+
+inline struct sieve_error_handler *sieve_generator_error_handler
+	(struct sieve_generator *gentr)
+{
+	return gentr->ehandler;
+}
+
+inline pool_t sieve_generator_pool(struct sieve_generator *gentr)
+{
+	return gentr->pool;
+}
+
+inline struct sieve_script *sieve_generator_script
+	(struct sieve_generator *gentr)
+{
+	return gentr->script;
+}
+
+
 
diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h
index e2d021913c8b449853960eb0b8f413c32e0cb53e..64b1fe6d3c546ec19d9bc33c77a1bcd3a5bad7cb 100644
--- a/src/lib-sieve/sieve-generator.h
+++ b/src/lib-sieve/sieve-generator.h
@@ -6,11 +6,33 @@
 
 struct sieve_generator;
 
-struct sieve_generator *sieve_generator_create(struct sieve_ast *ast);
+struct sieve_generator *sieve_generator_create
+	(struct sieve_ast *ast, struct sieve_error_handler *ehandler);
 void sieve_generator_free(struct sieve_generator *generator);
 
-inline void sieve_generator_link_extension
-    (struct sieve_generator *generator, int ext_id);
+inline struct sieve_script *sieve_generator_get_script
+	(struct sieve_generator *gentr);
+
+/* Error handling */
+
+void sieve_generator_warning
+(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+	const char *fmt, ...) ATTR_FORMAT(3, 4);; 
+void sieve_generator_error
+(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+	const char *fmt, ...) ATTR_FORMAT(3, 4);
+void sieve_generator_critical
+(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+	const char *fmt, ...) ATTR_FORMAT(3, 4); 
+
+/* Extension support */
+
+bool sieve_generator_link_extension
+	(struct sieve_generator *gentr, int ext_id);
+inline void sieve_generator_extension_set_context
+	(struct sieve_generator *gentr, int ext_id, void *context);
+inline const void *sieve_generator_extension_get_context
+	(struct sieve_generator *gentr, int ext_id);
     		
 /* Jump list */
 
@@ -19,16 +41,22 @@ struct sieve_jumplist {
 	ARRAY_DEFINE(jumps, sieve_size_t);
 };
 
-void sieve_jumplist_init(struct sieve_jumplist *jlist, struct sieve_binary *sbin);
-void sieve_jumplist_add(struct sieve_jumplist *jlist, sieve_size_t jump);
+void sieve_jumplist_init
+	(struct sieve_jumplist *jlist, struct sieve_binary *sbin);
+void sieve_jumplist_add
+	(struct sieve_jumplist *jlist, sieve_size_t jump);
 void sieve_jumplist_resolve(struct sieve_jumplist *jlist);
 
 /* Code emission API */
-inline sieve_size_t sieve_generator_emit_data(struct sieve_generator *generator, void *data, sieve_size_t size);
-inline sieve_size_t sieve_generator_emit_byte(struct sieve_generator *generator, unsigned char byte); 
+inline sieve_size_t sieve_generator_emit_data
+	(struct sieve_generator *generator, void *data, sieve_size_t size);
+inline sieve_size_t sieve_generator_emit_byte
+	(struct sieve_generator *generator, unsigned char byte); 
 inline void sieve_generator_update_data
-	(struct sieve_generator *generator, sieve_size_t address, void *data, sieve_size_t size);
-inline sieve_size_t sieve_generator_get_current_address(struct sieve_generator *generator);
+	(struct sieve_generator *generator, sieve_size_t address, void *data, 
+		sieve_size_t size);
+inline sieve_size_t sieve_generator_get_current_address
+	(struct sieve_generator *generator);
 
 inline struct sieve_binary *sieve_generator_get_binary
 	(struct sieve_generator *gentr);
@@ -39,10 +67,13 @@ inline sieve_size_t sieve_generator_emit_opcode_ext
 
 /* Offset emission */
 
-inline sieve_size_t sieve_generator_emit_offset(struct sieve_generator *generator, int offset);
-inline void sieve_generator_resolve_offset(struct sieve_generator *generator, sieve_size_t address); 
+inline sieve_size_t sieve_generator_emit_offset
+	(struct sieve_generator *generator, int offset);
+inline void sieve_generator_resolve_offset
+	(struct sieve_generator *generator, sieve_size_t address); 
 
 /* Literal emission */
+
 inline sieve_size_t sieve_generator_emit_byte
 	(struct sieve_generator *generator, unsigned char btval);
 inline sieve_size_t sieve_generator_emit_integer
@@ -52,8 +83,6 @@ inline sieve_size_t sieve_generator_emit_string
 
 /* API */
 
-inline void sieve_generator_register_extension
-	(struct sieve_generator *gnr, const struct sieve_extension *ext);
 bool sieve_generate_arguments(struct sieve_generator *generator, 
 	struct sieve_command_context *cmd, struct sieve_ast_argument **arg);
 
@@ -64,5 +93,13 @@ bool sieve_generate_test
 		struct sieve_jumplist *jlist, bool jump_true);
 struct sieve_binary *sieve_generator_run(struct sieve_generator *genarator);
 
+/* Accessors */
+
+inline struct sieve_error_handler *sieve_generator_error_handler
+	(struct sieve_generator *gentr);
+inline pool_t sieve_generator_pool(struct sieve_generator *gentr);
+inline struct sieve_script *sieve_generator_script
+	(struct sieve_generator *gentr);
+
 #endif /* __SIEVE_GENERATOR_H */
 
diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c
index 03ad7c9d8185f5bc941af99659a2f22cead663af..11e4639dd9162a8c7eb4695c5d75b4f0c76f02b8 100644
--- a/src/lib-sieve/sieve-script.c
+++ b/src/lib-sieve/sieve-script.c
@@ -35,23 +35,22 @@ struct sieve_script *sieve_script_create
 	pool_t pool;
 	struct stat st;
 	struct sieve_script *script;
-	const char *dirpath;
+	const char *filename, *dirpath;
 
 	T_FRAME(
+		/* Extract filename from path */
+		filename = strrchr(path, '/');
+		if ( filename == NULL ) {
+			dirpath = "";
+			filename = path;
+		} else {
+			dirpath = t_strdup_until(path, filename);
+			filename++;
+		}
+	
 		if ( name == NULL || *name == '\0' ) {
-			const char *filename;
 			const char *ext;
 		
-			/* Extract filename from path */
-			filename = strrchr(path, '/');
-			if ( filename == NULL ) {
-				dirpath = "";
-				filename = path;
-			} else {
-				dirpath = t_strdup_until(path, filename);
-				filename++;
-			}
-	
 			/* Extract the script name */
 			ext = strrchr(filename, '.');
 			if ( ext == NULL || ext == filename || strncmp(ext,".sieve",6) != 0 )
@@ -64,7 +63,7 @@ struct sieve_script *sieve_script_create
 	
 		if ( stat(path, &st) < 0 ) {
 			if ( errno == ENOENT )
-				sieve_error(ehandler, name, "sieve script does not exist");
+				sieve_error(ehandler, path, "sieve script does not exist");
 			else 
 				sieve_critical(ehandler, path, "failed to stat sieve script: %m");
 			script = NULL;
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index 6ca58191e98bee0bd159371ad5381e91b78a322e..77d0fbd74bcdfcdd79c49ba1e3a27823b1aa9a8f 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -40,12 +40,9 @@ void sieve_validator_warning
 	const char *fmt, ...) 
 { 
 	va_list args;
-	va_start(args, fmt);
-	
-	T_FRAME(sieve_vwarning(validator->ehandler, 
-		t_strdup_printf("%s:%d", sieve_script_name(validator->script),
-			sieve_ast_node_line(node)), fmt, args)); 
 	
+	va_start(args, fmt);
+	sieve_ast_error(validator->ehandler, sieve_vwarning, node, fmt, args);
 	va_end(args);
 }
  
@@ -54,12 +51,9 @@ void sieve_validator_error
 	const char *fmt, ...) 
 {
 	va_list args;
-	va_start(args, fmt);
-	
-	T_FRAME(sieve_verror(validator->ehandler, 
-		t_strdup_printf("%s:%d", sieve_script_name(validator->script),
-		sieve_ast_node_line(node)), fmt, args)); 
 	
+	va_start(args, fmt);
+	sieve_ast_error(validator->ehandler, sieve_verror, node, fmt, args);
 	va_end(args);
 }
 
@@ -68,12 +62,9 @@ void sieve_validator_critical
 	const char *fmt, ...) 
 {
 	va_list args;
-	va_start(args, fmt);
-	
-	T_FRAME(sieve_vcritical(validator->ehandler, 
-		t_strdup_printf("%s:%d", sieve_script_name(validator->script),
-		sieve_ast_node_line(node)), fmt, args)); 
 	
+	va_start(args, fmt);
+	sieve_ast_error(validator->ehandler, sieve_vcritical, node, fmt, args);
 	va_end(args);
 }
 
@@ -100,6 +91,12 @@ struct sieve_validator *sieve_validator_create
 	array_create(&validator->ext_contexts, pool, sizeof(void *), 
 		sieve_extensions_get_count());
 		
+	/* Setup command registry */
+	validator->commands = hash_create
+		(pool, pool, 0, str_hash, (hash_cmp_callback_t *)strcmp);
+	sieve_validator_register_core_commands(validator);
+	sieve_validator_register_core_tests(validator);
+	
 	/* Pre-load core language features implemented as 'extensions' */
 	for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) {
 		const struct sieve_extension *ext = sieve_preloaded_extensions[i];
@@ -107,13 +104,7 @@ struct sieve_validator *sieve_validator_create
 		if ( ext->validator_load != NULL )
 			(void)ext->validator_load(validator);		
 	}
-
-	/* Setup command registry */
-	validator->commands = hash_create
-		(pool, pool, 0, str_hash, (hash_cmp_callback_t *)strcmp);
-	sieve_validator_register_core_commands(validator);
-	sieve_validator_register_core_tests(validator);
-
+	
 	return validator;
 }
 
@@ -132,19 +123,19 @@ inline pool_t sieve_validator_pool(struct sieve_validator *validator)
 	return validator->pool;
 }
 
-inline struct sieve_error_handler *sieve_validator_get_error_handler
+inline struct sieve_error_handler *sieve_validator_error_handler
 	(struct sieve_validator *validator)
 {
 	return validator->ehandler;
 }
 
-inline struct sieve_ast *sieve_validator_get_ast
+inline struct sieve_ast *sieve_validator_ast
 	(struct sieve_validator *validator)
 {
 	return validator->ast;
 }
 
-inline struct sieve_script *sieve_validator_get_script
+inline struct sieve_script *sieve_validator_script
 	(struct sieve_validator *validator)
 {
 	return validator->script;
diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h
index dbeb709898f2bdc9c6467eaaf49b615b6befbe9d..4072ff5c1a798ef7190135a141b45b004a0a1d33 100644
--- a/src/lib-sieve/sieve-validator.h
+++ b/src/lib-sieve/sieve-validator.h
@@ -14,11 +14,11 @@ struct sieve_validator *sieve_validator_create
 void sieve_validator_free(struct sieve_validator **validator);
 inline pool_t sieve_validator_pool(struct sieve_validator *validator);
 
-inline struct sieve_error_handler *sieve_validator_get_error_handler
+inline struct sieve_error_handler *sieve_validator_error_handler
 	(struct sieve_validator *validator);
-inline struct sieve_ast *sieve_validator_get_ast
+inline struct sieve_ast *sieve_validator_ast
 	(struct sieve_validator *validator);
-inline struct sieve_script *sieve_validator_get_script
+inline struct sieve_script *sieve_validator_script
 	(struct sieve_validator *validator);
 
 bool sieve_validator_run(struct sieve_validator *validator);
diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index f2bc2c76db24fee953ccd0e12e9b10c921a2188c..55c9caea4c13383df24aed69b11ff33064c80dbf 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -57,7 +57,7 @@ struct sieve_ast *sieve_parse
 	return ast;
 }
 
-static bool sieve_validate(struct sieve_ast *ast, struct sieve_error_handler *ehandler)
+bool sieve_validate(struct sieve_ast *ast, struct sieve_error_handler *ehandler)
 {
 	bool result = TRUE;
 	struct sieve_validator *validator = sieve_validator_create(ast, ehandler);
@@ -70,9 +70,10 @@ static bool sieve_validate(struct sieve_ast *ast, struct sieve_error_handler *eh
 	return result;
 }
 
-static struct sieve_binary *sieve_generate(struct sieve_ast *ast)
+static struct sieve_binary *sieve_generate
+	(struct sieve_ast *ast, struct sieve_error_handler *ehandler)
 {
-	struct sieve_generator *generator = sieve_generator_create(ast);
+	struct sieve_generator *generator = sieve_generator_create(ast, ehandler);
 	struct sieve_binary *result;
 		
 	result = sieve_generator_run(generator);
@@ -103,7 +104,7 @@ static struct sieve_binary *sieve_compile_script
  	}
  	
 	/* Generate */
-	if ( (sbin=sieve_generate(ast)) == NULL ) {
+	if ( (sbin=sieve_generate(ast, ehandler)) == NULL ) {
 		sieve_error(ehandler, sieve_script_name(script), "code generation failed");
 		
 		sieve_ast_unref(&ast);
@@ -146,7 +147,7 @@ struct sieve_binary *sieve_open
 
 	T_FRAME(
 		binpath = sieve_script_binpath(script);	
-		sbin = sieve_binary_load(binpath);
+		sbin = sieve_binary_load(binpath, script);
 	
 		if ( sbin == NULL ) {
 			sbin = sieve_compile_script(script, ehandler);
diff --git a/src/sieve-bin/sieved.c b/src/sieve-bin/sieved.c
index fc0527345470c613b183a0bd2546234d8e66490c..566e8d7536159dc9502ce4c4a90d29201f9439a3 100644
--- a/src/sieve-bin/sieved.c
+++ b/src/sieve-bin/sieved.c
@@ -45,7 +45,7 @@ int main(int argc, char **argv) {
 	
 	bin_init();
 	
-	sbin = sieve_binary_load(binfile);
+	sbin = sieve_binary_load(binfile, NULL);
 
 	if ( sbin != NULL ) {
 		bin_dump_sieve_binary_to(sbin, outfile == NULL ? "-" : outfile);