Inheritance: java.util.AbstractSet, java.lang.Cloneable, java.io.Serializable
 private void checkAccessors(EnumSet<Modifier> modifiers, AccessorDeclarationNode get, AccessorDeclarationNode set, SyntaxNode node) {
     if (get != null && set != null) {
         if (!get.Modifiers.isEmpty() && !set.Modifiers.isEmpty()) {
             context.addError(CompileErrorId.IllegalGetOrSetModifiers, node);
         }
         if ((get.Body == null) != (set.Body == null)) {
             context.addError(CompileErrorId.IllegalGetOrSetBody, node);
         }
     } else if (get != null) {
         if (!get.Modifiers.isEmpty()) {
             context.addError(CompileErrorId.IllegalGetOrSetModifiers, node);
         }
         if (!modifiers.contains(Modifier.Abstract) && get.Body == null) {
             context.addError(CompileErrorId.IllegalGetOrSetBody, node);
         }
     } else {
         if (!set.Modifiers.isEmpty()) {
             context.addError(CompileErrorId.IllegalGetOrSetModifiers, node);
         }
         if (!modifiers.contains(Modifier.Abstract) && set.Body == null) {
             context.addError(CompileErrorId.IllegalGetOrSetBody, node);
         }
     }
 }
        private void setPropertyOrIndexerModifiers(AccessorDeclarationNode accessor, EnumSet<Modifier> propertyModifiers,
                MethodBuilder methodBuilder) {
            var protectionSet = false;
            var isFinal = true;
            var modifiers = accessor.Modifiers;
            foreach (var mod in modifiers) {
                switch (mod) {
                case Public:
                    if (methodBuilder.IsPrivate || methodBuilder.IsProtected) {
                        context.addError(CompileErrorId.PublicProtectedPrivate, accessor);
                    } else {
                        methodBuilder.setPublic(true);
                        protectionSet = true;
                    }
                    break;

                case Private:
                    if (methodBuilder.IsPublic || methodBuilder.IsProtected) {
                        context.addError(CompileErrorId.PublicProtectedPrivate, accessor);
                    } else {
                        methodBuilder.setPrivate(true);
                        protectionSet = true;
                    }
                    isFinal = false;
                    break;
                    
                case Protected:
                    if (methodBuilder.IsPrivate || methodBuilder.IsPublic) {
                        context.addError(CompileErrorId.PublicProtectedPrivate, accessor);
                    } else {
                        methodBuilder.setProtected(true);
                        protectionSet = true;
                    }
                    break;
                default:
                    context.addError(CompileErrorId.UnexpectedModifier, accessor, mod.toString().toLowerCase());
                    break;
                }
            }
            foreach (var mod in propertyModifiers) {
                switch (mod) {
                case Public:
                    if (!protectionSet) {
                        methodBuilder.setPublic(true);
                    }
                    break;

                case Private:
                    if (methodBuilder.IsPublic || methodBuilder.IsProtected) {
                        context.addError(CompileErrorId.PublicProtectedPrivate, accessor);
                    } else {
                        if (!protectionSet) {
                            methodBuilder.setPrivate(true);
                        }
                    }
                    break;
                    
                case Protected:
                    if (methodBuilder.IsPublic) {
                        context.addError(CompileErrorId.PublicProtectedPrivate, accessor);
                    } else {
                        if (!protectionSet) {
                            methodBuilder.setProtected(true);
                        }
                    }
                    break;

                case Final:
                    methodBuilder.setFinal(true);
                    break;
                    
                case Abstract:
                    if (methodBuilder.IsFinal || methodBuilder.IsStatic) {
                        context.addError(CompileErrorId.FinalAbstractStaticMethod, accessor);
                    } else {
                        methodBuilder.setAbstract(true);
                    }
                    isFinal = false;
                    break;

                case Static:
                    if (methodBuilder.IsAbstract) {
                        context.addError(CompileErrorId.FinalAbstractStaticMethod, accessor);
                    } else {
                        methodBuilder.setStatic(true);
                    }
                    break;

                case Synchronized:
                    methodBuilder.setSynchronized(true);
                    break;

                case Native:
                    methodBuilder.setNative(true);
                    break;

                case Strictfp:
                    methodBuilder.setStrict(true);
                    break;

                case Virtual:
                case Override:
                    isFinal = false;
                    break;

                default:
                    context.addError(CompileErrorId.UnexpectedModifier, accessor, mod.toString().toLowerCase());
                    break;
                }
            }
            methodBuilder.setFinal(isFinal);
        }
        private ITypeMember parseFieldOrPropertyOrMethod(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers,
                bool partial, TypeReferenceNode type, int startPosition) {
            if (!isIdentifier(lexicalUnit)) {
                throw error(ParseErrorId.IdentifierExpected);
            }
            int sp = scanner.StartPosition;
            int len = getLexicalUnitLength();
            saveScannerState();
            var typeParameters = new ArrayList<SimpleNameTypeReferenceNode>();
            nextLexicalUnit(true);
            parseTypeParameters(typeParameters);
			Modifier setterAccess = checkSetterAccess();
			bool forceAsField = false;
			if (lexicalUnit == LexicalUnit.Multiply) {
				forceAsField = true;
                nextLexicalUnit(true);			
			}
            switch (lexicalUnit) {
            case OpenParenthesis:
				if (setterAccess != Modifier.Public || forceAsField) {
					throw error(ParseErrorId.IdentifierExpected);
				}
                var methodDeclaration = new MethodDeclarationNode { IsPartial = partial, ReturnType = type, NameOffset = sp, NameLength = len,
						StartPosition = startPosition };
                if (docCommentEndPosition > 0) {
                    methodDeclaration.DocumentationOffset = docCommentStartPosition;
                    methodDeclaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
                    docCommentEndPosition = 0;
                }
                setSavedScannerState(methodDeclaration);
                methodDeclaration.Modifiers.addAll(modifiers);
                methodDeclaration.Annotations.addAll(annotations);
                foreach (var t in typeParameters) {
                    if (t.TypeReferenceKind != TypeReferenceKind.SimpleName || t.TypeArguments.size() > 0) {
                        throw error(ParseErrorId.SimpleNameExpected);
                    }
                    methodDeclaration.TypeParameters.add((SimpleNameTypeReferenceNode)t);
                }

                if (nextLexicalUnit(true) != LexicalUnit.CloseParenthesis) {
                    parseFormalParameters(methodDeclaration.Parameters, LexicalUnit.CloseParenthesis);
                } else {
                    nextLexicalUnit(true);
                }
                parseTypeParameterConstraintsClauses(methodDeclaration.ConstraintsClauses);
                switch (lexicalUnit) {
                case OpenBrace:
                    methodDeclaration.Body = parseBlockStatement();
					methodDeclaration.EndPosition = methodDeclaration.Body.EndPosition;
                    break;

                case SemiColon:
					methodDeclaration.EndPosition = scanner.EndPosition;
                    nextLexicalUnit(true);
                    break;

                default:
                    throw error(ParseErrorId.OpenBraceExpected);
                }
                return methodDeclaration;

            case OpenBrace:
				if (setterAccess != Modifier.Public || forceAsField) {
					throw error(ParseErrorId.IdentifierExpected);
				}
                var propertyDeclaration = new PropertyDeclarationNode { Type = type, NameOffset = sp, NameLength = len,
						StartPosition = startPosition };
                if (docCommentEndPosition > 0) {
                    propertyDeclaration.DocumentationOffset = docCommentStartPosition;
                    propertyDeclaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
                    docCommentEndPosition = 0;
                }
                setSavedScannerState(propertyDeclaration);
                propertyDeclaration.Modifiers.addAll(modifiers);
                nextLexicalUnit(true);
                parseAccessorDeclaration(propertyDeclaration, false);
                if (lexicalUnit != LexicalUnit.CloseBrace) {
                    parseAccessorDeclaration(propertyDeclaration, false);
                }
                docCommentEndPosition = 0;
				propertyDeclaration.EndPosition = scanner.EndPosition;
                nextLexicalUnit(false);
                return propertyDeclaration;

            case Assign: {
				if (setterAccess != Modifier.Public || forceAsField) {
					throw error(ParseErrorId.IdentifierExpected);
				}
                var declaration = new FieldDeclarationNode { Type = type, StartPosition = startPosition };
                if (docCommentEndPosition > 0) {
                    declaration.DocumentationOffset = docCommentStartPosition;
                    declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
                    docCommentEndPosition = 0;
                }
                setSavedScannerState(declaration);
                declaration.Modifiers.addAll(modifiers);
                declaration.Annotations.addAll(annotations);
                nextLexicalUnit(true);
                var decl = new VariableDeclaratorNode { NameOffset = sp, NameLength = len };
                setSavedScannerState(decl);
                decl.Value = parseFieldInitializer();
                decl.EndPosition = decl.Value.EndPosition;
                declaration.Declarators.add(decl);
                while (lexicalUnit == LexicalUnit.Comma) {
                    if (!isIdentifier(nextLexicalUnit(true))) {
                        throw error(ParseErrorId.IdentifierExpected);
                    }
                    decl = new VariableDeclaratorNode { NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength() };
                    setScannerState(decl);
                    decl.EndPosition = scanner.EndPosition;
                    declaration.Declarators.add(decl);
                    if (nextLexicalUnit(true) == LexicalUnit.Assign) {
                        nextLexicalUnit(true);
                        decl.Value = parseFieldInitializer();
                        decl.EndPosition = decl.Value.EndPosition;
                    }
                }
                docCommentEndPosition = 0;
                declaration.EndPosition = parseSemiColon(false, false);
                return declaration;
            }

            case Comma: {
				if (setterAccess != Modifier.Public || forceAsField) {
					throw error(ParseErrorId.IdentifierExpected);
				}
                var declaration = new FieldDeclarationNode { Type = type, StartPosition = startPosition };
                if (docCommentEndPosition > 0) {
                    declaration.DocumentationOffset = docCommentStartPosition;
                    declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
                    docCommentEndPosition = 0;
                }
                setSavedScannerState(declaration);
                declaration.Modifiers.addAll(modifiers);
                declaration.Annotations.addAll(annotations);
                var decl = new VariableDeclaratorNode { NameOffset = sp, NameLength = len };
                setSavedScannerState(decl);
                decl.EndPosition = sp + len;
                declaration.Declarators.add(decl);
                do {
                    if (!isIdentifier(nextLexicalUnit(true))) {
                        throw error(ParseErrorId.IdentifierExpected);
                    }
                    decl = new VariableDeclaratorNode { NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength() };
                    setScannerState(decl);
                    declaration.Declarators.add(decl);
                    decl.EndPosition = scanner.EndPosition;
                    if (nextLexicalUnit(true) == LexicalUnit.Assign) {
                        nextLexicalUnit(true);
                        decl.Value = parseFieldInitializer();
                        decl.EndPosition = decl.Value.EndPosition;
                    }
                } while (lexicalUnit == LexicalUnit.Comma);
                docCommentEndPosition = 0;
                declaration.EndPosition = parseSemiColon(false, false);
                return declaration;
            }

            case SemiColon: {
				if ((modifiers.contains(Modifier.Public) || modifiers.contains(Modifier.Protected)) && !forceAsField) {
					var propertyShortDeclaration = new PropertyDeclarationNode { Type = type, NameOffset = sp, NameLength = len,
							StartPosition = startPosition };
					if (docCommentEndPosition > 0) {
						propertyShortDeclaration.DocumentationOffset = docCommentStartPosition;
						propertyShortDeclaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
						docCommentEndPosition = 0;
					}
					setSavedScannerState(propertyShortDeclaration);
					propertyShortDeclaration.Modifiers.addAll(modifiers);
					fakeParseShortProperty(propertyShortDeclaration, setterAccess, false);
					docCommentEndPosition = 0;
					propertyShortDeclaration.EndPosition = scanner.EndPosition;
					nextLexicalUnit(false);
					return propertyShortDeclaration;
				}
                var declaration = new FieldDeclarationNode { Type = type, StartPosition = startPosition };
                if (docCommentEndPosition > 0) {
                    declaration.DocumentationOffset = docCommentStartPosition;
                    declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
                    docCommentEndPosition = 0;
                }
                setSavedScannerState(declaration);
                declaration.Modifiers.addAll(modifiers);
                declaration.Annotations.addAll(annotations);
                var decl = new VariableDeclaratorNode { NameOffset = sp, NameLength = len };
                setSavedScannerState(decl);
                decl.EndPosition = sp + len;
                declaration.Declarators.add(decl);
                docCommentEndPosition = 0;
				declaration.EndPosition = scanner.EndPosition;
                nextLexicalUnit(false);
                return declaration;
            }

            default:
                throw error(ParseErrorId.UnexpectedLexicalUnit);
            }
        }
        private ITypeMember parseConstructorDeclaration(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers,
                bool partial, int position, int length, List<SimpleNameTypeReferenceNode> typeParameters, int startPosition) {
            var declaration = new ConstructorDeclarationNode { NameOffset = position, NameLength = length, StartPosition = startPosition };
            if (docCommentEndPosition > 0) {
                declaration.DocumentationOffset = docCommentStartPosition;
                declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
                docCommentEndPosition = 0;
            }
            setSavedScannerState(declaration);
            declaration.Modifiers.addAll(modifiers);
            declaration.Annotations.addAll(annotations);
            declaration.TypeParameters.addAll(typeParameters);
            if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                parseFormalParameters(declaration.Parameters, LexicalUnit.CloseParenthesis);
            } else {
                nextLexicalUnit(true);
            }
            if (lexicalUnit == LexicalUnit.Colon) {
                if (modifiers.contains(Modifier.Static)) {
                    throw error(ParseErrorId.UnexpectedLexicalUnit);
                }
                bool isSuper = false;
                switch (nextLexicalUnit(true)) {
                case Keyword:
                    switch (scanner.Keyword) {
                    case Super:
                        isSuper = true;
                        break;

                    case This:
                        break;

                    default:
                        throw error(ParseErrorId.SuperOrThisExpected);
                    }
                    break;

                default:
                    throw error(ParseErrorId.SuperOrThisExpected);
                }
                saveScannerState();
                if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) {
                    throw error(ParseErrorId.OpenParenthesisExpected);
                }
                var initializer = new ConstructorInitializerNode();
                setSavedScannerState(initializer);
                initializer.IsSuper = isSuper;
                declaration.Initializer = initializer;
                nextLexicalUnit(true);
                initializer.EndPosition = parseArguments(initializer.Arguments);
            }
            parseTypeParameterConstraintsClauses(declaration.ConstraintsClauses);
            switch (lexicalUnit) {
            case OpenBrace:
                declaration.Body = parseBlockStatement();
				declaration.EndPosition = declaration.Body.EndPosition;
                break;

            case SemiColon:
				declaration.EndPosition = scanner.StartPosition;
                docCommentEndPosition = 0;
                nextLexicalUnit(true);
                break;

            default:
                throw error(ParseErrorId.OpenBraceExpected);
            }
            return declaration;
        }
 private ITypeMember parseClassMember(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers, bool partial,
 		int startPosition) {
     var restorePoint = this.createRestorePoint();
     int sp = scanner.StartPosition;
     int len = getLexicalUnitLength();
     saveScannerState();
     switch (nextLexicalUnit(true)) {
     case OpenParenthesis:
         nextLexicalUnit(true);
         return parseConstructorDeclaration(annotations, modifiers, partial, sp, len,
             Collections.emptyList<SimpleNameTypeReferenceNode>(), startPosition);
     case LessThan:
         var typeParameters = new ArrayList<SimpleNameTypeReferenceNode>();
         if (parseTypeParameters(typeParameters, false)) {
             if (lexicalUnit == LexicalUnit.OpenParenthesis) {
                 return parseConstructorDeclaration(annotations, modifiers, partial, sp, len, typeParameters, startPosition);
             }
         }
         goto default;
         
     default:
         this.restore(restorePoint);
         var type = parseType(true, true);
         if (lexicalUnit == LexicalUnit.Keyword && scanner.Keyword == Keyword.This) {
             saveScannerState();
             nextLexicalUnit(true);
             return parseIndexerDeclaration(annotations, modifiers, partial, type, false, startPosition);
         }
         return parseFieldOrPropertyOrMethod(annotations, modifiers, partial, type, startPosition);
     }
 }
        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;
        }
 private void addModifier(EnumSet<Modifier> modifiers, Modifier modifier) {
     if (modifiers.contains(modifier)) {
         addError(ParseErrorId.DuplicateModifier, modifier.toString().toLowerCase());
     } else {
         modifiers.add(modifier);
     }
 }
 private ClassDeclarationNode parseClass(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers, bool isEnum,
         bool partial, int startPosition) {
     if (!isIdentifier(lexicalUnit)) {
         throw error(ParseErrorId.IdentifierExpected);
     }
     var result = new ClassDeclarationNode { IsEnum = isEnum, IsPartial = partial,
             NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength(), StartPosition = startPosition };
     if (docCommentEndPosition > 0) {
         result.DocumentationOffset = docCommentStartPosition;
         result.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
         docCommentEndPosition = 0;
     }
     setScannerState(result);
     result.Modifiers.addAll(modifiers);
     result.Annotations.addAll(annotations);
     nextLexicalUnit(true);
     if (!isEnum) {
         parseTypeParameters(result.TypeParameters);
     }
     parseClassBase(result.ClassBase);
     if (!isEnum) {
         parseTypeParameterConstraintsClauses(result.ConstraintsClauses);
     }
     if (lexicalUnit != LexicalUnit.OpenBrace) {
         throw error(ParseErrorId.OpenBraceExpected);
     }
     result.EndPosition = parseClassBody(annotations, modifiers, isEnum, result.Members);
     if (lexicalUnit == LexicalUnit.SemiColon) {
         nextLexicalUnit(false);
     }
     return result;
 }
        private IndexerDeclarationNode parseIndexerDeclaration(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers,
                bool partial, TypeReferenceNode type, bool inInterface, int startPosition) {
            var declaration = new IndexerDeclarationNode { Type = type, StartPosition = startPosition };
            if (docCommentEndPosition > 0) {
                declaration.DocumentationOffset = docCommentStartPosition;
                declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
                docCommentEndPosition = 0;
            }
            setSavedScannerState(declaration);
            declaration.Modifiers.addAll(modifiers);
            declaration.Annotations.addAll(annotations);
            if (lexicalUnit != LexicalUnit.OpenBracket) {
                throw error(ParseErrorId.OpenBracketExpected);
            }
            if (nextLexicalUnit(true) != LexicalUnit.CloseBracket) {
                parseFormalParameters(declaration.Parameters, LexicalUnit.CloseBracket);
            } else {
                nextLexicalUnit(true);
            }
			Modifier setterAccess = Modifier.Public;
			if (lexicalUnit == LexicalUnit.Xor) {
				if (!inInterface) {
					throw error(ParseErrorId.OpenBraceExpected);
				}
				setterAccess = Modifier.Private;
                nextLexicalUnit(true);			
			}
			if (lexicalUnit == LexicalUnit.SemiColon) {
				if (!inInterface) {
					throw error(ParseErrorId.OpenBraceExpected);
				}
				fakeParseShortProperty(declaration, setterAccess, inInterface);
				docCommentEndPosition = 0;
				declaration.EndPosition = scanner.EndPosition;
				nextLexicalUnit(false);
				return declaration;
			}
            if (lexicalUnit != LexicalUnit.OpenBrace) {
                throw error(ParseErrorId.OpenBraceExpected);
            }
            nextLexicalUnit(true);
            parseAccessorDeclaration(declaration, inInterface);
            if (lexicalUnit != LexicalUnit.CloseBrace) {
                parseAccessorDeclaration(declaration, inInterface);
            }
            docCommentEndPosition = 0;
			declaration.EndPosition = scanner.EndPosition;
            nextLexicalUnit(false);
            return declaration;
        }
        private IInterfaceMember parseInterfaceMember(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers, int startPosition) {
            var type = parseType(true, true);
            if (lexicalUnit == LexicalUnit.Keyword && scanner.Keyword == Keyword.This) {
                saveScannerState();
                nextLexicalUnit(true);
                return parseIndexerDeclaration(annotations, modifiers, false, type, true, startPosition);
            }
            if (!isIdentifier(lexicalUnit)) {
                throw error(ParseErrorId.IdentifierExpected);
            }
            int sp = scanner.StartPosition;
            int len = getLexicalUnitLength();
            saveScannerState();
			var lexicalUnitShorter = nextLexicalUnit(true);
            if (lexicalUnitShorter == LexicalUnit.OpenBrace) {
                var declaration = new PropertyDeclarationNode { Type = type, NameOffset = sp, NameLength = len, StartPosition = startPosition };
                if (docCommentEndPosition > 0) {
                    declaration.DocumentationOffset = docCommentStartPosition;
                    declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
                    docCommentEndPosition = 0;
                }
                setSavedScannerState(declaration);
                declaration.Modifiers.addAll(modifiers);
                declaration.Annotations.addAll(annotations);
                nextLexicalUnit(true);
                parseAccessorDeclaration(declaration, true);
                if (lexicalUnit != LexicalUnit.CloseBrace) {
                    parseAccessorDeclaration(declaration, true);
                }
				declaration.EndPosition = scanner.EndPosition;
                nextLexicalUnit(false);
                return declaration;
			} 
			Modifier setterAccess = Modifier.Public;
			if (lexicalUnitShorter == LexicalUnit.Xor) {
				setterAccess = Modifier.Private;
				lexicalUnitShorter = nextLexicalUnit(true);
			}
			if (lexicalUnitShorter == LexicalUnit.SemiColon) {
				var propertyShortDeclaration = new PropertyDeclarationNode { Type = type, NameOffset = sp, NameLength = len,
						StartPosition = startPosition };
				if (docCommentEndPosition > 0) {
					propertyShortDeclaration.DocumentationOffset = docCommentStartPosition;
					propertyShortDeclaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
					docCommentEndPosition = 0;
				}
				setSavedScannerState(propertyShortDeclaration);
				propertyShortDeclaration.Modifiers.addAll(modifiers);
                propertyShortDeclaration.Annotations.addAll(annotations);
				fakeParseShortProperty(propertyShortDeclaration, setterAccess, true);
				docCommentEndPosition = 0;
				propertyShortDeclaration.EndPosition = scanner.EndPosition;
				nextLexicalUnit(false);
				return propertyShortDeclaration;
			}
			var declaration = new MethodDeclarationNode { ReturnType = type, NameOffset = sp, NameLength = len, StartPosition = startPosition };
			if (docCommentEndPosition > 0) {
				declaration.DocumentationOffset = docCommentStartPosition;
				declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
				docCommentEndPosition = 0;
			}
			setSavedScannerState(declaration);
			declaration.Modifiers.addAll(modifiers);
			declaration.Annotations.addAll(annotations);
			parseTypeParameters(declaration.TypeParameters);
			if (lexicalUnit != LexicalUnit.OpenParenthesis) {
				throw error(ParseErrorId.OpenParenthesisExpected);
			}
			if (nextLexicalUnit(true) != LexicalUnit.CloseParenthesis) {
				parseFormalParameters(declaration.Parameters, LexicalUnit.CloseParenthesis);
			} else {
				nextLexicalUnit(true);
			}
			if (lexicalUnit == LexicalUnit.Assign) {
				nextLexicalUnit(true);
				declaration.DefaultValue = parseAnnotationValue();
			} else {
				parseTypeParameterConstraintsClauses(declaration.ConstraintsClauses);
			}
			docCommentEndPosition = 0;
			declaration.EndPosition = parseSemiColon(false, false);
			return declaration;
        }
 private DelegateDeclarationNode parseDelegate(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers, int startPosition) {
     var declaration = new DelegateDeclarationNode { ReturnType = parseType(true, true), StartPosition = startPosition };
     if (docCommentEndPosition > 0) {
         declaration.DocumentationOffset = docCommentStartPosition;
         declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
         docCommentEndPosition = 0;
     }
     declaration.Modifiers.addAll(modifiers);
     declaration.Annotations.addAll(annotations);
     if (!isIdentifier(lexicalUnit)) {
         throw error(ParseErrorId.IdentifierExpected);
     }
     setScannerState(declaration);
     declaration.NameOffset = scanner.StartPosition;
     declaration.NameLength = getLexicalUnitLength();
     nextLexicalUnit(true);
     parseTypeParameters(declaration.TypeParameters);
     if (lexicalUnit != LexicalUnit.OpenParenthesis) {
         throw error(ParseErrorId.OpenParenthesisExpected);
     }
     if (nextLexicalUnit(true) != LexicalUnit.CloseParenthesis) {
         parseFormalParameters(declaration.Parameters, LexicalUnit.CloseParenthesis);
     } else {
         nextLexicalUnit(true);
     }
     parseTypeParameterConstraintsClauses(declaration.ConstraintsClauses);
     docCommentEndPosition = 0;
     declaration.EndPosition = parseSemiColon(false, false);
     return declaration;
 }
        private ITypeMember parseDestructorDeclaration(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers) {
            if (!isIdentifier(lexicalUnit)) {
                throw error(ParseErrorId.IdentifierExpected);
            }
            var declaration = new DestructorDeclarationNode { NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength() };
            if (docCommentEndPosition > 0) {
                declaration.DocumentationOffset = docCommentStartPosition;
                declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
                docCommentEndPosition = 0;
            }
            setScannerState(declaration);
            declaration.Modifiers.addAll(modifiers);
            declaration.Annotations.addAll(annotations);
            if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) {
                throw error(ParseErrorId.OpenParenthesisExpected);
            }
            if (nextLexicalUnit(true) != LexicalUnit.CloseParenthesis) {
                throw error(ParseErrorId.CloseParenthesisExpected);
            }
            nextLexicalUnit(true);
            switch (lexicalUnit) {
            case OpenBrace:
                declaration.Body = parseBlockStatement();
				declaration.EndPosition = declaration.Body.EndPosition;
                break;

            case SemiColon:
				declaration.EndPosition = scanner.StartPosition;
                docCommentEndPosition = 0;
                nextLexicalUnit(true);
                break;

            default:
                throw error(ParseErrorId.OpenBraceExpected);
            }
            return declaration;
        }