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 LocalDeclarationStatementNode parseLocalDeclarationStatement(TypeReferenceNode type, bool eatSemiColon) {
            var declaration = new LocalDeclarationStatementNode();
            setSavedScannerState(declaration);
            declaration.Type = type;
            var declarator = new VariableDeclaratorNode();
            setScannerState(declarator);
            declarator.NameOffset = scanner.StartPosition;
            declarator.NameLength = getLexicalUnitLength();
            declaration.Declarators.add(declarator);
            nextLexicalUnit(true);
            if (lexicalUnit == LexicalUnit.Assign) {
                nextLexicalUnit(true);
                declarator.Value = parseLocalVariableInitializer();
                declarator.EndPosition = declarator.Value.EndPosition;
            } else {
            	declarator.EndPosition = declarator.NameOffset + declarator.NameLength;
            }
            int endPosition = declarator.EndPosition;
            while (lexicalUnit == LexicalUnit.Comma) {
                if (!isIdentifier(nextLexicalUnit(true))) {
                    throw error(ParseErrorId.IdentifierExpected);
                }
                declarator = new VariableDeclaratorNode();
                setScannerState(declarator);
                declarator.NameOffset = scanner.StartPosition;
                declarator.NameLength = getLexicalUnitLength();
                declaration.Declarators.add(declarator);
                nextLexicalUnit(true);
                if (lexicalUnit == LexicalUnit.Assign) {
                    nextLexicalUnit(true);
                    declarator.Value = parseLocalVariableInitializer();
	                declarator.EndPosition = declarator.Value.EndPosition;
	            } else {
	            	declarator.EndPosition = declarator.NameOffset + declarator.NameLength;
                }
                endPosition = declarator.EndPosition;
            }
            if (eatSemiColon) {
                declaration.EndPosition = parseSemiColon(false, false);
            } else {
            	declaration.EndPosition = endPosition;
            }
            return declaration;
        }