diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c
index d23693ea721a3c2d89cf364b40cc6e183f905bea..e9f0097104745018e576c8af7b8eecb361732a23 100644
--- a/src/lib-sieve/sieve-binary.c
+++ b/src/lib-sieve/sieve-binary.c
@@ -681,6 +681,93 @@ static struct sieve_binary_file *_file_memory_open(const char *path)
 	return &file->binfile;
 }
 
+/* File open in lazy mode (only read what is needed into memory) */
+
+static bool _file_lazy_read
+(struct sieve_binary_file *file, off_t *offset, void *buffer, size_t size)
+{
+	off_t start = *offset;
+	int ret;
+	void *indata = buffer;
+	size_t insize = size;
+	
+	*offset = SIEVE_BINARY_ALIGN(*offset);
+
+	/* Seek to the correct position */ 
+	if ( *offset != start && lseek(file->fd, *offset, SEEK_SET) == (off_t) -1 ) {
+		i_error("sieve: failed to seek(fd, %lld, SEEK_SET) in binary %s: %m", 
+			(long long) *offset, file->path);
+		return FALSE;
+	}	
+
+	/* Read record into memory */
+	while (insize > 0) {
+		if ( (ret=read(file->fd, indata, insize)) < 0 ) {
+			i_error("sieve: failed to read from binary %s: %m", file->path);
+			break;
+		}
+		
+		indata = PTR_OFFSET(indata, ret);
+		insize -= ret;
+	}	
+
+	if ( insize != 0 ) {
+		/* Failed to read the whole requested record */
+		return FALSE;
+	}
+	
+	*offset += size;
+
+	return TRUE;
+}
+
+static const void *_file_lazy_load_data
+	(struct sieve_binary_file *file, off_t *offset, size_t size)
+{	
+	void *data = t_malloc(size);
+
+	if ( _file_lazy_read(file, offset, data, size) ) {
+		return data;
+	}
+	
+	return NULL;
+}
+
+static buffer_t *_file_lazy_load_buffer
+	(struct sieve_binary_file *file, off_t *offset, size_t size)
+{			
+	buffer_t *buffer = buffer_create_static_hard(file->pool, size);
+	
+	if ( _file_lazy_read
+		(file, offset, buffer_get_space_unsafe(buffer, 0, size), size) ) {
+		return buffer;
+	}
+	
+	return NULL;
+}
+
+static struct sieve_binary_file *_file_lazy_open(const char *path)
+{
+	pool_t pool;
+	struct sieve_binary_file *file;
+	
+	pool = pool_alloconly_create("sieve_binary_file_memory", 1024);
+	file = p_new(pool, struct sieve_binary_file, 1);
+	file->pool = pool;
+	file->path = p_strdup(pool, path);
+	file->load_data = _file_lazy_load_data;
+	file->load_buffer = _file_lazy_load_buffer;
+	
+	if ( !sieve_binary_file_open(file, path) ) {
+		pool_unref(&pool);
+		return NULL;
+	}
+
+	return file;
+}
+
+/* Load binary */
+
 #define LOAD_HEADER(sbin, offset, header) \
 	(header *) sbin->file->load_data(sbin->file, offset, sizeof(header))
 
@@ -784,73 +871,84 @@ static bool _sieve_binary_load_extensions(struct sieve_binary *sbin)
 
 static bool _sieve_binary_load(struct sieve_binary *sbin)
 {
+	bool result = TRUE;
 	off_t offset = 0;
 	const struct sieve_binary_header *header;
 	struct sieve_binary_block *extensions;
-	unsigned int i;
+	unsigned int i, blk_count;
 	
 	/* Verify header */
 	
-	header = LOAD_HEADER(sbin, &offset, const struct sieve_binary_header);
-	if ( header == NULL ) {
-		i_error("sieve: loaded binary %s is not even large enough "
-			"to contain a header.", sbin->path);
-		return FALSE;
-	}
-	
-	if ( header->magic != SIEVE_BINARY_MAGIC ) {
-		if ( header->magic != SIEVE_BINARY_MAGIC_OTHER_ENDIAN ) 
-			i_error("sieve: loaded binary %s has corrupted header %08x", 
-				sbin->path, header->magic);
-
-		return FALSE;
-	}
-	
-	if ( header->version_major != SIEVE_BINARY_VERSION_MAJOR || 
-		header->version_minor != SIEVE_BINARY_VERSION_MINOR ) {
-		/* Binary is of different version. Caller will have to recompile */
-		return FALSE;
-	} 
+	T_FRAME(
+		header = LOAD_HEADER(sbin, &offset, const struct sieve_binary_header);
+		if ( header == NULL ) {
+			i_error("sieve: loaded binary %s is not even large enough "
+				"to contain a header.", sbin->path);
+			result = FALSE;
+		} else if ( header->magic != SIEVE_BINARY_MAGIC ) {
+			if ( header->magic != SIEVE_BINARY_MAGIC_OTHER_ENDIAN ) 
+				i_error("sieve: loaded binary %s has corrupted header %08x", 
+					sbin->path, header->magic);
+			result = FALSE;
+		} else if ( result && (
+		  header->version_major != SIEVE_BINARY_VERSION_MAJOR || 
+			header->version_minor != SIEVE_BINARY_VERSION_MINOR ) ) {
+			/* Binary is of different version. Caller will have to recompile */
+			result = FALSE;
+		} else if ( result && header->blocks == 0 ) {
+			i_error("sieve: loaded binary %s contains no blocks", sbin->path);
+			result = FALSE; 
+		} else {
+			blk_count = header->blocks;
+		}
+	);
 	
-	if ( header->blocks == 0 ) {
-		i_error("sieve: loaded binary %s contains no blocks", sbin->path);
-		return FALSE; 
-	}
+	if ( !result ) return FALSE;
 	
 	/* Load block index */
-	printf("BLOCKS: %d\n", header->blocks);
 	
-	for ( i = 0; i < header->blocks; i++ ) {	
-		if ( !_load_block_index_record(sbin, &offset, i) ) {
-			i_error("sieve: block index record %d of loaded binary %s is corrupt", 
-				i, sbin->path);
-			return FALSE;
-		}
+	printf("BLOCKS: %d\n", blk_count);
+	
+	for ( i = 0; i < blk_count && result; i++ ) {	
+		T_FRAME(
+			if ( !_load_block_index_record(sbin, &offset, i) ) {
+				i_error("sieve: block index record %d of loaded binary %s is corrupt", 
+					i, sbin->path);
+				result = FALSE;
+			}
+		);
 	}
 	
+	if ( !result ) return FALSE;
+	
 	/* Load extensions used by this binary */
 	
-	extensions =_load_block(sbin, &offset, 0);
-	if ( extensions == NULL ) 
-		return FALSE;
-		
-	if ( !_sieve_binary_load_extensions(sbin) ) {
-		i_error("sieve: extension block of loaded binary %s is corrupt", 
-			sbin->path);
-		return FALSE;
-	}	
+	T_FRAME(
+		extensions =_load_block(sbin, &offset, 0);
+		if ( extensions == NULL ) {
+			result = FALSE;
+		} else if ( !_sieve_binary_load_extensions(sbin) ) {
+			i_error("sieve: extension block of loaded binary %s is corrupt", 
+				sbin->path);
+			result = FALSE;
+		}
+	);
+	
+	if ( !result ) return FALSE;
 	
 	/* Load the other blocks */
 	
-	for ( i = 1; i < header->blocks; i++ ) {	
-		if ( _load_block(sbin, &offset, i) == NULL ) {
-			i_error("sieve: block %d of loaded binary %s is corrupt", 
-				i, sbin->path);
-			return FALSE;
-		}
+	for ( i = 1; result && i < blk_count; i++ ) {	
+		T_FRAME(
+			if ( _load_block(sbin, &offset, i) == NULL ) {
+				i_error("sieve: block %d of loaded binary %s is corrupt", 
+					i, sbin->path);
+				result = FALSE;
+			}
+		);
 	}
 				
-	return TRUE;
+	return result;
 }
 
 struct sieve_binary *sieve_binary_open
@@ -859,7 +957,8 @@ struct sieve_binary *sieve_binary_open
 	struct sieve_binary *sbin;
 	struct sieve_binary_file *file;
 		
-	file = _file_memory_open(path);	
+	//file = _file_memory_open(path);	
+	file = _file_lazy_open(path);
 	if ( file == NULL )
 		return NULL;
 		
@@ -875,7 +974,7 @@ bool sieve_binary_load(struct sieve_binary *sbin)
 {
 	i_assert(sbin->file != NULL);
 
-	if ( !sbin->file->load(sbin->file) )
+	if ( sbin->file->load != NULL && !sbin->file->load(sbin->file) )
 		return FALSE;			
 	
 	if ( !_sieve_binary_load(sbin) ) {