/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Technical University Berlin - extended API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.parser;

import java.util.List;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.IJavadocTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Javadoc;
import org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.JavadocArgumentExpression;
import org.eclipse.jdt.internal.compiler.ast.JavadocArrayQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.JavadocArraySingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference;
import org.eclipse.jdt.internal.compiler.ast.JavadocImplicitTypeReference;
import org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend;
import org.eclipse.jdt.internal.compiler.ast.JavadocQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.JavadocReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.JavadocSingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.JavadocSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.util.Util;

/**
 * Parser specialized for decoding javadoc comments
 */
public class JavadocParser extends AbstractCommentParser {
	private static final JavadocSingleNameReference[] NO_SINGLE_NAME_REFERENCE = new JavadocSingleNameReference[0];
	private static final JavadocSingleTypeReference[] NO_SINGLE_TYPE_REFERENCE = new JavadocSingleTypeReference[0];
	private static final JavadocQualifiedTypeReference[] NO_QUALIFIED_TYPE_REFERENCE = new JavadocQualifiedTypeReference[0];
	private static final TypeReference[] NO_TYPE_REFERENCE = new TypeReference[0];
	private static final Expression[] NO_EXPRESSION = new Expression[0];

	// Public fields
	public Javadoc docComment;

	// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
	// Store param references for tag with invalid syntax
	private int invalidParamReferencesPtr = -1;
	private ASTNode[] invalidParamReferencesStack;

	// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=153399
	// Store value tag positions
	private long validValuePositions, invalidValuePositions;

	// returns whether this JavadocParser should report errors or not (overrides reportProblems)
	// see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=192449"
	public boolean shouldReportProblems = true;
	
	// flag to let the parser know that the current tag is waiting for a description
	// see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=222900"
	private int tagWaitingForDescription;

	public JavadocParser(Parser sourceParser) {
		super(sourceParser);
		this.kind = COMPIL_PARSER | TEXT_VERIF;
		if (sourceParser != null && sourceParser.options != null) {
			this.setJavadocPositions = sourceParser.options.processAnnotations;
		}
	}

	/* (non-Javadoc)
	 * Returns true if tag @deprecated is present in javadoc comment.
	 *
	 * If javadoc checking is enabled, will also construct an Javadoc node, which will be stored into Parser.javadoc
	 * slot for being consumed later on.
	 */
	public boolean checkDeprecation(int commentPtr) {

		// Store javadoc positions
		this.javadocStart = this.sourceParser.scanner.commentStarts[commentPtr];
		this.javadocEnd = this.sourceParser.scanner.commentStops[commentPtr]-1;
		this.firstTagPosition = this.sourceParser.scanner.commentTagStarts[commentPtr];
		this.validValuePositions = -1;
		this.invalidValuePositions = -1;
		this.tagWaitingForDescription = NO_TAG_VALUE;

		// Init javadoc if necessary
		if (this.checkDocComment) {
			this.docComment = new Javadoc(this.javadocStart, this.javadocEnd);
		} else if (this.setJavadocPositions) {
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=189459
			// if annotation processors are there, javadoc object is required but
			// they need not be resolved
			this.docComment = new Javadoc(this.javadocStart, this.javadocEnd);
			this.docComment.bits &= ~ASTNode.ResolveJavadoc;
		} else {
			this.docComment = null;
		}

		// If there's no tag in javadoc, return without parsing it
		if (this.firstTagPosition == 0) {
			switch (this.kind & PARSER_KIND) {
				case COMPIL_PARSER:
				case SOURCE_PARSER:
					return false;
			}
		}

		// Parse
		try {
			this.source = this.sourceParser.scanner.source;
			this.scanner.setSource(this.source); // updating source in scanner
			if (this.checkDocComment) {
				// Initialization
				this.scanner.lineEnds = this.sourceParser.scanner.lineEnds;
				this.scanner.linePtr = this.sourceParser.scanner.linePtr;
				this.lineEnds = this.scanner.lineEnds;
				commentParse();
			} else {

				// Parse comment
				Scanner sourceScanner = this.sourceParser.scanner;
				int firstLineNumber = Util.getLineNumber(this.javadocStart, sourceScanner.lineEnds, 0, sourceScanner.linePtr);
				int lastLineNumber = Util.getLineNumber(this.javadocEnd, sourceScanner.lineEnds, 0, sourceScanner.linePtr);
				this.index = this.javadocStart +3;

				// scan line per line, since tags must be at beginning of lines only
				this.deprecated = false;
				nextLine : for (int line = firstLineNumber; line <= lastLineNumber; line++) {
					int lineStart = line == firstLineNumber
							? this.javadocStart + 3 // skip leading /**
							: this.sourceParser.scanner.getLineStart(line);
					this.index = lineStart;
					this.lineEnd = line == lastLineNumber
							? this.javadocEnd - 2 // remove trailing * /
							: this.sourceParser.scanner.getLineEnd(line);
					nextCharacter : while (this.index < this.lineEnd) {
						char c = readChar(); // consider unicodes
						switch (c) {
							case '*' :
							case '\u000c' :	/* FORM FEED               */
							case ' ' :			/* SPACE                   */
							case '\t' :			/* HORIZONTAL TABULATION   */
							case '\n' :			/* LINE FEED   */
							case '\r' :			/* CR */
								// do nothing for space or '*' characters
						        continue nextCharacter;
						    case '@' :
						    	parseSimpleTag();
						    	if (this.tagValue == TAG_DEPRECATED_VALUE) {
						    		if (this.abort) break nextCharacter;
						    	}
						}
			        	continue nextLine;
					}
				}
				return this.deprecated;
			}
		} finally {
			this.source = null; // release source as soon as finished
			this.scanner.setSource((char[]) null); //release source in scanner
		}
		return this.deprecated;
	}

	@Override
	protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException {
		try {
			TypeReference argTypeRef = (TypeReference) typeRef;
			if (dim > 0) {
				long pos = (((long) argTypeRef.sourceStart) << 32) + argTypeRef.sourceEnd;
				if (typeRef instanceof JavadocSingleTypeReference) {
					JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) typeRef;
					argTypeRef = new JavadocArraySingleTypeReference(singleRef.token, dim, pos);
				} else {
					JavadocQualifiedTypeReference qualifRef = (JavadocQualifiedTypeReference) typeRef;
					argTypeRef = new JavadocArrayQualifiedTypeReference(qualifRef, dim);
				}
			}
			int argEnd = argTypeRef.sourceEnd;
			if (dim > 0) {
				argEnd = (int) dimPositions[dim-1];
				if (isVarargs) {
					argTypeRef.bits |= ASTNode.IsVarArgs; // set isVarArgs
				}
			}
			if (argNamePos >= 0) argEnd = (int) argNamePos;
			return new JavadocArgumentExpression(name, argTypeRef.sourceStart, argEnd, argTypeRef);
		}
		catch (ClassCastException ex) {
			throw new InvalidInputException();
		}
	}

	@Override
	protected Object createFieldReference(Object receiver) throws InvalidInputException {
		try {
			// Get receiver type
			TypeReference typeRef = (TypeReference) receiver;
			if (typeRef == null) {
				char[] name = this.sourceParser.compilationUnit.getMainTypeName();
				typeRef = new JavadocImplicitTypeReference(name, this.memberStart);
			}
			// Create field
			JavadocFieldReference field = new JavadocFieldReference(this.identifierStack[0], this.identifierPositionStack[0]);
			field.receiver = typeRef;
			field.tagSourceStart = this.tagSourceStart;
			field.tagSourceEnd = this.tagSourceEnd;
			field.tagValue = this.tagValue;
			return field;
		}
		catch (ClassCastException ex) {
			throw new InvalidInputException();
		}
	}

	@Override
	protected Object createMethodReference(Object receiver, List arguments) throws InvalidInputException {
		try {
			// Get receiver type
			TypeReference typeRef = (TypeReference) receiver;
			// Decide whether we have a constructor or not
			boolean isConstructor = false;
			int length = this.identifierLengthStack[0];	// may be > 1 for member class constructor reference
			if (typeRef == null) {
				char[] name = this.sourceParser.compilationUnit.getMainTypeName();
				TypeDeclaration typeDecl = getParsedTypeDeclaration();
				if (typeDecl != null) {
					name = typeDecl.name;
				}
				isConstructor = CharOperation.equals(this.identifierStack[length-1], name);
				typeRef = new JavadocImplicitTypeReference(name, this.memberStart);
			} else {
				if (typeRef instanceof JavadocSingleTypeReference) {
					char[] name = ((JavadocSingleTypeReference)typeRef).token;
					isConstructor = CharOperation.equals(this.identifierStack[length-1], name);
				} else if (typeRef instanceof JavadocQualifiedTypeReference) {
					char[][] tokens = ((JavadocQualifiedTypeReference)typeRef).tokens;
					int last = tokens.length-1;
					isConstructor = CharOperation.equals(this.identifierStack[length-1], tokens[last]);
					if (isConstructor) {
						boolean valid = true;
						if (valid) {
							for (int i=0; i<length-1 && valid; i++) {
								valid = CharOperation.equals(this.identifierStack[i], tokens[i]);
							}
						}
						if (!valid) {
							if (this.reportProblems) {
								this.sourceParser.problemReporter().javadocInvalidMemberTypeQualification((int)(this.identifierPositionStack[0]>>>32), (int)this.identifierPositionStack[length-1], -1);
							}
							return null;
						}
					}
				} else {
					throw new InvalidInputException();
				}
			}
			// Create node
			if (arguments == null) {
				if (isConstructor) {
					JavadocAllocationExpression allocation = new JavadocAllocationExpression(this.identifierPositionStack[length-1]);
					allocation.type = typeRef;
					allocation.tagValue = this.tagValue;
					allocation.sourceEnd = this.scanner.getCurrentTokenEndPosition();
					if (length == 1) {
						allocation.qualification = new char[][] { this.identifierStack[0] };
					} else {
						System.arraycopy(this.identifierStack, 0, allocation.qualification = new char[length][], 0, length);
						allocation.sourceStart = (int) (this.identifierPositionStack[0] >>> 32);
					}
					allocation.memberStart = this.memberStart;
					return allocation;
				} else {
					JavadocMessageSend msg = new JavadocMessageSend(this.identifierStack[length-1], this.identifierPositionStack[length-1]);
					msg.receiver = typeRef;
					msg.tagValue = this.tagValue;
					msg.sourceEnd = this.scanner.getCurrentTokenEndPosition();
					return msg;
				}
			} else {
				JavadocArgumentExpression[] expressions = new JavadocArgumentExpression[arguments.size()];
				arguments.toArray(expressions);
				if (isConstructor) {
					JavadocAllocationExpression allocation = new JavadocAllocationExpression(this.identifierPositionStack[length-1]);
					allocation.arguments = expressions;
					allocation.type = typeRef;
					allocation.tagValue = this.tagValue;
					allocation.sourceEnd = this.scanner.getCurrentTokenEndPosition();
					if (length == 1) {
						allocation.qualification = new char[][] { this.identifierStack[0] };
					} else {
						System.arraycopy(this.identifierStack, 0, allocation.qualification = new char[length][], 0, length);
						allocation.sourceStart = (int) (this.identifierPositionStack[0] >>> 32);
					}
					allocation.memberStart = this.memberStart;
					return allocation;
				} else {
					JavadocMessageSend msg = new JavadocMessageSend(this.identifierStack[length-1], this.identifierPositionStack[length-1], expressions);
					msg.receiver = typeRef;
					msg.tagValue = this.tagValue;
					msg.sourceEnd = this.scanner.getCurrentTokenEndPosition();
					return msg;
				}
			}
		}
		catch (ClassCastException ex) {
			throw new InvalidInputException();
		}
	}

	@Override
	protected Object createReturnStatement() {
		return new JavadocReturnStatement(this.scanner.getCurrentTokenStartPosition(),
					this.scanner.getCurrentTokenEndPosition());
	}

	@Override
	protected void createTag() {
		this.tagValue = TAG_OTHERS_VALUE;
	}

	@Override
	protected Object createTypeReference(int primitiveToken) {
		TypeReference typeRef = null;
		int size = this.identifierLengthStack[this.identifierLengthPtr];
		if (size == 1) { // Single Type ref
			typeRef = new JavadocSingleTypeReference(
						this.identifierStack[this.identifierPtr],
						this.identifierPositionStack[this.identifierPtr],
						this.tagSourceStart,
						this.tagSourceEnd);
		} else if (size > 1) { // Qualified Type ref
			char[][] tokens = new char[size][];
			System.arraycopy(this.identifierStack, this.identifierPtr - size + 1, tokens, 0, size);
			long[] positions = new long[size];
			System.arraycopy(this.identifierPositionStack, this.identifierPtr - size + 1, positions, 0, size);
			typeRef = new JavadocQualifiedTypeReference(tokens, positions, this.tagSourceStart, this.tagSourceEnd);
		}
		return typeRef;
	}

	/*
	 * Get current parsed type declaration.
	 */
	protected TypeDeclaration getParsedTypeDeclaration() {
		int ptr = this.sourceParser.astPtr;
		while (ptr >= 0) {
			Object node = this.sourceParser.astStack[ptr];
			if (node instanceof TypeDeclaration) {
				TypeDeclaration typeDecl = (TypeDeclaration) node;
				if (typeDecl.bodyEnd == 0) { // type declaration currenly parsed
					return typeDecl;
				}
			}
			ptr--;
		}
		return null;
	}

	/*
	 * Parse @throws tag declaration and flag missing description if corresponding option is enabled
	 */
	@Override
	protected boolean parseThrows() {
		boolean valid = super.parseThrows();
		this.tagWaitingForDescription = valid && this.reportProblems ? TAG_THROWS_VALUE : NO_TAG_VALUE;
		return valid;
	}

	/*
	 * Parse @return tag declaration
	 */
	protected boolean parseReturn() {
		if (this.returnStatement == null) {
			this.returnStatement = createReturnStatement();
			return true;
		}
		if (this.reportProblems) {
			this.sourceParser.problemReporter().javadocDuplicatedReturnTag(
				this.scanner.getCurrentTokenStartPosition(),
				this.scanner.getCurrentTokenEndPosition());
		}
		return false;
	}


	protected void parseSimpleTag() {

		// Read first char
		// readChar() code is inlined to balance additional method call in checkDeprectation(int)
		char first = this.source[this.index++];
		if (first == '\\' && this.source[this.index] == 'u') {
			int c1, c2, c3, c4;
			int pos = this.index;
			this.index++;
			while (this.source[this.index] == 'u')
				this.index++;
			if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c1 < 0)
					|| ((c2 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c2 < 0)
					|| ((c3 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c3 < 0)
					|| ((c4 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c4 < 0))) {
				first = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
			} else {
				this.index = pos;
			}
		}

		// switch on first tag char
		switch (first) {
			case 'd':
		        if ((readChar() == 'e') &&
						(readChar() == 'p') && (readChar() == 'r') &&
						(readChar() == 'e') && (readChar() == 'c') &&
						(readChar() == 'a') && (readChar() == 't') &&
						(readChar() == 'e') && (readChar() == 'd')) {
					// ensure the tag is properly ended: either followed by a space, a tab, line end or asterisk.
					char c = readChar();
					if (ScannerHelper.isWhitespace(c) || c == '*') {
						this.abort = true;
			    		this.deprecated = true;
						this.tagValue = TAG_DEPRECATED_VALUE;
					}
		        }
				break;
		}
	}

	@Override
	protected boolean parseTag(int previousPosition) throws InvalidInputException {

		// Complain when tag is missing a description
		// Note that if the parse of an inline tag has already started, consider it
		// as the expected description, hence do not report any warning
		switch (this.tagWaitingForDescription) {
			case TAG_PARAM_VALUE:
			case TAG_THROWS_VALUE:
				if (!this.inlineTagStarted) {
					int start = (int) (this.identifierPositionStack[0] >>> 32);
					int end = (int) this.identifierPositionStack[this.identifierPtr];
					this.sourceParser.problemReporter().javadocMissingTagDescriptionAfterReference(start, end, this.sourceParser.modifiers);
				}
				break;
			case NO_TAG_VALUE:
				break;
			default:
				if (!this.inlineTagStarted) {
					this.sourceParser.problemReporter().javadocMissingTagDescription(TAG_NAMES[this.tagWaitingForDescription], this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
				}
				break;
		}
		this.tagWaitingForDescription = NO_TAG_VALUE;

		// Verify first character
		this.tagSourceStart = this.index;
		this.tagSourceEnd = previousPosition;
		this.scanner.startPosition = this.index;
		int currentPosition = this.index;
		char firstChar = readChar();
		switch (firstChar) {
			case ' ':
			case '*':
			case '}':
			case '#':
				// the first character is not valid, hence report invalid empty tag
				if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(previousPosition, currentPosition);
				if (this.textStart == -1) this.textStart = currentPosition;
				this.scanner.currentCharacter = firstChar;
				return false;
			default:
				if (ScannerHelper.isWhitespace(firstChar)) {
					// the first character is not valid, hence report invalid empty tag
					if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(previousPosition, currentPosition);
					if (this.textStart == -1) this.textStart = currentPosition;
					this.scanner.currentCharacter = firstChar;
					return false;
				}
				break;
		}
		
		// Read tag name
		char[] tagName = new char[32];
		int length = 0;
		char currentChar = firstChar;
		int tagNameLength = tagName.length;
		boolean validTag = true;
		tagLoop: while (true) {
			if (length == tagNameLength) {
				System.arraycopy(tagName, 0, tagName = new char[tagNameLength+32], 0, tagNameLength);
				tagNameLength = tagName.length;
			}
			tagName[length++] = currentChar;
			currentPosition = this.index;
			currentChar = readChar();
			switch (currentChar) {
				case ' ':
				case '*':
				case '}':
					// these characters mark the end of the tag reading
					break tagLoop;
				case '#':
					// invalid tag character, mark the tag as invalid but continue until the end of the tag
					validTag = false;
					break;
				default:
					if (ScannerHelper.isWhitespace(currentChar)) {
						// whitespace characters mark the end of the tag reading
						break tagLoop;
					}
					break;
			}
		}

		// Init positions
		this.tagSourceEnd = currentPosition - 1;
		this.scanner.currentCharacter = currentChar;
		this.scanner.currentPosition = currentPosition;
		this.index = this.tagSourceEnd+1;

		// Return if the tag is not valid
		if (!validTag) {
			if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(this.tagSourceStart, this.tagSourceEnd);
			if (this.textStart == -1) this.textStart = this.index;
			this.scanner.currentCharacter = currentChar;
			return false;
		}

		// Decide which parse to perform depending on tag name
		this.tagValue = TAG_OTHERS_VALUE;
		boolean valid = false;
		switch (firstChar) {
			case 'a':
				if (length == TAG_AUTHOR_LENGTH && CharOperation.equals(TAG_AUTHOR, tagName, 0, length)) {
					this.tagValue = TAG_AUTHOR_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				}else if (length == TAG_API_NOTE_LENGTH && CharOperation.equals(TAG_API_NOTE, tagName, 0, length)) {
					this.tagValue = TAG_API_NOTE_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				}
				break;
			case 'c':
				if (length == TAG_CATEGORY_LENGTH && CharOperation.equals(TAG_CATEGORY, tagName, 0, length)) {
					this.tagValue = TAG_CATEGORY_VALUE;
					if (!this.inlineTagStarted) {
						valid = parseIdentifierTag(false); // TODO (frederic) reconsider parameter value when @category will be significant in spec
					}
				} else if (length == TAG_CODE_LENGTH && this.inlineTagStarted && CharOperation.equals(TAG_CODE, tagName, 0, length)) {
					this.tagValue = TAG_CODE_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				}
				break;
			case 'd':
				if (length == TAG_DEPRECATED_LENGTH && CharOperation.equals(TAG_DEPRECATED, tagName, 0, length)) {
					this.deprecated = true;
					valid = true;
					this.tagValue = TAG_DEPRECATED_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				} else if (length == TAG_DOC_ROOT_LENGTH && CharOperation.equals(TAG_DOC_ROOT, tagName, 0, length)) {
					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=227730
					// identify @docRoot tag as a base tag that does not expect any argument
					valid = true;
					this.tagValue = TAG_DOC_ROOT_VALUE;
				}
				break;
			case 'e':
				if (length == TAG_EXCEPTION_LENGTH && CharOperation.equals(TAG_EXCEPTION, tagName, 0, length)) {
					this.tagValue = TAG_EXCEPTION_VALUE;
					if (!this.inlineTagStarted) {
						valid = parseThrows();
					}
				}
				break;
			case 'h':
				if (length == TAG_HIDDEN_LENGTH && CharOperation.equals(TAG_HIDDEN, tagName, 0, length)) {
					valid = true;
					this.tagValue = TAG_HIDDEN_VALUE;
				}
				break;
			case 'i':
				if (length == TAG_INDEX_LENGTH && CharOperation.equals(TAG_INDEX, tagName, 0, length)) {
					valid = true;
					this.tagValue = TAG_INDEX_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				} else if (length == TAG_INHERITDOC_LENGTH && CharOperation.equals(TAG_INHERITDOC, tagName, 0, length)) {
					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, @inheritDoc usage is illegal
					// outside of few block tags and the main description.
					switch (this.lastBlockTagValue) {
						case TAG_RETURN_VALUE:
						case TAG_THROWS_VALUE:
						case TAG_EXCEPTION_VALUE:
						case TAG_PARAM_VALUE:
						case NO_TAG_VALUE:     // Still in main description
							valid = true;
							if (this.reportProblems) {
								recordInheritedPosition((((long) this.tagSourceStart) << 32) + this.tagSourceEnd);
							}
							if (this.inlineTagStarted) {
								// parse a 'valid' inheritDoc tag
								parseInheritDocTag();
							}
							break;
						default:
							valid = false;
							if (this.reportProblems) {
								this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart,
										this.tagSourceEnd);
							}
					}
					this.tagValue = TAG_INHERITDOC_VALUE;
				} else if (length == TAG_IMPL_SPEC_LENGTH && CharOperation.equals(TAG_IMPL_SPEC, tagName, 0, length)) {
					this.tagValue = TAG_IMPL_SPEC_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				} else if (length == TAG_IMPL_NOTE_LENGTH && CharOperation.equals(TAG_IMPL_NOTE, tagName, 0, length)) {
					this.tagValue = TAG_IMPL_NOTE_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				}
				break;
			case 'l':
				if (length == TAG_LINK_LENGTH && CharOperation.equals(TAG_LINK, tagName, 0, length)) {
					this.tagValue = TAG_LINK_VALUE;
					if (this.inlineTagStarted || (this.kind & COMPLETION_PARSER) != 0) {
						valid= parseReference();
					}
				} else if (length == TAG_LINKPLAIN_LENGTH && CharOperation.equals(TAG_LINKPLAIN, tagName, 0, length)) {
					this.tagValue = TAG_LINKPLAIN_VALUE;
					if (this.inlineTagStarted) {
						valid = parseReference();
					} 
				} else if (length == TAG_LITERAL_LENGTH && this.inlineTagStarted && CharOperation.equals(TAG_LITERAL, tagName, 0, length)) {
					this.tagValue = TAG_LITERAL_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				}
				break;
			case 'p':
				if (length == TAG_PARAM_LENGTH && CharOperation.equals(TAG_PARAM, tagName, 0, length)) {
					this.tagValue = TAG_PARAM_VALUE;
					if (!this.inlineTagStarted) {
						valid = parseParam();
					}
				} else if (length == TAG_PROVIDES_LENGTH && CharOperation.equals(TAG_PROVIDES, tagName, 0, length)) {
					this.tagValue = TAG_PROVIDES_VALUE;
					if (!this.inlineTagStarted) {
						valid = parseProvidesReference();
					}
				}
				break;
			case 'r':
				if (length == TAG_RETURN_LENGTH && CharOperation.equals(TAG_RETURN, tagName, 0, length)) {
					this.tagValue = TAG_RETURN_VALUE;
					if (!this.inlineTagStarted) {
						valid = parseReturn();
					}
				}
//{ObjectTeams: role tag:
				else if (length == TAG_ROLE_LENGTH && CharOperation.equals(TAG_ROLE, tagName, 0, length)) {
					this.tagValue = TAG_ROLE_VALUE;
					if (!this.inlineTagStarted) {
						valid = parseIdentifierTag(true);
						if (valid) {
							pushRoleName(createTypeReference(TerminalTokens.TokenNameIdentifier));
						} else {
							// parseIdentifierTag already reported the missing identifier
							// reset scanner to previous position:
							this.index = this.tokenPreviousPosition;
							this.scanner.resetTo(this.index, this.javadocEnd);
						}
					}
				}
//SH}
				break;
			case 's':
				if (length == TAG_SEE_LENGTH && CharOperation.equals(TAG_SEE, tagName, 0, length)) {
					this.tagValue = TAG_SEE_VALUE;
					if (!this.inlineTagStarted) {
						valid = parseReference();
					}
				} else if (length == TAG_SERIAL_LENGTH && CharOperation.equals(TAG_SERIAL, tagName, 0, length)) {
					this.tagValue = TAG_SERIAL_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				} else if (length == TAG_SERIAL_DATA_LENGTH && CharOperation.equals(TAG_SERIAL_DATA, tagName, 0, length)) {
					this.tagValue = TAG_SERIAL_DATA_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				} else if (length == TAG_SERIAL_FIELD_LENGTH && CharOperation.equals(TAG_SERIAL_FIELD, tagName, 0, length)) {
					this.tagValue = TAG_SERIAL_FIELD_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				} else if (length == TAG_SINCE_LENGTH && CharOperation.equals(TAG_SINCE, tagName, 0, length)) {
					this.tagValue = TAG_SINCE_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				} else if (length == TAG_SYSTEM_PROPERTY_LENGTH && CharOperation.equals(TAG_SYSTEM_PROPERTY, tagName, 0, length)) {
					this.tagValue = TAG_SYSTEM_PROPERTY_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				} else if (length == TAG_SUMMARY_LENGTH && CharOperation.equals(TAG_SUMMARY, tagName, 0, length)) {
					this.tagValue = TAG_SUMMARY_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				}
				break;
			case 't':
				if (length == TAG_THROWS_LENGTH && CharOperation.equals(TAG_THROWS, tagName, 0, length)) {
					this.tagValue = TAG_THROWS_VALUE;
					if (!this.inlineTagStarted) {
						valid = parseThrows();
					}
				}
				break;
			case 'u':
				if (length == TAG_USES_LENGTH && CharOperation.equals(TAG_USES, tagName, 0, length)) {
					this.tagValue = TAG_USES_VALUE;
					if (!this.inlineTagStarted) {
						valid = parseUsesReference();
					}
				}
				break;
			case 'v':
				if (length == TAG_VALUE_LENGTH && CharOperation.equals(TAG_VALUE, tagName, 0, length)) {
					this.tagValue = TAG_VALUE_VALUE;
					if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
						if (this.inlineTagStarted) {
							valid = parseReference();
						}
					} else {
						if (this.validValuePositions == -1) {
							if (this.invalidValuePositions != -1) {
								if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag((int) (this.invalidValuePositions>>>32), (int) this.invalidValuePositions);
							}
							if (valid) {
								this.validValuePositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd;
								this.invalidValuePositions = -1;
							} else {
								this.invalidValuePositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd;
							}
						} else {
							if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
						}
					}
				} else if (length == TAG_VERSION_LENGTH && CharOperation.equals(TAG_VERSION, tagName, 0, length)) {
					this.tagValue = TAG_VERSION_VALUE;
					this.tagWaitingForDescription = this.tagValue;
				} else {
					createTag();
				}
				break;
			default:
				createTag();
				break;
		}
		this.textStart = this.index;
		if (this.tagValue != TAG_OTHERS_VALUE) {
			if (!this.inlineTagStarted) {
				this.lastBlockTagValue = this.tagValue;
			}
			// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=267833
			// Report a problem if a block tag is being used in the context of an inline tag and vice versa.
			if ((this.inlineTagStarted && JAVADOC_TAG_TYPE[this.tagValue] == TAG_TYPE_BLOCK)
					|| (!this.inlineTagStarted && JAVADOC_TAG_TYPE[this.tagValue] == TAG_TYPE_INLINE)) {
				valid = false;
				this.tagValue = TAG_OTHERS_VALUE;
				this.tagWaitingForDescription = NO_TAG_VALUE;
				if (this.reportProblems) {
					this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
				}
			}
		}
		return valid;
	}

	protected void parseInheritDocTag() {
		// do nothing
	}

	/*
	 * Parse @param tag declaration and flag missing description if corresponding option is enabled
	 */
	@Override
	protected boolean parseParam() throws InvalidInputException {
		boolean valid = super.parseParam();
		this.tagWaitingForDescription = valid && this.reportProblems ? TAG_PARAM_VALUE : NO_TAG_VALUE;
		return valid;
	}

	/*
	 * Push a param name in ast node stack.
	 */
	@Override
	protected boolean pushParamName(boolean isTypeParam) {
		// Create param reference
		ASTNode nameRef = null;
		if (isTypeParam) {
			JavadocSingleTypeReference ref = new JavadocSingleTypeReference(this.identifierStack[1],
				this.identifierPositionStack[1],
				this.tagSourceStart,
				this.tagSourceEnd);
			nameRef = ref;
		} else {
			JavadocSingleNameReference ref = new JavadocSingleNameReference(this.identifierStack[0],
				this.identifierPositionStack[0],
				this.tagSourceStart,
				this.tagSourceEnd);
			nameRef = ref;
		}
		// Push ref on stack
		if (this.astLengthPtr == -1) { // First push
			pushOnAstStack(nameRef, true);
		} else {
			// Verify that no @throws has been declared before
			if (!isTypeParam) { // do not verify for type parameters as @throws may be invalid tag (when declared in class)
				for (int i=THROWS_TAG_EXPECTED_ORDER; i<=this.astLengthPtr; i+=ORDERED_TAGS_NUMBER) {
					if (this.astLengthStack[i] != 0) {
						if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
						// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
						// store invalid param references in specific array
						if (this.invalidParamReferencesPtr == -1l) {
							this.invalidParamReferencesStack = new JavadocSingleNameReference[10];
						}
						int stackLength = this.invalidParamReferencesStack.length;
						if (++this.invalidParamReferencesPtr >= stackLength) {
							System.arraycopy(
								this.invalidParamReferencesStack, 0,
								this.invalidParamReferencesStack = new JavadocSingleNameReference[stackLength + AST_STACK_INCREMENT], 0,
								stackLength);
						}
						this.invalidParamReferencesStack[this.invalidParamReferencesPtr] = nameRef;
						return false;
					}
				}
			}
			switch (this.astLengthPtr % ORDERED_TAGS_NUMBER) {
//{ObjectTeams: @role
				case ROLE_TAG_EXPECTED_ORDER:
					// previous push was a @role tag => push new param name
					pushOnAstStack(nameRef, true);
					break;
// SH}
				case PARAM_TAG_EXPECTED_ORDER :
					// previous push was a @param tag => push another param name
					pushOnAstStack(nameRef, false);
					break;
				case SEE_TAG_EXPECTED_ORDER :
//{ObjectTeams:        push empty @role tag
					pushOnAstStack(null, true);
// SH}
					// previous push was a @see tag => push new param name
					pushOnAstStack(nameRef, true);
					break;
				default:
					return false;
			}
		}
		return true;
	}

	/*
	 * Push a reference statement in ast node stack.
	 */
	@Override
	protected boolean pushSeeRef(Object statement) {
		if (this.astLengthPtr == -1) { // First push
			pushOnAstStack(null, true);
			pushOnAstStack(null, true);
			pushOnAstStack(statement, true);
		} else {
			switch (this.astLengthPtr % ORDERED_TAGS_NUMBER) {
//{ObjectTeams:
				case ROLE_TAG_EXPECTED_ORDER :
					// previous push was a @role tag => push empty @param tag and ...
					pushOnAstStack(null, true);
// SH}
					//$FALL-THROUGH$
				case PARAM_TAG_EXPECTED_ORDER :
					// previous push was a @param tag => push empty @throws tag and new @see tag
					pushOnAstStack(null, true);
					pushOnAstStack(statement, true);
					break;
				case THROWS_TAG_EXPECTED_ORDER :
					// previous push was a @throws tag => push new @see tag
					pushOnAstStack(statement, true);
					break;
				case SEE_TAG_EXPECTED_ORDER :
					// previous push was a @see tag => push another @see tag
					pushOnAstStack(statement, false);
					break;
				default:
					return false;
			}
		}
		return true;
	}

	@Override
	protected void pushText(int start, int end) {
		// The tag gets its description => clear the flag
		this.tagWaitingForDescription = NO_TAG_VALUE;
	}

	/*
	 * Push a throws type ref in ast node stack.
	 */
	@Override
	protected boolean pushThrowName(Object typeRef) {
		if (this.astLengthPtr == -1) { // First push
			pushOnAstStack(null, true);
			pushOnAstStack(typeRef, true);
		} else {
			switch (this.astLengthPtr % ORDERED_TAGS_NUMBER) {
//{ObjectTeams:
				case ROLE_TAG_EXPECTED_ORDER :
					// previous push was a @role tag => push empty @param tag and ...
					pushOnAstStack(null, true);
// SH}
					//$FALL-THROUGH$
				case PARAM_TAG_EXPECTED_ORDER :
					// previous push was a @param tag => push new @throws tag
					pushOnAstStack(typeRef, true);
					break;
				case THROWS_TAG_EXPECTED_ORDER :
					// previous push was a @throws tag => push another @throws tag
					pushOnAstStack(typeRef, false);
					break;
				case SEE_TAG_EXPECTED_ORDER :
					// previous push was a @see tag => push empty @param and new @throws tags
//{ObjectTeams:     empty @role
					pushOnAstStack(null, true);
// SH}
					pushOnAstStack(null, true);
					pushOnAstStack(typeRef, true);
					break;
				default:
					return false;
			}
		}
		return true;
	}
//{ObjectTeams: push @role tag ref:
	/*
	 * Push a throws type ref in ast node stack.
	 */
	protected boolean pushRoleName(Object typeRef) {
		if (this.astLengthPtr == -1) { // First push
			pushOnAstStack(null, true);
			pushOnAstStack(null, true);
					pushOnAstStack(null, true);
					pushOnAstStack(typeRef, true);
		} else {
			switch (this.astLengthPtr % ORDERED_TAGS_NUMBER) {
				case ROLE_TAG_EXPECTED_ORDER :
					// previous push was a @role tag => push another @role tag
					pushOnAstStack(typeRef, false);
					break;
				case PARAM_TAG_EXPECTED_ORDER :
					// previous push was a @param tag => push empty @throws tag
					pushOnAstStack(null, true);
					//$FALL-THROUGH$
				case THROWS_TAG_EXPECTED_ORDER :
					// previous push was a @throws tag => push empty @see tag and ...
					pushOnAstStack(null, true);
					//$FALL-THROUGH$
				case SEE_TAG_EXPECTED_ORDER :
					// previous push was a @see tag => push new @role tags
					pushOnAstStack(typeRef, true);
					break;
				default:
					return false;
			}
		}
		return true;
	}

	@Override
	protected void refreshInlineTagPosition(int previousPosition) {

		// Signal tag missing description if necessary
		if (this.tagWaitingForDescription!= NO_TAG_VALUE) {
			this.sourceParser.problemReporter().javadocMissingTagDescription(TAG_NAMES[this.tagWaitingForDescription], this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
			this.tagWaitingForDescription = NO_TAG_VALUE;
		}
	}

	/*
	 * Refresh return statement
	 */
	@Override
	protected void refreshReturnStatement() {
		((JavadocReturnStatement) this.returnStatement).bits &= ~ASTNode.Empty;
	}

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("check javadoc: ").append(this.checkDocComment).append("\n");	//$NON-NLS-1$ //$NON-NLS-2$
		buffer.append("javadoc: ").append(this.docComment).append("\n");	//$NON-NLS-1$ //$NON-NLS-2$
		buffer.append(super.toString());
		return buffer.toString();
	}

	/*
	 * Fill associated comment fields with ast nodes information stored in stack.
	 */
	@Override
	protected void updateDocComment() {

		// Complain when tag is missing a description
		// Note that if the parse of an inline tag has already started, consider it
		// as the expected description, hence do not report any warning
		switch (this.tagWaitingForDescription) {
			case TAG_PARAM_VALUE:
			case TAG_THROWS_VALUE:
				if (!this.inlineTagStarted) {
					int start = (int) (this.identifierPositionStack[0] >>> 32);
					int end = (int) this.identifierPositionStack[this.identifierPtr];
					this.sourceParser.problemReporter().javadocMissingTagDescriptionAfterReference(start, end, this.sourceParser.modifiers);
				}
				break;
			case NO_TAG_VALUE:
				break;
			default:
				if (!this.inlineTagStarted) {
					this.sourceParser.problemReporter().javadocMissingTagDescription(TAG_NAMES[this.tagWaitingForDescription], this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
				}
				break;
		}
		this.tagWaitingForDescription = NO_TAG_VALUE;

		// Set positions
		if (this.inheritedPositions != null && this.inheritedPositionsPtr != this.inheritedPositions.length) {
			// Compact array by shrinking.
			System.arraycopy(this.inheritedPositions, 0, 
					this.inheritedPositions = new long[this.inheritedPositionsPtr], 0, this.inheritedPositionsPtr);
		}
		this.docComment.inheritedPositions = this.inheritedPositions;
		this.docComment.valuePositions = this.validValuePositions != -1 ? this.validValuePositions : this.invalidValuePositions;

		// Set return node if present
		if (this.returnStatement != null) {
			this.docComment.returnStatement = (JavadocReturnStatement) this.returnStatement;
		}

		// Copy array of invalid syntax param tags
		if (this.invalidParamReferencesPtr >= 0) {
			this.docComment.invalidParameters = new JavadocSingleNameReference[this.invalidParamReferencesPtr+1];
			System.arraycopy(this.invalidParamReferencesStack, 0, this.docComment.invalidParameters, 0, this.invalidParamReferencesPtr+1);
		}

		this.docComment.usesReferences = this.usesReferencesPtr >= 0 ? new IJavadocTypeReference[this.usesReferencesPtr+1] : NO_QUALIFIED_TYPE_REFERENCE;
		for (int i = 0; i <= this.usesReferencesPtr; ++i) {
			TypeReference ref = this.usesReferencesStack[i];
			this.docComment.usesReferences[i] = (IJavadocTypeReference)ref; 
		}

		this.docComment.providesReferences = this.providesReferencesPtr >= 0 ? new IJavadocTypeReference[this.providesReferencesPtr+1] : NO_QUALIFIED_TYPE_REFERENCE;
		for (int i = 0; i <= this.providesReferencesPtr; ++i) {
			TypeReference ref = this.providesReferencesStack[i];
			this.docComment.providesReferences[i] = (IJavadocTypeReference)ref; 
		}

		// If no nodes stored return
		if (this.astLengthPtr == -1) {
			return;
		}

		// Initialize arrays
		int[] sizes = new int[ORDERED_TAGS_NUMBER];
		for (int i=0; i<=this.astLengthPtr; i++) {
			sizes[i%ORDERED_TAGS_NUMBER] += this.astLengthStack[i];
		}
//{ObjectTeams: role references:
		this.docComment.roleReferences = new JavadocSingleTypeReference[sizes[ROLE_TAG_EXPECTED_ORDER]];
// SH}
		this.docComment.seeReferences = sizes[SEE_TAG_EXPECTED_ORDER] > 0 ? new Expression[sizes[SEE_TAG_EXPECTED_ORDER]] : NO_EXPRESSION;
		this.docComment.exceptionReferences = sizes[THROWS_TAG_EXPECTED_ORDER] > 0 ? new TypeReference[sizes[THROWS_TAG_EXPECTED_ORDER]] : NO_TYPE_REFERENCE;
		int paramRefPtr = sizes[PARAM_TAG_EXPECTED_ORDER];
		this.docComment.paramReferences = paramRefPtr > 0 ? new JavadocSingleNameReference[paramRefPtr] : NO_SINGLE_NAME_REFERENCE;
		int paramTypeParamPtr = sizes[PARAM_TAG_EXPECTED_ORDER];
		this.docComment.paramTypeParameters = paramTypeParamPtr > 0 ? new JavadocSingleTypeReference[paramTypeParamPtr] : NO_SINGLE_TYPE_REFERENCE;

		// Store nodes in arrays
		while (this.astLengthPtr >= 0) {
			int ptr = this.astLengthPtr % ORDERED_TAGS_NUMBER;
			// Starting with the stack top, so get references (Expression) coming from @see declarations
			switch(ptr) {
				case SEE_TAG_EXPECTED_ORDER:
					int size = this.astLengthStack[this.astLengthPtr--];
					for (int i=0; i<size; i++) {
						this.docComment.seeReferences[--sizes[ptr]] = (Expression) this.astStack[this.astPtr--];
					}
					break;

				// Then continuing with class names (TypeReference) coming from @throw/@exception declarations
				case THROWS_TAG_EXPECTED_ORDER:
					size = this.astLengthStack[this.astLengthPtr--];
					for (int i=0; i<size; i++) {
						this.docComment.exceptionReferences[--sizes[ptr]] = (TypeReference) this.astStack[this.astPtr--];
					}
					break;

				// Finally, finishing with parameters names (Argument) coming from @param declaration
				case PARAM_TAG_EXPECTED_ORDER:
					size = this.astLengthStack[this.astLengthPtr--];
					for (int i=0; i<size; i++) {
						Expression reference = (Expression) this.astStack[this.astPtr--];
						if (reference instanceof JavadocSingleNameReference)
							this.docComment.paramReferences[--paramRefPtr] = (JavadocSingleNameReference) reference;
						else if (reference instanceof JavadocSingleTypeReference)
							this.docComment.paramTypeParameters[--paramTypeParamPtr] = (JavadocSingleTypeReference) reference;
					}
					break;
//{ObjectTeams:
				// also TypeReferences coming from @role declarations
				case ROLE_TAG_EXPECTED_ORDER:
					size = this.astLengthStack[this.astLengthPtr--];
					for (int i=0; i<size; i++) {
						this.docComment.roleReferences[--sizes[ptr]] = (JavadocSingleTypeReference) this.astStack[this.astPtr--];
					}
					break;
// SH}
			}
		}

		// Resize param tag references arrays
		if (paramRefPtr == 0) { // there's no type parameters references
			this.docComment.paramTypeParameters = null;
		} else if (paramTypeParamPtr == 0) { // there's no names references
			this.docComment.paramReferences = null;
		} else { // there both of references => resize arrays
			int size = sizes[PARAM_TAG_EXPECTED_ORDER];
			System.arraycopy(this.docComment.paramReferences, paramRefPtr, this.docComment.paramReferences = new JavadocSingleNameReference[size - paramRefPtr], 0, size - paramRefPtr);
			System.arraycopy(this.docComment.paramTypeParameters, paramTypeParamPtr, this.docComment.paramTypeParameters = new JavadocSingleTypeReference[size - paramTypeParamPtr], 0, size - paramTypeParamPtr);
		}
	}

	/*
	 * Parse @uses tag declaration
	 */
	protected boolean parseUsesReference() {
		int start = this.scanner.currentPosition;
		try {
			Object typeRef = parseQualifiedName(true);
			if (this.abort) return false; // May be aborted by specialized parser
			if (typeRef == null) {
				if (this.reportProblems)
					this.sourceParser.problemReporter().javadocMissingUsesClassName(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
			} else {
				return pushUsesReference(typeRef);
			}
		} catch (InvalidInputException ex) {
			if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidUsesClass(start, getTokenEndPosition());
		}
		return false;
	}

	protected boolean pushUsesReference(Object typeRef) {
		// TODO Auto-generated method stub
		if (this.usesReferencesPtr == -1l) {
			this.usesReferencesStack = new TypeReference[10];
		}
		int stackLength = this.usesReferencesStack.length;
		if (++this.usesReferencesPtr >= stackLength) {
			System.arraycopy(
				this.usesReferencesStack, 0,
				this.usesReferencesStack = new TypeReference[stackLength + AST_STACK_INCREMENT], 0,
				stackLength);
		}
		this.usesReferencesStack[this.usesReferencesPtr] = (TypeReference)typeRef;
		return true;
	}

	/*
	 * Parse @uses tag declaration
	 */
	protected boolean parseProvidesReference() {
		int start = this.scanner.currentPosition;
		try {
			Object typeRef = parseQualifiedName(true);
			if (this.abort) return false; // May be aborted by specialized parser
			if (typeRef == null) {
				if (this.reportProblems)
					this.sourceParser.problemReporter().javadocMissingProvidesClassName(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
			} else {
				return pushProvidesReference(typeRef);
			}
		} catch (InvalidInputException ex) {
			if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidProvidesClass(start, getTokenEndPosition());
		}
		return false;
	}

	protected boolean pushProvidesReference(Object typeRef) {
		// TODO Auto-generated method stub
		if (this.providesReferencesPtr == -1l) {
			this.providesReferencesStack = new TypeReference[10];
		}
		int stackLength = this.providesReferencesStack.length;
		if (++this.providesReferencesPtr >= stackLength) {
			System.arraycopy(
				this.providesReferencesStack, 0,
				this.providesReferencesStack = new TypeReference[stackLength + AST_STACK_INCREMENT], 0,
				stackLength);
		}
		this.providesReferencesStack[this.providesReferencesPtr] = (TypeReference)typeRef;
		return true;

	}

}
