/*******************************************************************************
 * Copyright (c) 2000, 2020 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *     Stephan Herrmann - Contributions for
 *								bug 349326 - [1.7] new warning for missing try-with-resources
 *								bug 186342 - [compiler][null] Using annotations for null checking
 *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
 *								bug 358903 - Filter practically unimportant resource leak warnings
 *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
 *								bug 388281 - [compiler][null] inheritance of null annotations as an option
 *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
 *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
 *								bug 400421 - [compiler] Null analysis for fields does not take @com.google.inject.Inject into account
 *								bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions
 *								bug 392384 - [1.8][compiler][null] Restore nullness info from type annotations in class files
 *								Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
 *								Bug 415291 - [1.8][null] differentiate type incompatibilities due to null annotations
 *								Bug 415043 - [1.8][null] Follow-up re null type annotations after bug 392099
 *								Bug 416176 - [1.8][compiler][null] null type annotations cause grief on type variables
 *								Bug 400874 - [1.8][compiler] Inference infrastructure should evolve to meet JLS8 18.x (Part G of JSR335 spec)
 *								Bug 423504 - [1.8] Implement "18.5.3 Functional Interface Parameterization Inference"
 *								Bug 426792 - [1.8][inference][impl] generify new type inference engine
 *								Bug 428019 - [1.8][compiler] Type inference failure with nested generic invocation.
 *								Bug 427199 - [1.8][resource] avoid resource leak warnings on Streams that have no resource
 *								Bug 418743 - [1.8][null] contradictory annotations on invocation of generic method not reported
 *								Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
 *								Bug 431581 - Eclipse compiles what it should not
 *								Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
 *								Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
 *								Bug 446442 - [1.8] merge null annotations from super methods
 *								Bug 456532 - [1.8][null] ReferenceBinding.appendNullAnnotation() includes phantom annotations in error messages
 *								Bug 410218 - Optional warning for arguments of "unexpected" types to Map#get(Object), Collection#remove(Object) et al.
 *      Jesper S Moller - Contributions for
 *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
 *								bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
 *								bug 527554 - [18.3] Compiler support for JEP 286 Local-Variable Type
 *     Ulrich Grave <ulrich.grave@gmx.de> - Contributions for
 *                              bug 386692 - Missing "unused" warning on "autowired" fields
 *     Pierre-Yves B. <pyvesdev@gmail.com> - Contribution for
 *                              bug 542520 - [JUnit 5] Warning The method xxx from the type X is never used locally is shown when using MethodSource
 *     Sebastian Zarnekow - Contributions for
 *								bug 544921 - [performance] Poor performance with large source files
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;

import java.util.Arrays;
import java.util.Comparator;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.AbstractOTReferenceBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.TypeModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.RoleSplitter;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TSuperHelper;

/*
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.
*/

/**
 * OTDT changes:
 *
 * Note: New supertype AbstractOTReferenceBinding holds most of what we changed here.
 *
 *
 * What: Slightly changed strategy for enclosingType
 * Why:  Binary local types don't set enclosingType, but role local types need it.
 * Where BinaryTypeBinding.setEnclosingOfRoleLocal()
 *
 * What: new function attributeName()
 * Why:  in byte code attributes type names are encoded differently
 *
 * What: new functions getMemberTypeRecurse(name), getMethod(Scope scope, char[] selector)
 * Why:  need deep lookup.
 *
 * What: isStrictlyCompatibleWith()
 * Why:  confined types are not compatible to Object (which other methods assume)
 *
 * What: variants of printable names: filter out __OT__,
 * Note: now sourceName and sourceName() have different semantics.
 *
 */
//{ObjectTeams: changed superclass in order to separate out OT features:
abstract public class ReferenceBinding extends AbstractOTReferenceBinding {
	@Override
	protected ReferenceBinding _this() { return this; } // used in AbstractOTReferenceBinding to refer to 'this'
// SH}

	public char[][] compoundName;
	public char[] sourceName;
//{ObjectTeams: now in AbstractOTReferenceBinding:
/* orig:
	public int modifiers;
  :giro */
// SH}
	public PackageBinding fPackage;
//{ObjectTeams: accessible for sub-classes:
/* orig:
    char[] fileName;
    char[] constantPoolName;
    char[] signature;
  :giro */
    public char[] fileName;
    public char[] constantPoolName;
    protected char[] signature;
// SH}


	private SimpleLookupTable compatibleCache;

	int typeBits; // additional bits characterizing this type
	protected MethodBinding [] singleAbstractMethod;

	public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */
		{ this.id = TypeIds.T_undefined; }
		@Override
		public boolean hasTypeBit(int bit) { return false; }
	};

	private static final Comparator<FieldBinding> FIELD_COMPARATOR = new Comparator<FieldBinding>() {
		@Override
		public int compare(FieldBinding o1, FieldBinding o2) {
			char[] n1 = o1.name;
			char[] n2 = o2.name;
			return ReferenceBinding.compare(n1, n2, n1.length, n2.length);
		}
	};
	private static final Comparator<MethodBinding> METHOD_COMPARATOR = new Comparator<MethodBinding>() {
		@Override
		public int compare(MethodBinding m1, MethodBinding m2) {
			char[] s1 = m1.selector;
			char[] s2 = m2.selector;
			int c = ReferenceBinding.compare(s1, s2, s1.length, s2.length);
			return c == 0 ? m1.parameters.length - m2.parameters.length : c;
		}
	};
	static protected ProblemMethodBinding samProblemBinding = new ProblemMethodBinding(TypeConstants.ANONYMOUS_METHOD, null, ProblemReasons.NoSuchSingleAbstractMethod);


	public ReferenceBinding(ReferenceBinding prototype) {
	super(prototype);

	this.compoundName = prototype.compoundName;
	this.sourceName = prototype.sourceName;
	this.modifiers = prototype.modifiers;
	this.fPackage = prototype.fPackage;
	this.fileName = prototype.fileName;
	this.constantPoolName = prototype.constantPoolName;
	this.signature = prototype.signature;
	this.compatibleCache = prototype.compatibleCache;
	this.typeBits = prototype.typeBits;
	this.singleAbstractMethod = prototype.singleAbstractMethod;
//{ObjectTeams: most subclasses need model to be set:
	this.model = new TypeModel(prototype.model, this);
// SH}
}

public ReferenceBinding() {
	super();
//{ObjectTeams: most subclasses need model to be set:
	this.model = new TypeModel(this);
// SH}
}

public static FieldBinding binarySearch(char[] name, FieldBinding[] sortedFields) {
	if (sortedFields == null)
		return null;
	int max = sortedFields.length;
	if (max == 0)
		return null;
	int left = 0, right = max - 1, nameLength = name.length;
	int mid = 0;
	char[] midName;
	while (left <= right) {
		mid = left + (right - left) /2;
		int compare = compare(name, midName = sortedFields[mid].name, nameLength, midName.length);
		if (compare < 0) {
			right = mid-1;
		} else if (compare > 0) {
			left = mid+1;
		} else {
			return sortedFields[mid];
		}
	}
	return null;
}

//{ObjectTeams:
public static FieldBinding[] sortedInsert(FieldBinding[] sortedFields, FieldBinding newField) {
	if (sortedFields != null) {
		int max = sortedFields.length;
		if (max > 0) {
			int insertBefore = 0;
			char[] name = newField.name;
			int left = 0, right = max - 1, nameLength = name.length;
			int mid = 0;
			char[] midName;
			while (left <= right) {
				mid = (left + right) /2;
				int compare = compare(name, midName = sortedFields[mid].name, nameLength, midName.length);
				if (compare < 0) {
					right = mid-1;
					insertBefore = mid;
				} else if (compare > 0) {
					left = mid+1;
					insertBefore = mid+1;
				} else {
					insertBefore = mid;
					break; // mid's name is equal to `name'
				}
			}
			FieldBinding[] result = new FieldBinding[max+1];
			System.arraycopy(sortedFields, 0, result, 0, insertBefore);
			System.arraycopy(sortedFields, insertBefore, result, insertBefore+1, max-insertBefore);
			result[insertBefore] = newField;
			return result;
		}
	}
	return new FieldBinding[] {newField};
}
public static MethodBinding[] sortedInsert(MethodBinding[] sortedMethods, MethodBinding newMethod) {
	if (sortedMethods != null) {
		int max = sortedMethods.length;
		if (max > 0) {
			int insertBefore = 0;
			int left = 0, right = max - 1;
			int mid = 0;
			binarySearch:
			while (left <= right) {
				mid = (left + right) /2;
				MethodBinding midM = sortedMethods[mid];
				if (midM == null) {
					// revert to linear search:
					while (left <= right) {
						midM = sortedMethods[right];
						while (midM == null && left <= right)
							midM = sortedMethods[--right];
						int compare = METHOD_COMPARATOR.compare(newMethod, midM);
						if (compare < 0) {
							right--;
						} else if (compare > 0) {
							insertBefore = right+1;
							break binarySearch;
						} else {
							insertBefore = right;
							break binarySearch;
						}
					}
				}
				int compare = METHOD_COMPARATOR.compare(newMethod, midM);
				if (compare < 0) {
					right = mid-1;
					insertBefore = mid;
				} else if (compare > 0) {
					left = mid+1;
					insertBefore = mid+1;
				} else {
					insertBefore = mid;
					break; // mid's name is equal to `name'
				}
			}
			MethodBinding[] result = new MethodBinding[max+1];
			System.arraycopy(sortedMethods, 0, result, 0, insertBefore);
			System.arraycopy(sortedMethods, insertBefore, result, insertBefore+1, max-insertBefore);
			result[insertBefore] = newMethod;
			return result;
		}
	}
	return new MethodBinding[] {newMethod};
}
// SH}
/**
 * Returns a combined range value representing: (start + (end<<32)), where start is the index of the first matching method
 * (remember methods are sorted alphabetically on selectors), and end is the index of last contiguous methods with same
 * selector.
 * -1 means no method got found
 * @param selector
 * @param sortedMethods
 * @return (start + (end<<32)) or -1 if no method found
 */
public static long binarySearch(char[] selector, MethodBinding[] sortedMethods) {
	if (sortedMethods == null)
		return -1;
	int max = sortedMethods.length;
	if (max == 0)
		return -1;
	int left = 0, right = max - 1, selectorLength = selector.length;
	int mid = 0;
	char[] midSelector;
	while (left <= right) {
		mid = left + (right - left) /2;
		int compare = compare(selector, midSelector = sortedMethods[mid].selector, selectorLength, midSelector.length);
		if (compare < 0) {
			right = mid-1;
		} else if (compare > 0) {
			left = mid+1;
		} else {
			int start = mid, end = mid;
			// find first method with same selector
			while (start > left && CharOperation.equals(sortedMethods[start-1].selector, selector)){ start--; }
			// find last method with same selector
			while (end < right && CharOperation.equals(sortedMethods[end+1].selector, selector)){ end++; }
			return start + ((long)end<< 32);
		}
	}
	return -1;
}

/**
 * Compares two strings lexicographically.
 * The comparison is based on the Unicode value of each character in
 * the strings.
 *
 * @return  the value <code>0</code> if the str1 is equal to str2;
 *          a value less than <code>0</code> if str1
 *          is lexicographically less than str2;
 *          and a value greater than <code>0</code> if str1 is
 *          lexicographically greater than str2.
 */
static int compare(char[] str1, char[] str2, int len1, int len2) {
	int n= Math.min(len1, len2);
	int i= 0;
	while (n-- != 0) {
		char c1= str1[i];
		char c2= str2[i++];
		if (c1 != c2) {
			return c1 - c2;
		}
	}
	return len1 - len2;
}

/**
 * Sort the field array using a quicksort
 */
public static void sortFields(FieldBinding[] sortedFields, int left, int right) {
	Arrays.sort(sortedFields, left, right, FIELD_COMPARATOR);
}

/**
 * Sort the field array using a quicksort
 */
public static void sortMethods(MethodBinding[] sortedMethods, int left, int right) {
	Arrays.sort(sortedMethods, left, right, METHOD_COMPARATOR);
}

//{ObjectTeams: some subclasses share an existing model
	protected ReferenceBinding(TypeModel model) {
		this.model = model;
		if (model != null && model.getBinding() == null)
			model.setBinding(this);
	}
// SH}

// {ObjectTeams: new API for adding elements:
    /**
     * add a generated method
     * @param method
     */
    public void addMethod(MethodBinding method) {
    	throw new InternalCompilerError("Method not applicable on this type"); //$NON-NLS-1$
    }
// SH}

/**
 * Sort the member types using a quicksort
 */
static void sortMemberTypes(ReferenceBinding[] sortedMemberTypes, int left, int right) {
/*{ObjectTeams: completely disable name-based membertype sorting:
	Arrays.sort(sortedMemberTypes, left, right, BASIC_MEMBER_TYPES_COMPARATOR);
  SH}*/
}

/**
 * Compares two reference bindings by the value of the {@link #sourceName} field.
 * A ReferenceBinding with a sourceName field that has the value null is considered
 * to be smaller than a ReferenceBinding that does have a source name.
 */
static final Comparator<ReferenceBinding> BASIC_MEMBER_TYPES_COMPARATOR = (ReferenceBinding o1, ReferenceBinding o2) -> {
	char[] n1 = o1.sourceName;
	char[] n2 = o2.sourceName;
	// n1 or n2 may be null - compare without accessing the length of the array
	if (n1 == null) {
		if (n2 == null) {
			return 0;
		}
		return -1;
	} else if (n2 == null) {
		return 1;
	}
	return ReferenceBinding.compare(n1, n2, n1.length, n2.length);
};

/**
 * Return the array of resolvable fields (resilience)
 */
public FieldBinding[] availableFields() {
	return fields();
}

/**
 * Return the array of resolvable methods (resilience)
 */
public MethodBinding[] availableMethods() {
//{ObjectTeams: clients should see some generated methods, too:
	try {
		if (isRole())
			Dependencies.ensureBindingState(this, ITranslationStates.STATE_METHODS_CREATED);
	} catch (Throwable t) { /* don't care about exceptions in compiler */ }
// SH}
	return methods();
}

public boolean hasHierarchyCheckStarted() {
	return  (this.tagBits & TagBits.BeginHierarchyCheck) != 0;
}

public void setHierarchyCheckDone() {
	return;
}


/**
 * Answer true if the receiver can be instantiated
 */
@Override
public boolean canBeInstantiated() {
	return (this.modifiers & (ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation)) == 0;
}

/**
 * Answer true if the receiver is visible to the invocationPackage.
 */
public boolean canBeSeenBy(PackageBinding invocationPackage) {
	if (isPublic()) return true;
	if (isPrivate()) return false;

	// isProtected() or isDefault()
	return invocationPackage == this.fPackage;
}

/**
 * Answer true if the receiver is visible to the receiverType and the invocationType.
 */
public boolean canBeSeenBy(ReferenceBinding receiverType, ReferenceBinding invocationType) {
	if (isPublic()) return true;

	if (isStatic() && (receiverType.isRawType() || receiverType.isParameterizedType()))
		receiverType = receiverType.actualType(); // outer generics are irrelevant

	if (TypeBinding.equalsEquals(invocationType, this) && TypeBinding.equalsEquals(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 (TypeBinding.equalsEquals(invocationType, this)) return true;
		if (invocationType.fPackage == this.fPackage) return true;

		TypeBinding currentType = invocationType.erasure();
		TypeBinding declaringClass = enclosingType().erasure(); // protected types always have an enclosing one
		if (TypeBinding.equalsEquals(declaringClass, invocationType)) return true;
		if (declaringClass == null) return false; // could be null if incorrect top-level protected type
		//int depth = 0;
		do {
			if (currentType.findSuperTypeOriginatingFrom(declaringClass) != 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 (!(TypeBinding.equalsEquals(receiverType, this) || TypeBinding.equalsEquals(receiverType, enclosingType()))) {
				// special tolerance for type variable direct bounds, but only if compliance <= 1.6, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=334622
				if (receiverType.isTypeVariable()) {
					TypeVariableBinding typeVariable = (TypeVariableBinding) receiverType;
					if (typeVariable.environment.globalOptions.complianceLevel <= ClassFileConstants.JDK1_6 && (typeVariable.isErasureBoundTo(erasure()) || typeVariable.isErasureBoundTo(enclosingType().erasure())))
						break receiverCheck;
				}
				return false;
			}
		}

		if (TypeBinding.notEquals(invocationType, this)) {
			ReferenceBinding outerInvocationType = invocationType;
			ReferenceBinding temp = outerInvocationType.enclosingType();
			while (temp != null) {
				outerInvocationType = temp;
				temp = temp.enclosingType();
			}

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

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

	ReferenceBinding currentType = receiverType;
	TypeBinding originalDeclaringClass = (enclosingType() == null ? this : enclosingType()).original();
	do {
		if (currentType.isCapture()) {  // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002
			if (TypeBinding.equalsEquals(originalDeclaringClass, currentType.erasure().original())) return true;
		} else {
			if (TypeBinding.equalsEquals(originalDeclaringClass, currentType.original())) return true;
		}
		PackageBinding currentPackage = currentType.fPackage;
		// package could be null for wildcards/intersection types, ignore and recurse in superclass
		if (currentPackage != null && currentPackage != this.fPackage) return false;
	} while ((currentType = currentType.superclass()) != null);
	return false;
}

/**
 * Answer true if the receiver is visible to the type provided by the scope.
 */
@Override
public boolean canBeSeenBy(Scope scope) {
	if (isPublic()) return true;

	SourceTypeBinding invocationType = scope.enclosingSourceType();
	if (TypeBinding.equalsEquals(invocationType, this)) return true;

	if (invocationType == null) // static import call
		return !isPrivate() && scope.getCurrentPackage() == this.fPackage;

	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 == this.fPackage) return true;

		TypeBinding declaringClass = enclosingType(); // protected types always have an enclosing one
		if (declaringClass == null) return false; // could be null if incorrect top-level protected type
		declaringClass = declaringClass.erasure();// erasure cannot be null
		TypeBinding currentType = invocationType.erasure();
		// int depth = 0;
		do {
			if (TypeBinding.equalsEquals(declaringClass, invocationType)) return true;
			if (currentType.findSuperTypeOriginatingFrom(declaringClass) != null) 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)erasure();
		temp = outerDeclaringClass.enclosingType();
		while (temp != null) {
			outerDeclaringClass = temp;
			temp = temp.enclosingType();
		}
		return TypeBinding.equalsEquals(outerInvocationType, outerDeclaringClass);
	}

	// isDefault()
	return invocationType.fPackage == this.fPackage;
}

public char[] computeGenericTypeSignature(TypeVariableBinding[] typeVariables) {

	boolean isMemberOfGeneric = isMemberType() && hasEnclosingInstanceContext() && (enclosingType().modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0;
	if (typeVariables == Binding.NO_TYPE_VARIABLES && !isMemberOfGeneric) {
		return signature();
	}
	StringBuffer sig = new StringBuffer(10);
	if (isMemberOfGeneric) {
	    char[] typeSig = enclosingType().genericTypeSignature();
	    sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
	    sig.append('.'); // NOTE: cannot override trailing ';' with '.' in enclosing signature, since shared char[]
	    sig.append(this.sourceName);
	}	else {
	    char[] typeSig = signature();
	    sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
	}
	if (typeVariables == Binding.NO_TYPE_VARIABLES) {
	    sig.append(';');
	} else {
	    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() {
	// note that more (configurable) ids are assigned from PackageBinding#checkIfNullAnnotationType()

	// try to avoid multiple checks against a package/type name
	switch (this.compoundName.length) {

		case 3 :
//{ObjectTeams: org.objectteams...
			if (   CharOperation.equals(IOTConstants.ORG, this.compoundName[0])
				&& CharOperation.equals(IOTConstants.OBJECTTEAMS, this.compoundName[1]))
			{
				if(CharOperation.equals(IOTConstants.ITEAM, this.compoundName[2]))
					this.id = IOTConstants.T_OrgObjectTeamsITeam;
				else if(CharOperation.equals(IOTConstants.TEAM, this.compoundName[2]))
					this.id = IOTConstants.T_OrgObjectTeamsTeam;
				else if(CharOperation.equals(IOTConstants.IBOUNDBASE, this.compoundName[2]))
					this.id = IOTConstants.T_OrgObjectTeamsIBoundBase;
				else if(CharOperation.equals(IOTConstants.IBOUNDBASE2, this.compoundName[2]))
					this.id = IOTConstants.T_OrgObjectTeamsIBoundBase2;
				else if(CharOperation.equals(IOTConstants.INSTANTIATION, this.compoundName[2]))
					this.id = IOTConstants.T_OrgObjectTeamsInstantiation;
				else if(CharOperation.equals(IOTConstants.ICONFINED, this.compoundName[2]))
					this.id = IOTConstants.T_OrgObjectteamsIConfined;
				else if(CharOperation.equals(IOTConstants.ITEAM_ICONFINED, this.compoundName[2]))
					this.id = IOTConstants.T_OrgObjectteamsITeamIConfined;
				else if(CharOperation.equals(IOTConstants.TEAM_CONFINED, this.compoundName[2]))
					this.id = IOTConstants.T_OrgObjectteamsTeamConfined;
				else if(CharOperation.equals(IOTConstants.TEAM_OTCONFINED, this.compoundName[2]))
					this.id = IOTConstants.T_OrgObjectteamsTeamOTConfined;
				return;
			}
// SH}
			char[] packageName = this.compoundName[0];
			// expect only java.*.* and javax.*.* and junit.*.* and org.junit.*
			switch (packageName.length) {
				case 3: // only one type in this group, yet:
					if (CharOperation.equals(TypeConstants.ORG_JUNIT_ASSERT, this.compoundName))
						this.id = TypeIds.T_OrgJunitAssert;
					return;
				case 4:
					if (!CharOperation.equals(TypeConstants.JAVA, packageName))
						return;
					break; // continue below ...
				case 5:
					switch (packageName[1]) {
						case 'a':
							if (CharOperation.equals(TypeConstants.JAVAX_ANNOTATION_INJECT_INJECT, this.compoundName))
								this.id = TypeIds.T_JavaxInjectInject;
							return;
						case 'u':
							if (CharOperation.equals(TypeConstants.JUNIT_FRAMEWORK_ASSERT, this.compoundName))
								this.id = TypeIds.T_JunitFrameworkAssert;
							return;
					}
				return;
				default: return;
			}
			// ... at this point we know it's java.*.*

			packageName = this.compoundName[1];
			if (packageName.length == 0) return; // just to be safe
			char[] typeName = this.compoundName[2];
			if (typeName.length == 0) return; // just to be safe
			// remaining types MUST be in java.*.*
			if (!CharOperation.equals(TypeConstants.LANG, this.compoundName[1])) {
				switch (packageName[0]) {
					case 'i' :
						if (CharOperation.equals(packageName, TypeConstants.IO)) {
							switch (typeName[0]) {
								case 'C' :
									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_CLOSEABLE[2]))
										this.typeBits |= TypeIds.BitCloseable; // don't assign id, only typeBit (for analysis of resource leaks)
									return;
								case 'E' :
									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_EXTERNALIZABLE[2]))
										this.id = TypeIds.T_JavaIoExternalizable;
									return;
								case 'I' :
									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_IOEXCEPTION[2]))
										this.id = TypeIds.T_JavaIoException;
									return;
								case 'O' :
									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_OBJECTSTREAMEXCEPTION[2]))
										this.id = TypeIds.T_JavaIoObjectStreamException;
									return;
								case 'P' :
									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_PRINTSTREAM[2]))
										this.id = TypeIds.T_JavaIoPrintStream;
									return;
								case 'S' :
									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_SERIALIZABLE[2]))
										this.id = TypeIds.T_JavaIoSerializable;
									return;
							}
						}
						return;
					case 'u' :
						if (CharOperation.equals(packageName, TypeConstants.UTIL)) {
							switch (typeName[0]) {
								case 'C' :
									if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_COLLECTION[2])) {
										this.id = TypeIds.T_JavaUtilCollection;
										this.typeBits |= TypeIds.BitCollection;
									}
									return;
								case 'I' :
									if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_ITERATOR[2]))
										this.id = TypeIds.T_JavaUtilIterator;
									return;
								case 'L' :
									if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_LIST[2])) {
										this.id = TypeIds.T_JavaUtilList;
										this.typeBits |= TypeIds.BitList;
									}
									return;
								case 'M' :
									if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_MAP[2])) {
										this.id = TypeIds.T_JavaUtilMap;
										this.typeBits |= TypeIds.BitMap;
									}
									return;
								case 'O' :
									if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_OBJECTS[2]))
										this.id = TypeIds.T_JavaUtilObjects;
									return;
							}
						}
						return;
				}
				return;
			}

			// remaining types MUST be in java.lang.*
			switch (typeName[0]) {
				case 'A' :
					switch(typeName.length) {
						case 13 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2])) {
								this.id = TypeIds.T_JavaLangAutoCloseable;
								this.typeBits |= TypeIds.BitAutoCloseable;
							}
							return;
						case 14:
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
								this.id = TypeIds.T_JavaLangAssertionError;
							return;
					}
					return;
				case 'B' :
					switch (typeName.length) {
						case 4 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_BYTE[2]))
								this.id = TypeIds.T_JavaLangByte;
							return;
						case 7 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_BOOLEAN[2]))
								this.id = TypeIds.T_JavaLangBoolean;
							return;
					}
					return;
				case 'C' :
					switch (typeName.length) {
						case 5 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLASS[2]))
								this.id = TypeIds.T_JavaLangClass;
							return;
						case 9 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CHARACTER[2]))
								this.id = TypeIds.T_JavaLangCharacter;
							else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLONEABLE[2]))
							    this.id = TypeIds.T_JavaLangCloneable;
							return;
						case 22 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLASSNOTFOUNDEXCEPTION[2]))
								this.id = TypeIds.T_JavaLangClassNotFoundException;
							return;
					}
					return;
				case 'D' :
					switch (typeName.length) {
						case 6 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_DOUBLE[2]))
								this.id = TypeIds.T_JavaLangDouble;
							return;
						case 10 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_DEPRECATED[2]))
								this.id = TypeIds.T_JavaLangDeprecated;
							return;
					}
					return;
				case 'E' :
					switch (typeName.length) {
						case 4 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ENUM[2]))
								this.id = TypeIds.T_JavaLangEnum;
							return;
						case 5 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ERROR[2]))
								this.id = TypeIds.T_JavaLangError;
							return;
						case 9 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_EXCEPTION[2]))
								this.id = TypeIds.T_JavaLangException;
							return;
					}
					return;
				case 'F' :
					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_FLOAT[2]))
						this.id = TypeIds.T_JavaLangFloat;
					else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_FUNCTIONAL_INTERFACE[2]))
						this.id = TypeIds.T_JavaLangFunctionalInterface;
					return;
				case 'I' :
					switch (typeName.length) {
						case 7 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INTEGER[2]))
								this.id = TypeIds.T_JavaLangInteger;
							return;
						case 8 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ITERABLE[2]))
								this.id = TypeIds.T_JavaLangIterable;
							return;
						case 24 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ILLEGALARGUMENTEXCEPTION[2]))
								this.id = TypeIds.T_JavaLangIllegalArgumentException;
							return;
					}
					return;
				case 'L' :
					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_LONG[2]))
						this.id = TypeIds.T_JavaLangLong;
					return;
				case 'N' :
					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_NOCLASSDEFERROR[2]))
						this.id = TypeIds.T_JavaLangNoClassDefError;
					return;
				case 'O' :
					switch (typeName.length) {
						case 6 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_OBJECT[2]))
								this.id = TypeIds.T_JavaLangObject;
							return;
						case 8 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_OVERRIDE[2]))
								this.id = TypeIds.T_JavaLangOverride;
							return;
					}
					return;
				case 'R' :
					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION[2]))
						this.id = 	TypeIds.T_JavaLangRuntimeException;
					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_RECORD[2]))
						this.id = TypeIds.T_JavaLangRecord;
					break;
				case 'S' :
					switch (typeName.length) {
						case 5 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SHORT[2]))
								this.id = TypeIds.T_JavaLangShort;
							return;
						case 6 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRING[2]))
								this.id = TypeIds.T_JavaLangString;
							else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SYSTEM[2]))
								this.id = TypeIds.T_JavaLangSystem;
							return;
						case 11 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SAFEVARARGS[2]))
								this.id = TypeIds.T_JavaLangSafeVarargs;
							return;
						case 12 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRINGBUFFER[2]))
								this.id = TypeIds.T_JavaLangStringBuffer;
							return;
						case 13 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRINGBUILDER[2]))
								this.id = TypeIds.T_JavaLangStringBuilder;
							return;
						case 16 :
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SUPPRESSWARNINGS[2]))
								this.id = TypeIds.T_JavaLangSuppressWarnings;
							return;
					}
					return;
				case 'T' :
					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_THROWABLE[2]))
						this.id = TypeIds.T_JavaLangThrowable;
					return;
				case 'V' :
					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_VOID[2]))
						this.id = TypeIds.T_JavaLangVoid;
					return;
			}
		break;

		case 4:
			// expect one type from com.*.*.*:
			if (CharOperation.equals(TypeConstants.COM_GOOGLE_INJECT_INJECT, this.compoundName)) {
				this.id = TypeIds.T_ComGoogleInjectInject;
				return;
			}
			// otherwise only expect java.*.*.*
			if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]))
				return;
			packageName = this.compoundName[1];
			if (packageName.length == 0) return; // just to be safe

			packageName = this.compoundName[2];
			if (packageName.length == 0) return; // just to be safe
			typeName = this.compoundName[3];
			if (typeName.length == 0) return; // just to be safe
			switch (packageName[0]) {
				case 'a' :
					if (CharOperation.equals(packageName, TypeConstants.ANNOTATION)) {
						switch (typeName[0]) {
							case 'A' :
								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_ANNOTATION[3]))
									this.id = TypeIds.T_JavaLangAnnotationAnnotation;
								return;
							case 'D' :
								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED[3]))
									this.id = TypeIds.T_JavaLangAnnotationDocumented;
								return;
							case 'E' :
								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE[3]))
									this.id = TypeIds.T_JavaLangAnnotationElementType;
								return;
							case 'I' :
								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_INHERITED[3]))
									this.id = TypeIds.T_JavaLangAnnotationInherited;
								return;
							case 'R' :
								switch (typeName.length) {
									case 9 :
										if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTION[3]))
											this.id = TypeIds.T_JavaLangAnnotationRetention;
										return;
									case 10 :
										if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_REPEATABLE[3]))
											this.id = TypeIds.T_JavaLangAnnotationRepeatable;
										return;
									case 15 :
										if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY[3]))
											this.id = TypeIds.T_JavaLangAnnotationRetentionPolicy;
										return;
								}
								return;
							case 'T' :
								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_TARGET[3]))
									this.id = TypeIds.T_JavaLangAnnotationTarget;
								return;
						}
					}
					return;
				case 'i':
					if (CharOperation.equals(packageName, TypeConstants.INVOKE)) {
						if (typeName.length == 0) return; // just to be safe
						switch (typeName[0]) {
							case 'M' :
								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE[3]))
									this.id = TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature;
								return;
						}
					}
					return;
				case 'r' :
					if (CharOperation.equals(packageName, TypeConstants.REFLECT)) {
						switch (typeName[0]) {
							case 'C' :
								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_CONSTRUCTOR[2]))
									this.id = TypeIds.T_JavaLangReflectConstructor;
								return;
							case 'F' :
								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_FIELD[2]))
									this.id = TypeIds.T_JavaLangReflectField;
								return;
							case 'M' :
								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_METHOD[2]))
									this.id = TypeIds.T_JavaLangReflectMethod;
								return;
						}
					}
					return;
			}
			break;
		case 5 :
			packageName = this.compoundName[0];
			switch (packageName[0]) {
				case 'j' :
					if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]))
						return;
					packageName = this.compoundName[1];
					if (packageName.length == 0) return; // just to be safe

					if (CharOperation.equals(TypeConstants.LANG, packageName)) {
						packageName = this.compoundName[2];
						if (packageName.length == 0) return; // just to be safe
						switch (packageName[0]) {
							case 'i' :
								if (CharOperation.equals(packageName, TypeConstants.INVOKE)) {
									typeName = this.compoundName[3];
									if (typeName.length == 0) return; // just to be safe
									switch (typeName[0]) {
										case 'M' :
											char[] memberTypeName = this.compoundName[4];
											if (memberTypeName.length == 0) return; // just to be safe
											if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE[3])
													&& CharOperation.equals(memberTypeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE[4]))
												this.id = TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature;
											return;
									}
								}
								return;
						}
						return;
					}
					return;
				case 'o':
					if (!CharOperation.equals(TypeConstants.ORG, this.compoundName[0]))
						return;
					packageName = this.compoundName[1];
					if (packageName.length == 0) return; // just to be safe

					switch (packageName[0]) {
						case 'e':
					if (CharOperation.equals(TypeConstants.ECLIPSE, packageName)) {
						packageName = this.compoundName[2];
						if (packageName.length == 0) return; // just to be safe
						switch (packageName[0]) {
							case 'c' :
								if (CharOperation.equals(packageName, TypeConstants.CORE)) {
									typeName = this.compoundName[3];
									if (typeName.length == 0) return; // just to be safe
									switch (typeName[0]) {
										case 'r' :
											char[] memberTypeName = this.compoundName[4];
											if (memberTypeName.length == 0) return; // just to be safe
											if (CharOperation.equals(typeName, TypeConstants.ORG_ECLIPSE_CORE_RUNTIME_ASSERT[3])
													&& CharOperation.equals(memberTypeName, TypeConstants.ORG_ECLIPSE_CORE_RUNTIME_ASSERT[4]))
												this.id = TypeIds.T_OrgEclipseCoreRuntimeAssert;
											return;
									}
								}
								return;
						}
						return;
					}
					return;
						case 'a':
							if (CharOperation.equals(TypeConstants.APACHE, packageName)) {
								if (CharOperation.equals(TypeConstants.COMMONS, this.compoundName[2])) {
									if (CharOperation.equals(TypeConstants.ORG_APACHE_COMMONS_LANG_VALIDATE, this.compoundName))
										this.id = TypeIds.T_OrgApacheCommonsLangValidate;
									else if (CharOperation.equals(TypeConstants.ORG_APACHE_COMMONS_LANG3_VALIDATE, this.compoundName))
										this.id = TypeIds.T_OrgApacheCommonsLang3Validate;
			}
							}
							return;
					}
					return;
				case 'c':
					if (!CharOperation.equals(TypeConstants.COM, this.compoundName[0]))
						return;
					if (CharOperation.equals(TypeConstants.COM_GOOGLE_COMMON_BASE_PRECONDITIONS, this.compoundName))
						this.id = TypeIds.T_ComGoogleCommonBasePreconditions;
					return;
			}
			break;
		case 6:
			if (CharOperation.equals(TypeConstants.ORG, this.compoundName[0])) {
				if (CharOperation.equals(TypeConstants.SPRING, this.compoundName[1])) {
					if (CharOperation.equals(TypeConstants.AUTOWIRED, this.compoundName[5])) {
						if (CharOperation.equals(TypeConstants.ORG_SPRING_AUTOWIRED, this.compoundName)) {
							this.id = TypeIds.T_OrgSpringframeworkBeansFactoryAnnotationAutowired;
						}
					}
					return;
				}
				if (CharOperation.equals(TypeConstants.JUNIT, this.compoundName[1])) {
					if (CharOperation.equals(TypeConstants.METHOD_SOURCE, this.compoundName[5])) {
						if (CharOperation.equals(TypeConstants.ORG_JUNIT_METHOD_SOURCE, this.compoundName)) {
							this.id = TypeIds.T_OrgJunitJupiterParamsProviderMethodSource;
						}
					}
					return;
				}
				if (!CharOperation.equals(TypeConstants.JDT, this.compoundName[2]) || !CharOperation.equals(TypeConstants.ITYPEBINDING, this.compoundName[5]))
					return;
				if (CharOperation.equals(TypeConstants.ORG_ECLIPSE_JDT_CORE_DOM_ITYPEBINDING, this.compoundName))
					this.typeBits |= TypeIds.BitUninternedType;
			}
			break;
		case 7 :
			if (!CharOperation.equals(TypeConstants.JDT, this.compoundName[2]) || !CharOperation.equals(TypeConstants.TYPEBINDING, this.compoundName[6]))
				return;
			if (CharOperation.equals(TypeConstants.ORG_ECLIPSE_JDT_INTERNAL_COMPILER_LOOKUP_TYPEBINDING, this.compoundName))
				this.typeBits |= TypeIds.BitUninternedType;
			break;
	}
}

public void computeId(LookupEnvironment environment) {
	environment.getUnannotatedType(this);
}

/**
 * p.X<T extends Y & I, U extends Y> {} -> Lp/X<TT;TU;>;
 */
@Override
public char[] computeUniqueKey(boolean isLeaf) {
	if (!isLeaf) return signature();
	return genericTypeSignature();
}

/**
 * Answer the receiver's constant pool name.
 *
 * NOTE: This method should only be used during/after code gen.
 */
@Override
public char[] constantPoolName() /* java/lang/Object */ {
	if (this.constantPoolName != null) return this.constantPoolName;
	return this.constantPoolName = CharOperation.concatWith(this.compoundName, '/');
}

//{ObjectTeams: this is how type names are encoded in OT byte code attributes
public char[] attributeName() /* p1.p2.COuter$CInner */ {
    return CharOperation.concatWith(this.compoundName, '.');
}
// SH}
@Override
public String debugName() {
	return (this.compoundName != null) ? this.hasTypeAnnotations() ? annotatedDebugName() : new String(readableName()) : "UNNAMED TYPE"; //$NON-NLS-1$
}

@Override
public 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();
	boolean inCycle = false; // check each method before failing
	for (int i = 0, l = currentMethods.length; i < l; i++) {
		TypeBinding returnType = currentMethods[i].returnType.leafComponentType().erasure();
		if (TypeBinding.equalsEquals(this, returnType)) {
			if (this instanceof SourceTypeBinding) {
				MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod();
				((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, this, decl != null ? decl.returnType : null);
			}
		} else 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);
			}
			inCycle = true;
		}
	}
	if (inCycle)
		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 & ClassFileConstants.AccEnum) != 0) count++;
	}
	return count;
}

public int fieldCount() {
//{ObjectTeams: don't count faked base field:
	if (isRole()) {
		int count = 0;
		for (FieldBinding field : fields()) {
			if ((field.otBits & IOTConstants.IsFakedField) ==0)
				count++;
		}
		return count;
	}
// SH}
	return fields().length;
}

public FieldBinding[] fields() {
	return Binding.NO_FIELDS;
}

public final int getAccessFlags() {
//{ObjectTeams: use extended mask (was AccJustFlag):
	return this.modifiers & ExtraCompilerModifiers.AccOTTypeJustFlag;
// SH}
}

/**
 * @return the JSR 175 annotations for this type.
 */
@Override
public AnnotationBinding[] getAnnotations() {
	return retrieveAnnotations(this);
}

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

/**
 * @return the enclosingInstancesSlotSize
 */
public int getEnclosingInstancesSlotSize() {
	if (isStatic()) return 0;
	return enclosingType() == null ? 0 : 1;
}

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 this.fileName;
}

/**
 * Find the member type with the given simple typeName. Benefits from the fact that
 * the array of {@link #memberTypes()} is sorted.
 */
public ReferenceBinding getMemberType(char[] typeName) {
	ReferenceBinding[] memberTypes = memberTypes();
//{ObjectTeams: restore old linear lookup:
	for (int i = memberTypes.length; --i >= 0;)
		if (CharOperation.equals(memberTypes[i].sourceName, typeName))
			return memberTypes[i];
/* orig: 4.13M1
	int memberTypeIndex = binarySearch(typeName, memberTypes);
	if (memberTypeIndex >= 0) {
		return memberTypes[memberTypeIndex];
	}
  :giro */
// SH}
	return null;
}
//{ObjectTeams: new utility function
public ReferenceBinding getMemberTypeRecurse(char[] typeName) {
	ReferenceBinding[] memberTypes = memberTypes();
	for (int i = memberTypes.length; --i >= 0;) {
		if (CharOperation.equals(memberTypes[i].sourceName, typeName))
			return memberTypes[i];
		ReferenceBinding result = memberTypes[i].getMemberTypeRecurse(typeName);
		if (result != null)
			return result;
	}
	return null;
}
// SH}

/**
 * Search the given sourceName in the list of sorted member types.
 *
 * Neither the array of sortedMemberTypes nor the given sourceName may be null.
 */
static int binarySearch(char[] sourceName, ReferenceBinding[] sortedMemberTypes) {
	if (sortedMemberTypes == null)
		return -1;
	int max = sortedMemberTypes.length, nameLength = sourceName.length;
	if (max == 0)
		return -1;
	int left = 0, right = max - 1;
	while (left <= right) {
		int mid = left + (right - left) / 2;
		char[] midName = sortedMemberTypes[mid].sourceName;
		// The read source name may be null. In that case, the given sourceName is considered
		// to be larger than the current value at mid.
		int compare = midName == null ? 1 : compare(sourceName, midName, nameLength, midName.length);
		if (compare < 0) {
			right = mid-1;
		} else if (compare > 0) {
			left = mid+1;
		} else {
			return mid;
		}
	}
	return -1;
}

@Override
public MethodBinding[] getMethods(char[] selector) {
	return Binding.NO_METHODS;
}

//Answer methods named selector, which take no more than the suggestedParameterLength.
//The suggested parameter length is optional and may not be guaranteed by every type.
public MethodBinding[] getMethods(char[] selector, int suggestedParameterLength) {
	return getMethods(selector);
}

//{ObjectTeams:
	/**
	 * get method by its selector, search includes superclasses, superinterfaces
	 * (except when searching a constructor).
	 * If more than one method (significantly, ie., not overriding each other)
	 * is found, return a ProblemMethodBinding, if none is found return null.
	 * Ignore tsuper versions of methods.
	 */
	public MethodBinding getMethod(Scope scope, char[] selector) {
		MethodBinding[] currentMethods = getMethods(selector);
		MethodBinding foundMethod = null;
		if (currentMethods != null)
		{
			int numFound = currentMethods.length;
			int suitableIdx = 0;
			for (int i=0; i<currentMethods.length; i++) {
				if (TSuperHelper.isTSuper(currentMethods[i]))
					numFound--;
				else
					suitableIdx = i;
			}
			if (numFound == 1)
				foundMethod = currentMethods[suitableIdx];
			else if (numFound > 1)
				return new ProblemMethodBinding(selector, Binding.NO_PARAMETERS, ProblemReasons.Ambiguous);
		}
		if (CharOperation.equals(TypeConstants.INIT, selector))
			return foundMethod; // don't search supers for constructor
		MethodVerifier verifier = scope.environment().methodVerifier(); // respect source level.
		if (superclass() != null) {
			MethodBinding superclassMethod = superclass().getMethod(scope, selector);
			foundMethod = combineFoundMethods(foundMethod, superclassMethod, verifier);
		}
		if (foundMethod != null && !foundMethod.isValidBinding())
			return foundMethod; // one problem is enough
		ReferenceBinding[] superInterfaces = superInterfaces();
		if (superInterfaces != null) {
			for (int i = 0; i < superInterfaces.length; i++) {
				MethodBinding superIfcMethod = superInterfaces[i].getMethod(scope, selector);
				foundMethod = combineFoundMethods(foundMethod, superIfcMethod, verifier);
				if (foundMethod != null && !foundMethod.isValidBinding())
					return foundMethod; // one problem is enough
			}
		}
		return foundMethod;
	}
	/**
	 * helper for the above
	 * @param match1
	 * @param superMethod
	 * @param verifier
	 * @return either match1 or superMethod or a ProblemMethodBinding (Ambiguous)
	 */
	private MethodBinding combineFoundMethods(
			MethodBinding match1,
			MethodBinding superMethod,
			MethodVerifier verifier)
	{

		MethodBinding foundMethod = match1;
		if (superMethod != null)
		{
			if (superMethod.isPrivate())
				return match1;  // ignore private method
			if (!superMethod.isValidBinding()) {
				foundMethod = superMethod; // propagate problem
			} else {
				if (match1 == null) {
					foundMethod = superMethod;
				} else {
					MethodBinding superSubstitute= verifier.computeSubstituteMethod(superMethod, match1);
					if (superSubstitute != null)
						superMethod= superSubstitute;
					if (!ImplicitNullAnnotationVerifier.areParametersEqual(match1, superMethod, verifier.environment))
						foundMethod = new ProblemMethodBinding(match1.selector, Binding.NO_PARAMETERS, ProblemReasons.Ambiguous);
				}
			}
		}
		return foundMethod;
	}
// SH}

/**
 * @return the outerLocalVariablesSlotSize
 */
public int getOuterLocalVariablesSlotSize() {
	return 0;
}

@Override
public PackageBinding getPackage() {
	return this.fPackage;
}

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;
}

@Override
public int hashCode() {
	// ensure ReferenceBindings hash to the same position 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]);
}

final int identityHashCode() {
	return super.hashCode();
}

/**
 * Returns true if the two types have an incompatible common supertype,
 * e.g. List<String> and List<Integer>
 */
public boolean hasIncompatibleSuperType(ReferenceBinding otherType) {

    if (TypeBinding.equalsEquals(this, otherType)) return false;

	ReferenceBinding[] interfacesToVisit = null;
	int nextPosition = 0;
    ReferenceBinding currentType = this;
	TypeBinding match;
	do {
		match = otherType.findSuperTypeOriginatingFrom(currentType);
		if (match != null && match.isProvablyDistinct(currentType))
			return true;

		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
		if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
			if (interfacesToVisit == null) {
				interfacesToVisit = itsInterfaces;
				nextPosition = interfacesToVisit.length;
			} else {
				int itsLength = itsInterfaces.length;
				if (nextPosition + itsLength >= interfacesToVisit.length)
					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
				nextInterface : for (int a = 0; a < itsLength; a++) {
					ReferenceBinding next = itsInterfaces[a];
					for (int b = 0; b < nextPosition; b++)
						if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
					interfacesToVisit[nextPosition++] = next;
				}
			}
		}
	} while ((currentType = currentType.superclass()) != null);

	for (int i = 0; i < nextPosition; i++) {
		currentType = interfacesToVisit[i];
		if (TypeBinding.equalsEquals(currentType, otherType)) return false;
		match = otherType.findSuperTypeOriginatingFrom(currentType);
		if (match != null && match.isProvablyDistinct(currentType))
			return true;

		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
		if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
			int itsLength = itsInterfaces.length;
			if (nextPosition + itsLength >= interfacesToVisit.length)
				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
			nextInterface : for (int a = 0; a < itsLength; a++) {
				ReferenceBinding next = itsInterfaces[a];
				for (int b = 0; b < nextPosition; b++)
					if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
				interfacesToVisit[nextPosition++] = next;
			}
		}
	}
	return false;
}

public boolean hasMemberTypes() {
    return false;
}

/**
 * Answer whether a @NonNullByDefault is applicable at the reference binding,
 * for 1.8 check if the default is applicable to the given kind of location.
 */
// pre: null annotation analysis is enabled
boolean hasNonNullDefaultFor(int location, int sourceStart) {
	// Note, STB overrides for correctly handling local types
	ReferenceBinding currentType = this;
	while (currentType != null) {
		int nullDefault = ((ReferenceBinding)currentType.original()).getNullDefault();
		if (nullDefault != 0)
			return (nullDefault & location) != 0;
		currentType = currentType.enclosingType();
	}
	// package
	return (this.getPackage().getDefaultNullness() & location) != 0;
}

int getNullDefault() {
	return 0;
}

@Override
public boolean acceptsNonNullDefault() {
	return true;
}

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

/** Query typeBits without triggering supertype lookup. */
public boolean hasNullBit(int mask) {
	return (this.typeBits & mask) != 0;
}

//{ObjectTeams: support asymmetric comparison. // FIXME(SH): is this needed or is super-impl smart enough??
@Override
public boolean isProvablyDistinct(TypeBinding otherType) {
	if (otherType.isRoleType())
		return otherType.isProvablyDistinct(this);
	else
		return super.isProvablyDistinct(otherType);
}
// SH}

/** 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 (TypeBinding.equalsEquals(this, anInterface))
		return true;

	ReferenceBinding[] interfacesToVisit = null;
	int nextPosition = 0;
	ReferenceBinding currentType = this;
	do {
		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
		if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { // in code assist cases when source types are added late, may not be finished connecting hierarchy
			if (interfacesToVisit == null) {
				interfacesToVisit = itsInterfaces;
				nextPosition = interfacesToVisit.length;
			} else {
				int itsLength = itsInterfaces.length;
				if (nextPosition + itsLength >= interfacesToVisit.length)
					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
				nextInterface : for (int a = 0; a < itsLength; a++) {
					ReferenceBinding next = itsInterfaces[a];
					for (int b = 0; b < nextPosition; b++)
						if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
					interfacesToVisit[nextPosition++] = next;
				}
			}
		}
	} while (searchHierarchy && (currentType = currentType.superclass()) != null);

	for (int i = 0; i < nextPosition; i++) {
		currentType = interfacesToVisit[i];
		if (currentType.isEquivalentTo(anInterface))
			return true;

		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
		if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { // in code assist cases when source types are added late, may not be finished connecting hierarchy
			int itsLength = itsInterfaces.length;
			if (nextPosition + itsLength >= interfacesToVisit.length)
				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
			nextInterface : for (int a = 0; a < itsLength; a++) {
				ReferenceBinding next = itsInterfaces[a];
				for (int b = 0; b < nextPosition; b++)
					if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
				interfacesToVisit[nextPosition++] = next;
			}
		}
	}
//{ObjectTeams: special case: bound base classes are conform to o.o.IBoundBase:
	if (isBoundBase())
		return (anInterface.id == IOTConstants.T_OrgObjectTeamsIBoundBase
				|| anInterface.id == IOTConstants.T_OrgObjectTeamsIBoundBase2); // assume only one of these can be used during one compile
//SH}
	return false;
}

// Internal method... assume its only sent to classes NOT interfaces
//{ObjectTeams: accessible to sub-class:
@Override
protected
// SH}
boolean implementsMethod(MethodBinding method) {
	char[] selector = method.selector;
	ReferenceBinding type = this;
	while (type != null) {
		MethodBinding[] methods = type.methods();
		long range;
		if ((range = ReferenceBinding.binarySearch(selector, methods)) >= 0) {
			int start = (int) range, end = (int) (range >> 32);
			for (int i = start; i <= end; i++) {
				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 (this.modifiers & ClassFileConstants.AccAbstract) != 0;
}

@Override
public boolean isAnnotationType() {
	return (this.modifiers & ClassFileConstants.AccAnnotation) != 0;
}

@Override
public final boolean isBinaryBinding() {
	return (this.tagBits & TagBits.IsBinaryBinding) != 0;
}

@Override
public boolean isClass() {
	return (this.modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) == 0;
}

private static SourceTypeBinding getSourceTypeBinding(ReferenceBinding ref) {
	if (ref instanceof SourceTypeBinding)
		return (SourceTypeBinding) ref;
	if (ref instanceof ParameterizedTypeBinding) {
		ParameterizedTypeBinding ptb = (ParameterizedTypeBinding) ref;
		return ptb.type instanceof SourceTypeBinding ? (SourceTypeBinding) ptb.type : null;
	}
	return null;
}
public  boolean isNestmateOf(ReferenceBinding other) {
	SourceTypeBinding s1 = getSourceTypeBinding(this);
	SourceTypeBinding s2 = getSourceTypeBinding(other);
	if (s1 == null || s2 == null) return false;

	return s1.isNestmateOf(s2);
}

@Override
public boolean isProperType(boolean admitCapture18) {
	ReferenceBinding outer = enclosingType();
	if (outer != null && !outer.isProperType(admitCapture18))
		return false;
	return super.isProperType(admitCapture18);
}

//{ObjectTeams: more queries in preparition of RoleTypeBinding:
/**
 * Overridden in RoleTypeBinding.
 * @return the source type (even if we had a RoleTypeBinding).
 */
public ReferenceBinding getRealType() {
	if (this.roleModel != null)
	{
		ReferenceBinding ifcPart = this.roleModel.getInterfacePartBinding();
		if (ifcPart != null) {
			if (isRawType() && !ifcPart.isRawType())
				return (ReferenceBinding) ((ParameterizedTypeBinding)this).environment.convertToRawType(ifcPart, false);
			return ifcPart;
		}
	}
    return this;
}

/**
 * Overridden in RoleTypeBinding.
 * @return the class (even if we had a RoleTypeBinding).
 */
public ReferenceBinding getRealClass() {
	if (this.roleModel != null)
	{
		ReferenceBinding classPart = this.roleModel.getClassPartBinding();
		if (classPart != null)
			return classPart;
	}
    return this;
}
/**
 * Return a version of other that has the same type arguments as this.
 */
public ReferenceBinding transferTypeArguments(ReferenceBinding other) {
	// only subclasses do real work
	return other;
}
// SH}


/**
 * Answer true if the receiver type can be assigned to the argument type (right)
 * In addition to improving performance, caching also ensures there is no infinite regression
 * since per nature, the compatibility check is recursive through parameterized type arguments (122775)
 */
@Override
public boolean isCompatibleWith(TypeBinding otherType, /*@Nullable*/ Scope captureScope) {
//{ObjectTeams: behind the facade introduce new parameter useObjectShortcut.
	return isCompatibleWith(otherType, true, captureScope);
}
// version which does not consider everything conform to Object:
public boolean isStrictlyCompatibleWith(TypeBinding otherType, /*@Nullable*/ Scope captureScope) {
	return isCompatibleWith(otherType, false, captureScope);
}
public boolean isCompatibleWith(TypeBinding otherType, boolean useObjectShortcut, /*@Nullable*/ Scope captureScope) {
// SH}
	if (equalsEquals(otherType, this))
		return true;

//{ObjectTeams: respect new argument useObjectShortcut:
/* orig:
	if (otherType.id == TypeIds.T_JavaLangObject)
  :giro */
	if (otherType.id == TypeIds.T_JavaLangObject && useObjectShortcut)
// SH}
		return true;
	Object result;
	if (this.compatibleCache == null) {
		this.compatibleCache = new SimpleLookupTable(3);
		result = null;
	} else {
		result = this.compatibleCache.get(otherType); // [dbg reset] this.compatibleCache.put(otherType,null)
		if (result != null) {
			return result == Boolean.TRUE;
		}
	}
	this.compatibleCache.put(otherType, Boolean.FALSE); // protect from recursive call
//{ObjectTeams: propagate:
/* orig:
	if (isCompatibleWith0(otherType, captureScope)) {
  :giro */
	if (isCompatibleWith0(otherType, useObjectShortcut, captureScope)) {
// SH}
		this.compatibleCache.put(otherType, Boolean.TRUE);
		return true;
	}
	if (captureScope == null
			&& this instanceof TypeVariableBinding
			&& ((TypeVariableBinding)this).firstBound instanceof ParameterizedTypeBinding) {
		// see https://bugs.eclipse.org/395002#c9
		// in this case a subsequent check with captureScope != null may actually get
		// a better result, reset this info to ensure we're not blocking that re-check.
		this.compatibleCache.put(otherType, null);
	}
	return false;
}

//{ObjectTeams: after re-wiring superclass/ifc reset all false values in the compatibleCache
public void resetIncompatibleTypes() {
	if (this.compatibleCache == null) return;
	for (int i=0; i< this.compatibleCache.valueTable.length; i++) {
		if (this.compatibleCache.valueTable[i] == Boolean.FALSE) {
			this.compatibleCache.keyTable[i] = null;
			this.compatibleCache.elementSize--;
		}
	}
}
// SH}
/**
 * Answer true if the receiver type can be assigned to the argument type (right)
 */
//{ObjectTeams: new parameter useObjectShortcut
private boolean isCompatibleWith0(TypeBinding otherType, boolean useObjectShortcut, /*@Nullable*/ Scope captureScope) {
// SH}
	if (TypeBinding.equalsEquals(otherType, this))
		return true;
//{ObjectTeams: respect new param:
/*orig:
	if (otherType.id == TypeIds.T_JavaLangObject)
 :giro*/
	if (otherType.id == TypeIds.T_JavaLangObject && useObjectShortcut)
// SH}
		return true;
	// equivalence may allow compatibility with array type through wildcard
	// bound
	if (isEquivalentTo(otherType))
		return true;
	switch (otherType.kind()) {
		case Binding.WILDCARD_TYPE :
		case Binding.INTERSECTION_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;
				TypeBinding otherLowerBound;
				if ((otherLowerBound = otherCapture.lowerBound) != null) {
					if (otherLowerBound.isArrayType()) return false;
					return isCompatibleWith(otherLowerBound);
				}
			}
			if (otherType instanceof InferenceVariable) {
				// may interpret InferenceVariable as a joker, but only when within an outer lambda inference:
				if (captureScope != null) {
					MethodScope methodScope = captureScope.methodScope();
					if (methodScope != null) {
						ReferenceContext referenceContext = methodScope.referenceContext;
						if (referenceContext instanceof LambdaExpression
								&& ((LambdaExpression)referenceContext).inferenceContext != null)
							return true;
					}
				}
			}
			//$FALL-THROUGH$
		case Binding.GENERIC_TYPE :
		case Binding.TYPE :
		case Binding.PARAMETERIZED_TYPE :
		case Binding.RAW_TYPE :
		case Binding.INTERSECTION_TYPE18 :
			switch (kind()) {
				case Binding.GENERIC_TYPE :
				case Binding.PARAMETERIZED_TYPE :
				case Binding.RAW_TYPE :
					if (TypeBinding.equalsEquals(erasure(), otherType.erasure()))
						return false; // should have passed equivalence check
										// above if same erasure
			}
			ReferenceBinding otherReferenceType = (ReferenceBinding) otherType;
			if (otherReferenceType.isIntersectionType18()) {
				ReferenceBinding[] intersectingTypes = ((IntersectionTypeBinding18)otherReferenceType).intersectingTypes;
				for (ReferenceBinding binding : intersectingTypes) {
					if (!isCompatibleWith(binding))
						return false;
				}
				return true;
			}
			if (otherReferenceType.isInterface()) { // could be annotation type
				if (implementsInterface(otherReferenceType, true))
					return true;
				if (this instanceof TypeVariableBinding && captureScope != null) {
					TypeVariableBinding typeVariable = (TypeVariableBinding) this;
					if (typeVariable.firstBound instanceof ParameterizedTypeBinding) {
						TypeBinding bound = typeVariable.firstBound.capture(captureScope, -1, -1); // no position needed as this capture will never escape this context
						return bound.isCompatibleWith(otherReferenceType);
					}
				}
			}
//{ObjectTeams: only leave if we have checked for java.lang.Object above:
/* orig:
			if (isInterface())  // Explicit conversion from an interface
										// to a class is not allowed
  :giro */
			if (isInterface() && useObjectShortcut)
// SH}
				return false;
			return otherReferenceType.isSuperclassOf(this);
		default :
			return false;
	}
}
//{ObjectTeams: type weakening and lowering
public ReferenceBinding weakenFrom(ReferenceBinding other) {
	return other;
}
public boolean isCompatibleViaLowering(ReferenceBinding other) {
	return false;
}
// SH}
/**
 * Answer true if the receiver has non-sealed modifier
 */
public final boolean isNonSealed() {
	return (this.modifiers & ExtraCompilerModifiers.AccNonSealed) != 0;
}

/**
 * Answer true if the receiver has sealed modifier
 */
public boolean isSealed() {
	return (this.modifiers & ExtraCompilerModifiers.AccSealed) != 0;
}

@Override
public boolean isSubtypeOf(TypeBinding other, boolean simulatingBugJDK8026527) {
	if (isSubTypeOfRTL(other))
		return true;
	// TODO: if this has wildcards, perform capture before the next call:
	TypeBinding candidate = findSuperTypeOriginatingFrom(other);
	if (candidate == null)
		return false;
	if (TypeBinding.equalsEquals(candidate, other))
		return true;

	// T<Ai...> <: T#RAW:
	if (other.isRawType() && TypeBinding.equalsEquals(candidate.erasure(), other.erasure()))
		return true;

	TypeBinding[] sis = other.typeArguments();
	TypeBinding[] tis = candidate.typeArguments();
	if (tis == null || sis == null)
		return false;
	if (sis.length != tis.length)
		return false;
	for (int i = 0; i < sis.length; i++) {
		if (!tis[i].isTypeArgumentContainedBy(sis[i]))
			return false;
	}
	return true;
}

protected boolean isSubTypeOfRTL(TypeBinding other) {
	if (TypeBinding.equalsEquals(this, other))
		return true;
	if (other instanceof CaptureBinding) {
		// for this one kind we must first unwrap the rhs:
		TypeBinding lower = ((CaptureBinding) other).lowerBound;
		return (lower != null && isSubtypeOf(lower, false));
	}
	if (other instanceof ReferenceBinding) {
		TypeBinding[] intersecting = ((ReferenceBinding) other).getIntersectingTypes();
		if (intersecting != null) {
			for (int i = 0; i < intersecting.length; i++) {
				if (!isSubtypeOf(intersecting[i], false))
					return false;
			}
			return true;
		}
	}
	return false;
}

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

/**
 * Answer true if the receiver is a deprecated type
 */
public final boolean isDeprecated() {
	return (this.modifiers & ClassFileConstants.AccDeprecated) != 0;
}

@Override
public boolean isEnum() {
	return (this.modifiers & ClassFileConstants.AccEnum) != 0;
}

/**
 * Answer true if the receiver is final and cannot be subclassed
 */
public final boolean isFinal() {
	return (this.modifiers & ClassFileConstants.AccFinal) != 0;
}

/**
 * Returns true if the type hierarchy is being connected
 */
public boolean isHierarchyBeingConnected() {
	return (this.tagBits & TagBits.EndHierarchyCheck) == 0 && (this.tagBits & TagBits.BeginHierarchyCheck) != 0;
}
/**
 * Returns true if the type hierarchy is being connected "actively" i.e not paused momentatrily,
 * while resolving type arguments. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057
 */
public boolean isHierarchyBeingActivelyConnected() {
	return (this.tagBits & TagBits.EndHierarchyCheck) == 0 && (this.tagBits & TagBits.BeginHierarchyCheck) != 0 && (this.tagBits & TagBits.PauseHierarchyCheck) == 0;
}

/**
 * Returns true if the type hierarchy is connected
 */
public boolean isHierarchyConnected() {
	return true;
}

@Override
public boolean isInterface() {
	// consider strict interfaces and annotation types
	return (this.modifiers & ClassFileConstants.AccInterface) != 0;
}

@Override
public boolean isFunctionalInterface(Scope scope) {
	MethodBinding method;
	return isInterface() && (method = getSingleAbstractMethod(scope, true)) != null && method.isValidBinding();
}

/**
 * Answer true if the receiver has private visibility
 */
public final boolean isPrivate() {
	return (this.modifiers & ClassFileConstants.AccPrivate) != 0;
}

/**
 * Answer true if the receiver or any of its enclosing types have private visibility
 */
public final boolean isOrEnclosedByPrivateType() {
	if (isLocalType()) return true; // catch all local types
	ReferenceBinding type = this;
	while (type != null) {
		if ((type.modifiers & ClassFileConstants.AccPrivate) != 0)
			return true;
		type = type.enclosingType();
	}
	return false;
}

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

/**
 * Answer true if the receiver has public visibility
 */
public final boolean isPublic() {
	return (this.modifiers & ClassFileConstants.AccPublic) != 0;
}

/**
 * Answer true if the receiver is a static member type (or toplevel)
 */
@Override
public final boolean isStatic() {
//{ObjectTeams: roles, even their interface part, are not static:
	if ((this.modifiers & ExtraCompilerModifiers.AccRole) != 0) return false;
// SH}
	return (this.modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccInterface)) != 0 || (this.tagBits & TagBits.IsNestedType) == 0;
}

/**
 * Answer true if all float operations must adher to IEEE 754 float/double rules
 */
public final boolean isStrictfp() {
	return (this.modifiers & ClassFileConstants.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;
}

/**
 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isThrowable()
 */
@Override
public boolean isThrowable() {
	ReferenceBinding current = this;
	do {
		switch (current.id) {
			case TypeIds.T_JavaLangThrowable :
			case TypeIds.T_JavaLangError :
			case TypeIds.T_JavaLangRuntimeException :
			case TypeIds.T_JavaLangException :
				return true;
		}
	} while ((current = current.superclass()) != null);
	return false;
}

/**
 * JLS 11.5 ensures that Throwable, Exception, RuntimeException and Error are directly connected.
 * (Throwable<- Exception <- RumtimeException, Throwable <- Error). Thus no need to check #isCompatibleWith
 * but rather check in type IDs so as to avoid some eager class loading for JCL writers.
 * When 'includeSupertype' is true, answers true if the given type can be a supertype of some unchecked exception
 * type (i.e. Throwable or Exception).
 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isUncheckedException(boolean)
 */
@Override
public boolean isUncheckedException(boolean includeSupertype) {
	switch (this.id) {
			case TypeIds.T_JavaLangError :
			case TypeIds.T_JavaLangRuntimeException :
				return true;
			case TypeIds.T_JavaLangThrowable :
			case TypeIds.T_JavaLangException :
				return includeSupertype;
	}
	ReferenceBinding current = this;
	while ((current = current.superclass()) != null) {
		switch (current.id) {
			case TypeIds.T_JavaLangError :
			case TypeIds.T_JavaLangRuntimeException :
				return true;
			case TypeIds.T_JavaLangThrowable :
			case TypeIds.T_JavaLangException :
				return false;
		}
	}
	return false;
}

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

/**
 * Answer true if the receiver is deprecated (or any of its enclosing types)
 */
public final boolean isViewedAsDeprecated() {
	if ((this.modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0)
		return true;
	if (getPackage().isViewedAsDeprecated()) {
		this.tagBits |= (getPackage().tagBits & TagBits.AnnotationTerminallyDeprecated);
		return true;
	}
	return false;
}

/**
 * Returns the member types of this type sorted by simple name.
 */
@Override
public ReferenceBinding[] memberTypes() {
	return Binding.NO_MEMBER_TYPES;
}

public MethodBinding[] methods() {
	return Binding.NO_METHODS;
}

public final ReferenceBinding outermostEnclosingType() {
	ReferenceBinding current = this;
	while (true) {
		ReferenceBinding last = current;
		if ((current = current.enclosingType()) == null)
			return last;
	}
}
//{ObjectTeams: the following output-oriented methods should
//              never use field sourceName directly, but only sourceName()!
/**
 * 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".
 */
// orig (if internal names are desired, add a method qualifiedInternalName(),
//       here and in sub-classes.):
@Override
public char[] qualifiedSourceName() {
	if (isMemberType())
		return CharOperation.concat(enclosingType().qualifiedSourceName(), sourceName(), '.');
	return sourceName();
}

/**
 * Answer the receiver's signature.
 *
 * NOTE: This method should only be used during/after code gen.
 */
@Override
public char[] readableName() /*java.lang.Object,  p.X<T> */ {
	return readableName(true);
}
public char[] readableName(boolean showGenerics) /*java.lang.Object,  p.X<T> */ {
    char[] readableName;
	if (isMemberType()) {
		readableName = CharOperation.concat(enclosingType().readableName(showGenerics && hasEnclosingInstanceContext()), sourceName(), '.'); // OT: was this.sourceName
	} else {
		readableName = CharOperation.concatWith(this.compoundName, '.');
	}
	if (showGenerics) {
		TypeVariableBinding[] typeVars;
//{ObjectTeams: include value parameters:
		SyntheticArgumentBinding[] valueParams = valueParamSynthArgs();
/* orig:
		if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
  :giro */
		if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES || valueParams != Binding.NO_SYNTH_ARGUMENTS) {
// orig:
	    	StringBuffer nameBuffer = new StringBuffer(10);
	    	nameBuffer.append(readableName).append('<');
// :giro
		    for (int i = 0; i < valueParams.length; i++) {
		    	nameBuffer.append('@');
				nameBuffer.append(valueParams[i].readableName());
				if (typeVars.length > 0)
					nameBuffer.append(',');
			}
// SH}
		    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;
}

protected void appendNullAnnotation(StringBuffer nameBuffer, CompilerOptions options) {
	if (options.isAnnotationBasedNullAnalysisEnabled) {
		if (options.usesNullTypeAnnotations()) {
			for (AnnotationBinding annotation : this.typeAnnotations) {
				ReferenceBinding annotationType = annotation.getAnnotationType();
				if (annotationType.hasNullBit(TypeIds.BitNonNullAnnotation|TypeIds.BitNullableAnnotation)) {
					nameBuffer.append('@').append(annotationType.shortReadableName()).append(' ');
				}
			}
		} else {
			// restore applied null annotation from tagBits:
		    if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
		    	char[][] nonNullAnnotationName = options.nonNullAnnotationName;
				nameBuffer.append('@').append(nonNullAnnotationName[nonNullAnnotationName.length-1]).append(' ');
		    }
		    if ((this.tagBits & TagBits.AnnotationNullable) != 0) {
		    	char[][] nullableAnnotationName = options.nullableAnnotationName;
				nameBuffer.append('@').append(nullableAnnotationName[nullableAnnotationName.length-1]).append(' ');
		    }
		}
	}
}

public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
	SimpleLookupTable store = storedAnnotations(forceInitialization, false);
	return store == null ? null : (AnnotationHolder) store.get(binding);
}

//{ObjectTeams: accessible to classes in org.eclipse.objectteams...:
public
// SH}
AnnotationBinding[] retrieveAnnotations(Binding binding) {
	AnnotationHolder holder = retrieveAnnotationHolder(binding, true);
	return holder == null ? Binding.NO_ANNOTATIONS : holder.getAnnotations();
}

@Override
public void setAnnotations(AnnotationBinding[] annotations, boolean forceStore) {
	storeAnnotations(this, annotations, forceStore);
}
public void setContainerAnnotationType(ReferenceBinding value) {
	// Leave this to subclasses
}
public void tagAsHavingDefectiveContainerType() {
	// Leave this to subclasses
}

/**
 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#nullAnnotatedReadableName(CompilerOptions,boolean)
 */
@Override
public char[] nullAnnotatedReadableName(CompilerOptions options, boolean shortNames) {
	if (shortNames)
		return nullAnnotatedShortReadableName(options);
	return nullAnnotatedReadableName(options);
}

char[] nullAnnotatedReadableName(CompilerOptions options) {
    StringBuffer nameBuffer = new StringBuffer(10);
	if (isMemberType()) {
		nameBuffer.append(enclosingType().nullAnnotatedReadableName(options, false));
		nameBuffer.append('.');
		appendNullAnnotation(nameBuffer, options);
		nameBuffer.append(this.sourceName);
	} else if (this.compoundName != null) {
		int i;
		int l=this.compoundName.length;
		for (i=0; i<l-1; i++) {
			nameBuffer.append(this.compoundName[i]);
			nameBuffer.append('.');
		}
	    appendNullAnnotation(nameBuffer, options);
		nameBuffer.append(this.compoundName[i]);
	} else {
		// case of TypeVariableBinding with nullAnnotationTagBits:
		appendNullAnnotation(nameBuffer, options);
		if (this.sourceName != null)
			nameBuffer.append(this.sourceName);
		else // WildcardBinding, CaptureBinding have no sourceName
			nameBuffer.append(this.readableName());
	}
	TypeBinding [] arguments = typeArguments();
	if (arguments != null && arguments.length > 0) { // empty arguments array happens when PTB has been created just to capture type annotations
		nameBuffer.append('<');
	    for (int i = 0, length = arguments.length; i < length; i++) {
	        if (i > 0) nameBuffer.append(',');
	        nameBuffer.append(arguments[i].nullAnnotatedReadableName(options, false));
	    }
	    nameBuffer.append('>');
	}
	int nameLength = nameBuffer.length();
	char[] readableName = new char[nameLength];
	nameBuffer.getChars(0, nameLength, readableName, 0);
    return readableName;
}

char[] nullAnnotatedShortReadableName(CompilerOptions options) {
    StringBuffer nameBuffer = new StringBuffer(10);
	if (isMemberType()) {
		nameBuffer.append(enclosingType().nullAnnotatedReadableName(options, true));
		nameBuffer.append('.');
		appendNullAnnotation(nameBuffer, options);
		nameBuffer.append(this.sourceName);
	} else {
		appendNullAnnotation(nameBuffer, options);
		if (this.sourceName != null)
			nameBuffer.append(this.sourceName);
		else // WildcardBinding, CaptureBinding have no sourceName
			nameBuffer.append(this.shortReadableName());
	}
	TypeBinding [] arguments = typeArguments();
	if (arguments != null && arguments.length > 0) { // empty arguments array happens when PTB has been created just to capture type annotations
		nameBuffer.append('<');
	    for (int i = 0, length = arguments.length; i < length; i++) {
	        if (i > 0) nameBuffer.append(',');
	        nameBuffer.append(arguments[i].nullAnnotatedReadableName(options, true));
	    }
	    nameBuffer.append('>');
	}
	int nameLength = nameBuffer.length();
	char[] shortReadableName = new char[nameLength];
	nameBuffer.getChars(0, nameLength, shortReadableName, 0);
    return shortReadableName;
}

@Override
public char[] shortReadableName() /*Object*/ {
	return shortReadableName(true);
}
public char[] shortReadableName(boolean showGenerics) /*Object*/ {
	char[] shortReadableName;
	if (isMemberType()) {
		shortReadableName = CharOperation.concat(enclosingType().shortReadableName(showGenerics && hasEnclosingInstanceContext()), sourceName(), '.'); // OT: was this.sourceName
	} else {
		shortReadableName = sourceName(); // OT: was sourceName
	}
	if (showGenerics) {
		TypeVariableBinding[] typeVars;
//{ObjectTeams: include value parameters:
		SyntheticArgumentBinding[] valueParams = valueParamSynthArgs();
/* orig:
		if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
  :giro */
		if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES || valueParams != Binding.NO_SYNTH_ARGUMENTS) {
// orig:
		    StringBuffer nameBuffer = new StringBuffer(10);
		    nameBuffer.append(shortReadableName).append('<');
// :giro
		    for (int i = 0; i < valueParams.length; i++) {
		    	nameBuffer.append('@');
				nameBuffer.append(valueParams[i].shortReadableName());
				if (typeVars.length > 0)
					nameBuffer.append(',');
			}
// SH}
		    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;
}
// SH} // end sourceName - edited section

//{ObjectTeams: to be overridden in RoleTypeBinding
public char[] optimalName() {
	return readableName();
}
// SH}
//{ObjectTeams: beautify for completion:
@Override
public char[] genericTypeSignature(boolean retrenchCallin) {
	char[] result = genericTypeSignature();
	if (!retrenchCallin)
		return result;
	return CharOperation.replace(result, IOTConstants.OT_DELIM_NAME, new char[0]);
}
// SH}
@Override
public char[] signature() /* Ljava/lang/Object; */ {
	if (this.signature != null)
		return this.signature;

	return this.signature = CharOperation.concat('L', constantPoolName(), ';');
}

@Override
public char[] sourceName() {
//{ObjectTeams: human readable source name, stripping __OT__ prefix if present
    if (isSourceRole() && RoleSplitter.isClassPartName(this.sourceName))
        return RoleSplitter.getInterfacePartName(this.sourceName);
	return this.sourceName;
}
// original sourceName():
@Override
public char[] internalName() {
	return this.sourceName;
}
// SH}

/**
 * Perform an upwards type projection as per JLS 4.10.5
 * @param scope Relevant scope for evaluating type projection
 * @param mentionedTypeVariables Filter for mentioned type variabled
 * @returns Upwards type projection of 'this', or null if downwards projection is undefined
*/
@Override
public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
	return this;
}

/**
 * Perform a downwards type projection as per JLS 4.10.5
 * @param scope Relevant scope for evaluating type projection
 * @param mentionedTypeVariables Filter for mentioned type variabled
 * @returns Downwards type projection of 'this', or null if downwards projection is undefined
*/
@Override
public ReferenceBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
	return this;
}

void storeAnnotationHolder(Binding binding, AnnotationHolder holder) {
	if (holder == null) {
		SimpleLookupTable store = storedAnnotations(false, false);
		if (store != null)
			store.removeKey(binding);
	} else {
		SimpleLookupTable store = storedAnnotations(true, false);
		if (store != null)
			store.put(binding, holder);
	}
}

//{ObjectTeams: accessible to classes in org.eclipse.objectteams...:
public
// SH}
void storeAnnotations(Binding binding, AnnotationBinding[] annotations, boolean forceStore) {
	AnnotationHolder holder = null;
	if (annotations == null || annotations.length == 0) {
		SimpleLookupTable store = storedAnnotations(false, forceStore);
		if (store != null)
			holder = (AnnotationHolder) store.get(binding);
		if (holder == null) return; // nothing to delete
	} else {
		SimpleLookupTable store = storedAnnotations(true, forceStore);
		if (store == null) return; // not supported
		holder = (AnnotationHolder) store.get(binding);
		if (holder == null)
			holder = new AnnotationHolder();
	}
	storeAnnotationHolder(binding, holder.setAnnotations(annotations));
}

SimpleLookupTable storedAnnotations(boolean forceInitialize, boolean forceStore) {
	return null; // overrride if interested in storing annotations for the receiver, its fields and methods
}

@Override
public ReferenceBinding superclass() {
	return null;
}

@Override
public ReferenceBinding[] permittedTypes() {
	return Binding.NO_PERMITTEDTYPES;
}

@Override
public ReferenceBinding[] superInterfaces() {
	return Binding.NO_SUPERINTERFACES;
}

public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
	if (isStatic()) return null;
	ReferenceBinding enclosingType = enclosingType();
	if (enclosingType == null)
		return null;
	return new ReferenceBinding[] {enclosingType};
}

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

public FieldBinding[] unResolvedFields() {
	return Binding.NO_FIELDS;
}

/*
 * If a type - known to be a Closeable - is mentioned in one of our white lists
 * answer the typeBit for the white list (BitWrapperCloseable or BitResourceFreeCloseable).
 */
protected int applyCloseableClassWhitelists(CompilerOptions options) {
	switch (this.compoundName.length) {
		case 3:
			if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) {
				if (CharOperation.equals(TypeConstants.IO, this.compoundName[1])) {
					char[] simpleName = this.compoundName[2];
					int l = TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES.length;
					for (int i = 0; i < l; i++) {
						if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES[i]))
							return TypeIds.BitWrapperCloseable;
					}
					l = TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES.length;
					for (int i = 0; i < l; i++) {
						if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES[i]))
							return TypeIds.BitResourceFreeCloseable;
					}
				}
			}
			break;
		case 4:
			if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) {
				if (CharOperation.equals(TypeConstants.UTIL, this.compoundName[1])) {
					if (CharOperation.equals(TypeConstants.ZIP, this.compoundName[2])) {
						char[] simpleName = this.compoundName[3];
						int l = TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES.length;
						for (int i = 0; i < l; i++) {
							if (CharOperation.equals(simpleName, TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES[i]))
								return TypeIds.BitWrapperCloseable;
						}
					}
				}
			}
			break;
	}
	int l = TypeConstants.OTHER_WRAPPER_CLOSEABLES.length;
	for (int i = 0; i < l; i++) {
		if (CharOperation.equals(this.compoundName, TypeConstants.OTHER_WRAPPER_CLOSEABLES[i]))
			return TypeIds.BitWrapperCloseable;
	}
	if (options.analyseResourceLeaks) {
		ReferenceBinding mySuper = this.superclass();
		if (mySuper != null && mySuper.id != TypeIds.T_JavaLangObject) {
			if (hasMethodWithNumArgs(TypeConstants.CLOSE, 0))
				return 0; // close methods indicates: class may need more closing than super
			return mySuper.applyCloseableClassWhitelists(options);
		}
	}
	return 0;
}

protected boolean hasMethodWithNumArgs(char[] selector, int numArgs) {
	for (MethodBinding methodBinding : unResolvedMethods()) {
		if (CharOperation.equals(methodBinding.selector, selector)
				&& methodBinding.parameters.length == numArgs) {
			return true;
		}
	}
	return false;
}
/*
 * If a type - known to be a Closeable - is mentioned in one of our white lists
 * answer the typeBit for the white list (BitWrapperCloseable or BitResourceFreeCloseable).
 */
protected int applyCloseableInterfaceWhitelists() {
	switch (this.compoundName.length) {
		case 4:
			for (int i=0; i<2; i++)
				if (!CharOperation.equals(this.compoundName[i], TypeConstants.JAVA_UTIL_STREAM[i]))
					return 0;
			for (char[] streamName : TypeConstants.RESOURCE_FREE_CLOSEABLE_J_U_STREAMS)
				if (CharOperation.equals(this.compoundName[3], streamName))
					return TypeIds.BitResourceFreeCloseable;
			break;
	}
	return 0;
}

//{ObjectTeams: support for checking substitution of a value parameter
public VariableBinding valueParamSynthArgAt(int typeParamPosition) {
	SyntheticArgumentBinding[] args = valueParamSynthArgs();
	if (args.length > typeParamPosition)
		return args[typeParamPosition];
	return null;
}
// SH}

protected MethodBinding [] getInterfaceAbstractContracts(Scope scope, boolean replaceWildcards, boolean filterDefaultMethods) throws InvalidInputException {

	if (!isInterface() || !isValidBinding()) {
		throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$
	}

	MethodBinding [] methods = methods();
	MethodBinding [] contracts = new MethodBinding[0];
	int contractsCount = 0;
	int contractsLength = 0;

	ReferenceBinding [] superInterfaces = superInterfaces();
	for (int i = 0, length = superInterfaces.length; i < length; i++) {
		// filterDefaultMethods=false => keep default methods needed to filter out any abstract methods they may override:
		MethodBinding [] superInterfaceContracts = superInterfaces[i].getInterfaceAbstractContracts(scope, replaceWildcards, false);
		final int superInterfaceContractsLength = superInterfaceContracts == null  ? 0 : superInterfaceContracts.length;
		if (superInterfaceContractsLength == 0) continue;
		if (contractsLength < contractsCount + superInterfaceContractsLength) {
			System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength = contractsCount + superInterfaceContractsLength], 0, contractsCount);
		}
		System.arraycopy(superInterfaceContracts, 0, contracts, contractsCount,	superInterfaceContractsLength);
		contractsCount += superInterfaceContractsLength;
	}

	LookupEnvironment environment = scope.environment();
	for (int i = 0, length = methods == null ? 0 : methods.length; i < length; i++) {
		final MethodBinding method = methods[i];
		if (method == null || method.isStatic() || method.redeclaresPublicObjectMethod(scope) || method.isPrivate())
			continue;
		if (!method.isValidBinding())
			throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$
		for (int j = 0; j < contractsCount;) {
			if ( contracts[j] != null && MethodVerifier.doesMethodOverride(method, contracts[j], environment)) {
				contractsCount--;
				// abstract method from super type overridden by present interface ==> contracts[j] = null;
				if (j < contractsCount) {
					System.arraycopy(contracts, j+1, contracts, j, contractsCount - j);
					continue;
				}
			}
			j++;
		}
		if (filterDefaultMethods && method.isDefaultMethod())
			continue; // skip default method itself
		if (contractsCount == contractsLength) {
			System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength += 16], 0, contractsCount);
		}
		if(environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
			ImplicitNullAnnotationVerifier.ensureNullnessIsKnown(method, scope);
		}
		contracts[contractsCount++] = method;
	}
	// check mutual overriding of inherited methods (i.e., not from current type):
	for (int i = 0; i < contractsCount; i++) {
		MethodBinding contractI = contracts[i];
		if (TypeBinding.equalsEquals(contractI.declaringClass, this))
			continue;
		for (int j = 0; j < contractsCount; j++) {
			MethodBinding contractJ = contracts[j];
			if (i == j || TypeBinding.equalsEquals(contractJ.declaringClass, this))
				continue;
			if (contractI == contractJ || MethodVerifier.doesMethodOverride(contractI, contractJ, environment)) {
				contractsCount--;
				// abstract method from one super type overridden by other super interface ==> contracts[j] = null;
				if (j < contractsCount) {
					System.arraycopy(contracts, j+1, contracts, j, contractsCount - j);
				}
				j--;
				if (j < i)
					i--;
				continue;
			}
		}
		if (filterDefaultMethods && contractI.isDefaultMethod()) {
			contractsCount--;
			// remove default method after it has eliminated any matching abstract methods from contracts
			if (i < contractsCount) {
				System.arraycopy(contracts, i+1, contracts, i, contractsCount - i);
			}
			i--;
		}
	}
	if (contractsCount < contractsLength) {
		System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsCount], 0, contractsCount);
	}
	return contracts;
}
@Override
public MethodBinding getSingleAbstractMethod(Scope scope, boolean replaceWildcards) {

	int index = replaceWildcards ? 0 : 1;
	if (this.singleAbstractMethod != null) {
		if (this.singleAbstractMethod[index] != null)
		return this.singleAbstractMethod[index];
	} else {
		this.singleAbstractMethod = new MethodBinding[2];
	}

	if (this.compoundName != null)
		scope.compilationUnitScope().recordQualifiedReference(this.compoundName);
	MethodBinding[] methods = null;
	try {
		methods = getInterfaceAbstractContracts(scope, replaceWildcards, true);
		if (methods == null || methods.length == 0)
			return this.singleAbstractMethod[index] = samProblemBinding;
		int contractParameterLength = 0;
		char [] contractSelector = null;
		for (int i = 0, length = methods.length; i < length; i++) {
			MethodBinding method = methods[i];
			if (method == null) continue;
			if (contractSelector == null) {
				contractSelector = method.selector;
				contractParameterLength = method.parameters == null ? 0 : method.parameters.length;
			} else {
				int methodParameterLength = method.parameters == null ? 0 : method.parameters.length;
				if (methodParameterLength != contractParameterLength || !CharOperation.equals(method.selector, contractSelector))
					return this.singleAbstractMethod[index] = samProblemBinding;
			}
		}
	} catch (InvalidInputException e) {
		return this.singleAbstractMethod[index] = samProblemBinding;
	}
	if (methods.length == 1)
		return this.singleAbstractMethod[index] = methods[0];

	final LookupEnvironment environment = scope.environment();
	boolean genericMethodSeen = false;
	int length = methods.length;
	boolean analyseNullAnnotations = environment.globalOptions.isAnnotationBasedNullAnalysisEnabled;

	next:for (int i = length - 1; i >= 0; --i) {
		MethodBinding method = methods[i], otherMethod = null;
		if (method.typeVariables != Binding.NO_TYPE_VARIABLES)
			genericMethodSeen = true;
		TypeBinding returnType = method.returnType;
		TypeBinding[] parameters = method.parameters;
		for (int j = 0; j < length; j++) {
			if (i == j) continue;
			otherMethod = methods[j];
			if (otherMethod.typeVariables != Binding.NO_TYPE_VARIABLES)
				genericMethodSeen = true;

			if (genericMethodSeen) { // adapt type parameters.
				otherMethod = MethodVerifier.computeSubstituteMethod(otherMethod, method, environment);
				if (otherMethod == null)
					continue next;
			}
			if (!MethodVerifier.isSubstituteParameterSubsignature(method, otherMethod, environment) || !MethodVerifier.areReturnTypesCompatible(method, otherMethod, environment))
				continue next;
			if (analyseNullAnnotations) {
				returnType = NullAnnotationMatching.strongerType(returnType, otherMethod.returnType, environment);
				parameters = NullAnnotationMatching.weakerTypes(parameters, otherMethod.parameters, environment);
			}
		}
		// If we reach here, we found a method that is override equivalent with every other method and is also return type substitutable. Compute kosher exceptions now ...
		ReferenceBinding [] exceptions = new ReferenceBinding[0];
		int exceptionsCount = 0, exceptionsLength = 0;
		final MethodBinding theAbstractMethod = method;
		boolean shouldEraseThrows = theAbstractMethod.typeVariables == Binding.NO_TYPE_VARIABLES && genericMethodSeen;
		boolean shouldAdaptThrows = theAbstractMethod.typeVariables != Binding.NO_TYPE_VARIABLES;
		final int typeVariableLength = theAbstractMethod.typeVariables.length;

		none:for (i = 0; i < length; i++) {
			method = methods[i];
			ReferenceBinding[] methodThrownExceptions = method.thrownExceptions;
			int methodExceptionsLength = methodThrownExceptions == null ? 0: methodThrownExceptions.length;
			if (methodExceptionsLength == 0) break none;
			if (shouldAdaptThrows && method != theAbstractMethod) {
				System.arraycopy(methodThrownExceptions, 0, methodThrownExceptions = new ReferenceBinding[methodExceptionsLength], 0, methodExceptionsLength);
				for (int tv = 0; tv < typeVariableLength; tv++) {
					if (methodThrownExceptions[tv] instanceof TypeVariableBinding) {
						methodThrownExceptions[tv] = theAbstractMethod.typeVariables[tv];
					}
				}
			}
			nextException: for (int j = 0; j < methodExceptionsLength; j++) {
				ReferenceBinding methodException = methodThrownExceptions[j];
				if (shouldEraseThrows)
					methodException = (ReferenceBinding) methodException.erasure();
				nextMethod: for (int k = 0; k < length; k++) {
					if (i == k) continue;
					otherMethod = methods[k];
					ReferenceBinding[] otherMethodThrownExceptions = otherMethod.thrownExceptions;
					int otherMethodExceptionsLength =  otherMethodThrownExceptions == null ? 0 : otherMethodThrownExceptions.length;
					if (otherMethodExceptionsLength == 0) break none;
					if (shouldAdaptThrows && otherMethod != theAbstractMethod) {
						System.arraycopy(otherMethodThrownExceptions,
								0,
								otherMethodThrownExceptions = new ReferenceBinding[otherMethodExceptionsLength],
								0,
								otherMethodExceptionsLength);
						for (int tv = 0; tv < typeVariableLength; tv++) {
							if (otherMethodThrownExceptions[tv] instanceof TypeVariableBinding) {
								otherMethodThrownExceptions[tv] = theAbstractMethod.typeVariables[tv];
							}
						}
					}
					for (int l = 0; l < otherMethodExceptionsLength; l++) {
						ReferenceBinding otherException = otherMethodThrownExceptions[l];
						if (shouldEraseThrows)
							otherException = (ReferenceBinding) otherException.erasure();
						if (methodException.isCompatibleWith(otherException))
							continue nextMethod;
					}
					continue nextException;
				}
				// If we reach here, method exception or its super type is covered by every throws clause.
				if (exceptionsCount == exceptionsLength) {
					System.arraycopy(exceptions, 0, exceptions = new ReferenceBinding[exceptionsLength += 16], 0, exceptionsCount);
				}
				exceptions[exceptionsCount++] = methodException;
			}
		}
		if (exceptionsCount != exceptionsLength) {
			System.arraycopy(exceptions, 0, exceptions = new ReferenceBinding[exceptionsCount], 0, exceptionsCount);
		}
		this.singleAbstractMethod[index] = new MethodBinding(theAbstractMethod.modifiers | ClassFileConstants.AccSynthetic,
				theAbstractMethod.selector,
				returnType,
				parameters,
				exceptions,
				theAbstractMethod.declaringClass);
	    this.singleAbstractMethod[index].typeVariables = theAbstractMethod.typeVariables;
		return this.singleAbstractMethod[index];
	}
	return this.singleAbstractMethod[index] = samProblemBinding;
}

// See JLS 4.9 bullet 1
public static boolean isConsistentIntersection(TypeBinding[] intersectingTypes) {
	TypeBinding[] ci = new TypeBinding[intersectingTypes.length];
	for (int i = 0; i < ci.length; i++) {
		TypeBinding current = intersectingTypes[i];
		ci[i] = (current.isClass() || current.isArrayType())
					? current : current.superclass();
	}
	TypeBinding mostSpecific = ci[0];
	for (int i = 1; i < ci.length; i++) {
		TypeBinding current = ci[i];
		// when invoked during type inference we only want to check inconsistency among real types:
		if (current.isTypeVariable() || current.isWildcard() || !current.isProperType(true))
			continue;
		if (mostSpecific.isSubtypeOf(current, false))
			continue;
		else if (current.isSubtypeOf(mostSpecific, false))
			mostSpecific = current;
		else
			return false;
	}
	return true;
}
public ModuleBinding module() {
	if (this.fPackage != null)
		return this.fPackage.enclosingModule;
	return null;
}

public boolean hasEnclosingInstanceContext() {
	if (isMemberType() && !isStatic())
		return true;
	if (isLocalType() && isStatic())
		return false;
	MethodBinding enclosingMethod = enclosingMethod();
	if (enclosingMethod != null)
		return !enclosingMethod.isStatic();
	return false;
}
}
