private void parseExplicitAnonymousFunctionSignature(List<ParameterNode> parameters) {
            while (lexicalUnit != LexicalUnit.CloseParenthesis) {
                saveScannerState();
                var type = parseType(true);
                if (!isIdentifier(lexicalUnit)) {
                    throw error(ParseErrorId.IdentifierExpected);
                }
                var param = new ParameterNode { NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength(), Type = type };
                setSavedScannerState(param);
                param.EndPosition = scanner.EndPosition;
                parameters.add(param);
                switch (nextLexicalUnit(true)) {
                default:
                    throw error(ParseErrorId.CloseParenthesisExpected);

                case Comma:
                    if (nextLexicalUnit(true) == LexicalUnit.CloseParenthesis) {
                        throw error(ParseErrorId.IdentifierExpected);
                    }
                    break;

                case CloseParenthesis:
                    break;
                }
            }
            nextLexicalUnit(false);
        }
 private void parseImplicitAnonymousFunctionSignature(List<ParameterNode> parameters) {
     while (lexicalUnit != LexicalUnit.CloseParenthesis) {
         var param = new ParameterNode { NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength() };
         setScannerState(param);
         param.EndPosition = scanner.EndPosition;
         parameters.add(param);
         if (nextLexicalUnit(true) == LexicalUnit.Comma) {
             nextLexicalUnit(true);
         }
     }
     nextLexicalUnit(false);
 }
        private void parseFormalParameters(List<ParameterNode> parameters, LexicalUnit endLexicalUnit) {
            while (true) {
                var param = new ParameterNode();
                parameters.add(param);
                while (lexicalUnit == LexicalUnit.OpenBracket) {
                    param.Annotations.add(parseAnnotationSection());
                }
                setScannerState(param);
                switch (lexicalUnit) {
                case Keyword:
                    switch (scanner.Keyword) {
                    case Params:
                        param.Modifier = ParameterModifier.Params;
                        nextLexicalUnit(true);
                        break;

                    case This:
                        if (parameters.size() > 1) {
                            throw error(ParseErrorId.UnexpectedLexicalUnit);
                        }
                        param.Modifier = ParameterModifier.This;
                        nextLexicalUnit(true);
                        break;
                    }
                    break;
                }
                param.Type = parseType(true);
                if (!isIdentifier(lexicalUnit)) {
                    throw error(ParseErrorId.IdentifierExpected);
                }
                param.NameOffset = scanner.StartPosition;
                param.NameLength = getLexicalUnitLength();
                param.EndPosition = scanner.EndPosition;
                nextLexicalUnit(true);
                if (param.Modifier == ParameterModifier.Params) {
                    if (param.Type.TypeReferenceKind != TypeReferenceKind.Array) {
                        throw error(ParseErrorId.ArrayTypeExpected);
                    }
                    break;
                }
                if (lexicalUnit == LexicalUnit.Comma) {
                    nextLexicalUnit(true);
                } else {
                    break;
                }
            }
            if (lexicalUnit != endLexicalUnit) {
                if (endLexicalUnit == LexicalUnit.CloseParenthesis) {
                    throw error(ParseErrorId.CloseParenthesisExpected);
                } else if (endLexicalUnit == LexicalUnit.CloseBracket) {
                    throw error(ParseErrorId.CloseBracketExpected);
                } else {
                    throw error(ParseErrorId.CommaExpected);
                }
            }
            nextLexicalUnit(false);
        }
        private ExpressionNode parseLambdaExpression() {
            switch (lexicalUnit) {
            case ContextualKeyword:
            case VerbatimIdentifier:
            case Identifier: {
                int sp = scanner.StartPosition;
                int len = getLexicalUnitLength();
                saveScannerState();
                if (nextLexicalUnit(false) == LexicalUnit.Lambda) {
                    var lambda = new LambdaExpressionNode();
                    setSavedScannerState(lambda);
                    var param = new ParameterNode { NameOffset = sp, NameLength = len };
                    setSavedScannerState(param);
                    param.EndPosition = sp + len;
                    lambda.Parameters.add(param);
                    if (nextLexicalUnit(true) == LexicalUnit.OpenBrace) {
                        lambda.Body = parseBlockStatement();
                    } else {
                    	var expression = parseExpression();
                    	var expressionStatement = new ExpressionStatementNode { Expression = expression };
                    	copyScannerState(expression, expressionStatement);
                        lambda.Body = expressionStatement;
                    }
                    lambda.EndPosition = lambda.Body.EndPosition;
                    return lambda;
                }
	            break;
            }

            default: {
                var implicitSignature = true;
                var prev = LexicalUnit.Comma;
                var restorePoint = this.createRestorePoint();
                while (nextLexicalUnit(false) != LexicalUnit.CloseParenthesis) {
                    switch (lexicalUnit) {
                    case Identifier:
                    case ContextualKeyword:
                    case VerbatimIdentifier:
                        if (implicitSignature) {
                            if (prev != LexicalUnit.Comma) {
                                implicitSignature = false;
                            }
                        }
                        break;

                    case Comma:
                        if (implicitSignature) {
                            if (!isIdentifier(prev)) {
                                implicitSignature = false;
                            }
                        }
                        break;

                    case Keyword:
                        switch (scanner.Keyword) {
                        case Byte:
                        case Char:
                        case Short:
                        case Int:
                        case Long:
                        case Boolean:
                        case Double:
                        case Float:
                        case Void:
						case String:
                            break;

                        default:
                            return null;
                        }
                        implicitSignature = false;
                        break;

                    case GreaterThan:
                    case LessThan:
                    case Dot:
                    case OpenBracket:
                    case CloseBracket:
                    case QuestionMark:
                        implicitSignature = false;
                        break;

                    default:
                        return null;
                    }
                    prev = lexicalUnit;
                }
                if (nextLexicalUnit(false) != LexicalUnit.Lambda) {
                    return null;
                }
                this.restore(restorePoint);
                nextLexicalUnit(true);
                var lambda = new LambdaExpressionNode();
                setScannerState(lambda);
                if (implicitSignature) {
                    parseImplicitAnonymousFunctionSignature(lambda.Parameters);
                } else {
                    parseExplicitAnonymousFunctionSignature(lambda.Parameters);
                }
                if (nextLexicalUnit(true) == LexicalUnit.OpenBrace) {
                    lambda.Body = parseBlockStatement();
                } else {
                	var expression = parseExpression();
                	var expressionStatement = new ExpressionStatementNode { Expression = expression };
                	copyScannerState(expression, expressionStatement);
                    lambda.Body = expressionStatement;
                }
                lambda.EndPosition = lambda.Body.EndPosition;
                return lambda;
            }
            }
            return null;
        }
		private void print(ParameterNode p, StringBuilder sb) {
			foreach (var attr in p.Annotations) {
				print(attr, false, sb);
			}
			if (p.Modifier != ParameterModifier.None) {
				sb.append(p.Modifier.toString().toLowerCase());
				sb.append(" ");
			}
			print(p.Type, sb);
			sb.append(" ");
			sb.append(new String(text, p.NameOffset, p.NameLength));
		}