/*******************************************************************************
 * 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
 *     Stephan Herrmann - Contribution for
 *								Bug 400874 - [1.8][compiler] Inference infrastructure should evolve to meet JLS8 18.x (Part G of JSR335 spec)
 *								Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;

/**
 * Node representing a structured Javadoc comment
 */
public class Javadoc extends ASTNode {

	public JavadocSingleNameReference[] paramReferences; // @param
	public JavadocSingleTypeReference[] paramTypeParameters; // @param
	public TypeReference[] exceptionReferences; // @throws, @exception
	public JavadocReturnStatement returnStatement; // @return
	public Expression[] seeReferences; // @see
	public IJavadocTypeReference[] usesReferences; // @uses
	public IJavadocTypeReference[] providesReferences; // @provides
	public long[] inheritedPositions = null;
	// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
	// Store param references for tag with invalid syntax
	public JavadocSingleNameReference[] invalidParameters; // @param
	// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=153399
	// Store value tag positions
	public long valuePositions = -1;

	public Javadoc(int sourceStart, int sourceEnd) {
		this.sourceStart = sourceStart;
		this.sourceEnd = sourceEnd;
		this.bits |= ASTNode.ResolveJavadoc;
	}
	/**
	 * Returns whether a type can be seen at a given visibility level or not.
	 *
	 * @param visibility Level of visiblity allowed to see references
	 * @param modifiers modifiers of java element to be seen
	 * @return true if the type can be seen, false otherwise
	 */
	boolean canBeSeen(int visibility, int modifiers) {
		if (modifiers < 0) return true;
		switch (modifiers & ExtraCompilerModifiers.AccVisibilityMASK) {
			case ClassFileConstants.AccPublic :
				return true;
			case ClassFileConstants.AccProtected:
				return (visibility != ClassFileConstants.AccPublic);
			case ClassFileConstants.AccDefault:
				return (visibility == ClassFileConstants.AccDefault || visibility == ClassFileConstants.AccPrivate);
			case ClassFileConstants.AccPrivate:
				return (visibility == ClassFileConstants.AccPrivate);
		}
		return true;
	}

	/*
	 * Search node with a given staring position in javadoc objects arrays.
	 */
	public ASTNode getNodeStartingAt(int start) {
		int length = 0;
		// parameters array
		if (this.paramReferences != null) {
			length = this.paramReferences.length;
			for (int i=0; i<length; i++) {
				JavadocSingleNameReference param = this.paramReferences[i];
				if (param.sourceStart==start) {
					return param;
				}
			}
		}
		// array of invalid syntax tags parameters
		if (this.invalidParameters != null) {
			length = this.invalidParameters.length;
			for (int i=0; i<length; i++) {
				JavadocSingleNameReference param = this.invalidParameters[i];
				if (param.sourceStart==start) {
					return param;
				}
			}
		}
		// type parameters array
		if (this.paramTypeParameters != null) {
			length = this.paramTypeParameters.length;
			for (int i=0; i<length; i++) {
				JavadocSingleTypeReference param = this.paramTypeParameters[i];
				if (param.sourceStart==start) {
					return param;
				}
			}
		}
		// thrown exception array
		if (this.exceptionReferences != null) {
			length = this.exceptionReferences.length;
			for (int i=0; i<length; i++) {
				TypeReference typeRef = this.exceptionReferences[i];
				if (typeRef.sourceStart==start) {
					return typeRef;
				}
			}
		}
		// references array
		if (this.seeReferences != null) {
			length = this.seeReferences.length;
			for (int i=0; i<length; i++) {
				org.eclipse.jdt.internal.compiler.ast.Expression expression = this.seeReferences[i];
				if (expression.sourceStart==start) {
					return expression;
				} else if (expression instanceof JavadocAllocationExpression) {
					JavadocAllocationExpression allocationExpr = (JavadocAllocationExpression) this.seeReferences[i];
					// if binding is valid then look at arguments
					if (allocationExpr.binding != null && allocationExpr.binding.isValidBinding()) {
						if (allocationExpr.arguments != null) {
							for (int j=0, l=allocationExpr.arguments.length; j<l; j++) {
								if (allocationExpr.arguments[j].sourceStart == start) {
									return allocationExpr.arguments[j];
								}
							}
						}
					}
				} else if (expression instanceof JavadocMessageSend) {
					JavadocMessageSend messageSend = (JavadocMessageSend) this.seeReferences[i];
					// if binding is valid then look at arguments
					if (messageSend.binding != null && messageSend.binding.isValidBinding()) {
						if (messageSend.arguments != null) {
							for (int j=0, l=messageSend.arguments.length; j<l; j++) {
								if (messageSend.arguments[j].sourceStart == start) {
									return messageSend.arguments[j];
								}
							}
						}
					}
				}
			}
		}
		return null;
	}

	/*
	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#print(int, java.lang.StringBuffer)
	 */
	@Override
	public StringBuffer print(int indent, StringBuffer output) {
		printIndent(indent, output).append("/**\n"); //$NON-NLS-1$
		if (this.paramReferences != null) {
			for (int i = 0, length = this.paramReferences.length; i < length; i++) {
				printIndent(indent + 1, output).append(" * @param "); //$NON-NLS-1$
				this.paramReferences[i].print(indent, output).append('\n');
			}
		}
		if (this.paramTypeParameters != null) {
			for (int i = 0, length = this.paramTypeParameters.length; i < length; i++) {
				printIndent(indent + 1, output).append(" * @param <"); //$NON-NLS-1$
				this.paramTypeParameters[i].print(indent, output).append(">\n"); //$NON-NLS-1$
			}
		}
		if (this.returnStatement != null) {
			printIndent(indent + 1, output).append(" * @"); //$NON-NLS-1$
			this.returnStatement.print(indent, output).append('\n');
		}
		if (this.exceptionReferences != null) {
			for (int i = 0, length = this.exceptionReferences.length; i < length; i++) {
				printIndent(indent + 1, output).append(" * @throws "); //$NON-NLS-1$
				this.exceptionReferences[i].print(indent, output).append('\n');
			}
		}
		if (this.seeReferences != null) {
			for (int i = 0, length = this.seeReferences.length; i < length; i++) {
				printIndent(indent + 1, output).append(" * @see "); //$NON-NLS-1$
				this.seeReferences[i].print(indent, output).append('\n');
			}
		}
		printIndent(indent, output).append(" */\n"); //$NON-NLS-1$
		return output;
	}

	/*
	 * Resolve type javadoc
	 */
	public void resolve(ClassScope scope) {
		if ((this.bits & ASTNode.ResolveJavadoc) == 0) {
			return;
		}

		this.bits &= ~ASTNode.ResolveJavadoc;// avoid double resolution

		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, @inheritDoc tag cannot
		// be used in the documentation comment for a class or interface.
		if (this.inheritedPositions != null) {
			int length = this.inheritedPositions.length;
			for (int i = 0; i < length; ++i) {
				int start = (int) (this.inheritedPositions[i] >>> 32);
				int end = (int) this.inheritedPositions[i];
				scope.problemReporter().javadocUnexpectedTag(start, end);
			}
		}
		// @param tags
		int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length;
		for (int i = 0; i < paramTagsSize; i++) {
			if(scope.referenceContext instanceof RecordDeclaration) {
				RecordDeclaration rd = (RecordDeclaration)scope.referenceContext;
				if(  rd.nRecordComponents > 0)
					break;
			}
			JavadocSingleNameReference param = this.paramReferences[i];
			scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd);
		}
		resolveTypeParameterTags(scope, true);

		// @return tags
		if (this.returnStatement != null) {
			scope.problemReporter().javadocUnexpectedTag(this.returnStatement.sourceStart, this.returnStatement.sourceEnd);
		}

		// @throws/@exception tags
		int throwsTagsLength = this.exceptionReferences == null ? 0 : this.exceptionReferences.length;
		for (int i = 0; i < throwsTagsLength; i++) {
			TypeReference typeRef = this.exceptionReferences[i];
			int start, end;
			if (typeRef instanceof JavadocSingleTypeReference) {
				JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) typeRef;
				start = singleRef.tagSourceStart;
				end = singleRef.tagSourceEnd;
			} else if (typeRef instanceof JavadocQualifiedTypeReference) {
				JavadocQualifiedTypeReference qualifiedRef = (JavadocQualifiedTypeReference) typeRef;
				start = qualifiedRef.tagSourceStart;
				end = qualifiedRef.tagSourceEnd;
			} else {
				start = typeRef.sourceStart;
				end = typeRef.sourceEnd;
			}
			scope.problemReporter().javadocUnexpectedTag(start, end);
		}

		// @see tags
		int seeTagsLength = this.seeReferences == null ? 0 : this.seeReferences.length;
		for (int i = 0; i < seeTagsLength; i++) {
			resolveReference(this.seeReferences[i], scope);
		}

		// @value tag
		boolean source15 = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
		if (!source15 && this.valuePositions != -1) {
			scope.problemReporter().javadocUnexpectedTag((int)(this.valuePositions>>>32), (int) this.valuePositions);
		}
	}

	/*
	 * Resolve compilation unit javadoc
	 */
	public void resolve(CompilationUnitScope unitScope) {
		if ((this.bits & ASTNode.ResolveJavadoc) == 0) {
			return;
		}
		// Do nothing - This is to mimic the SDK's javadoc tool behavior, which neither
		// sanity checks nor generates documentation using comments at the CU scope
		// (unless the unit happens to be package-info.java - in which case we don't come here.)
	}

	/*
	 * Resolve module info javadoc
	 */
	public void resolve(ModuleScope moduleScope) {
		if ((this.bits & ASTNode.ResolveJavadoc) == 0) {
			return;
		}

		this.bits &= ~ASTNode.ResolveJavadoc;// avoid double resolution

		// @see tags
		int seeTagsLength = this.seeReferences == null ? 0 : this.seeReferences.length;
		for (int i = 0; i < seeTagsLength; i++) {
			// Resolve reference
			resolveReference(this.seeReferences[i], moduleScope);
		}

		resolveUsesTags(moduleScope, true);
		resolveProvidesTags(moduleScope, true);
	}

	/*
	 * Resolve method javadoc
	 */
	public void resolve(MethodScope methScope) {
		if ((this.bits & ASTNode.ResolveJavadoc) == 0) {
			return;
		}

		this.bits &= ~ASTNode.ResolveJavadoc;// avoid double resolution

		// get method declaration
		AbstractMethodDeclaration methDecl = methScope.referenceMethod();
		boolean overriding = methDecl == null /* field declaration */ || methDecl.binding == null /* compiler error */
			? false :
			!methDecl.binding.isStatic() && ((methDecl.binding.modifiers & (ExtraCompilerModifiers.AccImplementing | ExtraCompilerModifiers.AccOverriding)) != 0);

		// @see tags
		int seeTagsLength = this.seeReferences == null ? 0 : this.seeReferences.length;
		boolean superRef = false;
		for (int i = 0; i < seeTagsLength; i++) {

			// Resolve reference
			resolveReference(this.seeReferences[i], methScope);

			// see whether we can have a super reference
			if (methDecl != null && !superRef) {
				if (!methDecl.isConstructor()) {
					if (overriding && this.seeReferences[i] instanceof JavadocMessageSend) {
						JavadocMessageSend messageSend = (JavadocMessageSend) this.seeReferences[i];
						// if binding is valid then look if we have a reference to an overriden method/constructor
						if (messageSend.binding != null && messageSend.binding.isValidBinding() && messageSend.actualReceiverType instanceof ReferenceBinding) {
							ReferenceBinding methodReceiverType = (ReferenceBinding) messageSend.actualReceiverType;
							TypeBinding superType = methDecl.binding.declaringClass.findSuperTypeOriginatingFrom(methodReceiverType);
							if (superType != null && TypeBinding.notEquals(superType.original(), methDecl.binding.declaringClass) && CharOperation.equals(messageSend.selector, methDecl.selector)) {
								if (methScope.environment().methodVerifier().doesMethodOverride(methDecl.binding, messageSend.binding.original())) {
									superRef = true;
								}
							}
						}
					}
				} else if (this.seeReferences[i] instanceof JavadocAllocationExpression) {
					JavadocAllocationExpression allocationExpr = (JavadocAllocationExpression) this.seeReferences[i];
					// if binding is valid then look if we have a reference to an overriden method/constructor
					if (allocationExpr.binding != null && allocationExpr.binding.isValidBinding()) {
						ReferenceBinding allocType = (ReferenceBinding) allocationExpr.resolvedType.original();
						ReferenceBinding superType = (ReferenceBinding) methDecl.binding.declaringClass.findSuperTypeOriginatingFrom(allocType);
						if (superType != null && TypeBinding.notEquals(superType.original(), methDecl.binding.declaringClass)) {
							MethodBinding superConstructor = methScope.getConstructor(superType, methDecl.binding.parameters, allocationExpr);
							if (superConstructor.isValidBinding() && superConstructor.original() == allocationExpr.binding.original()) {
								MethodBinding current = methDecl.binding;
								// work 'against' better inference in 1.8 (otherwise comparing (G<T> with G<Object>) would fail):
								if (methScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8
									&& current.typeVariables != Binding.NO_TYPE_VARIABLES)
								{
									current = current.asRawMethod(methScope.environment());
								}
								if (superConstructor.areParametersEqual(current)) {
									superRef = true;
								}
							}
						}
					}
				}
			}
		}

		// Look at @Override annotations
		if (!superRef && methDecl != null && methDecl.annotations != null) {
			int length = methDecl.annotations.length;
			for (int i=0; i<length && !superRef; i++) {
				superRef = (methDecl.binding.tagBits & TagBits.AnnotationOverride) != 0;
			}
		}

		// Store if a reference exists to an overriden method/constructor or the method is in a local type,
		boolean reportMissing = methDecl == null || !((overriding && this.inheritedPositions != null) || superRef || (methDecl.binding.declaringClass != null && methDecl.binding.declaringClass.isLocalType()));
		if (!overriding && this.inheritedPositions != null) {
			int length = this.inheritedPositions.length;
			for (int i = 0; i < length; ++i) {
				int start = (int) (this.inheritedPositions[i] >>> 32);
				int end = (int) this.inheritedPositions[i];
				methScope.problemReporter().javadocUnexpectedTag(start, end);
			}
		}

		// @param tags
		CompilerOptions compilerOptions = methScope.compilerOptions();
		resolveParamTags(methScope, reportMissing, compilerOptions.reportUnusedParameterIncludeDocCommentReference /* considerParamRefAsUsage*/);
		resolveTypeParameterTags(methScope, reportMissing && compilerOptions.reportMissingJavadocTagsMethodTypeParameters);

		// @return tags
		if (this.returnStatement == null) {
			if (reportMissing && methDecl != null) {
				if (methDecl.isMethod()) {
					MethodDeclaration meth = (MethodDeclaration) methDecl;
					if (meth.binding.returnType != TypeBinding.VOID) {
						// method with return should have @return tag
						methScope.problemReporter().javadocMissingReturnTag(meth.returnType.sourceStart, meth.returnType.sourceEnd, methDecl.binding.modifiers);
					}
				}
			}
		} else {
			this.returnStatement.resolve(methScope);
		}

		// @throws/@exception tags
		resolveThrowsTags(methScope, reportMissing);

		// @value tag
		boolean source15 = compilerOptions.sourceLevel >= ClassFileConstants.JDK1_5;
		if (!source15 && methDecl != null && this.valuePositions != -1) {
			methScope.problemReporter().javadocUnexpectedTag((int)(this.valuePositions>>>32), (int) this.valuePositions);
		}

		// Resolve param tags with invalid syntax
		int length = this.invalidParameters == null ? 0 : this.invalidParameters.length;
		for (int i = 0; i < length; i++) {
			this.invalidParameters[i].resolve(methScope, false, false);
		}
	}

	private void resolveReference(Expression reference, Scope scope) {

		// Perform resolve
		int problemCount = scope.referenceContext().compilationResult().problemCount;
		switch (scope.kind) {
			case Scope.METHOD_SCOPE:
				reference.resolveType((MethodScope)scope);
				break;
			case Scope.CLASS_SCOPE:
				reference.resolveType((ClassScope)scope);
				break;
		}
		boolean hasProblems = scope.referenceContext().compilationResult().problemCount > problemCount;

		// Verify field references
		boolean source15 = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
		int scopeModifiers = -1;
		if (reference instanceof JavadocFieldReference) {
			JavadocFieldReference fieldRef = (JavadocFieldReference) reference;

			// Verify if this is a method reference
			// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51911
			if (fieldRef.methodBinding != null) {
				// cannot refer to method for @value tag
				if (fieldRef.tagValue == JavadocTagConstants.TAG_VALUE_VALUE) {
					if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
					scope.problemReporter().javadocInvalidValueReference(fieldRef.sourceStart, fieldRef.sourceEnd, scopeModifiers);
				}
				else if (fieldRef.actualReceiverType != null) {
					if (scope.kind != Scope.MODULE_SCOPE && scope.enclosingSourceType().isCompatibleWith(fieldRef.actualReceiverType)) {
						fieldRef.bits |= ASTNode.SuperAccess;
					}
					ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.actualReceiverType;
					if (CharOperation.equals(resolvedType.sourceName(), fieldRef.token)) {
						fieldRef.methodBinding = scope.getConstructor(resolvedType, Binding.NO_TYPES, fieldRef);
					} else {
						fieldRef.methodBinding = scope.findMethod(resolvedType, fieldRef.token, Binding.NO_TYPES, fieldRef, false);
					}
				}
			}

			// Verify whether field ref should be static or not (for @value tags)
			else if (source15 && fieldRef.binding != null && fieldRef.binding.isValidBinding()) {
				if (fieldRef.tagValue == JavadocTagConstants.TAG_VALUE_VALUE && !fieldRef.binding.isStatic()) {
					if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
					scope.problemReporter().javadocInvalidValueReference(fieldRef.sourceStart, fieldRef.sourceEnd, scopeModifiers);
				}
			}

			// Verify type references
			if (!hasProblems && fieldRef.binding != null && fieldRef.binding.isValidBinding() && fieldRef.actualReceiverType instanceof ReferenceBinding) {
				ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.actualReceiverType;
				verifyTypeReference(fieldRef, fieldRef.receiver, scope, source15, resolvedType, fieldRef.binding.modifiers);
			}

			// That's it for field references
			return;
		}

		// Verify type references
		if (!hasProblems && (reference instanceof JavadocSingleTypeReference || reference instanceof JavadocQualifiedTypeReference) && reference.resolvedType instanceof ReferenceBinding) {
			ReferenceBinding resolvedType = (ReferenceBinding) reference.resolvedType;
			verifyTypeReference(reference, reference, scope, source15, resolvedType, resolvedType.modifiers);
		}

		// Verify that message reference are not used for @value tags
		if (reference instanceof JavadocMessageSend) {
			JavadocMessageSend msgSend = (JavadocMessageSend) reference;

			// tag value
			if (source15 && msgSend.tagValue == JavadocTagConstants.TAG_VALUE_VALUE) { // cannot refer to method for @value tag
				if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
				scope.problemReporter().javadocInvalidValueReference(msgSend.sourceStart, msgSend.sourceEnd, scopeModifiers);
			}

			// Verify type references
			if (!hasProblems && msgSend.binding != null && msgSend.binding.isValidBinding() && msgSend.actualReceiverType instanceof ReferenceBinding) {
				ReferenceBinding resolvedType = (ReferenceBinding) msgSend.actualReceiverType;
				verifyTypeReference(msgSend, msgSend.receiver, scope, source15, resolvedType, msgSend.binding.modifiers);
			}
		}

		// Verify that constructor reference are not used for @value tags
		else if (reference instanceof JavadocAllocationExpression) {
			JavadocAllocationExpression alloc = (JavadocAllocationExpression) reference;

			// tag value
			if (source15 && alloc.tagValue == JavadocTagConstants.TAG_VALUE_VALUE) { // cannot refer to method for @value tag
				if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
				scope.problemReporter().javadocInvalidValueReference(alloc.sourceStart, alloc.sourceEnd, scopeModifiers);
			}

			// Verify type references
			if (!hasProblems && alloc.binding != null && alloc.binding.isValidBinding() && alloc.resolvedType instanceof ReferenceBinding) {
				ReferenceBinding resolvedType = (ReferenceBinding) alloc.resolvedType;
				verifyTypeReference(alloc, alloc.type, scope, source15, resolvedType, alloc.binding.modifiers);
			}
		}

		// Verify that there's no type variable reference
		// (javadoc does not accept them and this is not a referenced bug or requested enhancement)
		else if (reference instanceof JavadocSingleTypeReference && reference.resolvedType != null && reference.resolvedType.isTypeVariable()) {
			scope.problemReporter().javadocInvalidReference(reference.sourceStart, reference.sourceEnd);
		}
	}

	/*
	 * Resolve @param tags while method scope
	 */
	private void resolveParamTags(MethodScope scope, boolean reportMissing, boolean considerParamRefAsUsage) {
		AbstractMethodDeclaration methodDecl = scope.referenceMethod();
		int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length;

		// If no referenced method (field initializer for example) then report a problem for each param tag
		if (methodDecl == null) {
			for (int i = 0; i < paramTagsSize; i++) {
				JavadocSingleNameReference param = this.paramReferences[i];
				scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd);
			}
			return;
		}

		// If no param tags then report a problem for each method argument
		int argumentsSize = methodDecl.arguments == null ? 0 : methodDecl.arguments.length;
		if (paramTagsSize == 0) {
			if (reportMissing) {
				for (int i = 0; i < argumentsSize; i++) {
					Argument arg = methodDecl.arguments[i];
					scope.problemReporter().javadocMissingParamTag(arg.name, arg.sourceStart, arg.sourceEnd, methodDecl.binding.modifiers);
				}
			}
		} else {
			LocalVariableBinding[] bindings = new LocalVariableBinding[paramTagsSize];
			int maxBindings = 0;

			// Scan all @param tags
			for (int i = 0; i < paramTagsSize; i++) {
				JavadocSingleNameReference param = this.paramReferences[i];
				param.resolve(scope, true, considerParamRefAsUsage);
				if (param.binding != null && param.binding.isValidBinding()) {
					// Verify duplicated tags
					boolean found = false;
					for (int j = 0; j < maxBindings && !found; j++) {
						if (bindings[j] == param.binding) {
							scope.problemReporter().javadocDuplicatedParamTag(param.token, param.sourceStart, param.sourceEnd, methodDecl.binding.modifiers);
							found = true;
						}
					}
					if (!found) {
						bindings[maxBindings++] = (LocalVariableBinding) param.binding;
					}
				}
			}

			// Look for undocumented arguments
			if (reportMissing) {
				for (int i = 0; i < argumentsSize; i++) {
					Argument arg = methodDecl.arguments[i];
					boolean found = false;
					for (int j = 0; j < maxBindings && !found; j++) {
						LocalVariableBinding binding = bindings[j];
						if (arg.binding == binding) {
							found = true;
						}
					}
					if (!found) {
						scope.problemReporter().javadocMissingParamTag(arg.name, arg.sourceStart, arg.sourceEnd, methodDecl.binding.modifiers);
					}
				}
			}
		}
	}

	/*
	 * Resolve @uses tags while block scope
	 */
	private void resolveUsesTags(BlockScope scope, boolean reportMissing) {
		ModuleDeclaration moduleDecl = (ModuleDeclaration)scope.referenceContext();
		int usesTagsSize = this.usesReferences == null ? 0 : this.usesReferences.length;

		// If no referenced module then report a problem for each uses tag
		if (moduleDecl == null) {
			for (int i = 0; i < usesTagsSize; i++) {
				IJavadocTypeReference uses = this.usesReferences[i];
				scope.problemReporter().javadocUnexpectedTag(uses.getTagSourceStart(), uses.getTagSourceEnd());
			}
			return;
		}

		// If no uses tags then report a problem for each uses reference
		int usesSize = moduleDecl.usesCount;
		if (usesTagsSize == 0) {
			if (reportMissing) {
				for (int i = 0; i < usesSize; i++) {
					UsesStatement uses = moduleDecl.uses[i];
					scope.problemReporter().javadocMissingUsesTag(uses.serviceInterface, uses.sourceStart, uses.sourceEnd, moduleDecl.binding.modifiers);
				}
			}
		} else {
			TypeBinding[] bindings = new TypeBinding[usesTagsSize];
			int maxBindings = 0;

			// Scan all @uses tags
			for (int i = 0; i < usesTagsSize; i++) {
				TypeReference usesRef = (TypeReference)this.usesReferences[i];
				try {
					usesRef.resolve(scope);
					if (usesRef.resolvedType != null && usesRef.resolvedType.isValidBinding()) {
						// Verify duplicated tags
						boolean found = false;
						for (int j = 0; j < maxBindings && !found; j++) {
							if (bindings[j].equals(usesRef.resolvedType)) {
								scope.problemReporter().javadocDuplicatedUsesTag(usesRef.sourceStart, usesRef.sourceEnd);
								found = true;
							}
						}
						if (!found) {
							bindings[maxBindings++] = usesRef.resolvedType;
						}
					}
				} catch (Exception e) {
					scope.problemReporter().javadocInvalidUsesClass(usesRef.sourceStart, usesRef.sourceEnd);
				}
			}

			// Look for undocumented uses
			if (reportMissing) {
				for (int i = 0; i < usesSize; i++) {
					UsesStatement uses = moduleDecl.uses[i];
					boolean found = false;
					for (int j = 0; j < maxBindings && !found; j++) {
						TypeBinding binding = bindings[j];
						if (uses.serviceInterface.getTypeBinding(scope).equals(binding)) {
							found = true;
						}
					}
					if (!found) {
						scope.problemReporter().javadocMissingUsesTag(uses.serviceInterface, uses.sourceStart, uses.sourceEnd, moduleDecl.binding.modifiers);
					}
				}
			}
		}
	}

	/*
	 * Resolve @provides tags while block scope
	 */
	private void resolveProvidesTags(BlockScope scope, boolean reportMissing) {
		ModuleDeclaration moduleDecl = (ModuleDeclaration)scope.referenceContext();
		int providesTagsSize = this.providesReferences == null ? 0 : this.providesReferences.length;

		// If no referenced module then report a problem for each uses tag
		if (moduleDecl == null) {
			for (int i = 0; i < providesTagsSize; i++) {
				IJavadocTypeReference provides = this.providesReferences[i];
				scope.problemReporter().javadocUnexpectedTag(provides.getTagSourceStart(), provides.getTagSourceEnd());
			}
			return;
		}

		// If no uses tags then report a problem for each uses reference
		int providesSize = moduleDecl.servicesCount;
		if (providesTagsSize == 0) {
			if (reportMissing) {
				for (int i = 0; i < providesSize; i++) {
					ProvidesStatement provides = moduleDecl.services[i];
					scope.problemReporter().javadocMissingProvidesTag(provides.serviceInterface, provides.sourceStart, provides.sourceEnd, moduleDecl.binding.modifiers);
				}
			}
		} else {
			TypeBinding[] bindings = new TypeBinding[providesTagsSize];
			int maxBindings = 0;

			// Scan all @provides tags
			for (int i = 0; i < providesTagsSize; i++) {
				TypeReference providesRef = (TypeReference)this.providesReferences[i];
				try {
					providesRef.resolve(scope);
					if (providesRef.resolvedType != null && providesRef.resolvedType.isValidBinding()) {
						// Verify duplicated tags
						boolean found = false;
						for (int j = 0; j < maxBindings && !found; j++) {
							if (bindings[j].equals(providesRef.resolvedType)) {
								scope.problemReporter().javadocDuplicatedProvidesTag(providesRef.sourceStart, providesRef.sourceEnd);
								found = true;
							}
						}
						if (!found) {
							bindings[maxBindings++] = providesRef.resolvedType;
						}
					}
				} catch (Exception e) {
					scope.problemReporter().javadocInvalidProvidesClass(providesRef.sourceStart, providesRef.sourceEnd);
				}
			}

			// Look for undocumented uses
			if (reportMissing) {
				for (int i = 0; i < providesSize; i++) {
					ProvidesStatement provides = moduleDecl.services[i];
					boolean found = false;
					for (int j = 0; j < maxBindings && !found; j++) {
						TypeBinding binding = bindings[j];
						if (provides.serviceInterface.getTypeBinding(scope).equals(binding)) {
							found = true;
						}
					}
					if (!found) {
						scope.problemReporter().javadocMissingProvidesTag(provides.serviceInterface, provides.sourceStart, provides.sourceEnd, moduleDecl.binding.modifiers);
					}
				}
			}
		}
	}

	/*
	 * Resolve @param tags for type parameters
	 */
	private void resolveTypeParameterTags(Scope scope, boolean reportMissing) {
		int paramTypeParamLength = this.paramTypeParameters == null ? 0 : this.paramTypeParameters.length;
		int paramReferencesLength = this.paramReferences == null ? 0 : this.paramReferences.length;

		// Get declaration infos
		TypeParameter[] parameters = null;
		TypeVariableBinding[] typeVariables = null;
		Argument[] recordParameters = null;
		int modifiers = -1;
		switch (scope.kind) {
			case Scope.METHOD_SCOPE:
				AbstractMethodDeclaration methodDeclaration = ((MethodScope)scope).referenceMethod();
				// If no referenced method (field initializer for example) then report a problem for each param tag
				if (methodDeclaration == null) {
					for (int i = 0; i < paramTypeParamLength; i++) {
						JavadocSingleTypeReference param = this.paramTypeParameters[i];
						scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd);
					}
					return;
				}
				parameters = methodDeclaration.typeParameters();
				typeVariables = methodDeclaration.binding.typeVariables;
				modifiers = methodDeclaration.binding.modifiers;
				break;
			case Scope.CLASS_SCOPE:
				TypeDeclaration typeDeclaration = ((ClassScope) scope).referenceContext;
				parameters = typeDeclaration.typeParameters;
				typeVariables = typeDeclaration.binding.typeVariables;
				modifiers = typeDeclaration.binding.modifiers;
				if (typeDeclaration instanceof RecordDeclaration) {
					RecordDeclaration recordDecl = (RecordDeclaration)typeDeclaration;
					recordParameters = recordDecl.getArgs();
				}
				break;
		}

		// If no type variables then report a problem for each param type parameter tag
		if ((recordParameters == null || recordParameters.length == 0)
				&& (typeVariables == null || typeVariables.length == 0)) {
			for (int i = 0; i < paramTypeParamLength; i++) {
				JavadocSingleTypeReference param = this.paramTypeParameters[i];
				scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd);
			}
			return;
		}

		// If no param tags then report a problem for each record parameter
		if (recordParameters != null) {
			reportMissing = reportMissing && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
			int recordParametersLength = recordParameters.length;
			String argNames[] = new String[paramReferencesLength];
			if (paramReferencesLength == 0) {
				if (reportMissing) {
					for (int i = 0, l=recordParametersLength; i<l; i++) {
						scope.problemReporter().javadocMissingParamTag(recordParameters[i].name, recordParameters[i].sourceStart, recordParameters[i].sourceEnd, modifiers);
					}
				}
			} else {
				// Otherwise verify that all param tags match record args
				// Scan all @param tags
				for (int i = 0; i < paramReferencesLength; ++i) {
					JavadocSingleNameReference param = this.paramReferences[i];
					String paramName = new String(param.getName()[0]);
					// Verify duplicated tags
					boolean duplicate = false;
					for (int j = 0; j < i && !duplicate; j++) {
						if (paramName.equals(argNames[j])) {
							scope.problemReporter().javadocDuplicatedParamTag(param.token, param.sourceStart, param.sourceEnd, modifiers);
							duplicate = true;
						}
					}
					if (!duplicate) {
						argNames[i] = paramName;
					}
				}
				// Look for undocumented arguments
				if (reportMissing) {
					for (int i = 0; i < recordParameters.length; i++) {
						Argument arg = recordParameters[i];
						boolean found = false;
						for (int j = 0; j < paramReferencesLength && !found; j++) {
							JavadocSingleNameReference param = this.paramReferences[j];
							String paramName = new String(param.getName()[0]);
							if (paramName.equals(new String(arg.name))) {
								found = true;
							}
						}
						if (!found) {
							scope.problemReporter().javadocMissingParamTag(arg.name, arg.sourceStart, arg.sourceEnd, modifiers);
						}
					}
				}
				// Look for param tags that specify non-existent arguments
				for (int i = 0; i < paramReferencesLength; i++) {
					JavadocSingleNameReference param = this.paramReferences[i];
					String paramName = new String(param.getName()[0]);
					boolean found = false;
					for (int j = 0; j < recordParameters.length; j++) {
						Argument arg = recordParameters[j];
						if (paramName.equals(new String(arg.name))) {
							found = true;
						}
					}
					if (!found) {
						scope.problemReporter().javadocInvalidParamTagName(param.sourceStart, param.sourceEnd);
					}
				}
			}
		}

		// If no param tags then report a problem for each declaration type parameter
		if (parameters != null) {
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, avoid secondary errors when <= 1.4
			reportMissing = reportMissing && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
			int typeParametersLength = parameters.length;
			if (paramTypeParamLength == 0) {
				if (reportMissing) {
					for (int i = 0, l=typeParametersLength; i<l; i++) {
						scope.problemReporter().javadocMissingParamTag(parameters[i].name, parameters[i].sourceStart, parameters[i].sourceEnd, modifiers);
					}
				}

			// Otherwise verify that all param tags match type parameters
			} else if (typeVariables.length == typeParametersLength) {
				TypeVariableBinding[] bindings = new TypeVariableBinding[paramTypeParamLength];

				// Scan all @param tags
				for (int i = 0; i < paramTypeParamLength; i++) {
					JavadocSingleTypeReference param = this.paramTypeParameters[i];
					TypeBinding paramBindind = param.internalResolveType(scope, 0);
					if (paramBindind != null && paramBindind.isValidBinding()) {
						if (paramBindind.isTypeVariable()) {
							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=397888
							if (scope.compilerOptions().reportUnusedParameterIncludeDocCommentReference) {
								TypeVariableBinding typeVariableBinding = (TypeVariableBinding) paramBindind;
								typeVariableBinding.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
							}
							// Verify duplicated tags
							boolean duplicate = false;
							for (int j = 0; j < i && !duplicate; j++) {
								if (TypeBinding.equalsEquals(bindings[j], param.resolvedType)) {
									scope.problemReporter().javadocDuplicatedParamTag(param.token, param.sourceStart, param.sourceEnd, modifiers);
									duplicate = true;
								}
							}
							if (!duplicate) {
								bindings[i] = (TypeVariableBinding) param.resolvedType;
							}
						} else {
							scope.problemReporter().javadocUndeclaredParamTagName(param.token, param.sourceStart, param.sourceEnd, modifiers);
						}
					}
				}

				// Look for undocumented type parameters
				for (int i = 0; i < typeParametersLength; i++) {
					TypeParameter parameter = parameters[i];
					boolean found = false;
					for (int j = 0; j < paramTypeParamLength && !found; j++) {
						if (TypeBinding.equalsEquals(parameter.binding, bindings[j])) {
							found = true;
							bindings[j] = null;
						}
					}
					if (!found && reportMissing) {
						scope.problemReporter().javadocMissingParamTag(parameter.name, parameter.sourceStart, parameter.sourceEnd, modifiers);
					}
				}

				// Report invalid param
				for (int i=0; i<paramTypeParamLength; i++) {
					if (bindings[i] != null) {
						JavadocSingleTypeReference param = this.paramTypeParameters[i];
						scope.problemReporter().javadocUndeclaredParamTagName(param.token, param.sourceStart, param.sourceEnd, modifiers);
					}
				}
			}
		}
	}

	/*
	 * Resolve @throws/@exception tags while method scope
	 */
	private void resolveThrowsTags(MethodScope methScope, boolean reportMissing) {
		AbstractMethodDeclaration md = methScope.referenceMethod();
		int throwsTagsLength = this.exceptionReferences == null ? 0 : this.exceptionReferences.length;

		// If no referenced method (field initializer for example) then report a problem for each throws tag
		if (md == null) {
			for (int i = 0; i < throwsTagsLength; i++) {
				TypeReference typeRef = this.exceptionReferences[i];
				int start = typeRef.sourceStart;
				int end = typeRef.sourceEnd;
				if (typeRef instanceof JavadocQualifiedTypeReference) {
					start = ((JavadocQualifiedTypeReference) typeRef).tagSourceStart;
					end = ((JavadocQualifiedTypeReference) typeRef).tagSourceEnd;
				} else if (typeRef instanceof JavadocSingleTypeReference) {
					start = ((JavadocSingleTypeReference) typeRef).tagSourceStart;
					end = ((JavadocSingleTypeReference) typeRef).tagSourceEnd;
				}
				methScope.problemReporter().javadocUnexpectedTag(start, end);
			}
			return;
		}

		// If no throws tags then report a problem for each method thrown exception
		int boundExceptionLength = (md.binding == null) ? 0 : md.binding.thrownExceptions.length;
		int thrownExceptionLength = md.thrownExceptions == null ? 0 : md.thrownExceptions.length;
		if (throwsTagsLength == 0) {
			if (reportMissing) {
				for (int i = 0; i < boundExceptionLength; i++) {
					ReferenceBinding exceptionBinding = md.binding.thrownExceptions[i];
					if (exceptionBinding != null && exceptionBinding.isValidBinding()) { // flag only valid class name
						int j=i;
						while (j<thrownExceptionLength && TypeBinding.notEquals(exceptionBinding, md.thrownExceptions[j].resolvedType)) j++;
						if (j<thrownExceptionLength) {
							methScope.problemReporter().javadocMissingThrowsTag(md.thrownExceptions[j], md.binding.modifiers);
						}
					}
				}
			}
		} else {
			int maxRef = 0;
			TypeReference[] typeReferences = new TypeReference[throwsTagsLength];

			// Scan all @throws tags
			for (int i = 0; i < throwsTagsLength; i++) {
				TypeReference typeRef = this.exceptionReferences[i];
				typeRef.resolve(methScope);
				TypeBinding typeBinding = typeRef.resolvedType;

				if (typeBinding != null && typeBinding.isValidBinding() && typeBinding.isClass()) {
					// accept only valid class binding
					typeReferences[maxRef++] = typeRef;
				}
			}

			// Look for undocumented thrown exception
			for (int i = 0; i < boundExceptionLength; i++) {
				ReferenceBinding exceptionBinding = md.binding.thrownExceptions[i];
				if (exceptionBinding != null) exceptionBinding = (ReferenceBinding) exceptionBinding.erasure();
				boolean found = false;
				for (int j = 0; j < maxRef && !found; j++) {
					if (typeReferences[j] != null) {
						TypeBinding typeBinding = typeReferences[j].resolvedType;
						if (TypeBinding.equalsEquals(exceptionBinding, typeBinding)) {
							found = true;
							typeReferences[j] = null;
						}
					}
				}
				if (!found && reportMissing) {
					if (exceptionBinding != null && exceptionBinding.isValidBinding()) { // flag only valid class name
						int k=i;
						while (k<thrownExceptionLength && TypeBinding.notEquals(exceptionBinding, md.thrownExceptions[k].resolvedType)) k++;
						if (k<thrownExceptionLength) {
							methScope.problemReporter().javadocMissingThrowsTag(md.thrownExceptions[k], md.binding.modifiers);
						}
					}
				}
			}

			// Verify additional @throws tags
			for (int i = 0; i < maxRef; i++) {
				TypeReference typeRef = typeReferences[i];
				if (typeRef != null) {
					boolean compatible = false;
					// thrown exceptions subclasses are accepted
					for (int j = 0; j<thrownExceptionLength && !compatible; j++) {
						TypeBinding exceptionBinding = md.thrownExceptions[j].resolvedType;
						if (exceptionBinding != null) {
							compatible = typeRef.resolvedType.isCompatibleWith(exceptionBinding);
						}
					}

					//  If not compatible only complain on unchecked exception
					if (!compatible && !typeRef.resolvedType.isUncheckedException(false)) {
						methScope.problemReporter().javadocInvalidThrowsClassName(typeRef, md.binding.modifiers);
					}
				}
			}
		}
	}

	private void verifyTypeReference(Expression reference, Expression typeReference, Scope scope, boolean source15, ReferenceBinding resolvedType, int modifiers) {
		if (resolvedType.isValidBinding()) {
			int scopeModifiers = -1;

			// reference must have enough visibility to be used
			if (!canBeSeen(scope.problemReporter().options.reportInvalidJavadocTagsVisibility, modifiers)) {
				scope.problemReporter().javadocHiddenReference(typeReference.sourceStart, reference.sourceEnd, scope, modifiers);
				return;
			}

			// type reference must have enough visibility to be used
			if (reference != typeReference) {
				if (!canBeSeen(scope.problemReporter().options.reportInvalidJavadocTagsVisibility, resolvedType.modifiers)) {
					scope.problemReporter().javadocHiddenReference(typeReference.sourceStart, typeReference.sourceEnd, scope, resolvedType.modifiers);
					return;
				}
			}

			// member types
			if (resolvedType.isMemberType()) {
				ReferenceBinding topLevelType = resolvedType;
				// rebuild and store (in reverse order) compound name to handle embedded inner class
				int packageLength = topLevelType.fPackage.compoundName.length;
				int depth = resolvedType.depth();
				int idx = depth + packageLength;
				char[][] computedCompoundName = new char[idx+1][];
				computedCompoundName[idx] = topLevelType.sourceName;
				while (topLevelType.enclosingType() != null) {
					topLevelType = topLevelType.enclosingType();
					computedCompoundName[--idx] = topLevelType.sourceName;
				}

				// add package information
				for (int i = packageLength; --i >= 0;) {
					computedCompoundName[--idx] = topLevelType.fPackage.compoundName[i];
				}

				if (scope.kind != Scope.MODULE_SCOPE) {
					ClassScope topLevelScope = scope.classScope();
					// when scope is not on compilation unit type, then inner class may not be visible...
					if (topLevelScope.parent.kind != Scope.COMPILATION_UNIT_SCOPE ||
						!CharOperation.equals(topLevelType.sourceName, topLevelScope.referenceContext.name)) {
						topLevelScope = topLevelScope.outerMostClassScope();
						if (typeReference instanceof JavadocSingleTypeReference) {
							// inner class single reference can only be done in same unit
							if ((!source15 && depth == 1) || TypeBinding.notEquals(topLevelType, topLevelScope.referenceContext.binding)) {
								// search for corresponding import
								boolean hasValidImport = false;
								if (source15) {
									CompilationUnitScope unitScope = topLevelScope.compilationUnitScope();
									ImportBinding[] imports = unitScope.imports;
									int length = imports == null ? 0 : imports.length;
									mainLoop: for (int i=0; i<length; i++) {
										char[][] compoundName = imports[i].compoundName;
										int compoundNameLength = compoundName.length;
										if ((imports[i].onDemand && compoundNameLength == computedCompoundName.length-1)
												|| (compoundNameLength == computedCompoundName.length)) {
											for (int j = compoundNameLength; --j >= 0;) {
												if (CharOperation.equals(imports[i].compoundName[j], computedCompoundName[j])) {
													if (j == 0) {
														hasValidImport = true;
														ImportReference importReference = imports[i].reference;
														if (importReference != null) {
															importReference.bits |= ASTNode.Used;
														}
														break mainLoop;
													}
												} else {
													break;
												}
											}
										}
									}
									if (!hasValidImport) {
										if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
										scope.problemReporter().javadocInvalidMemberTypeQualification(typeReference.sourceStart, typeReference.sourceEnd, scopeModifiers);
									}
								} else {
									if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
									scope.problemReporter().javadocInvalidMemberTypeQualification(typeReference.sourceStart, typeReference.sourceEnd, scopeModifiers);
									return;
								}
							}
						}
					}
					if (typeReference instanceof JavadocQualifiedTypeReference && !scope.isDefinedInSameUnit(resolvedType)) {
						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=222188
						// partially qualified references from a different CU should be warned
						char[][] typeRefName = ((JavadocQualifiedTypeReference) typeReference).getTypeName();
						int skipLength = 0;
						if (topLevelScope.getCurrentPackage() == resolvedType.getPackage()
								&& typeRefName.length < computedCompoundName.length) {
							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=221539: references can be partially qualified
							// in same package and hence if the package name is not given, ignore package name check
							skipLength = resolvedType.fPackage.compoundName.length;
						}
						boolean valid = true;
						if (typeRefName.length == computedCompoundName.length - skipLength) {
							checkQualification: for (int i = 0; i < typeRefName.length; i++) {
								if (!CharOperation.equals(typeRefName[i], computedCompoundName[i + skipLength])) {
									valid = false;
									break checkQualification;
								}
							}
						} else {
							valid = false;
						}
						// report invalid reference
						if (!valid) {
							if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
							scope.problemReporter().javadocInvalidMemberTypeQualification(typeReference.sourceStart, typeReference.sourceEnd, scopeModifiers);
							return;
						}
					}
				}
			}
			/*
			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=286918
			 *
			 * We are concerned only about the Single type references (i.e. without any package) If they are not in default package,
			 * then report an error. References with qualified yet incorrect names would have already been taken care of.
			 */
			if (scope.referenceCompilationUnit().isPackageInfo() && typeReference instanceof JavadocSingleTypeReference) {
				if (resolvedType.fPackage.compoundName.length > 0) {
					scope.problemReporter().javadocInvalidReference(typeReference.sourceStart, typeReference.sourceEnd);
					return; // Not really needed - just in case more code added in future
				}
			}
		}
	}

	@Override
	public void traverse(ASTVisitor visitor, BlockScope scope) {
		if (visitor.visit(this, scope)) {
			if (this.paramReferences != null) {
				for (int i = 0, length = this.paramReferences.length; i < length; i++) {
					this.paramReferences[i].traverse(visitor, scope);
				}
			}
			if (this.paramTypeParameters != null) {
				for (int i = 0, length = this.paramTypeParameters.length; i < length; i++) {
					this.paramTypeParameters[i].traverse(visitor, scope);
				}
			}
			if (this.returnStatement != null) {
				this.returnStatement.traverse(visitor, scope);
			}
			if (this.exceptionReferences != null) {
				for (int i = 0, length = this.exceptionReferences.length; i < length; i++) {
					this.exceptionReferences[i].traverse(visitor, scope);
				}
			}
			if (this.seeReferences != null) {
				for (int i = 0, length = this.seeReferences.length; i < length; i++) {
					this.seeReferences[i].traverse(visitor, scope);
				}
			}
		}
		visitor.endVisit(this, scope);
	}
	public void traverse(ASTVisitor visitor, ClassScope scope) {
		if (visitor.visit(this, scope)) {
			if (this.paramReferences != null) {
				for (int i = 0, length = this.paramReferences.length; i < length; i++) {
					this.paramReferences[i].traverse(visitor, scope);
				}
			}
			if (this.paramTypeParameters != null) {
				for (int i = 0, length = this.paramTypeParameters.length; i < length; i++) {
					this.paramTypeParameters[i].traverse(visitor, scope);
				}
			}
			if (this.returnStatement != null) {
				this.returnStatement.traverse(visitor, scope);
			}
			if (this.exceptionReferences != null) {
				for (int i = 0, length = this.exceptionReferences.length; i < length; i++) {
					this.exceptionReferences[i].traverse(visitor, scope);
				}
			}
			if (this.seeReferences != null) {
				for (int i = 0, length = this.seeReferences.length; i < length; i++) {
					this.seeReferences[i].traverse(visitor, scope);
				}
			}
		}
		visitor.endVisit(this, scope);
	}
}
