diff --git a/src/lib-sieve/sieve-lexer.c b/src/lib-sieve/sieve-lexer.c
index 54aa08f0ca905cecd09b47c50186f75a157b8a86..93607573cd60bcdf08b7c079eb43430989e295a7 100644
--- a/src/lib-sieve/sieve-lexer.c
+++ b/src/lib-sieve/sieve-lexer.c
@@ -1,8 +1,12 @@
+/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file 
+ */
+ 
 #include "lib.h"
 #include "compat.h"
 #include "str.h"
 #include "istream.h"
 
+#include "sieve-common.h"
 #include "sieve-error.h"
 #include "sieve-script.h"
 
@@ -15,11 +19,28 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+/* 
+ * Useful macros
+ */
+
 #define IS_DIGIT(c) ( c >= '0' && c <= '9' )
 #define DIGIT_VAL(c) ( c - '0' )
 #define IS_ALPHA(c) ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') )
 #define IS_QUANTIFIER(c) (c == 'K' || c == 'M' || c =='G') 
 
+/*
+ * Forward declarations
+ */
+ 
+inline static void sieve_lexer_error
+	(struct sieve_lexer *lexer, const char *fmt, ...) ATTR_FORMAT(2, 3);
+inline static void sieve_lexer_warning
+	(struct sieve_lexer *lexer, const char *fmt, ...) ATTR_FORMAT(2, 3);
+
+/*
+ * Lexer object
+ */
+
 struct sieve_lexer {
 	pool_t pool;
 
@@ -40,43 +61,6 @@ struct sieve_lexer {
 	size_t buffer_pos;
 };
 
-inline static void sieve_lexer_error
-	(struct sieve_lexer *lexer, const char *fmt, ...) ATTR_FORMAT(2, 3);
-inline static void sieve_lexer_warning
-	(struct sieve_lexer *lexer, const char *fmt, ...) ATTR_FORMAT(2, 3);
-
-inline static void sieve_lexer_error
-(struct sieve_lexer *lexer, const char *fmt, ...)
-{
-	va_list args;
-	va_start(args, fmt);
-
-	T_BEGIN {
-		sieve_verror(lexer->ehandler, 
-			t_strdup_printf("%s:%d", sieve_script_name(lexer->script), 
-				lexer->current_line),
-			fmt, args);
-	} T_END;
-		
-	va_end(args);
-}
-
-inline static void sieve_lexer_warning
-(struct sieve_lexer *lexer, const char *fmt, ...)
-{
-	va_list args;
-	va_start(args, fmt);
-
-	T_BEGIN { 
-		sieve_vwarning(lexer->ehandler, 
-			t_strdup_printf("%s:%d", sieve_script_name(lexer->script), 
-			lexer->current_line),
-			fmt, args);
-	} T_END;
-		
-	va_end(args);
-}
-
 struct sieve_lexer *sieve_lexer_create
 (struct sieve_script *script, struct sieve_error_handler *ehandler) 
 {
@@ -127,31 +111,40 @@ void sieve_lexer_free(struct sieve_lexer **lexer)
 	*lexer = NULL;
 }
 
-static void sieve_lexer_shift(struct sieve_lexer *lexer) 
+/*
+ * Internal error handling
+ */
+
+inline static void sieve_lexer_error
+(struct sieve_lexer *lexer, const char *fmt, ...)
 {
-	if ( lexer->buffer != NULL && lexer->buffer[lexer->buffer_pos] == '\n' ) 
-		lexer->current_line++;	
-	
-	if ( lexer->buffer != NULL && lexer->buffer_pos + 1 < lexer->buffer_size )
-		lexer->buffer_pos++;
-	else {
-		if ( lexer->buffer != NULL )
-			i_stream_skip(lexer->input, lexer->buffer_size);
+	va_list args;
+	va_start(args, fmt);
+
+	T_BEGIN {
+		sieve_verror(lexer->ehandler, 
+			t_strdup_printf("%s:%d", sieve_script_name(lexer->script), 
+				lexer->current_line),
+			fmt, args);
+	} T_END;
 		
-		lexer->buffer = i_stream_get_data(lexer->input, &lexer->buffer_size);
-	  
-		if ( lexer->buffer == NULL && i_stream_read(lexer->input) > 0 )
-	  		lexer->buffer = i_stream_get_data(lexer->input, &lexer->buffer_size);
-	  	
-		lexer->buffer_pos = 0;
-	}
+	va_end(args);
 }
 
-static inline int sieve_lexer_curchar(struct sieve_lexer *lexer) {	
-	if ( lexer->buffer == NULL )
-		return -1;
-	
-	return lexer->buffer[lexer->buffer_pos];
+inline static void sieve_lexer_warning
+(struct sieve_lexer *lexer, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+
+	T_BEGIN { 
+		sieve_vwarning(lexer->ehandler, 
+			t_strdup_printf("%s:%d", sieve_script_name(lexer->script), 
+			lexer->current_line),
+			fmt, args);
+	} T_END;
+		
+	va_end(args);
 }
 
 const char *sieve_lexer_token_string(struct sieve_lexer *lexer) 
@@ -185,6 +178,10 @@ const char *sieve_lexer_token_string(struct sieve_lexer *lexer)
 	return "unknown token (bug)";
 }
 	
+/* 
+ * Debug 
+ */
+ 
 void sieve_lexer_print_token(struct sieve_lexer *lexer) 
 {
 	switch ( lexer->token_type ) {
@@ -217,17 +214,24 @@ void sieve_lexer_print_token(struct sieve_lexer *lexer)
 	}
 }
 
-enum sieve_token_type sieve_lexer_current_token(struct sieve_lexer *lexer) {
+/*
+ * Token access
+ */ 
+
+enum sieve_token_type sieve_lexer_current_token(struct sieve_lexer *lexer) 
+{
 	return lexer->token_type;
 }
 
-const string_t *sieve_lexer_token_str(struct sieve_lexer *lexer) {
+const string_t *sieve_lexer_token_str(struct sieve_lexer *lexer) 
+{
 	i_assert(	lexer->token_type == STT_STRING );
 		
 	return lexer->token_str_value;
 }
 
-const char *sieve_lexer_token_ident(struct sieve_lexer *lexer) {
+const char *sieve_lexer_token_ident(struct sieve_lexer *lexer) 
+{
 	i_assert(
 		lexer->token_type == STT_TAG ||
 		lexer->token_type == STT_IDENTIFIER);
@@ -235,24 +239,59 @@ const char *sieve_lexer_token_ident(struct sieve_lexer *lexer) {
 	return str_c(lexer->token_str_value);
 }
 
-int sieve_lexer_token_int(struct sieve_lexer *lexer) {
+int sieve_lexer_token_int(struct sieve_lexer *lexer) 
+{
 	i_assert(lexer->token_type == STT_NUMBER);
 		
 	return lexer->token_int_value;
 }
 
-bool sieve_lexer_eof(struct sieve_lexer *lexer) {
+bool sieve_lexer_eof(struct sieve_lexer *lexer) 
+{
 	return lexer->token_type == STT_EOF;
 }
 
-int sieve_lexer_current_line(struct sieve_lexer *lexer) {
+int sieve_lexer_current_line(struct sieve_lexer *lexer) 
+{
 	return lexer->current_line;
 }
 
+/*
+ * Lexical scanning 
+ */
+
+static void sieve_lexer_shift(struct sieve_lexer *lexer) 
+{
+	if ( lexer->buffer != NULL && lexer->buffer[lexer->buffer_pos] == '\n' ) 
+		lexer->current_line++;	
+	
+	if ( lexer->buffer != NULL && lexer->buffer_pos + 1 < lexer->buffer_size )
+		lexer->buffer_pos++;
+	else {
+		if ( lexer->buffer != NULL )
+			i_stream_skip(lexer->input, lexer->buffer_size);
+		
+		lexer->buffer = i_stream_get_data(lexer->input, &lexer->buffer_size);
+	  
+		if ( lexer->buffer == NULL && i_stream_read(lexer->input) > 0 )
+	  		lexer->buffer = i_stream_get_data(lexer->input, &lexer->buffer_size);
+	  	
+		lexer->buffer_pos = 0;
+	}
+}
+
+static inline int sieve_lexer_curchar(struct sieve_lexer *lexer) 
+{	
+	if ( lexer->buffer == NULL )
+		return -1;
+	
+	return lexer->buffer[lexer->buffer_pos];
+}
+
 /* sieve_lexer_scan_raw_token:
  *   Scans valid tokens and whitespace 
  */
-bool sieve_lexer_scan_raw_token(struct sieve_lexer *lexer) 
+static bool sieve_lexer_scan_raw_token(struct sieve_lexer *lexer) 
 {
 	int start_line;
 	string_t *str;
@@ -511,9 +550,11 @@ bool sieve_lexer_scan_raw_token(struct sieve_lexer *lexer)
 					sieve_lexer_shift(lexer);
 				} else {
 					if ( sieve_lexer_curchar(lexer) == -1 ) {
-						sieve_lexer_error(lexer, "end of file before end of multi-line string");
+						sieve_lexer_error(lexer, 
+							"end of file before end of multi-line string");
 					} else {
- 						sieve_lexer_error(lexer, "invalid character '%c' after 'text:' in multiline string",
+ 						sieve_lexer_error(lexer, 
+ 							"invalid character '%c' after 'text:' in multiline string",
 							sieve_lexer_curchar(lexer));
 					}
 
@@ -546,7 +587,8 @@ bool sieve_lexer_scan_raw_token(struct sieve_lexer *lexer)
 					/* Scan the rest of the line */
 					while ( sieve_lexer_curchar(lexer) != '\n' ) {
 						if ( sieve_lexer_curchar(lexer) == -1 ) {
-							sieve_lexer_error(lexer, "end of file before end of multi-line string");
+							sieve_lexer_error(lexer, 
+								"end of file before end of multi-line string");
  							lexer->token_type = STT_ERROR;
  							return FALSE;
  						}
@@ -569,7 +611,8 @@ bool sieve_lexer_scan_raw_token(struct sieve_lexer *lexer)
 	
 		/* Error (unknown character and EOF handled already) */
 		if ( lexer->token_type != STT_GARBAGE ) 
-			sieve_lexer_error( lexer, "unexpected character(s) starting with '%c'", sieve_lexer_curchar(lexer) );
+			sieve_lexer_error(lexer, "unexpected character(s) starting with '%c'", 
+				sieve_lexer_curchar(lexer));
 		sieve_lexer_shift(lexer);
 		lexer->token_type = STT_GARBAGE;
 		return FALSE;
diff --git a/src/lib-sieve/sieve-lexer.h b/src/lib-sieve/sieve-lexer.h
index 4d8f6c3bd0ff8abe3189b2f7f00e59daa5094a4e..7d13b41e0afe4c826a5b994c1b4555c36768b267 100644
--- a/src/lib-sieve/sieve-lexer.h
+++ b/src/lib-sieve/sieve-lexer.h
@@ -1,8 +1,9 @@
+/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file 
+ */
+
 #ifndef __SIEVE_LEXER_H
 #define __SIEVE_LEXER_H
 
-#include "lib.h"
-
 #include "sieve-common.h"
 
 enum sieve_token_type {
@@ -34,21 +35,23 @@ enum sieve_token_type {
   
 	/* Error tokens */
 	STT_GARBAGE, /* Error reporting deferred to parser */ 
-	STT_ERROR    /* Lexer is responsible for error, parser won't report additional errors */
+	STT_ERROR    /* Lexer is responsible for error, parser won't report additional 
+	                errors */
 };
 
-struct sieve_token;
 struct sieve_lexer;
 
+/* Lexer object */
 struct sieve_lexer *sieve_lexer_create
 	(struct sieve_script *script, struct sieve_error_handler *ehandler);
 void sieve_lexer_free(struct sieve_lexer **lexer);
 
-bool sieve_lexer_scan_raw_token(struct sieve_lexer *lexer);
+/* Scanning */
 bool sieve_lexer_skip_token(struct sieve_lexer *lexer);
 const char *sieve_lexer_token_string(struct sieve_lexer *lexer);
 void sieve_lexer_print_token(struct sieve_lexer *lexer);
 
+/* Token access */
 enum sieve_token_type sieve_lexer_current_token(struct sieve_lexer *lexer);
 const string_t *sieve_lexer_token_str(struct sieve_lexer *lexer);
 const char *sieve_lexer_token_ident(struct sieve_lexer *lexer);
diff --git a/src/lib-sieve/sieve-parser.c b/src/lib-sieve/sieve-parser.c
index 0e2f8274a8d42c7599597174a5b2dca005abe5cb..90867af4908bb387e2d62518a689e53b2a15eb29 100644
--- a/src/lib-sieve/sieve-parser.c
+++ b/src/lib-sieve/sieve-parser.c
@@ -1,3 +1,6 @@
+/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file 
+ */
+ 
 #include <stdio.h>
 
 #include "lib.h"
@@ -14,6 +17,22 @@
  * nesting levels, etc.
  */
 
+/*
+ * Forward declarations
+ */
+ 
+inline static void sieve_parser_error
+	(struct sieve_parser *parser, const char *fmt, ...) ATTR_FORMAT(2, 3);
+inline static void sieve_parser_warning
+	(struct sieve_parser *parser, const char *fmt, ...) ATTR_FORMAT(2, 3); 
+ 
+static bool sieve_parser_recover
+	(struct sieve_parser *parser, enum sieve_token_type end_token);
+
+/*
+ * Parser object
+ */
+
 struct sieve_parser {
 	pool_t pool;
 	
@@ -27,55 +46,6 @@ struct sieve_parser {
 	struct sieve_ast *ast;
 };
 
-inline static void sieve_parser_error
-	(struct sieve_parser *parser, const char *fmt, ...) ATTR_FORMAT(2, 3);
-inline static void sieve_parser_warning
-	(struct sieve_parser *parser, const char *fmt, ...) ATTR_FORMAT(2, 3);
-
-inline static void sieve_parser_error
-	(struct sieve_parser *parser, const char *fmt, ...)
-{ 
-	va_list args;
-	va_start(args, fmt);
-
-	/* Don't report a parse error if the lexer complained already */ 
-	if ( sieve_lexer_current_token(parser->lexer) != STT_ERROR )  
-	{
-		T_BEGIN {
-			sieve_verror(parser->ehandler, 
-				t_strdup_printf("%s:%d", 
-				sieve_script_name(parser->script),
-				sieve_lexer_current_line(parser->lexer)),
-				fmt, args);
-		} T_END; 
-	}
-	
-	parser->valid = FALSE;
-	
-	va_end(args);
-}
-
-inline static void sieve_parser_warning
-	(struct sieve_parser *parser, const char *fmt, ...)
-{
-	va_list args;
-	va_start(args, fmt);
-
-	T_BEGIN	{
-		sieve_vwarning(parser->ehandler, 
-			t_strdup_printf("%s:%d", 
-			sieve_script_name(parser->script),
-			sieve_lexer_current_line(parser->lexer)),
-			fmt, args);
-	} T_END;
-		
-	va_end(args);
-} 
-
-/* Forward declarations */
-static bool sieve_parser_recover
-	(struct sieve_parser *parser, enum sieve_token_type end_token);
-
 struct sieve_parser *sieve_parser_create
 (struct sieve_script *script, struct sieve_error_handler *ehandler)
 {
@@ -121,20 +91,73 @@ void sieve_parser_free(struct sieve_parser **parser)
 	*parser = NULL;
 }
 
-/* arguments = *argument [test / test-list]
- * argument = string-list / number / tag
- * string = quoted-string / multi-line   [[implicitly handled in lexer]]
- * string-list = "[" string *("," string) "]" / string         ;; if
- *   there is only a single string, the brackets are optional
- * test-list = "(" test *("," test) ")"
- * test = identifier arguments
+/*
+ * Internal error handling
  */
-static bool sieve_parse_arguments
-	(struct sieve_parser *parser, struct sieve_ast_node *node) {
+
+inline static void sieve_parser_error
+(struct sieve_parser *parser, const char *fmt, ...)
+{ 
+	va_list args;
+	va_start(args, fmt);
+
+	/* Don't report a parse error if the lexer complained already */ 
+	if ( sieve_lexer_current_token(parser->lexer) != STT_ERROR )  
+	{
+		T_BEGIN {
+			sieve_verror(parser->ehandler, 
+				t_strdup_printf("%s:%d", 
+				sieve_script_name(parser->script),
+				sieve_lexer_current_line(parser->lexer)),
+				fmt, args);
+		} T_END; 
+	}
+	
+	parser->valid = FALSE;
 	
+	va_end(args);
+}
+
+inline static void sieve_parser_warning
+(struct sieve_parser *parser, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+
+	T_BEGIN	{
+		sieve_vwarning(parser->ehandler, 
+			t_strdup_printf("%s:%d", 
+			sieve_script_name(parser->script),
+			sieve_lexer_current_line(parser->lexer)),
+			fmt, args);
+	} T_END;
+		
+	va_end(args);
+} 
+
+/*
+ * Sieve grammar parsing
+ */
+
+/* sieve_parse_arguments():
+ *
+ * Parses both command arguments and sub-tests:
+ *   arguments = *argument [test / test-list]
+ *   argument = string-list / number / tag
+ *   string = quoted-string / multi-line   [[implicitly handled in lexer]]
+ *   string-list = "[" string *("," string) "]" / string         ;; if
+ *     there is only a single string, the brackets are optional
+ *   test-list = "(" test *("," test) ")"
+ *   test = identifier arguments
+ */
+static bool sieve_parse_arguments
+(struct sieve_parser *parser, struct sieve_ast_node *node) 
+{	
 	struct sieve_lexer *lexer = parser->lexer;
 	struct sieve_ast_node *test = NULL;
-	bool argument = TRUE, result = TRUE;
+	bool argument = TRUE;
+	bool result = TRUE; /* Indicates whether the parser is in a defined, not 
+	                       necessarily error-free state */
 	
 	/* Parse arguments */
 	while ( argument && result && 
@@ -145,25 +168,35 @@ static bool sieve_parse_arguments
 		
 		/* String list */
 		case STT_LSQUARE:
+			/* Create stinglist object */
 			arg = sieve_ast_argument_stringlist_create
 				(node, sieve_lexer_current_line(parser->lexer));
-			sieve_lexer_skip_token(lexer);
+				
+			sieve_lexer_skip_token(lexer);			
 			
 			if ( sieve_lexer_current_token(lexer) == STT_STRING ) {
+				/* Add the string to the list */
 				sieve_ast_stringlist_add
-					(arg, sieve_lexer_token_str(lexer), sieve_lexer_current_line(parser->lexer));
+					(arg, sieve_lexer_token_str(lexer), 
+						sieve_lexer_current_line(parser->lexer));
+				
 				sieve_lexer_skip_token(lexer);
 				 
 				while ( sieve_lexer_current_token(lexer) == STT_COMMA &&
 					(parser->valid || sieve_errors_more_allowed(parser->ehandler)) ) {
+			
 					sieve_lexer_skip_token(lexer);
 				
 					if ( sieve_lexer_current_token(lexer) == STT_STRING ) {
+						/* Add the string to the list */
 						sieve_ast_stringlist_add
-							(arg, sieve_lexer_token_str(lexer), sieve_lexer_current_line(parser->lexer));
+							(arg, sieve_lexer_token_str(lexer), 
+								sieve_lexer_current_line(parser->lexer));
+							
 						sieve_lexer_skip_token(lexer);
 					} else {
-						sieve_parser_error(parser, "expecting string after ',' in string list, but found %s",
+						sieve_parser_error(parser, 
+							"expecting string after ',' in string list, but found %s",
 							sieve_lexer_token_string(lexer));
 					
 						result = sieve_parser_recover(parser, STT_RSQUARE);
@@ -171,16 +204,19 @@ static bool sieve_parse_arguments
 					}
 				}
 			} else {
-				sieve_parser_error(parser, "expecting string after '[' in string list, but found %s",
+				sieve_parser_error(parser, 
+					"expecting string after '[' in string list, but found %s",
 					sieve_lexer_token_string(lexer));
 			
 				result = sieve_parser_recover(parser, STT_RSQUARE);
 			}
 		
+			/* Finish the string list */
 			if ( sieve_lexer_current_token(lexer) == STT_RSQUARE ) {
 				sieve_lexer_skip_token(lexer);
 			} else {
-				sieve_parser_error(parser, "expecting ',' or end of string list ']', but found %s",
+				sieve_parser_error(parser, 
+					"expecting ',' or end of string list ']', but found %s",
 					sieve_lexer_token_string(lexer));
 			
 				if ( (result=sieve_parser_recover(parser, STT_RSQUARE)) == TRUE ) 
@@ -192,21 +228,24 @@ static bool sieve_parse_arguments
 		/* Single string */
 		case STT_STRING: 
 			(void) sieve_ast_argument_string_create
-				(node, sieve_lexer_token_str(lexer), sieve_lexer_current_line(parser->lexer));
+				(node, sieve_lexer_token_str(lexer), 
+					sieve_lexer_current_line(parser->lexer));
 			sieve_lexer_skip_token(lexer);
 			break;
 		
 		/* Number */
 		case STT_NUMBER:
 			(void) sieve_ast_argument_number_create
-				(node, sieve_lexer_token_int(lexer), sieve_lexer_current_line(parser->lexer));
+				(node, sieve_lexer_token_int(lexer), 
+					sieve_lexer_current_line(parser->lexer));
 			sieve_lexer_skip_token(lexer);
 			break;
 			
 		/* Tag */
 		case STT_TAG:
 			(void) sieve_ast_argument_tag_create
-				(node, sieve_lexer_token_ident(lexer), sieve_lexer_current_line(parser->lexer));
+				(node, sieve_lexer_token_ident(lexer), 
+					sieve_lexer_current_line(parser->lexer));
 			sieve_lexer_skip_token(lexer);
 			break;
 			
@@ -228,7 +267,8 @@ static bool sieve_parse_arguments
 	/* Single test */
 	case STT_IDENTIFIER:
 		test = sieve_ast_test_create
-			(node, sieve_lexer_token_ident(lexer), sieve_lexer_current_line(parser->lexer));
+			(node, sieve_lexer_token_ident(lexer), 
+				sieve_lexer_current_line(parser->lexer));
 		sieve_lexer_skip_token(lexer);
 		
 		/* Parse test arguments, which may include more tests (recurse) */
@@ -247,7 +287,8 @@ static bool sieve_parse_arguments
 		/* Test starts with identifier */
 		if ( sieve_lexer_current_token(lexer) == STT_IDENTIFIER ) {
 			test = sieve_ast_test_create
-				(node, sieve_lexer_token_ident(lexer), sieve_lexer_current_line(parser->lexer));
+				(node, sieve_lexer_token_ident(lexer), 
+					sieve_lexer_current_line(parser->lexer));
 			sieve_lexer_skip_token(lexer);
 		
 			/* Parse test arguments, which may include more tests (recurse) */
@@ -261,7 +302,8 @@ static bool sieve_parse_arguments
 					/* Test starts with identifier */
 					if ( sieve_lexer_current_token(lexer) == STT_IDENTIFIER ) {
 						test = sieve_ast_test_create
-							(node, sieve_lexer_token_ident(lexer), sieve_lexer_current_line(parser->lexer));
+							(node, sieve_lexer_token_ident(lexer), 
+								sieve_lexer_current_line(parser->lexer));
 						sieve_lexer_skip_token(lexer);
 						
 						/* Parse test arguments, which may include more tests (recurse) */
@@ -270,7 +312,8 @@ static bool sieve_parse_arguments
 							break;
 						}
 					} else {
-						sieve_parser_error(parser, "expecting test identifier after ',' in test list, but found %s",
+						sieve_parser_error(parser, 
+							"expecting test identifier after ',' in test list, but found %s",
 							sieve_lexer_token_string(lexer));
 										
 						result = sieve_parser_recover(parser, STT_RBRACKET);
@@ -280,24 +323,26 @@ static bool sieve_parse_arguments
 			} else 
 				result = sieve_parser_recover(parser, STT_RBRACKET);
 		} else {
-			sieve_parser_error(parser, "expecting test identifier after '(' in test list, but found %s",
+			sieve_parser_error(parser, 
+				"expecting test identifier after '(' in test list, but found %s",
 				sieve_lexer_token_string(lexer));
 			
 			result = sieve_parser_recover(parser, STT_RBRACKET);
 		}
 		
 		/* The next token should be a ')', indicating the end of the test list
-		 *   --> privious sieve_parser_recover calls try to restore this situation after
-		 *       parse errors.  
+		 *   --> previous sieve_parser_recover calls try to restore this situation 
+		 *       after parse errors.  
 		 */
  		if ( sieve_lexer_current_token(lexer) == STT_RBRACKET ) {
 			sieve_lexer_skip_token(lexer);
 		} else {
-			sieve_parser_error(parser, "expecting ',' or end of test list ')', but found %s",
+			sieve_parser_error(parser, 
+				"expecting ',' or end of test list ')', but found %s",
 				sieve_lexer_token_string(lexer));
 			
-			/* Recover function tries to make next token equal to ')'. If it succeeds we need to 
-			 * skip it.
+			/* Recover function tries to make next token equal to ')'. If it succeeds 
+			 * we need to skip it.
 			 */
 			if ( (result = sieve_parser_recover(parser, STT_RBRACKET)) == TRUE ) 
 				sieve_lexer_skip_token(lexer);
@@ -319,8 +364,8 @@ static bool sieve_parse_arguments
  * block = "{" commands "}"
  */
 static bool sieve_parse_commands
-	(struct sieve_parser *parser, struct sieve_ast_node *block) { 
-
+(struct sieve_parser *parser, struct sieve_ast_node *block) 
+{ 
 	struct sieve_lexer *lexer = parser->lexer;
 	bool result = TRUE;
 
@@ -328,7 +373,8 @@ static bool sieve_parse_commands
 		(parser->valid || sieve_errors_more_allowed(parser->ehandler)) ) {
 		struct sieve_ast_node *command = 
 			sieve_ast_command_create
-				(block, sieve_lexer_token_ident(lexer), sieve_lexer_current_line(parser->lexer));
+				(block, sieve_lexer_token_ident(lexer), 
+					sieve_lexer_current_line(parser->lexer));
 	
 		/* Defined state */
 		result = TRUE;		
@@ -337,13 +383,17 @@ static bool sieve_parse_commands
 		
 		result = sieve_parse_arguments(parser, command);
 		
-		/* Check whether the command is properly terminated (i.e. with ; or a new block) */
+		/* Check whether the command is properly terminated 
+		 * (i.e. with ; or a new block) 
+		 */
 		if ( result &&
 			sieve_lexer_current_token(lexer) != STT_SEMICOLON &&
 			sieve_lexer_current_token(lexer) != STT_LCURLY ) {
 			
-			sieve_parser_error(parser, "expected end of command ';' or the beginning of a compound block '{', but found %s",
-					sieve_lexer_token_string(lexer));	
+			sieve_parser_error(parser, 
+				"expected end of command ';' or the beginning of a compound block '{', "
+				"but found %s",
+				sieve_lexer_token_string(lexer));	
 			result = FALSE;
 		}
 		
@@ -370,7 +420,8 @@ static bool sieve_parse_commands
 			if ( sieve_parse_commands(parser, command) ) {
 			
 				if ( sieve_lexer_current_token(lexer) != STT_RCURLY ) {
-					sieve_parser_error(parser, "expected end of compound block '}', but found %s",
+					sieve_parser_error(parser, 
+						"expected end of compound block '}', but found %s",
 						sieve_lexer_token_string(lexer));
 					result = sieve_parser_recover(parser, STT_RCURLY);				
 				} else 
@@ -390,11 +441,12 @@ static bool sieve_parse_commands
 }
 
 bool sieve_parser_run
-	(struct sieve_parser *parser, struct sieve_ast **ast) 
+(struct sieve_parser *parser, struct sieve_ast **ast) 
 {
 	if ( parser->ast != NULL )
 		sieve_ast_unref(&parser->ast);
 	
+	/* Create AST object if none is provided */
 	if ( *ast == NULL )
 		*ast = sieve_ast_create(parser->script);
 	else 
@@ -405,30 +457,33 @@ bool sieve_parser_run
 	/* Scan first token */
 	sieve_lexer_skip_token(parser->lexer);
 
-	if ( sieve_parse_commands(parser, sieve_ast_root(parser->ast)) ) { 
+	/* Parse */
+	if ( sieve_parse_commands(parser, sieve_ast_root(parser->ast)) && 
+		parser->valid ) {
+		 
+		/* Parsed right to EOF ? */
 		if ( sieve_lexer_current_token(parser->lexer) != STT_EOF ) { 
 			sieve_parser_error(parser, 
 				"unexpected %s found at (the presumed) end of file",
 				sieve_lexer_token_string(parser->lexer));
-	
-			parser->ast = NULL;
-			sieve_ast_unref(ast);
-			return FALSE;				
+			parser->valid = FALSE;
 		}
+	} else parser->valid = FALSE;
 	
-		return parser->valid;
-	} 
+	/* Clean up AST if parse failed */
+	if ( !parser->valid ) {
+		parser->ast = NULL;
+		sieve_ast_unref(ast);
+	}
 	
-	parser->ast = NULL;
-	sieve_ast_unref(ast);
-	return FALSE;
+	return parser->valid;
 }	
 
 /* Error recovery:
- *   To continue parsing after an error it is important to find the next parsible item in the 
- *   stream. The recover function skips over the remaining garbage after an error. It tries 
- *   to find the end of the failed syntax structure and takes nesting of structures into account.
- *   
+ *   To continue parsing after an error it is important to find the next 
+ *   parsible item in the stream. The recover function skips over the remaining 
+ *   garbage after an error. It tries  to find the end of the failed syntax 
+ *   structure and takes nesting of structures into account. 
  */
 
 /* Assign useful names to priorities for readability */ 
@@ -441,7 +496,9 @@ enum sieve_grammatical_prio {
 	SGP_OTHER = -1
 };
 
-static inline enum sieve_grammatical_prio __get_token_priority(enum sieve_token_type token) {
+static inline enum sieve_grammatical_prio __get_token_priority
+(enum sieve_token_type token) 
+{
 	switch ( token ) {
 	case STT_LCURLY:
 	case STT_RCURLY: 
@@ -461,7 +518,8 @@ static inline enum sieve_grammatical_prio __get_token_priority(enum sieve_token_
 	return SGP_OTHER;
 }
 
-static bool sieve_parser_recover(struct sieve_parser *parser, enum sieve_token_type end_token) 
+static bool sieve_parser_recover
+(struct sieve_parser *parser, enum sieve_token_type end_token) 
 {
 	/* The tokens that begin/end a specific block/command/list in order 
  	 * of ascending grammatical priority.
@@ -499,7 +557,8 @@ static bool sieve_parser_recover(struct sieve_parser *parser, enum sieve_token_t
 	}
 	
 	/* Special case: COMMAND */
-	if (end_token == STT_SEMICOLON && sieve_lexer_current_token(lexer) == STT_LCURLY)
+	if (end_token == STT_SEMICOLON && 
+		sieve_lexer_current_token(lexer) == STT_LCURLY)
 		return TRUE;
 	
 	/* End not found before eof or end of surrounding grammatical structure 
diff --git a/src/lib-sieve/sieve-parser.h b/src/lib-sieve/sieve-parser.h
index d12eb2a4d8e11222ea70f8918ed800f22d8375b7..e535ace3e981b060ff2a32d1708d6d7cdcb2bb47 100644
--- a/src/lib-sieve/sieve-parser.h
+++ b/src/lib-sieve/sieve-parser.h
@@ -1,3 +1,6 @@
+/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file 
+ */
+ 
 #ifndef __SIEVE_PARSER_H
 #define __SIEVE_PARSER_H
 
diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index 890d28b22825da3eb92f70cb8bd189ff6fc75158..7e330420619594282a2045d4337ba09c7db24b8d 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002-2007 Dovecot Sieve authors, see the included COPYING file */
+/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file 
+ */
 
 #include "lib.h"
 #include "str.h"
@@ -28,6 +29,10 @@
 #include <unistd.h>
 #include <stdio.h>
 
+/* 
+ * Main Sieve library interface
+ */
+
 bool sieve_init(const char *plugins)
 {
 	return sieve_extensions_init(plugins);
@@ -38,6 +43,15 @@ void sieve_deinit(void)
 	sieve_extensions_deinit();
 }
 
+const char *sieve_get_capabilities(void) 
+{
+	return sieve_extensions_get_string();
+}
+
+/*
+ * Low-level compiler functions 
+ */
+
 struct sieve_ast *sieve_parse
 	(struct sieve_script *script, struct sieve_error_handler *ehandler)
 {
@@ -83,6 +97,10 @@ static struct sieve_binary *sieve_generate
 	return sbin;
 }
 
+/*
+ * Sieve compilation
+ */
+
 struct sieve_binary *sieve_compile_script
 (struct sieve_script *script, struct sieve_error_handler *ehandler) 
 {
@@ -133,6 +151,10 @@ struct sieve_binary *sieve_compile
 	return sbin;
 }
 
+/*
+ * Reading/writing sieve binaries
+ */
+
 struct sieve_binary *sieve_open
 (const char *script_path, struct sieve_error_handler *ehandler)
 {
@@ -140,33 +162,47 @@ struct sieve_binary *sieve_open
 	struct sieve_binary *sbin;
 	const char *binpath;
 	
+	/* First open the scriptfile itself */
 	script = sieve_script_create(script_path, NULL, ehandler, NULL);
 
-	if ( script == NULL )
+	if ( script == NULL ) {
+		/* Failed */
 		return NULL;
+	}
 
 	T_BEGIN {
+		/* Then try to open the matching binary */
 		binpath = sieve_script_binpath(script);	
 		sbin = sieve_binary_open(binpath, script);
 	
 		if (sbin != NULL) {
+			/* Ok, it exists; now let's see if it is up to date */
 			if ( !sieve_binary_up_to_date(sbin) ) {
+				/* Not up to date */
 				sieve_binary_unref(&sbin);
 				sbin = NULL;
 			} else if ( !sieve_binary_load(sbin) ) {
+				/* Failed to load */
 				sieve_binary_unref(&sbin);
 				sbin = NULL;
 			}
 		}
 		
+		/* If the binary does not exist, is not up-to-date or fails to load, we need
+		 * to (re-)compile.
+		 */
 		if ( sbin == NULL ) {	
 			sbin = sieve_compile_script(script, ehandler);
 
-			if ( sbin != NULL )
+			/* Save the binary if compile was successful */
+			if ( sbin != NULL ) 
 				(void) sieve_binary_save(sbin, binpath);	
 		}
 	} T_END;
 	
+	/* Drop script reference, if sbin != NULL it holds a reference of its own. 
+	 * Otherwise the script object is freed here.
+	 */
 	sieve_script_unref(&script);
 
 	return sbin;
@@ -178,6 +214,15 @@ bool sieve_save
 	return sieve_binary_save(sbin, path);
 }
 
+void sieve_close(struct sieve_binary **sbin)
+{
+	sieve_binary_unref(sbin);
+}
+
+/*
+ * Debugging
+ */
+
 void sieve_dump(struct sieve_binary *sbin, struct ostream *stream) 
 {
 	struct sieve_binary_dumper *dumpr = sieve_binary_dumper_create(sbin);			
@@ -207,6 +252,10 @@ int sieve_test
 	return ret;
 }
 
+/*
+ * Script execution
+ */
+
 int sieve_execute
 (struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
 	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler, 
@@ -222,13 +271,3 @@ int sieve_execute
 	sieve_interpreter_free(&interp);
 	return ret;
 }
-
-void sieve_close(struct sieve_binary **sbin)
-{
-	sieve_binary_unref(sbin);
-}
-
-const char *sieve_get_capabilities(void) 
-{
-	return sieve_extensions_get_string();
-}
diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h
index ba207196751e58bf83b0d38d11f6b77385e9dc8d..12cd7eefe63134a60d7081ff55e02af245dd03cb 100644
--- a/src/lib-sieve/sieve.h
+++ b/src/lib-sieve/sieve.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002-2007 Dovecot authors, see the included COPYING file */
+/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file 
+ */
 
 #ifndef __SIEVE_H
 #define __SIEVE_H
@@ -10,6 +11,7 @@
 #define SIEVE_VERSION "0.0.1"
 #define SIEVE_IMPLEMENTATION "Dovecot Sieve " SIEVE_VERSION
 
+/* Enable runtime trace functionality */
 #define SIEVE_RUNTIME_TRACE
 
 struct sieve_script;
@@ -50,9 +52,30 @@ struct sieve_script_env {
                     const char *user, time_t time);
 };	
 
+/*
+ * Main Sieve library interface
+ */
+
+/* sieve_init(): 
+ *   Initializes the sieve engine. Must be called before any sieve functionality
+ *   is used.
+ */
 bool sieve_init(const char *plugins);
+
+/* sieve_deinit():
+ *   Frees all memory allocated by the sieve engine. 
+ */
 void sieve_deinit(void);
 
+/* sieve_get_capabilities:
+ *
+ */
+const char *sieve_get_capabilities(void);
+
+/*
+ * Script compilation
+ */
+
 /* sieve_compile_script:
  */
 struct sieve_binary *sieve_compile_script
@@ -65,6 +88,10 @@ struct sieve_binary *sieve_compile_script
 struct sieve_binary *sieve_compile
 	(const char *scriptpath, struct sieve_error_handler *ehandler);
 
+/* 
+ * Reading/writing Sieve binaries
+ */
+
 /* sieve_open:
  *
  *   First tries to open the binary version of the specified script and
@@ -76,18 +103,28 @@ struct sieve_binary *sieve_compile
 struct sieve_binary *sieve_open
 	(const char *scriptpath, struct sieve_error_handler *ehandler);
 
-/* sieve_dump:
- *
- *   Dumps the byte code in human-readable form to the specified ostream.
- */
-void sieve_dump(struct sieve_binary *sbin, struct ostream *stream);
-
 /* sieve_save:
  *  Saves the binary as the file indicated by the path parameter.
  */
 bool sieve_save
     (struct sieve_binary *sbin, const char *path);
 
+/* sieve_close:
+ *
+ *   Closes a compiled/opened sieve binary.
+ */
+void sieve_close(struct sieve_binary **sbin);
+
+/*
+ * Debugging
+ */
+
+/* sieve_dump:
+ *
+ *   Dumps the byte code in human-readable form to the specified ostream.
+ */
+void sieve_dump(struct sieve_binary *sbin, struct ostream *stream);
+
 /* sieve_test:
  *
  *   Executes the bytecode, but only prints the result to the given stream.
@@ -97,6 +134,10 @@ int sieve_test
 		const struct sieve_script_env *senv, struct ostream *stream,
 		struct sieve_error_handler *ehandler, struct ostream *trace_stream);
 
+/*
+ * Script execution
+ */
+
 /* sieve_execute:
  *
  *   Executes the binary, including the result.  
@@ -106,15 +147,4 @@ int sieve_execute
 		const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
 		struct ostream *trace_stream);
 
-/* sieve_close:
- *
- *   Closes a compiled/opened sieve binary.
- */
-void sieve_close(struct sieve_binary **sbin);
-
-/* sieve_get_capabilities:
- *
- */
-const char *sieve_get_capabilities(void);
-
 #endif
diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c
index f54d2bd60284fa96df008dda85effe976e49fbf7..f735ed82a284f8fa71a343c71d358bec34f318a7 100644
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002-2007 Dovecot authors, see the included COPYING file */
+/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file 
+ */
 
 #include "lib.h"
 #include "home-expand.h"
@@ -90,9 +91,12 @@ static int lda_sieve_run
 	const char *scriptlog;
 	int ret = 0;
 
+	/* Create error handler */
 	scriptlog = t_strconcat(script_path, ".log", NULL);
 	ehandler = sieve_logfile_ehandler_create(scriptlog, LDA_SIEVE_MAX_ERRORS);
 
+	/* Open the script */
+
 	if ( debug )
 		i_info("sieve: Opening script %s", script_path);
 
@@ -117,6 +121,7 @@ static int lda_sieve_run
 	msgdata.auth_user = username;
 	(void)mail_get_first_header(mail, "Message-ID", &msgdata.id);
 
+	/* Compose script execution environment */
 	memset(&scriptenv, 0, sizeof(scriptenv));
 	scriptenv.inbox = mailbox;
 	scriptenv.namespaces = namespaces;
@@ -128,6 +133,8 @@ static int lda_sieve_run
 	scriptenv.duplicate_mark = duplicate_mark;
 	scriptenv.duplicate_check = duplicate_check;
 
+	/* Execute the script */	
+	
 	if ( debug )
 		i_info("sieve: Executing (in-memory) script %s", script_path);
 
@@ -136,6 +143,8 @@ static int lda_sieve_run
 	if ( ret < 0 )
 		i_error("sieve: Failed to execute script %s", script_path);
 
+	/* Clean up */
+	sieve_close(&sbin);
 	sieve_error_handler_unref(&ehandler);
 
 	return ret;
@@ -148,6 +157,8 @@ static int lda_sieve_deliver_mail
 	const char *script_path;
 	int ret;
 
+	/* Find the script to execute */
+	
 	script_path = lda_sieve_get_path();
 	if (script_path == NULL)
 		return 0;
@@ -155,6 +166,8 @@ static int lda_sieve_deliver_mail
 	if (getenv("DEBUG") != NULL)
 		i_info("sieve: Using sieve path: %s", script_path);
 
+	/* Run the script */
+
 	T_BEGIN { 
 		ret = lda_sieve_run(namespaces, mail, script_path, destaddr, 
 			getenv("USER"), mailbox);
@@ -165,15 +178,19 @@ static int lda_sieve_deliver_mail
 
 void sieve_plugin_init(void)
 {
+	/* Initialize Sieve engine */
 	sieve_init("");
 
+	/* Hook into the delivery process */
 	next_deliver_mail = deliver_mail;
 	deliver_mail = lda_sieve_deliver_mail;
 }
 
 void sieve_plugin_deinit(void)
 {
+	/* Remove hook */
 	deliver_mail = next_deliver_mail;
 
+	/* Deinitialize Sieve engine */
 	sieve_deinit();
 }