/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.env.IDependent;

/*
Not all fields defined by this type (& its subclasses) are initialized when it is created.
Some are initialized only when needed.

Accessors have been provided for some public fields so all TypeBindings have the same API...
but access public fields directly whenever possible.
Non-public fields have accessors which should be used everywhere you expect the field to be initialized.

null is NOT a valid value for a non-public field... it just means the field is not initialized.
*/

abstract public class ReferenceBinding extends TypeBinding implements IDependent {
	
	public static ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */};
	
	public char[][] compoundName;
	public char[] sourceName;
	public int modifiers;
	public PackageBinding fPackage;

	char[] fileName;
	char[] constantPoolName;
	char[] signature;

public FieldBinding[] availableFields() {
	return fields();
}

public MethodBinding[] availableMethods() {
	return methods();
}	
/* Answer true if the receiver can be instantiated
*/

public boolean canBeInstantiated() {
	return (this.modifiers & (AccAbstract | AccInterface | AccEnum | AccAnnotation)) == 0;
}
/* Answer true if the receiver is visible to the invocationPackage.
*/

public final boolean canBeSeenBy(PackageBinding invocationPackage) {
	if (isPublic()) return true;
	if (isPrivate()) return false;

	// isProtected() or isDefault()
	return invocationPackage == fPackage;
}
/* Answer true if the receiver is visible to the receiverType and the invocationType.
*/

public final boolean canBeSeenBy(ReferenceBinding receiverType, SourceTypeBinding invocationType) {
	if (isPublic()) return true;

	if (invocationType == this && invocationType == receiverType) return true;

	if (isProtected()) {

		// answer true if the invocationType is the declaringClass or they are in the same package
		// OR the invocationType is a subclass of the declaringClass
		//    AND the invocationType is the invocationType or its subclass
		//    OR the type is a static method accessed directly through a type
		//    OR previous assertions are true for one of the enclosing type
		if (invocationType == this) return true;
		if (invocationType.fPackage == fPackage) return true;

		ReferenceBinding currentType = invocationType;
		ReferenceBinding declaringClass = enclosingType(); // protected types always have an enclosing one
		if (declaringClass == invocationType) return true;

		ReferenceBinding declaringErasure = (ReferenceBinding) declaringClass.erasure();
		if (declaringClass == null) return false; // could be null if incorrect top-level protected type
		//int depth = 0;
		do {
			if (currentType.findSuperTypeErasingTo(declaringErasure) != null) return true;
			//depth++;
			currentType = currentType.enclosingType();
		} while (currentType != null);
		return false;
	}

	if (isPrivate()) {
		// answer true if the receiverType is the receiver or its enclosingType
		// AND the invocationType and the receiver have a common enclosingType
		receiverCheck: {
			if (!(receiverType == this || receiverType == enclosingType())) {
				// special tolerance for type variable direct bounds
				if (receiverType.isTypeVariable()) {
					TypeVariableBinding typeVariable = (TypeVariableBinding) receiverType;
					if (typeVariable.isErasureBoundTo(this.erasure()) || typeVariable.isErasureBoundTo(enclosingType().erasure())) {
						break receiverCheck;
					}
				}
				return false;
			}
		}
		
		
		if (invocationType != this) {
			ReferenceBinding outerInvocationType = invocationType;
			ReferenceBinding temp = outerInvocationType.enclosingType();
			while (temp != null) {
				outerInvocationType = temp;
				temp = temp.enclosingType();
			}

			ReferenceBinding outerDeclaringClass = (ReferenceBinding)this.erasure();
			temp = outerDeclaringClass.enclosingType();
			while (temp != null) {
				outerDeclaringClass = temp;
				temp = temp.enclosingType();
			}
			if (outerInvocationType != outerDeclaringClass) return false;
		}
		return true;
	}

	// isDefault()
	if (invocationType.fPackage != fPackage) return false;

	ReferenceBinding type = receiverType;
	ReferenceBinding declaringClass = enclosingType() == null ? this : enclosingType();
	do {
		if (declaringClass == type) return true;
		if (fPackage != type.fPackage) return false;
	} while ((type = type.superclass()) != null);
	return false;
}
/* 
 * Answer true if the receiver is visible to the type provided by the scope.
 */

public final boolean canBeSeenBy(Scope scope) {
	
	if (isPublic()) return true;

	if (scope.kind == Scope.COMPILATION_UNIT_SCOPE){
		return this.canBeSeenBy(((CompilationUnitScope)scope).fPackage);
	}
	
	SourceTypeBinding invocationType = scope.enclosingSourceType();
	if (invocationType == this) return true;

	if (isProtected()) {
		// answer true if the invocationType is the declaringClass or they are in the same package
		// OR the invocationType is a subclass of the declaringClass
		//    AND the invocationType is the invocationType or its subclass
		//    OR the type is a static method accessed directly through a type
		//    OR previous assertions are true for one of the enclosing type
		if (invocationType.fPackage == fPackage) return true;

		ReferenceBinding currentType = invocationType;
		ReferenceBinding declaringClass = enclosingType(); // protected types always have an enclosing one
		if (declaringClass == null) return false; // could be null if incorrect top-level protected type
		// int depth = 0;
		do {
			if (declaringClass == invocationType) return true;
			if (declaringClass.isSuperclassOf(currentType)) return true;
			// depth++;
			currentType = currentType.enclosingType();
		} while (currentType != null);
		return false;
	}
	if (isPrivate()) {
		// answer true if the receiver and the invocationType have a common enclosingType
		// already know they are not the identical type
		ReferenceBinding outerInvocationType = invocationType;
		ReferenceBinding temp = outerInvocationType.enclosingType();
		while (temp != null) {
			outerInvocationType = temp;
			temp = temp.enclosingType();
		}

		ReferenceBinding outerDeclaringClass = (ReferenceBinding)this.erasure();
		temp = outerDeclaringClass.enclosingType();
		while (temp != null) {
			outerDeclaringClass = temp;
			temp = temp.enclosingType();
		}
		return outerInvocationType == outerDeclaringClass;
	}

	// isDefault()
	return invocationType.fPackage == fPackage;
}
public char[] computeGenericTypeSignature(TypeVariableBinding[] typeVariables) {
    if (typeVariables == NoTypeVariables) {
        return signature();
    } else {
	    char[] typeSig = signature();
	    StringBuffer sig = new StringBuffer(10);
	    for (int i = 0; i < typeSig.length-1; i++) { // copy all but trailing semicolon
	    	sig.append(typeSig[i]);
	    }
	    sig.append('<');
	    for (int i = 0, length = typeVariables.length; i < length; i++) {
	        sig.append(typeVariables[i].genericTypeSignature());
	    }
	    sig.append(">;"); //$NON-NLS-1$
		int sigLength = sig.length();
		char[] result = new char[sigLength];
		sig.getChars(0, sigLength, result, 0);
		return result;
    }
}
public void computeId() {
	
	switch (compoundName.length) {

		case 3 :
			if (!CharOperation.equals(JAVA, compoundName[0]))
				return;
		
			// remaining types MUST be in java.*.*
			if (!CharOperation.equals(LANG, compoundName[1])) {
				if (CharOperation.equals(JAVA_IO_PRINTSTREAM, compoundName))
					id = T_JavaIoPrintStream;
				else if (CharOperation.equals(JAVA_UTIL_ITERATOR, compoundName))
					id = T_JavaUtilIterator;
				else if (CharOperation.equals(JAVA_IO_SERIALIZABLE, compoundName))
				    id = T_JavaIoSerializable;
				return;
			}
		
			// remaining types MUST be in java.lang.*
			char[] typeName = compoundName[2];
			if (typeName.length == 0) return; // just to be safe
			switch (typeName[0]) {
				case 'A' :
					if (CharOperation.equals(typeName, JAVA_LANG_ASSERTIONERROR[2]))
						id = T_JavaLangAssertionError;
					return;
				case 'B' :
					if (CharOperation.equals(typeName, JAVA_LANG_BOOLEAN[2]))
						id = T_JavaLangBoolean;
					else if (CharOperation.equals(typeName, JAVA_LANG_BYTE[2]))
						id = T_JavaLangByte;
					return;
				case 'C' :
					if (CharOperation.equals(typeName, JAVA_LANG_CHARACTER[2]))
						id = T_JavaLangCharacter;
					else if (CharOperation.equals(typeName, JAVA_LANG_CLASS[2]))
						id = T_JavaLangClass;
					else if (CharOperation.equals(typeName, JAVA_LANG_CLASSNOTFOUNDEXCEPTION[2]))
						id = T_JavaLangClassNotFoundException;
					else if (CharOperation.equals(typeName, JAVA_LANG_CLONEABLE[2]))
					    id = T_JavaLangCloneable;
					return;
				case 'D' :
					if (CharOperation.equals(typeName, JAVA_LANG_DOUBLE[2]))
						id = T_JavaLangDouble;
					else if (CharOperation.equals(typeName, JAVA_LANG_DEPRECATED[2]))
						id = T_JavaLangDeprecated;
					return;
				case 'E' :
					if (CharOperation.equals(typeName, JAVA_LANG_ERROR[2]))
						id = T_JavaLangError;
					else if (CharOperation.equals(typeName, JAVA_LANG_EXCEPTION[2]))
						id = T_JavaLangException;
					else if (CharOperation.equals(typeName, JAVA_LANG_ENUM[2]))
						id = T_JavaLangEnum;
					return;
				case 'F' :
					if (CharOperation.equals(typeName, JAVA_LANG_FLOAT[2]))
						id = T_JavaLangFloat;
					return;
				case 'I' :
					if (CharOperation.equals(typeName, JAVA_LANG_INTEGER[2]))
						id = T_JavaLangInteger;
					else if (CharOperation.equals(typeName, JAVA_LANG_ITERABLE[2]))
						id = T_JavaLangIterable;
					else if (CharOperation.equals(typeName, JAVA_LANG_ILLEGALARGUMENTEXCEPTION[2]))
						id = T_JavaLangIllegalArgumentException;
					return;
				case 'L' :
					if (CharOperation.equals(typeName, JAVA_LANG_LONG[2]))
						id = T_JavaLangLong;
					return;
				case 'N' :
					if (CharOperation.equals(typeName, JAVA_LANG_NOCLASSDEFERROR[2]))
						id = T_JavaLangNoClassDefError;
					return;
				case 'O' :
					if (CharOperation.equals(typeName, JAVA_LANG_OBJECT[2]))
						id = T_JavaLangObject;
					else if (CharOperation.equals(typeName, JAVA_LANG_OVERRIDE[2]))
						id = T_JavaLangOverride;
					return;
				case 'S' :
					if (CharOperation.equals(typeName, JAVA_LANG_STRING[2]))
						id = T_JavaLangString;
					else if (CharOperation.equals(typeName, JAVA_LANG_STRINGBUFFER[2]))
						id = T_JavaLangStringBuffer;
					else if (CharOperation.equals(typeName, JAVA_LANG_STRINGBUILDER[2])) 
						id = T_JavaLangStringBuilder;
					else if (CharOperation.equals(typeName, JAVA_LANG_SYSTEM[2]))
						id = T_JavaLangSystem;
					else if (CharOperation.equals(typeName, JAVA_LANG_SHORT[2]))
						id = T_JavaLangShort;
					else if (CharOperation.equals(typeName, JAVA_LANG_SUPPRESSWARNINGS[2]))
						id = T_JavaLangSuppressWarnings;
					return;
				case 'T' :
					if (CharOperation.equals(typeName, JAVA_LANG_THROWABLE[2]))
						id = T_JavaLangThrowable;
					return;
				case 'V' :
					if (CharOperation.equals(typeName, JAVA_LANG_VOID[2]))
						id = T_JavaLangVoid;
					return;
			}
		break;
			
		case 4:
			if (!CharOperation.equals(JAVA, compoundName[0]))
				return;
			if (!CharOperation.equals(LANG, compoundName[1]))
				return;
			char[] packageName = compoundName[2];
			if (packageName.length == 0) return; // just to be safe			
			typeName = compoundName[3];
			if (typeName.length == 0) return; // just to be safe			
			if (CharOperation.equals(packageName, REFLECT)) {
				if (CharOperation.equals(typeName, JAVA_LANG_REFLECT_CONSTRUCTOR[3]))
					id = T_JavaLangReflectConstructor;
				return;
			} else if (CharOperation.equals(packageName, ANNOTATION)) {
				switch (typeName[0]) {
					case 'A' :			
						if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_ANNOTATION[3]))
							id = T_JavaLangAnnotationAnnotation;
						return;
					case 'D' :
						if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_DOCUMENTED[3]))
							id = T_JavaLangAnnotationDocumented;
						return;
					case 'E' :
						if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_ELEMENTTYPE[3]))
							id = T_JavaLangAnnotationElementType;
						return;
					case 'I' :
						if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_INHERITED[3]))
							id = T_JavaLangAnnotationInherited;
						return;
					case 'R' :
						if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_RETENTION[3]))
							id = T_JavaLangAnnotationRetention;
						else if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_RETENTIONPOLICY[3]))
							id = T_JavaLangAnnotationRetentionPolicy;
						return;
					case 'T' :
						if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_TARGET[3]))
							id = T_JavaLangAnnotationTarget;
						return;
				}				
			}
			break;
	}
}
/*
 * p.X<T extends Y & I, U extends Y> {} -> Lp/X<TT;TU;>;^123
 */
public char[] computeUniqueKey(boolean withAccessFlags) {
	// generic type signature
	char[] genericSignature = genericTypeSignature();
	int sigLength = genericSignature.length;
	
	if (!withAccessFlags) return genericSignature;
	
	// flags
	String flags = Integer.toString(getAccessFlags());
	int flagsLength = flags.length();
	
	// unique key
	char[] uniqueKey = new char[sigLength + 1 + flagsLength];
	int index = 0;
	System.arraycopy(genericSignature, 0, uniqueKey, index, sigLength);
	index += sigLength;
	uniqueKey[index++] = '^';
	flags.getChars(0, flagsLength, uniqueKey, index);
	
	return uniqueKey;
}
/* Answer the receiver's constant pool name.
*
* NOTE: This method should only be used during/after code gen.
*/

public char[] constantPoolName() /* java/lang/Object */ {
	if (constantPoolName != null) return constantPoolName;
	return constantPoolName = CharOperation.concatWith(compoundName, '/');
}
public String debugName() {
	return (compoundName != null) ? new String(readableName()) : "UNNAMED TYPE"; //$NON-NLS-1$
}
public final int depth() {
	int depth = 0;
	ReferenceBinding current = this;
	while ((current = current.enclosingType()) != null)
		depth++;
	return depth;
}
public boolean detectAnnotationCycle() {
	if ((this.tagBits & TagBits.EndAnnotationCheck) != 0) return false; // already checked
	if ((this.tagBits & TagBits.BeginAnnotationCheck) != 0) return true; // in the middle of checking its methods

	this.tagBits |= TagBits.BeginAnnotationCheck;
	MethodBinding[] currentMethods = methods();
	for (int i = 0, l = currentMethods.length; i < l; i++) {
		TypeBinding returnType = currentMethods[i].returnType.leafComponentType();
		if (returnType.isAnnotationType() && ((ReferenceBinding) returnType).detectAnnotationCycle()) {
			if (this instanceof SourceTypeBinding) {
				MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod();
				((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, returnType, decl != null ? decl.returnType : null);
			}
			return true;
		}
	}
	this.tagBits |= TagBits.EndAnnotationCheck;
	return false;
}
public final ReferenceBinding enclosingTypeAt(int relativeDepth) {
	ReferenceBinding current = this;
	while (relativeDepth-- > 0 && current != null)
		current = current.enclosingType();
	return current;
}
public int enumConstantCount() {
	int count = 0;
	FieldBinding[] fields = fields();
	for (int i = 0, length = fields.length; i < length; i++) {
		if ((fields[i].modifiers & AccEnum) != 0) count++;
	}
	return count;
}
public int fieldCount() {
	return fields().length;
}
public FieldBinding[] fields() {
	return NoFields;
}
/**
 * Find supertype which erases to a given well-known type, or null if not found
 * (using id avoids triggering the load of well-known type: 73740)
 * NOTE: only works for erasures of well-known types, as random other types may share
 * same id though being distincts.
 *
 */
public ReferenceBinding findSuperTypeErasingTo(int erasureId, boolean erasureIsClass) {

    if (this.id == erasureId || erasure().id == erasureId) return this;
    ReferenceBinding currentType = this;
    // iterate superclass to avoid recording interfaces if searched supertype is class
    if (erasureIsClass) {
		while ((currentType = currentType.superclass()) != null) { 
			if (currentType.id == erasureId || currentType.erasure().id == erasureId) return currentType;
		}    
		return null;
    }
	ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
	int lastPosition = -1;
	do {
		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
		if (itsInterfaces != NoSuperInterfaces) {
			if (++lastPosition == interfacesToVisit.length)
				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
			interfacesToVisit[lastPosition] = itsInterfaces;
		}
	} while ((currentType = currentType.superclass()) != null);
			
	for (int i = 0; i <= lastPosition; i++) {
		ReferenceBinding[] interfaces = interfacesToVisit[i];
		for (int j = 0, length = interfaces.length; j < length; j++) {
			if ((currentType = interfaces[j]).id == erasureId || currentType.erasure().id == erasureId)
				return currentType;

			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
			if (itsInterfaces != NoSuperInterfaces) {
				if (++lastPosition == interfacesToVisit.length)
					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
				interfacesToVisit[lastPosition] = itsInterfaces;
			}
		}
	}
	return null;
}
/**
 * Find supertype which erases to a given type, or null if not found
 */
public ReferenceBinding findSuperTypeErasingTo(ReferenceBinding erasure) {

    if (this == erasure || erasure() == erasure) return this;
    ReferenceBinding currentType = this;
    if (!erasure.isInterface()) {
		while ((currentType = currentType.superclass()) != null) {
			if (currentType == erasure || currentType.erasure() == erasure) return currentType;
		}
		return null;
    }
	ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
	int lastPosition = -1;
	do {
		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
		if (itsInterfaces != NoSuperInterfaces) {
			if (++lastPosition == interfacesToVisit.length)
				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
			interfacesToVisit[lastPosition] = itsInterfaces;
		}
	} while ((currentType = currentType.superclass()) != null);
			
	for (int i = 0; i <= lastPosition; i++) {
		ReferenceBinding[] interfaces = interfacesToVisit[i];
		for (int j = 0, length = interfaces.length; j < length; j++) {
			if ((currentType = interfaces[j]) == erasure || currentType.erasure() == erasure)
				return currentType;

			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
			if (itsInterfaces != NoSuperInterfaces) {
				if (++lastPosition == interfacesToVisit.length)
					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
				interfacesToVisit[lastPosition] = itsInterfaces;
			}
		}
	}
	return null;
}

public final int getAccessFlags() {
	return modifiers & AccJustFlag;
}

/**
 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#getAnnotationTagBits()
 */
public long getAnnotationTagBits() {
	return this.tagBits;
}

public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
	return null;
}

public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
	return null;
}
public FieldBinding getField(char[] fieldName, boolean needResolve) {
	return null;
}
/**
 * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
 */
public char[] getFileName() {
	return fileName;
}
public ReferenceBinding getMemberType(char[] typeName) {
	ReferenceBinding[] memberTypes = memberTypes();
	for (int i = memberTypes.length; --i >= 0;)
		if (CharOperation.equals(memberTypes[i].sourceName, typeName))
			return memberTypes[i];
	return null;
}
public MethodBinding[] getMethods(char[] selector) {
	return NoMethods;
}
public PackageBinding getPackage() {
	return fPackage;
}
public boolean hasMemberTypes() {
    return false;
}
public TypeVariableBinding getTypeVariable(char[] variableName) {
	TypeVariableBinding[] typeVariables = typeVariables();
	for (int i = typeVariables.length; --i >= 0;)
		if (CharOperation.equals(typeVariables[i].sourceName, variableName))
			return typeVariables[i];
	return null;
}
public int hashCode() {
	// ensure ReferenceBindings hash to the same posiiton as UnresolvedReferenceBindings so they can be replaced without rehashing
	// ALL ReferenceBindings are unique when created so equals() is the same as ==
	return (this.compoundName == null || this.compoundName.length == 0)
		? super.hashCode()
		: CharOperation.hashCode(this.compoundName[this.compoundName.length - 1]);
}

public final boolean hasRestrictedAccess() {
	return (modifiers & AccRestrictedAccess) != 0;
}

/* Answer true if the receiver implements anInterface or is identical to anInterface.
* If searchHierarchy is true, then also search the receiver's superclasses.
*
* NOTE: Assume that anInterface is an interface.
*/
public boolean implementsInterface(ReferenceBinding anInterface, boolean searchHierarchy) {
	if (this == anInterface)
		return true;

	ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
	int lastPosition = -1;
	ReferenceBinding currentType = this;
	do {
		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
		if (itsInterfaces != NoSuperInterfaces) {
			if (++lastPosition == interfacesToVisit.length)
				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
			interfacesToVisit[lastPosition] = itsInterfaces;
		}
	} while (searchHierarchy && (currentType = currentType.superclass()) != null);
			
	for (int i = 0; i <= lastPosition; i++) {
		ReferenceBinding[] interfaces = interfacesToVisit[i];
		for (int j = 0, length = interfaces.length; j < length; j++) {
			if ((currentType = interfaces[j]).isEquivalentTo(anInterface))
				return true;

			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
			if (itsInterfaces != NoSuperInterfaces) {
				if (++lastPosition == interfacesToVisit.length)
					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
				interfacesToVisit[lastPosition] = itsInterfaces;
			}
		}
	}
	return false;
}
// Internal method... assume its only sent to classes NOT interfaces

boolean implementsMethod(MethodBinding method) {
	ReferenceBinding type = this;
	while (type != null) {
		MethodBinding[] methods = type.getMethods(method.selector);
		for (int i = methods.length; --i >= 0;)
			if (methods[i].areParametersEqual(method))
				return true;
		type = type.superclass();
	}
	return false;
}
/* Answer true if the receiver is an abstract type
*/

public final boolean isAbstract() {
	return (modifiers & AccAbstract) != 0;
}
public boolean isAnnotationType() {
	return (modifiers & AccAnnotation) != 0;
}
public final boolean isAnonymousType() {
	return (tagBits & IsAnonymousType) != 0;
}
public final boolean isBinaryBinding() {
	return (tagBits & IsBinaryBinding) != 0;
}
public boolean isClass() {
	return (modifiers & (AccInterface | AccAnnotation | AccEnum)) == 0;
}
/*
 * Returns true if the type hierarchy is being connected
 */
public boolean isHierarchyBeingConnected() {
	return (this.tagBits & EndHierarchyCheck) == 0 && (this.tagBits & BeginHierarchyCheck) != 0;
}
/* Answer true if the receiver type can be assigned to the argument type (right)
*/
public boolean isCompatibleWith(TypeBinding otherType) {
    
	if (otherType == this) 
		return true;
	if (otherType.id == T_JavaLangObject) 
		return true;
	// equivalence may allow compatibility with array type through wildcard bound
	if (this.isEquivalentTo(otherType)) 
		return true;
	switch (otherType.kind()) {
		case Binding.WILDCARD_TYPE :
			return false; // should have passed equivalence check above if wildcard
		case Binding.TYPE_PARAMETER :
			// check compatibility with capture of ? super X
			if (otherType.isCapture()) {
				CaptureBinding otherCapture = (CaptureBinding) otherType;
				if (otherCapture.lowerBound != null) {
					return this.isCompatibleWith(otherCapture.lowerBound);
				}
			}
		case Binding.GENERIC_TYPE :
		case Binding.TYPE :
		case Binding.PARAMETERIZED_TYPE :
		case Binding.RAW_TYPE :
			ReferenceBinding otherReferenceType = (ReferenceBinding) otherType;
			if (otherReferenceType.isInterface()) // could be annotation type
				return implementsInterface(otherReferenceType, true);
			if (this.isInterface())  // Explicit conversion from an interface to a class is not allowed
				return false;
			return otherReferenceType.isSuperclassOf(this);
		default :
			return false;
	}
}

/* Answer true if the receiver has default visibility
*/
public final boolean isDefault() {
	return (modifiers & (AccPublic | AccProtected | AccPrivate)) == 0;
}

/* Answer true if the receiver is a deprecated type
*/
public final boolean isDeprecated() {
	return (modifiers & AccDeprecated) != 0;
}
public boolean isEnum() {
	return (modifiers & AccEnum) != 0;
}
/* Answer true if the receiver is final and cannot be subclassed
*/
public final boolean isFinal() {
	return (modifiers & AccFinal) != 0;
}
public boolean isInterface() {
	// consider strict interfaces and annotation types
	return (modifiers & AccInterface) != 0;
}
	
public final boolean isPartOfRawType() {
	ReferenceBinding current = this;
	do {
		if (current.isRawType())
			return true;
		// no static type
		if (isStatic()) 
			break;
	} while ((current = current.enclosingType()) != null);
    return false;
}

/* Answer true if the receiver has private visibility
*/
public final boolean isPrivate() {
	return (modifiers & AccPrivate) != 0;
}
/* Answer true if the receiver has private visibility and is used locally
*/

public final boolean isPrivateUsed() {
	return (modifiers & AccPrivateUsed) != 0;
}
/* Answer true if the receiver has protected visibility
*/

public final boolean isProtected() {
	return (modifiers & AccProtected) != 0;
}
/* Answer true if the receiver has public visibility
*/

public final boolean isPublic() {
	return (modifiers & AccPublic) != 0;
}
/* Answer true if the receiver is a static member type (or toplevel)
 */

public final boolean isStatic() {
	return (modifiers & (AccStatic | AccInterface)) != 0 || (tagBits & IsNestedType) == 0;
}
/* Answer true if all float operations must adher to IEEE 754 float/double rules
*/

public final boolean isStrictfp() {
	return (modifiers & AccStrictfp) != 0;
}
/* Answer true if the receiver is in the superclass hierarchy of aType
*
* NOTE: Object.isSuperclassOf(Object) -> false
*/

public boolean isSuperclassOf(ReferenceBinding otherType) {
	while ((otherType = otherType.superclass()) != null) {
		if (otherType.isEquivalentTo(this)) return true;
	}
	return false;
}

/* Answer true if the receiver is deprecated (or any of its enclosing types)
*/

public final boolean isViewedAsDeprecated() {
	return (modifiers & (AccDeprecated | AccDeprecatedImplicitly)) != 0;
}
public ReferenceBinding[] memberTypes() {
	return NoMemberTypes;
}

public MethodBinding[] methods() {
	return NoMethods;
}
public final ReferenceBinding outermostEnclosingType() {
	ReferenceBinding current = this;
	while (true) {
		ReferenceBinding last = current;
		if ((current = current.enclosingType()) == null) 
			return last;
	}
}
/**
* Answer the source name for the type.
* In the case of member types, as the qualified name from its top level type.
* For example, for a member type N defined inside M & A: "A.M.N".
*/

public char[] qualifiedSourceName() {
	if (isMemberType())
		return CharOperation.concat(enclosingType().qualifiedSourceName(), sourceName(), '.');
	return sourceName();
}

public char[] readableName() /*java.lang.Object,  p.X<T> */ {
    char[] readableName;
	if (isMemberType()) {
		readableName = CharOperation.concat(enclosingType().readableName(), sourceName, '.');
	} else {
		readableName = CharOperation.concatWith(compoundName, '.');
	}
	TypeVariableBinding[] typeVars;
	if ((typeVars = this.typeVariables()) != NoTypeVariables) {
	    StringBuffer nameBuffer = new StringBuffer(10);
	    nameBuffer.append(readableName).append('<');
	    for (int i = 0, length = typeVars.length; i < length; i++) {
	        if (i > 0) nameBuffer.append(',');
	        nameBuffer.append(typeVars[i].readableName());
	    }
	    nameBuffer.append('>');
		int nameLength = nameBuffer.length();
		readableName = new char[nameLength];
		nameBuffer.getChars(0, nameLength, readableName, 0);  
	}
	return readableName;
}

public char[] shortReadableName() /*Object*/ {
    char[] shortReadableName;
	if (isMemberType()) {
		shortReadableName = CharOperation.concat(enclosingType().shortReadableName(), sourceName, '.');
	} else {
		shortReadableName = this.sourceName;
	}
	TypeVariableBinding[] typeVars;
	if ((typeVars = this.typeVariables()) != NoTypeVariables) {
	    StringBuffer nameBuffer = new StringBuffer(10);
	    nameBuffer.append(shortReadableName).append('<');
	    for (int i = 0, length = typeVars.length; i < length; i++) {
	        if (i > 0) nameBuffer.append(',');
	        nameBuffer.append(typeVars[i].shortReadableName());
	    }
	    nameBuffer.append('>');
		int nameLength = nameBuffer.length();
		shortReadableName = new char[nameLength];
		nameBuffer.getChars(0, nameLength, shortReadableName, 0);	    
	}
	return shortReadableName;
}

/* Answer the receiver's signature.
*
* NOTE: This method should only be used during/after code gen.
*/

public char[] signature() /* Ljava/lang/Object; */ {
	if (signature != null)
		return signature;

	return signature = CharOperation.concat('L', constantPoolName(), ';');
}
public char[] sourceName() {
	return sourceName;
}

public ReferenceBinding superclass() {
	return null;
}
public ReferenceBinding[] superInterfaces() {
	return NoSuperInterfaces;
}
public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
	if (isStatic()) return null;

	ReferenceBinding enclosingType = enclosingType();
	if (enclosingType == null)
		return null;
	return new ReferenceBinding[] {enclosingType};
}
public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
	return null;		// is null if no enclosing instances are required
}

MethodBinding[] unResolvedMethods() { // for the MethodVerifier so it doesn't resolve types
	return methods();
}
}
