diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index ca87b2e5788052d558226e79b7159fd85ec0ad9a..e21020495b38fee7c06be8630cc7cb1db6ca720d 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -8,7 +8,27 @@
 
 #include "ext-include-common.h"
 
-/* Generator context management */
+/* Generator context */
+
+struct ext_include_generator_context {
+	unsigned int nesting_level;
+	struct sieve_script *script;
+	struct ext_include_main_context *main;
+	struct ext_include_generator_context *parent;
+};
+
+static inline struct ext_include_generator_context *
+	ext_include_get_generator_context
+	(struct sieve_generator *gentr);
+
+/* Binary context */
+
+struct ext_include_binary_context {
+	struct sieve_binary *binary;
+	struct hash_table *included_scripts;
+};
+
+/* Main context management */
 
 static struct ext_include_main_context *ext_include_create_main_context
 (struct sieve_generator *gentr)
@@ -19,12 +39,12 @@ static struct ext_include_main_context *ext_include_create_main_context
 		p_new(pool, struct ext_include_main_context, 1);
 	
 	ctx->generator = gentr;
-	ctx->included_scripts = hash_create
-		(pool, pool, 0, str_hash, (hash_cmp_callback_t *)strcmp);
 	
 	return ctx;
 }
 
+/* Generator context management */
+
 static struct ext_include_generator_context *
 	ext_include_create_generator_context
 (struct sieve_generator *gentr, struct ext_include_generator_context *parent, 
@@ -47,14 +67,24 @@ static struct ext_include_generator_context *
 	return ctx;
 }
 
-inline struct ext_include_generator_context *ext_include_get_generator_context
+static inline struct ext_include_generator_context *
+	ext_include_get_generator_context
 (struct sieve_generator *gentr)
 {
 	return (struct ext_include_generator_context *)
 		sieve_generator_extension_get_context(gentr, ext_include_my_id);
 }
 
-void ext_include_register_generator_context(struct sieve_generator *gentr)
+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,
+		ext_include_create_generator_context(gentr, parent, script));
+}
+
+void ext_include_register_generator_context
+(struct sieve_generator *gentr)
 {
 	struct ext_include_generator_context *ctx = 
 		ext_include_get_generator_context(gentr);
@@ -68,6 +98,82 @@ void ext_include_register_generator_context(struct sieve_generator *gentr)
 	}
 }
 
+/* Binary context functions */
+
+struct _included_script {
+	struct sieve_script *script;
+	unsigned int block_id;
+};
+
+static struct ext_include_binary_context *ext_include_create_binary_context
+(struct sieve_binary *sbin)
+{
+	pool_t pool = sieve_binary_pool(sbin);
+	
+	struct ext_include_binary_context *ctx = 
+		p_new(pool, struct ext_include_binary_context, 1);
+	
+	ctx->binary = sbin;
+	ctx->included_scripts = hash_create(pool, pool, 0, 
+		(hash_callback_t *) sieve_script_hash, 
+		(hash_cmp_callback_t *) sieve_script_cmp);
+	
+	return ctx;
+}
+
+static inline struct ext_include_binary_context *ext_include_get_binary_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);
+	
+	if ( ctx == NULL ) {
+		ctx = ext_include_create_binary_context(sbin);
+		sieve_binary_extension_set_context(sbin, ext_include_my_id, ctx);
+	};
+	
+	return ctx;
+}
+
+static void ext_include_script_include
+(struct ext_include_binary_context *binctx, struct sieve_script *script,
+	unsigned int block_id)
+{
+	pool_t pool = sieve_binary_pool(binctx->binary);
+	struct _included_script *incscript;
+	
+	incscript = p_new(pool, struct _included_script, 1);
+	incscript->script = script;
+	incscript->block_id = block_id;
+	
+	printf("INCLUDE: %s\n", sieve_script_path(script));
+	
+	/* FIXME: NOWW!!
+	 *   THIS WILL CAUSE A MEMORY LEAK!!
+	 */ 
+	sieve_script_ref(script);
+	
+	hash_insert(binctx->included_scripts, (void *) script, (void *) incscript);
+}
+
+static bool ext_include_script_is_included
+(struct ext_include_binary_context *binctx, struct sieve_script *script,
+	unsigned int *block_id)
+{
+	struct _included_script *incscript = (struct _included_script *)
+		hash_lookup(binctx->included_scripts, script);
+		
+	if ( incscript == 0 )
+		return FALSE;
+		
+	printf("ALREADY INCLUDED: %s\n", sieve_script_path(incscript->script));
+		
+	*block_id = incscript->block_id;
+	return TRUE;
+}
+
+/* Including a script during generation */
+
 bool ext_include_generate_include
 (struct sieve_generator *gentr, struct sieve_command_context *cmd,
 	const char *script_path, const char *script_name)
@@ -76,12 +182,13 @@ bool ext_include_generate_include
 	struct sieve_script *script;
 	struct sieve_ast *ast;
 	struct sieve_binary *sbin = sieve_generator_get_binary(gentr);
+	struct ext_include_binary_context *binctx;
 	struct sieve_generator *subgentr;
-	struct ext_include_generator_context *parent =
+	struct ext_include_generator_context *ctx =
 		ext_include_get_generator_context(gentr);
-	struct ext_include_generator_context *ctx;
+	struct ext_include_generator_context *pctx;
 	struct sieve_error_handler *ehandler = sieve_generator_error_handler(gentr);
-	unsigned this_block_id, new_block_id; 
+	unsigned this_block_id, inc_block_id; 
 		
 	/* Do not include more scripts when errors have occured already. */
 	if ( sieve_get_errors(ehandler) > 0 )
@@ -94,51 +201,65 @@ bool ext_include_generate_include
 	
 	/* Check for circular include */
 	
-	ctx = parent;
-	while ( ctx != NULL ) {
-		if ( sieve_script_equals(ctx->script, script) ) {
+	pctx = ctx;
+	while ( pctx != NULL ) {
+		if ( sieve_script_equals(pctx->script, script) ) {
 			sieve_command_generate_error(gentr, cmd, "circular include");
 				
 			sieve_script_unref(&script);
 			return FALSE;
 		}
 		
-		ctx = ctx->parent;
+		pctx = pctx->parent;
 	}	
-  	
-	/* Parse */
-	if ( (ast = sieve_parse(script, ehandler)) == NULL ) {
- 		sieve_command_generate_error(gentr, cmd, 
- 			"failed to parse included script '%s'", script_name);
-		return FALSE;
-	}
 
-	/* Validate */
-	if ( !sieve_validate(ast, ehandler) ) {
-		sieve_command_generate_error(gentr, cmd, 
-			"failed to validate included script '%s'", script_name);
+	binctx = ext_include_get_binary_context(sbin);
+	
+	/* Is the script already compiled into the current binary? */
+	if ( !ext_include_script_is_included(binctx, script, &inc_block_id) )	{	
+		/* Allocate a new block in the binary and mark the script as included 
+		 * already.
+		 */
+		inc_block_id = sieve_binary_block_create(sbin);
+		ext_include_script_include(binctx, script, inc_block_id);
 		
- 		sieve_ast_unref(&ast);
- 		return FALSE;
- 	}
-
-	new_block_id = sieve_binary_block_create(sbin);
-	this_block_id = sieve_binary_block_set_active(sbin, new_block_id); 	
- 	subgentr = sieve_generator_create(ast, ehandler);			
- 
-  sieve_generator_extension_set_context(subgentr, ext_include_my_id,
-		ext_include_create_generator_context(subgentr, parent, script));		
+		/* Include list now holds a reference */
+		sieve_script_unref(&script);
 		
-	if ( !sieve_generator_run(subgentr, &sbin) ) {
-		sieve_command_generate_error(gentr, cmd, 
-			"failed to validate included script '%s'", script_name);
- 		result = FALSE;
-	}
-	
-	(void) sieve_binary_block_set_active(sbin, this_block_id); 	
-	sieve_generator_free(&subgentr);
-	sieve_ast_unref(&ast); 	 	
+		/* Parse */
+		if ( (ast = sieve_parse(script, ehandler)) == NULL ) {
+	 		sieve_command_generate_error(gentr, cmd, 
+	 			"failed to parse included script '%s'", script_name);
+	 		return FALSE;
+		}
+
+		/* Validate */
+		if ( !sieve_validate(ast, ehandler) ) {
+			sieve_command_generate_error(gentr, cmd, 
+				"failed to validate included script '%s'", script_name);
+	 		sieve_ast_unref(&ast);
+	 		return FALSE;
+	 	}
+
+		/* Generate */
+		this_block_id = sieve_binary_block_set_active(sbin, inc_block_id); 	
+	 	subgentr = sieve_generator_create(ast, ehandler);			
+		ext_include_initialize_generator_context(subgentr, ctx, script);
+			
+		if ( !sieve_generator_run(subgentr, &sbin) ) {
+			sieve_command_generate_error(gentr, cmd, 
+				"failed to validate included script '%s'", script_name);
+	 		result = FALSE;
+		}
+				
+		(void) sieve_binary_block_set_active(sbin, this_block_id); 	
+		sieve_generator_free(&subgentr);
 		
+		/* Cleanup */
+		sieve_ast_unref(&ast);		
+	} else 
+		sieve_script_unref(&script);
+	
 	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 958e25fd42b8b1d63fa7905e5cb5ff370fd7761d..c260138a96ec63d7c532cc587d6ed7181eb873ac 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.h
+++ b/src/lib-sieve/plugins/include/ext-include-common.h
@@ -11,20 +11,12 @@
 extern int ext_include_my_id;
 extern const struct sieve_extension include_extension;
 
+/* Main context, currently not used for anything and might be removed */
+
 struct ext_include_main_context {
 	struct sieve_generator *generator;
-	struct hash_table *included_scripts;
-};
-
-struct ext_include_generator_context {
-	unsigned int nesting_level;
-	struct sieve_script *script;
-	struct ext_include_main_context *main;
-	struct ext_include_generator_context *parent;
 };
 
-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);
 
diff --git a/src/lib-sieve/plugins/include/ext-include.c b/src/lib-sieve/plugins/include/ext-include.c
index ea1156cdf715ba5edeb6a3c42f8c406d336b574e..d4c25330e3c1831579851de342fe3fef051863ae 100644
--- a/src/lib-sieve/plugins/include/ext-include.c
+++ b/src/lib-sieve/plugins/include/ext-include.c
@@ -3,10 +3,15 @@
  *
  * Authors: Stephan Bosch
  * Specification: draft-daboo-sieve-include-05
- * Implementation: skeleton
+ * Implementation: basic include functionality starts to emerge. 
  * Status: under development
  * 
  */
+ 
+/* FIXME: Current include implementation does not allow for parts of the script
+ * to be located in external binaries; all included scripts are recompiled and
+ * the resulting byte code is imported into the main binary in separate blocks.
+ */
 
 #include "lib.h"
 
diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c
index 11e4639dd9162a8c7eb4695c5d75b4f0c76f02b8..d4a5233b14664e0f43cb3d8c82fa0b071b170a77 100644
--- a/src/lib-sieve/sieve-script.c
+++ b/src/lib-sieve/sieve-script.c
@@ -136,10 +136,15 @@ void sieve_script_close(struct sieve_script *script)
 
 /* Comparison */
 
-bool sieve_script_equals
+int sieve_script_cmp
 (struct sieve_script *script1, struct sieve_script *script2)
 {	
-	return ( script1->st.st_ino == script2->st.st_ino );
+	return ( script1->st.st_ino == script2->st.st_ino ) ? 0 : -1;
+}
+
+unsigned int sieve_script_hash(struct sieve_script *script)
+{	
+	return (unsigned int) script->st.st_ino;
 }
 
 /* Inline accessors */
diff --git a/src/lib-sieve/sieve-script.h b/src/lib-sieve/sieve-script.h
index e0651b5bc10602163f3275a81112e4767f88f831..fb03531967c04ad4aab65d9e8e1a713cb5ef96f6 100644
--- a/src/lib-sieve/sieve-script.h
+++ b/src/lib-sieve/sieve-script.h
@@ -18,8 +18,15 @@ void sieve_script_unref(struct sieve_script **script);
 struct istream *sieve_script_open(struct sieve_script *script);
 void sieve_script_close(struct sieve_script *script);
 
-bool sieve_script_equals
-(struct sieve_script *script1, struct sieve_script *script2);
+int sieve_script_cmp
+	(struct sieve_script *script1, struct sieve_script *script2);
+unsigned int sieve_script_hash(struct sieve_script *script);
+
+static inline bool sieve_script_equals
+	(struct sieve_script *script1, struct sieve_script *script2)
+{
+	return ( sieve_script_cmp(script1, script2) == 0 );
+}
 
 inline const char *sieve_script_name(struct sieve_script *script);
 inline const char *sieve_script_path(struct sieve_script *script);