package org.eclipse.jdt.internal.compiler.problem;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.*;
import org.eclipse.jdt.internal.compiler.util.*;
import org.eclipse.jdt.internal.compiler.impl.*;

public class ProblemReporter extends ProblemHandler implements ProblemIrritants, ProblemReasons{
	public ReferenceContext referenceContext;
public ProblemReporter(IErrorHandlingPolicy policy, CompilerOptions options, IProblemFactory problemFactory) {
	super(policy, options, problemFactory);
}
public void abortDueToInternalError(String errorMessage) {
	this.handle(
		UnclassifiedProblem,
		new String[] {errorMessage},
		Error | Abort,
		0,
		0);
}
public void abortDueToInternalError(String errorMessage, AstNode location) {
	this.handle(
		UnclassifiedProblem,
		new String[] {errorMessage},
		Error | Abort,
		location.sourceStart,
		location.sourceEnd);
}
public void abstractMethodCannotBeOverridden(SourceTypeBinding type, MethodBinding concreteMethod) {

	this.handle(
		// %1 must be abstract since it cannot override the inherited package-private abstract method %2
		AbstractMethodCannotBeOverridden,
		new String[] {new String(type.sourceName()), new String(concreteMethod.readableName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void abstractMethodInAbstractClass(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
	this.handle(
		AbstractMethodInAbstractClass,
		new String[] {new String(type.sourceName()), new String(methodDecl.selector)},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void abstractMethodMustBeImplemented(SourceTypeBinding type, MethodBinding abstractMethod) {
	this.handle(
		// Must implement the inherited abstract method %1
		// 8.4.3 - Every non-abstract subclass of an abstract type, A, must provide a concrete implementation of all of A's methods.
		AbstractMethodMustBeImplemented,
		new String[] {
			new String(
				CharOperation.concat(
					abstractMethod.declaringClass.readableName(),
					abstractMethod.readableName(),
					'.'))},
		type.sourceStart(),
		type.sourceEnd());
}
public void abstractMethodNeedingNoBody(AbstractMethodDeclaration method, CompilationResult result) {
	this.handle(
		BodyForAbstractMethod,
		new String[0],
		method.sourceStart,
		method.sourceEnd,
		method,
		result);
}
public void alreadyDefinedLabel(char[] labelName, AstNode location) {
	this.handle(
		DuplicateLabel,
		new String[] {new String(labelName)},
		location.sourceStart,
		location.sourceEnd);
}
public void anonymousClassCannotExtendFinalClass(Expression expression, TypeBinding type) {
	this.handle(
		AnonymousClassCannotExtendFinalClass,
		new String[] {new String(type.readableName())},
		expression.sourceStart,
		expression.sourceEnd);
}
public void argumentTypeCannotBeVoid(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, Argument arg) {
	this.handle(
		ArgumentTypeCannotBeVoid,
		new String[] {new String(methodDecl.selector), new String(arg.name)},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void argumentTypeCannotBeVoidArray(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, Argument arg) {
	this.handle(
		ArgumentTypeCannotBeVoidArray,
		new String[] {new String(methodDecl.selector), new String(arg.name)},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void argumentTypeProblem(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, Argument arg, TypeBinding expectedType) {
	int problemId = expectedType.problemId();
	switch (problemId) {
		case NotFound : // 1
		case NotVisible : // 2
		case Ambiguous : // 3
		case InternalNameProvided : // 4
		case InheritedNameHidesEnclosingName : // 5
			this.handle(
				ArgumentProblemBase + problemId,
				new String[] {new String(methodDecl.selector), arg.name(), new String(expectedType.readableName())},
				arg.type.sourceStart,
				arg.type.sourceEnd);
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}
}
public void arrayConstantsOnlyInArrayInitializers(int sourceStart, int sourceEnd) {
	this.handle(
		ArrayConstantsOnlyInArrayInitializers,
		new String[0],
		sourceStart,
		sourceEnd);
}
public void attemptToReturnNonVoidExpression(ReturnStatement returnStatement, TypeBinding expectedType) {
	this.handle(
		VoidMethodReturnsValue,
		new String[] {new String(expectedType.readableName())},
		returnStatement.sourceStart,
		returnStatement.sourceEnd);
}
public void attemptToReturnVoidValue(ReturnStatement returnStatement) {
	this.handle(
		MethodReturnsVoid,
		new String[] {},
		returnStatement.sourceStart,
		returnStatement.sourceEnd);
}
public void bytecodeExceeds64KLimit(AbstractMethodDeclaration location) {
	this.handle(
		BytecodeExceeds64KLimit,
		new String[] {new String(location.selector)},
		Error | Abort,
		location.sourceStart,
		location.sourceEnd);
}
public void bytecodeExceeds64KLimit(TypeDeclaration location) {
	this.handle(
		BytecodeExceeds64KLimitForClinit,
		new String[0],
		Error | Abort,
		location.sourceStart,
		location.sourceEnd);
}
public void cannotAllocateVoidArray(Expression expression) {
	this.handle(
		CannotAllocateVoidArray,
		new String[] {},
		expression.sourceStart,
		expression.sourceEnd);
}
public void cannotAssignToFinalField(FieldBinding field, AstNode location) {
	this.handle(
		FinalFieldAssignment,
		new String[] {
			(field.declaringClass == null ? "array" : new String(field.declaringClass.readableName())), //$NON-NLS-1$
			new String(field.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void cannotAssignToFinalOuterLocal(LocalVariableBinding local, AstNode location) {
	this.handle(
		FinalOuterLocalAssignment,
		new String[] {new String(local.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void cannotDeclareLocalInterface(char[] interfaceName, int sourceStart, int sourceEnd) {
	this.handle(
		CannotDefineInterfaceInLocalType,
		new String[] {new String(interfaceName)},
		sourceStart,
		sourceEnd);
}
public void cannotDefineDimensionsAndInitializer(ArrayAllocationExpression expresssion) {
	this.handle(
		CannotDefineDimensionExpressionsWithInit,
		new String[0],
		expresssion.sourceStart,
		expresssion.sourceEnd);
}
public void cannotDireclyInvokeAbstractMethod(MessageSend messageSend, MethodBinding method) {
	this.handle(
		DirectInvocationOfAbstractMethod,
		new String[] {new String(method.declaringClass.readableName()), new String(method.selector), parametersAsString(method)},
		messageSend.sourceStart,
		messageSend.sourceEnd);
}
public void cannotImportPackage(ImportReference importRef) {
	this.handle(
		CannotImportPackage,
		new String[] {CharOperation.toString(importRef.tokens)},
		importRef.sourceStart,
		importRef.sourceEnd);
}
public void cannotInstantiate(TypeReference typeRef, TypeBinding type) {
	this.handle(
		InvalidClassInstantiation,
		new String[] {new String(type.readableName())},
		typeRef.sourceStart,
		typeRef.sourceEnd);
}
public void cannotReferToNonFinalOuterLocal(LocalVariableBinding local, AstNode location) {
	this.handle(
		OuterLocalMustBeFinal,
		new String[] {new String(local.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void cannotReturnInInitializer(AstNode location) {
	this.handle(
		CannotReturnInInitializer,
		new String[0],
		location.sourceStart,
		location.sourceEnd);
}
public void cannotThrowNull(ThrowStatement statement) {
	this.handle(
		CannotThrowNull,
		new String[0],
		statement.sourceStart,
		statement.sourceEnd);
}
public void cannotThrowType(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, TypeReference exceptionType, TypeBinding expectedType) {
	this.handle(
		CannotThrowType,
		new String[] {new String(expectedType.readableName())},
		exceptionType.sourceStart,
		exceptionType.sourceEnd);
}
public void cannotUseSuperInJavaLangObject(AstNode reference) {
	this.handle(
		ObjectHasNoSuperclass,
		new String[0],
		reference.sourceStart,
		reference.sourceEnd);
}
public void cannotUseSuperInCodeSnippet(int start, int end) {
	this.handle(
		CannotUseSuperInCodeSnippet,
		new String[0],
		Error | Abort,
		start,
		end);
}
public void caseExpressionMustBeConstant(Expression expression) {
	this.handle(
		NonConstantExpression,
		new String[0],
		expression.sourceStart,
		expression.sourceEnd);
}
public void classExtendFinalClass(SourceTypeBinding type, TypeReference superclass, TypeBinding expectedType) {
	this.handle(
		ClassExtendFinalClass,
		new String[] {new String(expectedType.readableName()), new String(type.sourceName())},
		superclass.sourceStart,
		superclass.sourceEnd);
}
public void codeSnippetMissingClass(String missing, int start, int end) {
	this.handle(
		CodeSnippetMissingClass,
		new String[]{ missing },
		Error | Abort,
		start,
		end);
}
public void codeSnippetMissingMethod(String className, String missingMethod, String argumentTypes, int start, int end) {
	this.handle(
		CodeSnippetMissingMethod,
		new String[]{ className, missingMethod, argumentTypes },
		Error | Abort,
		start,
		end);
}
/*
 * Given the current configuration, answers which category the problem
 * falls into:
 *		Error | Warning | Ignore
 */
public int computeSeverity(int problemId){

	// severity can have been preset on the problem
//	if ((problem.severity & Fatal) != 0){
//		return Error;
//	}

	// if not then check whether it is a configurable problem
	int errorThreshold = options.errorThreshold;
	int warningThreshold = options.warningThreshold;
	
	switch(problemId){

		case UnreachableCatch :
		case CodeCannotBeReached :
			if ((errorThreshold & CompilerOptions.UnreachableCode) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.UnreachableCode) != 0){
				return Warning;
			}
			return Ignore;

		case MaskedCatch : 
			if ((errorThreshold & CompilerOptions.MaskedCatchBlock) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.MaskedCatchBlock) != 0){
				return Warning;
			}
			return Ignore;
			
/*
		case Never Used  :
			if ((errorThreshold & ParsingOptionalError) != 0){
				return Error;
			}
			if ((warningThreshold & ParsingOptionalError) != 0){
				return Warning;
			}
			return Ignore;
*/
		case ImportProblemBase + NotFound :
		case ImportProblemBase + NotVisible :
		case ImportProblemBase + Ambiguous :
		case ImportProblemBase + InternalNameProvided :
		case ImportProblemBase + InheritedNameHidesEnclosingName :
		case DuplicateImport :
		case ConflictingImport :
		case CannotImportPackage :
			if ((errorThreshold & CompilerOptions.ImportProblem) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.ImportProblem) != 0){
				return Warning;
			}
			return Ignore;
/*		
		case UnnecessaryEnclosingInstanceSpecification :
			if ((errorThreshold & UnnecessaryEnclosingInstance) != 0){
				return Error;
			}
			if ((warningThreshold & UnnecessaryEnclosingInstance) != 0){
				return Warning;
			}
			return Ignore;
*/		
		case MethodButWithConstructorName :
			if ((errorThreshold & CompilerOptions.MethodWithConstructorName) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.MethodWithConstructorName) != 0){
				return Warning;
			}
			return Ignore;
		
		case OverridingNonVisibleMethod :
			if ((errorThreshold & CompilerOptions.OverriddenPackageDefaultMethod) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.OverriddenPackageDefaultMethod) != 0){
				return Warning;
			}
			return Ignore;

		case OverridingDeprecatedMethod :				
		case UsingDeprecatedType :				
		case UsingDeprecatedMethod :
		case UsingDeprecatedConstructor :
		case UsingDeprecatedField :
			if ((errorThreshold & CompilerOptions.UsingDeprecatedAPI) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.UsingDeprecatedAPI) != 0){
				return Warning;
			}
			return Ignore;
		
		case LocalVariableIsNeverUsed :
			if ((errorThreshold & CompilerOptions.UnusedLocalVariable) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.UnusedLocalVariable) != 0){
				return Warning;
			}
			return Ignore;
		
		case ArgumentIsNeverUsed :
			if ((errorThreshold & CompilerOptions.UnusedArgument) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.UnusedArgument) != 0){
				return Warning;
			}
			return Ignore;

		case NoImplicitStringConversionForCharArrayExpression :
			if ((errorThreshold & CompilerOptions.NoImplicitStringConversion) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.NoImplicitStringConversion) != 0){
				return Warning;
			}
			return Ignore;

		case NeedToEmulateFieldReadAccess :
		case NeedToEmulateFieldWriteAccess :
		case NeedToEmulateMethodAccess :
		case NeedToEmulateConstructorAccess :			
			if ((errorThreshold & CompilerOptions.AccessEmulation) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.AccessEmulation) != 0){
				return Warning;
			}
			return Ignore;
		case NonExternalizedStringLiteral :
			if ((errorThreshold & CompilerOptions.NonExternalizedString) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.NonExternalizedString) != 0){
				return Warning;
			}
			return Ignore;
		case UseAssertAsAnIdentifier :
			if ((errorThreshold & CompilerOptions.AssertUsedAsAnIdentifier) != 0){
				return Error;
			}
			if ((warningThreshold & CompilerOptions.AssertUsedAsAnIdentifier) != 0){
				return Warning;
			}
			return Ignore;		
		default:
			return Error;
	}
}
public void conditionalArgumentsIncompatibleTypes(ConditionalExpression expression, TypeBinding trueType, TypeBinding falseType) {
	this.handle(
		IncompatibleTypesInConditionalOperator,
		new String[] {new String(trueType.readableName()), new String(falseType.readableName())},
		expression.sourceStart,
		expression.sourceEnd);
}
public void conflictingImport(ImportReference importRef) {
	this.handle(
		ConflictingImport,
		new String[] {CharOperation.toString(importRef.tokens)},
		importRef.sourceStart,
		importRef.sourceEnd);
}
public void constantOutOfFormat(NumberLiteral lit) {
	// the literal is not in a correct format
	// this code is called on IntLiteral and LongLiteral 
	// example 000811 ...the 8 is uncorrect.

	if ((lit instanceof LongLiteral) || (lit instanceof IntLiteral)) {
		char[] source = lit.source();
		try {
			final String Radix;
			final int radix;
			if ((source[1] == 'x') || (source[1] == 'X')) {
				radix = 16;
				Radix = "Hexa"; //$NON-NLS-1$
			} else {
				radix = 8;
				Radix = "Octal"; //$NON-NLS-1$
			}
			//look for the first digit that is incorrect
			int place = -1;
			label : for (int i = radix == 8 ? 1 : 2; i < source.length; i++) {
				if (Character.digit(source[i], radix) == -1) {
					place = i;
					break label;
				}
			}

			this.handle(
				NumericValueOutOfRange,
				new String[] {Radix + " " + new String(source) + " (digit " + new String(new char[] {source[place]}) + ")"}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				lit.sourceStart,
				lit.sourceEnd);
			return;
		} catch (IndexOutOfBoundsException ex) {}
	
		// just in case .... use a predefined error..
		// we should never come here...(except if the code changes !)
		this.constantOutOfRange(lit);
	}
}
public void constantOutOfRange(Literal lit) {
	// lit is some how out of range of it declared type
	// example 9999999999999999999999999999999999999999999999999999999999999999999

	this.handle(
		NumericValueOutOfRange,
		new String[] {new String(lit.source())},
		lit.sourceStart,
		lit.sourceEnd);
}
public void deprecatedField(FieldBinding field, AstNode location) {
	this.handle(
		UsingDeprecatedField,
		new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
		location.sourceStart,
		location.sourceEnd);
}
public void deprecatedMethod(MethodBinding method, AstNode location) {
	if (method.isConstructor())
		this.handle(
			UsingDeprecatedConstructor,
			new String[] {new String(method.declaringClass.readableName()), parametersAsString(method)},
			location.sourceStart,
			location.sourceEnd);
	else
		this.handle(
			UsingDeprecatedMethod,
			new String[] {new String(method.declaringClass.readableName()), new String(method.selector), parametersAsString(method)},
			location.sourceStart,
			location.sourceEnd);
}
public void deprecatedType(TypeBinding type, AstNode location) {
	if (location == null) return; // 1G828DN - no type ref for synthetic arguments
	this.handle(
		UsingDeprecatedType,
		new String[] {new String(type.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void duplicateCase(Case statement, Constant constant) {
	this.handle(
		DuplicateCase,
		new String[] {String.valueOf(constant.intValue())},
		statement.sourceStart,
		statement.sourceEnd);
}
public void duplicateDefaultCase(DefaultCase statement) {
	this.handle(
		DuplicateDefaultCase,
		new String[0],
		statement.sourceStart,
		statement.sourceEnd);
}
public void duplicateFieldInType(SourceTypeBinding type, FieldDeclaration fieldDecl) {
	this.handle(
		DuplicateField,
		new String[] {new String(type.sourceName()), fieldDecl.name()},
		fieldDecl.sourceStart,
		fieldDecl.sourceEnd);
}
public void duplicateImport(ImportReference importRef) {
	this.handle(
		DuplicateImport,
		new String[] {CharOperation.toString(importRef.tokens)},
		importRef.sourceStart,
		importRef.sourceEnd);
}
public void duplicateInitializationOfBlankFinalField(FieldBinding field, Reference reference) {
	this.handle(
		DuplicateBlankFinalFieldInitialization,
		new String[] {new String(field.readableName())},
		reference.sourceStart,
		reference.sourceEnd);
}
public void duplicateInitializationOfFinalLocal(LocalVariableBinding local, NameReference reference) {
	this.handle(
		DuplicateFinalLocalInitialization,
		new String[] {new String(local.readableName())},
		reference.sourceStart,
		reference.sourceEnd);
}
public void duplicateMethodInType(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
	this.handle(
		DuplicateMethod,
		new String[] {new String(methodDecl.selector), new String(type.sourceName())},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void duplicateModifierForField(ReferenceBinding type, FieldDeclaration fieldDecl) {
/* to highlight modifiers use:
	this.handle(
		new Problem(
			DuplicateModifierForField,
			new String[] {fieldDecl.name()},
			fieldDecl.modifiers.sourceStart,
			fieldDecl.modifiers.sourceEnd));
*/

	this.handle(
		DuplicateModifierForField,
		new String[] {fieldDecl.name()},
		fieldDecl.sourceStart,
		fieldDecl.sourceEnd);
}
public void duplicateModifierForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
	this.handle(
		DuplicateModifierForMethod,
		new String[] {new String(type.sourceName()), new String(methodDecl.selector)},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void duplicateModifierForType(SourceTypeBinding type) {
	this.handle(
		DuplicateModifierForType,
		new String[] {new String(type.sourceName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void duplicateModifierForVariable(LocalDeclaration localDecl) {
	this.handle(
		DuplicateModifierForVariable,
		new String[] {localDecl.name()},
		localDecl.sourceStart,
		localDecl.sourceEnd);
}
public void duplicateNestedType(TypeDeclaration typeDecl) {
	this.handle(
		DuplicateNestedType,
		new String[] {new String(typeDecl.name)},
		typeDecl.sourceStart,
		typeDecl.sourceEnd);
}
public void duplicateSuperinterface(SourceTypeBinding type, TypeDeclaration typeDecl, ReferenceBinding superType) {
	this.handle(
		DuplicateSuperInterface,
		new String[] {
			new String(superType.readableName()),
			new String(type.sourceName())},
		typeDecl.sourceStart,
		typeDecl.sourceEnd);
}
public void duplicateTypes(CompilationUnitDeclaration compUnitDecl, TypeDeclaration typeDecl) {
	this.referenceContext = typeDecl; // report the problem against the type not the entire compilation unit
	this.handle(
		DuplicateTypes,
		new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.name)},
		typeDecl.sourceStart,
		typeDecl.sourceEnd,
		compUnitDecl.compilationResult);
}
public void errorNoMethodFor(MessageSend messageSend, TypeBinding recType, TypeBinding[] params) {
	StringBuffer buffer = new StringBuffer();
	for (int i = 0, length = params.length; i < length; i++) {
		if (i != 0)
			buffer.append(", "); //$NON-NLS-1$
		buffer.append(new String(params[i].readableName()));
	}

	this.handle(
		recType.isArrayType() ? NoMessageSendOnArrayType : NoMessageSendOnBaseType,
		new String[] {new String(recType.readableName()), new String(messageSend.selector), buffer.toString()},
		messageSend.sourceStart,
		messageSend.sourceEnd);
}
public void errorThisSuperInStatic(AstNode reference) {
	this.handle(
		ThisInStaticContext,
		new String[] {reference.isSuper() ? "super" : "this"}, //$NON-NLS-2$ //$NON-NLS-1$
		reference.sourceStart,
		reference.sourceEnd);
}
public void exceptionTypeProblem(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, TypeReference exceptionType, TypeBinding expectedType) {
	int problemId = expectedType.problemId();
	switch (problemId) {
		case NotFound : // 1
		case NotVisible : // 2
		case Ambiguous : // 3
		case InternalNameProvided : // 4
		case InheritedNameHidesEnclosingName : // 5
			this.handle(
				ExceptionTypeProblemBase + problemId,
				new String[] {new String(methodDecl.selector), new String(expectedType.readableName())},
				exceptionType.sourceStart,
				exceptionType.sourceEnd);
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}
}
public void fieldsOrThisBeforeConstructorInvocation(ThisReference reference) {
	this.handle(
		ThisSuperDuringConstructorInvocation,
		new String[0],
		reference.sourceStart,
		reference.sourceEnd);
}
public void fieldTypeProblem(SourceTypeBinding type, FieldDeclaration fieldDecl, TypeBinding expectedType) {
	int problemId = expectedType.problemId();
	switch (problemId) {
		case NotFound : // 1
		case NotVisible : // 2
		case Ambiguous : // 3
		case InternalNameProvided : // 4
		case InheritedNameHidesEnclosingName : // 5
			this.handle(
				FieldTypeProblemBase + problemId,
				new String[] {fieldDecl.name(), new String(type.sourceName()), new String(expectedType.readableName())},
				fieldDecl.type.sourceStart,
				fieldDecl.type.sourceEnd);
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}
}
public void finalMethodCannotBeOverridden(MethodBinding currentMethod, MethodBinding inheritedMethod) {
	this.handle(
		// Cannot override the final method from %1
		// 8.4.3.3 - Final methods cannot be overridden or hidden.
		FinalMethodCannotBeOverridden,
		new String[] {new String(inheritedMethod.declaringClass.readableName())},
		currentMethod.sourceStart(),
		currentMethod.sourceEnd());
}
public void forwardReference(Reference reference, int indexInQualification, TypeBinding type) {
	this.handle(
		ReferenceToForwardField,
		new String[] {},
		reference.sourceStart,
		reference.sourceEnd);
}
// use this private API when the compilation unit result can be found through the
// reference context. Otherwise, use the other API taking a problem and a compilation result
// as arguments

private void handle(
	int problemId, 
	String[] problemArguments,
	int problemStartPosition, 
	int problemEndPosition){

	this.handle(
			problemId,
			problemArguments,
			problemStartPosition,
			problemEndPosition,
			referenceContext, 
			referenceContext == null ? null : referenceContext.compilationResult()); 
	referenceContext = null;
}
// use this private API when the compilation unit result can be found through the
// reference context. Otherwise, use the other API taking a problem and a compilation result
// as arguments

private void handle(
	int problemId, 
	String[] problemArguments,
	int severity,
	int problemStartPosition, 
	int problemEndPosition){

	this.handle(
			problemId,
			problemArguments,
			severity,
			problemStartPosition,
			problemEndPosition,
			referenceContext, 
			referenceContext == null ? null : referenceContext.compilationResult()); 
	referenceContext = null;
}
// use this private API when the compilation unit result cannot be found through the
// reference context. 

private void handle(
	int problemId, 
	String[] problemArguments,
	int problemStartPosition, 
	int problemEndPosition,
	CompilationResult unitResult){

	this.handle(
			problemId,
			problemArguments,
			problemStartPosition,
			problemEndPosition,
			referenceContext, 
			unitResult); 
	referenceContext = null;
}
public void hidingEnclosingType(TypeDeclaration typeDecl) {
	this.handle(
		HidingEnclosingType,
		new String[] {new String(typeDecl.name)},
		typeDecl.sourceStart,
		typeDecl.sourceEnd);
}
public void hierarchyCircularity(SourceTypeBinding sourceType, ReferenceBinding superType, TypeReference reference) {
	int start = 0;
	int end = 0;
	String typeName = ""; //$NON-NLS-1$

	if (reference == null) {	// can only happen when java.lang.Object is busted
		start = sourceType.sourceStart();
		end = sourceType.sourceEnd();
		typeName = new String(superType.readableName());
	} else {
		start = reference.sourceStart;
		end = reference.sourceEnd;
		typeName = CharOperation.toString(reference.getTypeName());
	}

	if (sourceType == superType)
		this.handle(
			HierarchyCircularitySelfReference,
			new String[] {new String(sourceType.sourceName()), typeName},
			start,
			end);
	else
		this.handle(
			HierarchyCircularity,
			new String[] {new String(sourceType.sourceName()), typeName},
			start,
			end);
}
public void hierarchyHasProblems(SourceTypeBinding type) {
	this.handle(
		HierarchyHasProblems,
		new String[] {new String(type.sourceName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void illegalAbstractModifierCombinationForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
	this.handle(
		IllegalAbstractModifierCombinationForMethod,
		new String[] {new String(type.sourceName()), new String(methodDecl.selector)},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void illegalModifierCombinationFinalAbstractForClass(SourceTypeBinding type) {
	this.handle(
		IllegalModifierCombinationFinalAbstractForClass,
		new String[] {new String(type.sourceName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void illegalModifierCombinationFinalVolatileForField(ReferenceBinding type, FieldDeclaration fieldDecl) {
	this.handle(
		IllegalModifierCombinationFinalVolatileForField,
		new String[] {fieldDecl.name()},
		fieldDecl.sourceStart,
		fieldDecl.sourceEnd);
}
public void illegalModifierForArgument(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, Argument arg) {
	this.handle(
		IllegalModifierForArgument,
		new String[] {new String(type.sourceName()), new String(methodDecl.selector), arg.name()},
		arg.sourceStart,
		arg.sourceEnd);
}
public void illegalModifierForClass(SourceTypeBinding type) {
	this.handle(
		IllegalModifierForClass,
		new String[] {new String(type.sourceName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void illegalModifierForField(ReferenceBinding type, FieldDeclaration fieldDecl) {
	this.handle(
		IllegalModifierForField,
		new String[] {fieldDecl.name()},
		fieldDecl.sourceStart,
		fieldDecl.sourceEnd);
}
public void illegalModifierForInterface(SourceTypeBinding type) {
	this.handle(
		IllegalModifierForInterface,
		new String[] {new String(type.sourceName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void illegalModifierForInterfaceField(ReferenceBinding type, FieldDeclaration fieldDecl) {
	this.handle(
		IllegalModifierForInterfaceField,
		new String[] {fieldDecl.name()},
		fieldDecl.sourceStart,
		fieldDecl.sourceEnd);
}
public void illegalModifierForInterfaceMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
	this.handle(
		IllegalModifierForInterfaceMethod,
		new String[] {new String(type.sourceName()), new String(methodDecl.selector)},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void illegalModifierForLocalClass(SourceTypeBinding type) {
	this.handle(
		IllegalModifierForLocalClass,
		new String[] {new String(type.sourceName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void illegalModifierForMemberClass(SourceTypeBinding type) {
	this.handle(
		IllegalModifierForMemberClass,
		new String[] {new String(type.sourceName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void illegalModifierForMemberInterface(SourceTypeBinding type) {
	this.handle(
		IllegalModifierForMemberInterface,
		new String[] {new String(type.sourceName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void illegalModifierForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
	this.handle(
		IllegalModifierForMethod,
		new String[] {new String(type.sourceName()), new String(methodDecl.selector)},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void illegalModifierForVariable(LocalDeclaration localDecl) {
	this.handle(
		IllegalModifierForVariable,
		new String[] {localDecl.name()},
		localDecl.sourceStart,
		localDecl.sourceEnd);
}
public void illegalPrimitiveOrArrayTypeForEnclosingInstance(TypeBinding enclosingType, AstNode location) {
	this.handle(
		IllegalPrimitiveOrArrayTypeForEnclosingInstance,
		new String[] {new String(enclosingType.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void illegalStaticModifierForMemberType(SourceTypeBinding type) {
	this.handle(
		IllegalStaticModifierForMemberType,
		new String[] {new String(type.sourceName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void illegalVisibilityModifierCombinationForField(ReferenceBinding type, FieldDeclaration fieldDecl) {
	this.handle(
		IllegalVisibilityModifierCombinationForField,
		new String[] {new String(fieldDecl.name())},
		fieldDecl.sourceStart,
		fieldDecl.sourceEnd);
}
public void illegalVisibilityModifierCombinationForMemberType(SourceTypeBinding type) {
	this.handle(
		IllegalVisibilityModifierCombinationForMemberType,
		new String[] {new String(type.sourceName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void illegalVisibilityModifierCombinationForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
	this.handle(
		IllegalVisibilityModifierCombinationForMethod,
		new String[] {new String(type.sourceName()), new String(methodDecl.selector)},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void illegalVisibilityModifierForInterfaceMemberType(SourceTypeBinding type) {
	this.handle(
		IllegalVisibilityModifierForInterfaceMemberType,
		new String[] {new String(type.sourceName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void importProblem(ImportReference importRef, Binding expectedImport) {
	int problemId = expectedImport.problemId();
	switch (problemId) {
		case NotFound : // 1
		case NotVisible : // 2
		case Ambiguous : // 3
		case InternalNameProvided : // 4
		case InheritedNameHidesEnclosingName : // 5
			this.handle(
				ImportProblemBase + problemId,
				new String[] {CharOperation.toString(importRef.tokens)},
				importRef.sourceStart,
				importRef.sourceEnd);
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}
}
public void incompatibleExceptionInThrowsClause(SourceTypeBinding type, MethodBinding currentMethod, MethodBinding inheritedMethod, ReferenceBinding exceptionType) {
	if (type == currentMethod.declaringClass)
		this.handle(
			// Exception %1 is not compatible with throws clause in %2
			// 9.4.4 - The type of exception in the throws clause is incompatible.
			IncompatibleExceptionInThrowsClause,
			new String[] {
				new String(exceptionType.sourceName()),
				new String(
					CharOperation.concat(
						inheritedMethod.declaringClass.readableName(),
						inheritedMethod.readableName(),
						'.'))},
			currentMethod.sourceStart(),
			currentMethod.sourceEnd());
	else	
		this.handle(
			// Exception %1 in throws clause of %2 is not compatible with %3
			// 9.4.4 - The type of exception in the throws clause is incompatible.
			IncompatibleExceptionInInheritedMethodThrowsClause,
			new String[] {
				new String(exceptionType.sourceName()),
				new String(
					CharOperation.concat(
						currentMethod.declaringClass.sourceName(),
						currentMethod.readableName(),
						'.')),
				new String(
					CharOperation.concat(
						inheritedMethod.declaringClass.readableName(),
						inheritedMethod.readableName(),
						'.'))},
			type.sourceStart(),
			type.sourceEnd());
}
public void incompatibleReturnType(MethodBinding currentMethod, MethodBinding inheritedMethod) {
	StringBuffer methodSignature = new StringBuffer();
	methodSignature
		.append(inheritedMethod.declaringClass.readableName())
		.append('.')
		.append(inheritedMethod.readableName());

	this.handle(
		// Return type is incompatible with %1
		// 9.4.2 - The return type from the method is incompatible with the declaration.
		IncompatibleReturnType,
		new String[] {methodSignature.toString()},
		currentMethod.sourceStart(),
		currentMethod.sourceEnd());
}
public void incorrectEnclosingInstanceReference(
	QualifiedThisReference reference, 
	TypeBinding qualificationType) {
		
	this.handle(
		IncorrectEnclosingInstanceReference, 
		new String[] { new String(qualificationType.readableName())}, 
		reference.sourceStart, 
		reference.sourceEnd); 
}
public void incorrectLocationForEmptyDimension(ArrayAllocationExpression expression, int index) {
	this.handle(
		IllegalDimension,
		new String[0],
		expression.dimensions[index + 1].sourceStart,
		expression.dimensions[index + 1].sourceEnd);
}
public void incorrectSwitchType(Expression expression, TypeBinding testType) {
	this.handle(
		IncorrectSwitchType,
		new String[] {new String(testType.readableName())},
		expression.sourceStart,
		expression.sourceEnd);
}
public void inheritedMethodReducesVisibility(SourceTypeBinding type, MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
	this.handle(
		// The method %1 cannot hide the public abstract method in %2
		InheritedMethodReducesVisibility,
		new String[] {
			new String(concreteMethod.readableName()),
			new String(abstractMethods[0].declaringClass.readableName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void inheritedMethodsHaveIncompatibleReturnTypes(SourceTypeBinding type, MethodBinding[] inheritedMethods, int length) {
	StringBuffer methodSignatures = new StringBuffer();
	for (int i = length; --i >= 0;) {
		methodSignatures
			.append(inheritedMethods[i].declaringClass.readableName())
			.append('.')
			.append(inheritedMethods[i].readableName());
		if (i != 0)
			methodSignatures.append(", "); //$NON-NLS-1$
	}

	this.handle(
		// Return type is incompatible with %1
		// 9.4.2 - The return type from the method is incompatible with the declaration.
		IncompatibleReturnType,
		new String[] {methodSignatures.toString()},
		type.sourceStart(),
		type.sourceEnd());
}
public void initializerMustCompleteNormally(FieldDeclaration fieldDecl) {
	this.handle(
		InitializerMustCompleteNormally,
		new String[0],
		fieldDecl.sourceStart,
		fieldDecl.sourceEnd);
}
public void innerTypesCannotDeclareStaticInitializers(ReferenceBinding innerType, AstNode location) {
	this.handle(
		CannotDefineStaticInitializerInLocalType,
		new String[] {new String(innerType.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void interfaceCannotHaveConstructors(ConstructorDeclaration constructor, CompilationResult result) {
	this.handle(
		InterfaceCannotHaveConstructors,
		new String[0],
		constructor.sourceStart,
		constructor.sourceEnd,
		constructor,
		result);
}
public void interfaceCannotHaveInitializers(SourceTypeBinding type, FieldDeclaration fieldDecl) {
	this.handle(
		InterfaceCannotHaveInitializers,
		new String[] {new String(type.sourceName())},
		fieldDecl.sourceStart,
		fieldDecl.sourceEnd);
}
public void invalidBreak(AstNode location) {
	this.handle(
		InvalidBreak,
		new String[0],
		location.sourceStart,
		location.sourceEnd);
}
public void invalidConstructor(Statement statement, MethodBinding method) {
	// CODE should be UPDATED according to error coding in the different method binding errors
	// The different targetted errors should be :
	// UndefinedConstructor
	//	NotVisibleConstructor
	//	AmbiguousConstructor

	int flag = UndefinedConstructor; //default...
	switch (method.problemId()) {
		case NotFound :
			flag = UndefinedConstructor;
			break;
		case NotVisible :
			flag = NotVisibleConstructor;
			break;
		case Ambiguous :
			flag = AmbiguousConstructor;
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}

	this.handle(
		flag,
		new String[] {new String(method.declaringClass.readableName()), parametersAsString(method)},
		statement.sourceStart,
		statement.sourceEnd);
}
public void invalidContinue(AstNode location) {
	this.handle(
		InvalidContinue,
		new String[0],
		location.sourceStart,
		location.sourceEnd);
}
public void invalidEnclosingType(Expression expression, TypeBinding type, TypeBinding enclosingType) {
	//CODE should be UPDATED according to error coding in the different type binding errors
	//The different targetted errors should be :
		//UndefinedType
		//NotVisibleType
		//AmbiguousType
		//InternalNameProvided

	int flag = UndefinedType; // default
	switch (type.problemId()) {
		case NotFound : // 1
			flag = UndefinedType;
			break;
		case NotVisible : // 2
			flag = NotVisibleType;
			break;
		case Ambiguous : // 3
			flag = AmbiguousType;
			break;
		case InternalNameProvided :
			flag = InternalTypeNameProvided;
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}

	this.handle(
		flag,
		new String[] {new String(enclosingType.readableName()) + "." + new String(type.readableName())}, //$NON-NLS-1$
		expression.sourceStart,
		expression.sourceEnd);
}
public void invalidExpressionAsStatement(Expression expression){
	this.handle(
		InvalidExpressionAsStatement,
		new String[0],
		expression.sourceStart,
		expression.sourceEnd);
}
public void invalidField(FieldReference fieldRef, TypeBinding searchedType) {
	int severity = Error;
	int flag = UndefinedField;
	FieldBinding field = fieldRef.binding;
	switch (field.problemId()) {
		case NotFound :
			flag = UndefinedField;
/* also need to check that the searchedType is the receiver type
			if (searchedType.isHierarchyInconsistent())
				severity = SecondaryError;
*/
			break;
		case NotVisible :
			flag = NotVisibleField;
			break;
		case Ambiguous :
			flag = AmbiguousField;
			break;
		case NonStaticReferenceInStaticContext :
			flag = NonStaticFieldFromStaticInvocation;
			break;
		case NonStaticReferenceInConstructorInvocation :
			flag = InstanceFieldDuringConstructorInvocation;
			break;
		case InheritedNameHidesEnclosingName :
			flag = InheritedFieldHidesEnclosingName;
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}

	this.handle(
		flag,
		new String[] {new String(field.readableName())},
		severity,
		fieldRef.sourceStart,
		fieldRef.sourceEnd);
}
public void invalidField(NameReference nameRef, FieldBinding field) {
	int flag = UndefinedField;
	switch (field.problemId()) {
		case NotFound :
			flag = UndefinedField;
			break;
		case NotVisible :
			flag = NotVisibleField;
			break;
		case Ambiguous :
			flag = AmbiguousField;
			break;
		case NonStaticReferenceInStaticContext :
			flag = NonStaticFieldFromStaticInvocation;
			break;
		case NonStaticReferenceInConstructorInvocation :
			flag = InstanceFieldDuringConstructorInvocation;
			break;
		case InheritedNameHidesEnclosingName :
			flag = InheritedFieldHidesEnclosingName;
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}
	this.handle(
		flag,
		new String[] {new String(field.readableName())},
		nameRef.sourceStart,
		nameRef.sourceEnd);
}
public void invalidField(QualifiedNameReference nameRef, FieldBinding field, int index, TypeBinding searchedType) {
	//the resolution of the index-th field of qname failed
	//qname.otherBindings[index] is the binding that has produced the error

	//The different targetted errors should be :
	//UndefinedField
	//NotVisibleField
	//AmbiguousField

	if (searchedType.isBaseType()) {
		this.handle(
			NoFieldOnBaseType,
			new String[] {
				new String(searchedType.readableName()),
				CharOperation.toString(CharOperation.subarray(nameRef.tokens, 0, index)),
				new String(nameRef.tokens[index])},
			nameRef.sourceStart,
			nameRef.sourceEnd);
		return;
	}

	int flag = UndefinedField;
	switch (field.problemId()) {
		case NotFound :
			flag = UndefinedField;
/* also need to check that the searchedType is the receiver type
			if (searchedType.isHierarchyInconsistent())
				severity = SecondaryError;
*/
			break;
		case NotVisible :
			flag = NotVisibleField;
			break;
		case Ambiguous :
			flag = AmbiguousField;
			break;
		case NonStaticReferenceInStaticContext :
			flag = NonStaticFieldFromStaticInvocation;
			break;
		case NonStaticReferenceInConstructorInvocation :
			flag = InstanceFieldDuringConstructorInvocation;
			break;
		case InheritedNameHidesEnclosingName :
			flag = InheritedFieldHidesEnclosingName;
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}
	this.handle(
		flag, 
		new String[] {CharOperation.toString(CharOperation.subarray(nameRef.tokens, 0, index + 1))},
		nameRef.sourceStart, 
		nameRef.sourceEnd); 
}
public void invalidMethod(MessageSend messageSend, MethodBinding method) {
	// CODE should be UPDATED according to error coding in the different method binding errors
	// The different targetted errors should be :
	// 	UndefinedMethod
	//	NotVisibleMethod
	//	AmbiguousMethod
	//  InheritedNameHidesEnclosingName
	//	InstanceMethodDuringConstructorInvocation
	// StaticMethodRequested

	int flag = UndefinedMethod; //default...
	switch (method.problemId()) {
		case NotFound :
			flag = UndefinedMethod;
			break;
		case NotVisible :
			flag = NotVisibleMethod;
			break;
		case Ambiguous :
			flag = AmbiguousMethod;
			break;
		case InheritedNameHidesEnclosingName :
			flag = InheritedMethodHidesEnclosingName;
			break;
		case NonStaticReferenceInConstructorInvocation :
			flag = InstanceMethodDuringConstructorInvocation;
			break;
		case NonStaticReferenceInStaticContext :
			flag = StaticMethodRequested;
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}

	if (flag == UndefinedMethod) {
		ProblemMethodBinding problemMethod = (ProblemMethodBinding) method;
		if (problemMethod.closestMatch != null) {
				this.handle(
					ParameterMismatch,
					new String[] {
						new String(problemMethod.closestMatch.declaringClass.readableName()),
						new String(problemMethod.closestMatch.selector),
						parametersAsString(problemMethod.closestMatch),
						parametersAsString(method)},
					(int) (messageSend.nameSourcePosition >>> 32),
					(int) messageSend.nameSourcePosition);
				return;
		}
	}

	this.handle(
		flag,
		new String[] {
			new String(method.declaringClass.readableName()),
			new String(method.selector), parametersAsString(method)},
		(int) (messageSend.nameSourcePosition >>> 32),
		(int) messageSend.nameSourcePosition);
}
public void invalidNullToSynchronize(Expression expression) {
	this.handle(
		InvalidNullToSynchronized,
		new String[0],
		expression.sourceStart,
		expression.sourceEnd);
}
public void invalidOperator(BinaryExpression expression, TypeBinding leftType, TypeBinding rightType) {
	this.handle(
		InvalidOperator,
		new String[] {
			expression.operatorToString(),
			new String(leftType.readableName()) + ", " + new String(rightType.readableName())}, //$NON-NLS-1$
		expression.sourceStart,
		expression.sourceEnd);
}
public void invalidOperator(CompoundAssignment assign, TypeBinding leftType, TypeBinding rightType) {
	this.handle(
		InvalidOperator,
		new String[] {
			assign.operatorToString(),
			new String(leftType.readableName()) + ", " + new String(rightType.readableName())}, //$NON-NLS-1$
		assign.sourceStart,
		assign.sourceEnd);
}
public void invalidOperator(UnaryExpression expression, TypeBinding type) {
	this.handle(
		InvalidOperator,
		new String[] {expression.operatorToString(), new String(type.readableName())},
		expression.sourceStart,
		expression.sourceEnd);
}
public void invalidSuperclass(SourceTypeBinding type, TypeReference superclassRef, ReferenceBinding expectedType) {
	int problemId = expectedType.problemId();
	switch (problemId) {
		case NotFound : // 1
		case NotVisible : // 2
		case Ambiguous : // 3
		case InternalNameProvided : // 4
		case InheritedNameHidesEnclosingName : // 5
			this.handle(
				InvalidSuperclassBase + problemId,
				new String[] {new String(expectedType.readableName()), new String(type.sourceName())},
				superclassRef.sourceStart,
				superclassRef.sourceEnd);
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}
}
public void invalidSuperinterface(SourceTypeBinding type, TypeReference superinterfaceRef, ReferenceBinding expectedType) {
	int problemId = expectedType.problemId();
	switch (problemId) {
		case NotFound : // 1
		case NotVisible : // 2
		case Ambiguous : // 3
		case InternalNameProvided : // 4
		case InheritedNameHidesEnclosingName : // 5
			this.handle(
				InvalidInterfaceBase + problemId,
				new String[] {new String(expectedType.readableName()), new String(type.sourceName())},
				superinterfaceRef.sourceStart,
				superinterfaceRef.sourceEnd);
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}
}
public void invalidType(Expression expression, TypeBinding type) {
	// CODE should be UPDATED according to error coding in the different type binding errors
	//The different targetted errors should be :
		//UndefinedType
		//NotVisibleType
		//AmbiguousType
		//InternalTypeNameProvided
		//InheritedTypeHidesEnclosingName

	int flag = UndefinedType; // default
	switch (type.problemId()) {
		case NotFound :
			flag = UndefinedType;
			break;
		case NotVisible :
			flag = NotVisibleType;
			break;
		case Ambiguous :
			flag = AmbiguousType;
			break;
		case InternalNameProvided :
			flag = InternalTypeNameProvided;
			break;
		case InheritedNameHidesEnclosingName :
			flag = InheritedTypeHidesEnclosingName;
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}

	this.handle(
		flag,
		new String[] {new String(type.readableName())},
		expression.sourceStart,
		expression.sourceEnd);
}
public void invalidTypeReference(Expression expression) {
	this.handle(
		InvalidTypeExpression,
		new String[0],
		expression.sourceStart,
		expression.sourceEnd);
}
public void invalidTypeToSynchronize(Expression expression, TypeBinding type) {
	this.handle(
		InvalidTypeToSynchronized,
		new String[] {new String(type.readableName())},
		expression.sourceStart,
		expression.sourceEnd);
}
public void invalidUnaryExpression(Expression expression) {
	this.handle(
		InvalidUnaryExpression,
		new String[0],
		expression.sourceStart,
		expression.sourceEnd);
}
public void isClassPathCorrect(char[][] wellKnownTypeName, CompilationUnitDeclaration compUnitDecl) {
	referenceContext = compUnitDecl;
	this.handle(
		IsClassPathCorrect,
		new String[] {CharOperation.toString(wellKnownTypeName)}, 
		AbortCompilation | Error,
		compUnitDecl == null ? 0 : compUnitDecl.sourceStart,
		compUnitDecl == null ? 1 : compUnitDecl.sourceEnd);
}
public void maskedExceptionHandler(ReferenceBinding exceptionType, AstNode location) {
	this.handle(
		MaskedCatch,
		new String[0],
		location.sourceStart,
		location.sourceEnd);
}
public void methodNeedingAbstractModifier(MethodDeclaration methodDecl) {
	this.handle(
		MethodRequiresBody,
		new String[0],
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void methodNeedingNoBody(MethodDeclaration methodDecl) {
	this.handle(
		((methodDecl.modifiers & CompilerModifiers.AccNative) != 0) ? BodyForNativeMethod : BodyForAbstractMethod,
		new String[0],
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void methodWithConstructorName(MethodDeclaration methodDecl) {
	this.handle(
		MethodButWithConstructorName,
		new String[0],
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void missingEnclosingInstanceSpecification(ReferenceBinding enclosingType, AstNode location) {
	boolean insideConstructorCall =
		(location instanceof ExplicitConstructorCall)
			&& (((ExplicitConstructorCall) location).accessMode == ExplicitConstructorCall.ImplicitSuper);

	this.handle(
		insideConstructorCall
			? MissingEnclosingInstanceForConstructorCall
			: MissingEnclosingInstance,
		new String[] {new String(enclosingType.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void missingReturnType(AbstractMethodDeclaration methodDecl) {
	this.handle(
		MissingReturnType,
		new String[0],
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void mustDefineDimensionsOrInitializer(ArrayAllocationExpression expression) {
	this.handle(
		MustDefineEitherDimensionExpressionsOrInitializer,
		new String[0],
		expression.sourceStart,
		expression.sourceEnd);
}
public void mustSpecifyPackage(CompilationUnitDeclaration compUnitDecl) {
	this.handle(
		MustSpecifyPackage,
		new String[] {new String(compUnitDecl.getFileName())},
		compUnitDecl.sourceStart,
		compUnitDecl.sourceStart + 1);	
}
public void mustUseAStaticMethod(MessageSend messageSend, MethodBinding method) {
	this.handle(
		StaticMethodRequested,
		new String[] {new String(method.declaringClass.readableName()), new String(method.selector), parametersAsString(method)},
		messageSend.sourceStart,
		messageSend.sourceEnd);
}
public void nativeMethodsCannotBeStrictfp(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
	this.handle(
		NativeMethodsCannotBeStrictfp,
		new String[] {new String(type.sourceName()), new String(methodDecl.selector)},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void needImplementation() {
	this.abortDueToInternalError(Util.bind("abort.missingCode")); //$NON-NLS-1$
}
public void needToEmulateFieldReadAccess(FieldBinding field, AstNode location) {
	this.handle(
		NeedToEmulateFieldReadAccess,
		new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
		location.sourceStart,
		location.sourceEnd);
}
public void needToEmulateFieldWriteAccess(FieldBinding field, AstNode location) {
	this.handle(
		NeedToEmulateFieldWriteAccess,
		new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
		location.sourceStart,
		location.sourceEnd);
}
public void needToEmulateMethodAccess(
	MethodBinding method, 
	AstNode location) {

	if (method.isConstructor())
		this.handle(
			NeedToEmulateConstructorAccess, 
			new String[] {
				new String(method.declaringClass.readableName()), 
				parametersAsString(method)
			 }, 
			location.sourceStart, 
			location.sourceEnd); 
	else
		this.handle(
			NeedToEmulateMethodAccess, 
			new String[] {
				new String(method.declaringClass.readableName()), 
				new String(method.selector), 
				parametersAsString(method)
			 }, 
			location.sourceStart, 
			location.sourceEnd); 
}
public void nestedClassCannotDeclareInterface(TypeDeclaration typeDecl) {
	this.handle(
		CannotDefineInterfaceInLocalType,
		new String[] {new String(typeDecl.name)},
		typeDecl.sourceStart,
		typeDecl.sourceEnd);
}
public void noMoreAvailableSpaceForArgument(LocalVariableBinding local, AstNode location) {
	this.handle(
		TooManyArgumentSlots,
		new String[]{ new String(local.name) },
		Abort | Error,
		location.sourceStart,
		location.sourceEnd);
}
public void noMoreAvailableSpaceForLocal(LocalVariableBinding local, AstNode location) {
	this.handle(
		TooManyLocalVariableSlots,
		new String[]{ new String(local.name) },
		Abort | Error,
		location.sourceStart,
		location.sourceEnd);
}
public void notCompatibleTypesError(EqualExpression expression, TypeBinding leftType, TypeBinding rightType) {
	this.handle(
		IncompatibleTypesInEqualityOperator,
		new String[] {new String(leftType.readableName()), new String(rightType.readableName())},
		expression.sourceStart,
		expression.sourceEnd);
}
public void notCompatibleTypesError(InstanceOfExpression expression, TypeBinding leftType, TypeBinding rightType) {
	this.handle(
		IncompatibleTypesInConditionalOperator,
		new String[] {new String(leftType.readableName()), new String(rightType.readableName())},
		expression.sourceStart,
		expression.sourceEnd);
}
public void operatorOnlyValidOnNumericType(CompoundAssignment  assignment, TypeBinding leftType, TypeBinding rightType) {
	this.handle(
		TypeMismatch,
		new String[] {new String(leftType.readableName()), new String(rightType.readableName())},
		assignment.sourceStart,
		assignment.sourceEnd);
}
public void overridesDeprecatedMethod(MethodBinding currentMethod, MethodBinding inheritedMethod) {
	this.handle(
		OverridingDeprecatedMethod,
		new String[] {new String(inheritedMethod.declaringClass.readableName())},
		currentMethod.sourceStart(),
		currentMethod.sourceEnd());
}
public void overridesPackageDefaultMethod(MethodBinding localMethod, MethodBinding inheritedMethod) {
	this.handle(
		OverridingNonVisibleMethod,
		new String[] {
			new String(
					CharOperation.concat(
						localMethod.declaringClass.readableName(),
						localMethod.readableName(),
						'.')),
			new String(inheritedMethod.declaringClass.readableName())},
		localMethod.sourceStart(),
		localMethod.sourceEnd());
}
public void packageCollidesWithType(CompilationUnitDeclaration compUnitDecl) {
	this.handle(
		PackageCollidesWithType,
		new String[] {CharOperation.toString(compUnitDecl.currentPackage.tokens)},
		compUnitDecl.currentPackage.sourceStart,
		compUnitDecl.currentPackage.sourceEnd);
}
public void packageIsNotExpectedPackage(CompilationUnitDeclaration compUnitDecl) {
	this.handle(
		PackageIsNotExpectedPackage,
		new String[] {CharOperation.toString(compUnitDecl.compilationResult.compilationUnit.getPackageName())},
		compUnitDecl.currentPackage == null ? 0 : compUnitDecl.currentPackage.sourceStart,
		compUnitDecl.currentPackage == null ? 0 : compUnitDecl.currentPackage.sourceEnd);
}
private String parametersAsString(MethodBinding method) {
	TypeBinding[] params = method.parameters;
	StringBuffer buffer = new StringBuffer();
	for (int i = 0, length = params.length; i < length; i++) {
		if (i != 0)
			buffer.append(", "); //$NON-NLS-1$
		buffer.append(new String(params[i].readableName()));
	}
	return buffer.toString();
}
public void parseError(
	int startPosition, 
	int endPosition, 
	char[] currentTokenSource, 
	String errorTokenName, 
	String[] possibleTokens,
	ReferenceContext context,
	CompilationResult compilationResult) {
		
	if (possibleTokens.length == 0) { //no suggestion available
		if (isKeyword(currentTokenSource)) {
			this.handle(
				ParsingErrorOnKeywordNoSuggestion,
				new String[] {new String(currentTokenSource)},
				// this is the current -invalid- token position
				startPosition,
				endPosition,
				context,
				compilationResult);
			return;
		} else {
			this.handle(
				ParsingErrorNoSuggestion,
				new String[] {errorTokenName},
				// this is the current -invalid- token position
				startPosition,
				endPosition,
				context, 
				compilationResult);
			return;
		}
	}

	//build a list of probable right tokens
	StringBuffer list = new StringBuffer(20);
	for (int i = 0, max = possibleTokens.length; i < max; i++) {
		if (i > 0)
			list.append(", "); //$NON-NLS-1$
		list.append('"');
		list.append(possibleTokens[i]);
		list.append('"');
	}

	if (isKeyword(currentTokenSource)) {
		this.handle(
			ParsingErrorOnKeyword,
			new String[] {new String(currentTokenSource), list.toString()},
			// this is the current -invalid- token position
			startPosition,
			endPosition,
			context,
			compilationResult);
		return;
	}
	//extract the literal when it's a literal  
	if ((errorTokenName.equals("IntegerLiteral")) || //$NON-NLS-1$
		(errorTokenName.equals("LongLiteral")) || //$NON-NLS-1$
		(errorTokenName.equals("FloatingPointLiteral")) || //$NON-NLS-1$
		(errorTokenName.equals("DoubleLiteral")) || //$NON-NLS-1$
		(errorTokenName.equals("StringLiteral")) || //$NON-NLS-1$
		(errorTokenName.equals("CharacterLiteral")) || //$NON-NLS-1$
		(errorTokenName.equals("Identifier"))) { //$NON-NLS-1$
			errorTokenName = new String(currentTokenSource);
	}

	this.handle(
		ParsingError,
		new String[] {errorTokenName, list.toString()},
		// this is the current -invalid- token position
		startPosition,
		endPosition,
		context,
		compilationResult);
}
public void publicClassMustMatchFileName(CompilationUnitDeclaration compUnitDecl, TypeDeclaration typeDecl) {
	this.referenceContext = typeDecl; // report the problem against the type not the entire compilation unit
	this.handle(
		PublicClassMustMatchFileName,
		new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.name)},
		typeDecl.sourceStart,
		typeDecl.sourceEnd,
		compUnitDecl.compilationResult);
}
/*
 * Flag all constructors involved in a cycle, we know we have a cycle.
 */
public void recursiveConstructorInvocation(TypeDeclaration typeDeclaration) {

	// propagate the reference count, negative counts means leading to a super constructor invocation (directly or indirectly)
	boolean hasChanged;
	AbstractMethodDeclaration[] methods = typeDeclaration.methods;
	int max = methods.length;
	do {
		hasChanged = false;
		for(int i = 0; i < max; i++){
			if (methods[i].isConstructor()){
				ConstructorDeclaration constructor = (ConstructorDeclaration) methods[i];
				if (constructor.referenceCount > 0){
					ConstructorDeclaration targetConstructor = (ConstructorDeclaration)(typeDeclaration.declarationOf(constructor.constructorCall.binding));
					if ((targetConstructor == null) || (targetConstructor.referenceCount < 0)){
						hasChanged = true;
						constructor.referenceCount = -1;
					}	
				}
			}
		}
	} while (hasChanged);

	// all remaining constructors with a positive count are still involved in a cycle
	for(int i = 0; i < max; i++){
		if (methods[i].isConstructor()){
			ConstructorDeclaration constructor = (ConstructorDeclaration) methods[i];
			if (constructor.referenceCount > 0){
				this.referenceContext = constructor;
				this.handle(
					RecursiveConstructorInvocation,
					new String[] {
						new String(constructor.constructorCall.binding.declaringClass.readableName()), 
						parametersAsString(constructor.constructorCall.binding)
					},
					constructor.constructorCall.sourceStart,
					constructor.constructorCall.sourceEnd);
			}
		}
	}
}
public void redefineArgument(Argument arg) {
	this.handle(
		RedefinedArgument,
		new String[] {new String(arg.name)},
		arg.sourceStart,
		arg.sourceEnd);
}
public void redefineLocal(LocalDeclaration localDecl) {
	this.handle(
		RedefinedLocal,
		new String[] {new String(localDecl.name)},
		localDecl.sourceStart,
		localDecl.sourceEnd);
}
public void referenceMustBeArrayTypeAt(TypeBinding arrayType, ArrayReference arrayRef) {
	this.handle(
		ArrayReferenceRequired,
		new String[] {new String(arrayType.readableName())},
		arrayRef.sourceStart,
		arrayRef.sourceEnd);
}
public void returnTypeCannotBeVoidArray(SourceTypeBinding type, MethodDeclaration methodDecl) {
	this.handle(
		ReturnTypeCannotBeVoidArray,
		new String[] {new String(methodDecl.selector)},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void returnTypeProblem(SourceTypeBinding type, MethodDeclaration methodDecl, TypeBinding expectedType) {
	int problemId = expectedType.problemId();
	switch (problemId) {
		case NotFound : // 1
		case NotVisible : // 2
		case Ambiguous : // 3
		case InternalNameProvided : // 4
		case InheritedNameHidesEnclosingName : // 5
			this.handle(
				ReturnTypeProblemBase + problemId,
				new String[] {new String(methodDecl.selector), new String(expectedType.readableName())},
				methodDecl.returnType.sourceStart,
				methodDecl.returnType.sourceEnd);
			break;
		case NoError : // 0
		default :
			needImplementation(); // want to fail to see why we were here...
			break;
	}
}
public void scannerError(Parser parser, String errorTokenName) {
	Scanner scanner = parser.scanner;

	int flag = ParsingErrorNoSuggestion;
	int startPos = scanner.startPosition;

	//special treatment for recognized errors....
	if (errorTokenName.equals(Scanner.END_OF_SOURCE))
		flag = END_OF_SOURCE;
	else
		if (errorTokenName.equals(Scanner.INVALID_HEXA))
			flag = INVALID_HEXA;
		else
			if (errorTokenName.equals(Scanner.INVALID_OCTAL))
				flag = INVALID_OCTAL;
			else
				if (errorTokenName.equals(Scanner.INVALID_CHARACTER_CONSTANT))
					flag = INVALID_CHARACTER_CONSTANT;
				else
					if (errorTokenName.equals(Scanner.INVALID_ESCAPE))
						flag = INVALID_ESCAPE;
					else
						if (errorTokenName.equals(Scanner.INVALID_UNICODE_ESCAPE)){
							flag = INVALID_UNICODE_ESCAPE;
							// better locate the error message
							char[] source = scanner.source;
							int checkPos = scanner.currentPosition - 1;
							if (checkPos >= source.length) checkPos = source.length - 1;
							while (checkPos >= startPos){
								if (source[checkPos] == '\\') break;
								checkPos --;
							}
							startPos = checkPos;
						} else
							if (errorTokenName.equals(Scanner.INVALID_FLOAT))
								flag = INVALID_FLOAT;
							else
								if (errorTokenName.equals(Scanner.UNTERMINATED_STRING))
									flag = UNTERMINATED_STRING;
								else
									if (errorTokenName.equals(Scanner.UNTERMINATED_COMMENT))
										flag = UNTERMINATED_COMMENT;
									else
										if (errorTokenName.equals(Scanner.INVALID_CHAR_IN_STRING))
											flag = UNTERMINATED_STRING;

	this.handle(
		flag, 
		flag == ParsingErrorNoSuggestion 
			? new String[] {errorTokenName}
			: new String[0],
		// this is the current -invalid- token position
		startPos, 
		scanner.currentPosition - 1,
		parser.compilationUnit.compilationResult);
}
public void shouldReturn(TypeBinding returnType, AstNode location) {
	this.handle(
		ShouldReturnValue,
		new String[] { new String (returnType.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void signalNoImplicitStringConversionForCharArrayExpression(Expression expression) {
	this.handle(
		NoImplicitStringConversionForCharArrayExpression,
		new String[] {},
		expression.sourceStart,
		expression.sourceEnd);
}
public void staticAndInstanceConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) {
	if (currentMethod.isStatic())
		this.handle(
			// This static method cannot hide the instance method from %1
			// 8.4.6.4 - If a class inherits more than one method with the same signature a static (non-abstract) method cannot hide an instance method.
			CannotHideAnInstanceMethodWithAStaticMethod,
			new String[] {new String(inheritedMethod.declaringClass.readableName())},
			currentMethod.sourceStart(),
			currentMethod.sourceEnd());
	else
		this.handle(
			// This instance method cannot override the static method from %1
			// 8.4.6.4 - If a class inherits more than one method with the same signature an instance (non-abstract) method cannot override a static method.
			CannotOverrideAStaticMethodWithAnInstanceMethod,
			new String[] {new String(inheritedMethod.declaringClass.readableName())},
			currentMethod.sourceStart(),
			currentMethod.sourceEnd());
}
public void staticFieldAccessToNonStaticVariable(FieldReference fieldRef, FieldBinding field) {
	this.handle(
		NonStaticFieldFromStaticInvocation,
		new String[] {new String(field.readableName())},
		fieldRef.sourceStart,
		fieldRef.sourceEnd); 
}
public void staticFieldAccessToNonStaticVariable(QualifiedNameReference nameRef, FieldBinding field){
	this.handle(
		NonStaticFieldFromStaticInvocation,
		new String[] { new String(field.readableName())},
		nameRef.sourceStart,
		nameRef.sourceEnd);
}
public void staticFieldAccessToNonStaticVariable(SingleNameReference nameRef, FieldBinding field) {
	this.handle(
		NonStaticFieldFromStaticInvocation,
		new String[] {new String(field.readableName())},
		nameRef.sourceStart,
		nameRef.sourceEnd);
}
public void staticInheritedMethodConflicts(SourceTypeBinding type, MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
	this.handle(
		// The static method %1 conflicts with the abstract method in %2
		// 8.4.6.4 - If a class inherits more than one method with the same signature it is an error for one to be static (non-abstract) and the other abstract.
		StaticInheritedMethodConflicts,
		new String[] {
			new String(concreteMethod.readableName()),
			new String(abstractMethods[0].declaringClass.readableName())},
		type.sourceStart(),
		type.sourceEnd());
}
public void stringConstantIsExceedingUtf8Limit(AstNode location) {
	this.handle(
		StringConstantIsExceedingUtf8Limit,
		new String[0],
		location.sourceStart,
		location.sourceEnd);
}
public void superclassMustBeAClass(SourceTypeBinding type, TypeReference superclassRef, ReferenceBinding superType) {
	this.handle(
		SuperclassMustBeAClass,
		new String[] {new String(superType.readableName()), new String(type.sourceName())},
		superclassRef.sourceStart,
		superclassRef.sourceEnd);
}
public void superinterfaceMustBeAnInterface(SourceTypeBinding type, TypeDeclaration typeDecl, ReferenceBinding superType) {
	this.handle(
		SuperInterfaceMustBeAnInterface,
		new String[] {new String(superType.readableName()), new String(type.sourceName())},
		typeDecl.sourceStart,
		typeDecl.sourceEnd);
}
public void typeCastError(CastExpression expression, TypeBinding leftType, TypeBinding rightType) {
	this.handle(
		IllegalCast,
		new String[] {new String(rightType.readableName()), new String(leftType.readableName())},
		expression.sourceStart,
		expression.sourceEnd);
}
public void typeCollidesWithPackage(CompilationUnitDeclaration compUnitDecl, TypeDeclaration typeDecl) {
	this.referenceContext = typeDecl; // report the problem against the type not the entire compilation unit
	this.handle(
		TypeCollidesWithPackage,
		new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.name)},
		typeDecl.sourceStart,
		typeDecl.sourceEnd,
		compUnitDecl.compilationResult);
}
public void typeMismatchError(TypeBinding resultType, TypeBinding expectedType, AstNode location) {
	this.handle(
		TypeMismatch,
		new String[] {new String(resultType.readableName()), new String(expectedType.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void typeMismatchErrorActualTypeExpectedType(Expression expression, TypeBinding constantType, TypeBinding expectedType) {
	this.handle(
		TypeMismatch,
		new String[] {new String(constantType.readableName()), new String(expectedType.readableName())},
		expression.sourceStart,
		expression.sourceEnd);
}
public void undefinedLabel(BranchStatement statement) {
	this.handle(
		UndefinedLabel,
		new String[] {new String(statement.label)},
		statement.sourceStart,
		statement.sourceEnd);
}
public void unexpectedStaticModifierForField(SourceTypeBinding type, FieldDeclaration fieldDecl) {
	this.handle(
		UnexpectedStaticModifierForField,
		new String[] {fieldDecl.name()},
		fieldDecl.sourceStart,
		fieldDecl.sourceEnd);
}
public void unexpectedStaticModifierForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
	this.handle(
		UnexpectedStaticModifierForMethod,
		new String[] {new String(type.sourceName()), new String(methodDecl.selector)},
		methodDecl.sourceStart,
		methodDecl.sourceEnd);
}
public void unhandledException(TypeBinding exceptionType, AstNode location, Scope scope) {
	this.handle(
		scope.methodScope().isInsideInitializer()
			? CannotThrowCheckedExceptionInInitializer
			: (location instanceof AnonymousLocalTypeDeclaration
				? NoExceptionInAnonymousTypeConstructor
				: UnhandledException),
		new String[] {new String(exceptionType.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void uninitializedBlankFinalField(FieldBinding binding, AstNode location) {
	this.handle(
		UninitializedBlankFinalField,
		new String[] {new String(binding.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void uninitializedLocalVariable(LocalVariableBinding binding, AstNode location) {
	this.handle(
		UninitializedLocalVariable,
		new String[] {new String(binding.readableName())},
		location.sourceStart,
		location.sourceEnd);
}
public void unmatchedBracket(int position, ReferenceContext context, CompilationResult compilationResult) {

	this.handle(
		UnmatchedBracket, 
		new String[] {},
		position, 
		position,
		context,
		compilationResult);
}
public void unnecessaryEnclosingInstanceSpecification(Expression expression, ReferenceBinding targetType) {
	this.handle(
		IllegalEnclosingInstanceSpecification,
		new String[]{ new String(targetType.readableName())},
		expression.sourceStart,
		expression.sourceEnd);
}
public void unreachableCode(Statement statement) {
	this.handle(
		CodeCannotBeReached,
		new String[0],
		statement.sourceStart,
		statement.sourceEnd);
}
public void unreachableExceptionHandler(ReferenceBinding exceptionType, AstNode location) {
	this.handle(
		UnreachableCatch,
		new String[0],
		location.sourceStart,
		location.sourceEnd);
}
public void unresolvableReference(NameReference nameRef, Binding binding) {
	int severity = Error;
/* also need to check that the searchedType is the receiver type
	if (binding instanceof ProblemBinding) {
		ProblemBinding problem = (ProblemBinding) binding;
		if (problem.searchType != null && problem.searchType.isHierarchyInconsistent())
			severity = SecondaryError;
	}
*/
	this.handle(
		UndefinedName,
		new String[] {new String(binding.readableName())},
		severity,
		nameRef.sourceStart,
		nameRef.sourceEnd);
}
public void unusedArgument(LocalDeclaration localDecl) {
	this.handle(
		ArgumentIsNeverUsed,
		new String[] {localDecl.name()},
		localDecl.sourceStart,
		localDecl.sourceEnd);
}
public void unusedLocalVariable(LocalDeclaration localDecl) {
	this.handle(
		LocalVariableIsNeverUsed,
		new String[] {localDecl.name()},
		localDecl.sourceStart,
		localDecl.sourceEnd);
}

public void useAssertAsAnIdentifier(int sourceStart, int sourceEnd) {
	this.handle(
		UseAssertAsAnIdentifier,
		new String[0],
		sourceStart,
		sourceEnd);	
}

public void variableTypeCannotBeVoid(AbstractVariableDeclaration varDecl) {
	this.handle(
		VariableTypeCannotBeVoid,
		new String[] {new String(varDecl.name)},
		varDecl.sourceStart,
		varDecl.sourceEnd);
}
public void variableTypeCannotBeVoidArray(AbstractVariableDeclaration varDecl) {
	this.handle(
		VariableTypeCannotBeVoidArray,
		new String[] {new String(varDecl.name)},
		varDecl.sourceStart,
		varDecl.sourceEnd);
}
public void visibilityConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) {
	this.handle(
		//	Cannot reduce the visibility of the inherited method from %1
		// 8.4.6.3 - The access modifier of an hiding method must provide at least as much access as the hidden method.
		// 8.4.6.3 - The access modifier of an overiding method must provide at least as much access as the overriden method.
		MethodReducesVisibility,
		new String[] {new String(inheritedMethod.declaringClass.readableName())},
		currentMethod.sourceStart(),
		currentMethod.sourceEnd());
}
public void wrongSequenceOfExceptionTypesError(TryStatement statement, int under, int upper) {
	//the two catch block under and upper are in an incorrect order.
	//under should be define BEFORE upper in the source

	//notice that the compiler could arrange automatically the
	//correct order - and the only error would be on cycle ....
	//on this one again , java is compiler-driven instead of being
	//user-driven .....

	TypeReference typeRef = statement.catchArguments[under].type;
	this.handle(
		UnreachableCatch,
		new String[0],
		typeRef.sourceStart,
		typeRef.sourceEnd);
}

public void nonExternalizedStringLiteral(AstNode location) {
	this.handle(
		NonExternalizedStringLiteral,
		new String[] {},
		location.sourceStart,
		location.sourceEnd);
}

public void noMoreAvailableSpaceInConstantPool(TypeDeclaration typeDeclaration) {
	this.handle(
		TooManyConstantsInConstantPool,
		new String[]{ new String(typeDeclaration.binding.readableName())},
		Abort | Error,
		typeDeclaration.sourceStart,
		typeDeclaration.sourceEnd);
}

private boolean isKeyword(char[] tokenSource) {
	/*
	 * This code is heavily grammar dependant
	 */

	if (tokenSource == null) {
		return false;
	}
	try {
		Scanner scanner = new Scanner();
		scanner.setSourceBuffer(tokenSource);
		int token = scanner.getNextToken();
		char[] currentKeyword;
		try {
			currentKeyword = scanner.getCurrentIdentifierSource();
		} catch (ArrayIndexOutOfBoundsException e) {
			return false;
		}
		int nextToken= scanner.getNextToken();
		if (nextToken == TerminalSymbols.TokenNameEOF
			&& scanner.startPosition == scanner.source.length) { // to handle case where we had an ArrayIndexOutOfBoundsException 
															     // while reading the last token
			switch(token) {
				case Scanner.TokenNameERROR:
					if (CharOperation.equals("goto".toCharArray(), currentKeyword) ||CharOperation.equals("const".toCharArray(), currentKeyword)) { //$NON-NLS-1$ //$NON-NLS-2$
						return true;
					} else {
						return false;
					}
				case Scanner.TokenNameabstract:
				case Scanner.TokenNameassert:
				case Scanner.TokenNamebyte:
				case Scanner.TokenNamebreak:
				case Scanner.TokenNameboolean:
				case Scanner.TokenNamecase:
				case Scanner.TokenNamechar:
				case Scanner.TokenNamecatch:
				case Scanner.TokenNameclass:
				case Scanner.TokenNamecontinue:
				case Scanner.TokenNamedo:
				case Scanner.TokenNamedouble:
				case Scanner.TokenNamedefault:
				case Scanner.TokenNameelse:
				case Scanner.TokenNameextends:
				case Scanner.TokenNamefor:
				case Scanner.TokenNamefinal:
				case Scanner.TokenNamefloat:
				case Scanner.TokenNamefalse:
				case Scanner.TokenNamefinally:
				case Scanner.TokenNameif:
				case Scanner.TokenNameint:
				case Scanner.TokenNameimport:
				case Scanner.TokenNameinterface:
				case Scanner.TokenNameimplements:
				case Scanner.TokenNameinstanceof:
				case Scanner.TokenNamelong:
				case Scanner.TokenNamenew:
				case Scanner.TokenNamenull:
				case Scanner.TokenNamenative:
				case Scanner.TokenNamepublic:
				case Scanner.TokenNamepackage:
				case Scanner.TokenNameprivate:
				case Scanner.TokenNameprotected:
				case Scanner.TokenNamereturn:
				case Scanner.TokenNameshort:
				case Scanner.TokenNamesuper:
				case Scanner.TokenNamestatic:
				case Scanner.TokenNameswitch:
				case Scanner.TokenNamestrictfp:
				case Scanner.TokenNamesynchronized:
				case Scanner.TokenNametry:
				case Scanner.TokenNamethis:
				case Scanner.TokenNametrue:
				case Scanner.TokenNamethrow:
				case Scanner.TokenNamethrows:
				case Scanner.TokenNametransient:
				case Scanner.TokenNamevoid:
				case Scanner.TokenNamevolatile:
				case Scanner.TokenNamewhile:
					return true;
				default: 
					return false;
			}
		} else {
			return false;
		}
	}
	catch (InvalidInputException e) {
		return false;
	}
	
}
}
