private InterfaceDeclarationNode parseInterface(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers,
                bool partial, int startPosition) {
            if (!isIdentifier(lexicalUnit)) {
                throw error(ParseErrorId.IdentifierExpected);
            }
            var declaration = new InterfaceDeclarationNode { IsPartial = partial,
                NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength(), StartPosition = startPosition };
            if (docCommentEndPosition > 0) {
                declaration.DocumentationOffset = docCommentStartPosition;
                declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
                docCommentEndPosition = 0;
            }
            setScannerState(declaration);
            declaration.Modifiers.addAll(modifiers);
            declaration.Annotations.addAll(annotations);
            nextLexicalUnit(true);
            parseTypeParameters(declaration.TypeParameters);
            parseClassBase(declaration.InterfaceBase);
            parseTypeParameterConstraintsClauses(declaration.ConstraintsClauses);
            if (lexicalUnit != LexicalUnit.OpenBrace) {
                throw error(ParseErrorId.OpenBraceExpected);
            }
            if (nextLexicalUnit(true) != LexicalUnit.CloseBrace) {
                var done = false;
                annotations.clear();
                do {
                    while (lexicalUnit == LexicalUnit.OpenBracket) {
                        annotations.add(parseAnnotationSection());
                    }
                    switch (lexicalUnit) {
                    case CloseBrace:
                        if (annotations.size() > 0) {
                            addError(ParseErrorId.TypeExpected);
                            annotations.clear();
                        }
                        done = true;
                        break;

                    case Keyword:
                    case ContextualKeyword:
                    case Identifier:
                        declaration.Members.add(parseInterfaceMember(annotations, modifiers, startPosition));
                        modifiers.clear();
                        annotations.clear();
                        break;

                    default:
                        throw error(ParseErrorId.CloseBraceExpected);
                    }
                } while (!done);
            }
            if (lexicalUnit != LexicalUnit.CloseBrace) {
                throw error(ParseErrorId.CloseBraceExpected);
            }
            docCommentEndPosition = 0;
			declaration.EndPosition = scanner.EndPosition;
            if (nextLexicalUnit(false) == LexicalUnit.SemiColon) {
				declaration.EndPosition = scanner.EndPosition;
                nextLexicalUnit(false);
            }
            return declaration;
        }
        private int parseClassBody(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers, bool isEnum,
                List<ITypeMember> members) {
			int startPosition = 0;
            if (nextLexicalUnit(true, LexicalUnit.CloseBrace) != LexicalUnit.CloseBrace) {
                var done = false;
                modifiers.clear();
                annotations.clear();
                if (isEnum && lexicalUnit != LexicalUnit.SemiColon) {
                    do {
                        while (lexicalUnit == LexicalUnit.OpenBracket) {
                            annotations.add(parseAnnotationSection());
                        }
                        if (!isIdentifier(lexicalUnit)) {
                            throw error(ParseErrorId.IdentifierExpected);
                        }
                        members.add(parseEnumConstant(annotations));
                        switch (lexicalUnit) {
                        case Comma:
                            if (nextLexicalUnit(true) == LexicalUnit.CloseBrace) {
								int result = scanner.EndPosition;
                                if (nextLexicalUnit(false) == LexicalUnit.SemiColon) {
                                    nextLexicalUnit(false);
                                }
                                return result;
                            }
                            break;
                            
                        case CloseBrace:
							int result = scanner.EndPosition;
                            if (nextLexicalUnit(false) == LexicalUnit.SemiColon) {
                                nextLexicalUnit(false);
                            }
                            return result;
                            
                        case SemiColon:
                            done = true;
                            nextLexicalUnit(true);
                            break;
                        }
                    } while (!done);
                    done = false;
                }
                do {
                    while (lexicalUnit == LexicalUnit.OpenBracket) {
                        annotations.add(parseAnnotationSection());
                    }
                    switch (lexicalUnit) {
                    case Keyword:
                    case ContextualKeyword:
                        switch (scanner.Keyword) {
						case Public:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Public);
                            nextLexicalUnit(true);
                            break;

                        case Protected:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Protected);
                            nextLexicalUnit(true);
                            break;

                        case Private:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Private);
                            nextLexicalUnit(true);
                            break;

                        case Abstract:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Abstract);
                            nextLexicalUnit(true);
                            break;

                        case Override:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Override);
                            nextLexicalUnit(true);
                            break;

                        case Virtual:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Virtual);
                            nextLexicalUnit(true);
                            break;

                        case Native:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Native);
                            nextLexicalUnit(true);
                            break;

                        case Final:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Final);
                            nextLexicalUnit(true);
                            break;

                        case Static:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Static);
                            nextLexicalUnit(true);
                            break;

                        case Synchronized:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Synchronized);
                            nextLexicalUnit(true);
                            break;

                        case Transient:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Transient);
                            nextLexicalUnit(true);
                            break;

                        case Volatile:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            addModifier(modifiers, Modifier.Volatile);
                            nextLexicalUnit(true);
                            break;

                        case Partial:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            switch (nextLexicalUnit(true)) {
                            case Keyword:
                                switch (scanner.Keyword) {
                                case Class:
                                    nextLexicalUnit(true);
                                    members.add(parseClass(annotations, modifiers, false, true, startPosition));
                                    modifiers.clear();
                                    annotations.clear();
                                    break;

                                case Interface:
                                    nextLexicalUnit(true);
                                    members.add(parseInterface(annotations, modifiers, true, startPosition));
                                    modifiers.clear();
                                    annotations.clear();
                                    break;

                                case Enum:
                                    nextLexicalUnit(true);
                                    members.add(parseClass(annotations, modifiers, true, true, startPosition));
                                    modifiers.clear();
                                    annotations.clear();
                                    break;
                                    
                                default:
                                    throw error(ParseErrorId.ClassInterfaceEnumExpected);
                                }
                                break;

                            default:
                                members.add(parseClassMember(annotations, modifiers, true, startPosition));
                                modifiers.clear();
                                annotations.clear();
                                break;
                            }
                            break;

                        case Class:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            nextLexicalUnit(true);
                            members.add(parseClass(annotations, modifiers, false, false, startPosition));
                            modifiers.clear();
                            annotations.clear();
                            break;

                        case Interface:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            nextLexicalUnit(true);
                            members.add(parseInterface(annotations, modifiers, false, startPosition));
                            modifiers.clear();
                            annotations.clear();
                            break;

                        case Delegate:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            nextLexicalUnit(true);
                            members.add(parseDelegate(annotations, modifiers, startPosition));
                            modifiers.clear();
                            annotations.clear();
                            break;

                        case Enum:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            nextLexicalUnit(true);
                            members.add(parseClass(annotations, modifiers, true, false, startPosition));
                            modifiers.clear();
                            annotations.clear();
                            break;

                        default:
							if (modifiers.size() == 0) {
								startPosition = scanner.StartPosition;
							}
                            members.add(parseClassMember(annotations, modifiers, false, startPosition));
                            modifiers.clear();
                            annotations.clear();
                            break;
                        }
                        break;

                    case CloseBrace:
                        if (modifiers.size() > 0 || annotations.size() > 0) {
                            throw error(ParseErrorId.ClassInterfaceEnumDelegateExpected);
                        }
                        done = true;
                        break;

                    case Complement:
                        nextLexicalUnit(true);
                        members.add(parseDestructorDeclaration(annotations, modifiers));
                        modifiers.clear();
                        annotations.clear();
                        break;

                    case Identifier:
						if (modifiers.size() == 0) {
							startPosition = scanner.StartPosition;
						}
                        members.add(parseClassMember(annotations, modifiers, false, startPosition));
                        modifiers.clear();
                        annotations.clear();
                        break;

                    default:
                        throw error(ParseErrorId.ClassInterfaceEnumDelegateExpected);
                    }
                } while (!done);
            }
            if (lexicalUnit != LexicalUnit.CloseBrace) {
                throw error(ParseErrorId.CloseBraceExpected);
            }
            docCommentEndPosition = 0;
			int result = scanner.EndPosition;
            nextLexicalUnit(false);
			return result;
        }