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 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 void addModifier(EnumSet<Modifier> modifiers, Modifier modifier) {
     if (modifiers.contains(modifier)) {
         addError(ParseErrorId.DuplicateModifier, modifier.toString().toLowerCase());
     } else {
         modifiers.add(modifier);
     }
 }