/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 *
 * Copyright 2003, 2006 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute for Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany.
 *
 * 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
 * $Id: TypeAnalyzer.java 23416 2010-02-03 19:59:31Z stephan $
 *
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 *
 * Contributors:
 * Fraunhofer FIRST - Initial API and implementation
 * Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.otdt.internal.core.compiler.util;


import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.ExpressionContext;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18;
import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MemberTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.TypeAnchorReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.ITeamAnchor;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.TeamModel;

/**
 * Utility class for analyzing, and generating types.
 * Handles bindings, names and references.
 *
 * @author stephan <i>stephan@cs.tu-berlin.de</i>
 * @version $Id: TypeAnalyzer.java 23416 2010-02-03 19:59:31Z stephan $
 */
public class TypeAnalyzer  {

    public static final int EXACT_MATCH_ONLY        = 1;
    public static final int NEEDING_ADJUSTMENT_ONLY = 2;
    public static final int ANY_MATCH               = 3;


    /**
     * Given a method in a super Team, check wether the method declaration
     * from the sub Team is "the same method", which means, that role type
     * adjustments are taken into consideration.
     * These kinds of comparison are supported:
     * <dt>
     * <dt>EXACT_MATCH_ONLY
     *     <dd> these mathods are the same even in plain Java
     * <dt>NEEDING_ADJUSTMENT_ONLY
     *     <dd> only answer "true" if any parameter needs weakening
     * <dt>ANY_MATCH
     *     <dd> answer "true" if either kind of match is encountered.
     * </dt>
     * @param superTeam
     * @param superMeth
     * @param subTeam
     * @param subMeth
     * @param matchKind one of the above constants.
     * @return the answer
     */
    public static boolean isEqualMethodSignature(
            ReferenceBinding superTeam,
            MethodBinding    superMeth,
            ReferenceBinding subTeam,
            MethodBinding    subMeth,
            int              matchKind)
    {

        if(subMeth.parameters.length != superMeth.parameters.length)
            return false;
        TypeBinding[] params = subMeth.parameters;
        boolean needAdjustment = false;
        for (int i = 0; i < params.length; i++) {
            TypeBinding param = params[i];
            TypeBinding superTypeBind = superMeth.parameters[i];
            if (TypeBinding.equalsEquals(param, superTypeBind)) continue;
            if (areTypesMatchable(param, subTeam, superTypeBind, superTeam, matchKind))
            {
                needAdjustment = true;
            } else {
                return false;
            }

        }
        if (matchKind == NEEDING_ADJUSTMENT_ONLY)
            return needAdjustment;
        return true;
    }

    /**
     * Answer, whether two reference bindings are views of the same role
     * possibly seen from different teams.
     */
    public static boolean isSameRole(ReferenceBinding r1, ReferenceBinding r2)
    {
        if (TypeBinding.equalsEquals(r1, r2))
            return true;
        if (r1 == null || r2 == null)
        	return false;
        if (! (r1.isRole() && r2.isRole()))
            return false;
        ReferenceBinding t1 = r1.enclosingType();
        ReferenceBinding t2 = r2.enclosingType();
        if (TypeBinding.equalsEquals(t1, t2) || t1 == null || t2 == null)
            return false; // not two different teams: no other chance..
        if (! (t1.isCompatibleWith(t2) || t2.isCompatibleWith(t1)))
            return false; // not sub/super teams.
        return CharOperation.equals(r1.internalName(), r2.internalName());
    }

    /** does role refine the extends clause of its tsuper role? */
    public static boolean refinesExtends (ReferenceBinding role, ReferenceBinding tsuperRole)
    {
    	return !isSameRole(
				role.superclass(),
				tsuperRole.superclass());
    }
    /**
     * Answer, whether two type are the same, when regarding a class and an
     * interface part of a role as identical.
     */
    public static boolean isSameType(ReferenceBinding site, TypeBinding t1, TypeBinding t2)
    {
        if (TypeBinding.equalsEquals(t1, t2)) return true;
        if (t1 == null || t2 == null)
        	return false;
        if (t1.isArrayType()) {
            if (   !t2.isArrayType()
                || (t1.dimensions() != t2.dimensions()))
                return false;
            t1 = t1.leafComponentType();
            t2 = t2.leafComponentType();
        }
        else
        if (t2.isArrayType())
        {
        	return false;
        }

        if (t1.isBaseType())
            return TypeBinding.equalsEquals(t1, t2);
        if (t2.isBaseType())
            return false;
        ReferenceBinding r1 = (ReferenceBinding)t1;
        ReferenceBinding r2 = (ReferenceBinding)t2;
        if (r1.isDirectRole() && r2.isDirectRole()) {
        	r2 = (ReferenceBinding)TeamModel.strengthenRoleType(site, r2);
            return TypeBinding.equalsEquals(r1.roleModel.getInterfacePartBinding(),
            								 r2.roleModel.getInterfacePartBinding());
        }
        return false;
    }
    /**
     * Are type compatible possibly performing role type adjustment?
     * @param currentType
     * @param subTeam
     * @param tsuperType
     * @param superTeam
     * @param matchKind
     * @return the answer
     */
    public static boolean areTypesMatchable(
            TypeBinding      currentType,
            ReferenceBinding subTeam,
            TypeBinding      tsuperType,
            ReferenceBinding superTeam,
            int              matchKind)
    {
    	// be very defensive:
    	if (currentType instanceof ProblemReferenceBinding) {
    		TypeBinding closestMatch = ((ProblemReferenceBinding)currentType).closestMatch();
    		if (closestMatch == null)
    			return CharOperation.equals(currentType.sourceName(), tsuperType.sourceName());
			currentType = closestMatch;
    	}
    	if (tsuperType instanceof ProblemReferenceBinding) {
    		TypeBinding closestMatch = ((ProblemReferenceBinding)tsuperType).closestMatch();
    		if (closestMatch == null)
    			return CharOperation.equals(currentType.sourceName(), tsuperType.sourceName());
			tsuperType = closestMatch;
    	}

        // if it's array-types, compare dimension and extract leafComponentType
        if ((currentType instanceof ArrayBinding) || (tsuperType instanceof ArrayBinding))
        {
            if (!(tsuperType  instanceof ArrayBinding) ||
                !(currentType instanceof ArrayBinding))
                return false;
            ArrayBinding currentArray = (ArrayBinding)currentType;
            ArrayBinding superArray   = (ArrayBinding)tsuperType;
            if (currentArray.dimensions() != superArray.dimensions())
                return false;
            currentType = currentArray.leafComponentType();
            tsuperType  = superArray.leafComponentType();
        }

        // guaranteed to be scalar now
        if (currentType instanceof ReferenceBinding)
        {
            if (currentType instanceof DependentTypeBinding)
                currentType = ((DependentTypeBinding)currentType).getRealType();
            if (! (tsuperType instanceof ReferenceBinding))
                return false;
            if (tsuperType instanceof DependentTypeBinding)
                tsuperType = ((DependentTypeBinding)tsuperType).getRealType();
            if (currentType.isParameterizedType() || tsuperType.isParameterizedType()) {
            	// at least one type parameterized: get erasure(s)
            	if (currentType.isParameterizedType()) {
	        		if (tsuperType.isParameterizedType()) {
    					// both parameterized: check parameters:
		            	ParameterizedTypeBinding currentParameterized = ((ParameterizedTypeBinding)currentType);
	                	ParameterizedTypeBinding tsuperParameterized = ((ParameterizedTypeBinding)tsuperType);
		            	if (!CharOperation.equals(currentParameterized.genericTypeSignature,
		            							  tsuperParameterized.genericTypeSignature))
		            		return false;
            		} else if (!tsuperType.isRawType()) {
            			return false; // mismatch generic vs. non-generic
            		}

            	} else if (!currentType.isRawType()) {
            		return false; // mismatch non-generic vs. generic
            	}
				currentType = currentType.erasure();
				tsuperType  = tsuperType.erasure();
            }
            if (currentType.isTypeVariable() && tsuperType.isTypeVariable())
            	return TypeBinding.equalsEquals(currentType, tsuperType);

            char[][] tname1 = compoundNameOfReferenceType((ReferenceBinding)tsuperType, true, true);
            char[][] tname2 = compoundNameOfReferenceType((ReferenceBinding)currentType, true, true);
            if (CharOperation.equals(tname1, tname2)) {
            	if (TypeBinding.notEquals(tsuperType, currentType) && tsuperType.isValidBinding()) // don't complain about different missing types
                	throw new InternalCompilerError("different bindings for the same type??"+currentType+':'+tsuperType); //$NON-NLS-1$
            	return true;
            }
            if  (matchKind == EXACT_MATCH_ONLY)
            {
                return false;
            } else {
                tname1 = splitTypeNameRelativeToTeam((ReferenceBinding)tsuperType, superTeam);
                tname2 = splitTypeNameRelativeToTeam((ReferenceBinding)currentType, subTeam);
                if (!CharOperation.equals(tname1, tname2))
                    return false;
            }
        } else if (currentType instanceof BaseTypeBinding) {
            if (TypeBinding.notEquals(currentType, tsuperType))
                return false;
        } else {
            throw new InternalCompilerError("matching of unexpected type kind: "+currentType); //$NON-NLS-1$
        }
        return true;
    }


    /**
     * Extract a compound type name relativ to a given Team.
     * This means, if tb is a (transitiv) member type of team,
     * cut off the Team and return only remaining part.
     * If tb is not a (transitiv) member of team, return the
     * full compound name of outer/inner classes but not containing
     * the package.
     *
     * For features inherited from an indirect super team allow
     * the team prefix to relate to that super team.
     *
     * @param tb the type to represent
     * @param teamBinding the Team
     * @return non-null array of at least one component
     */
    public static char[][] splitTypeNameRelativeToTeam(ReferenceBinding tb, TypeBinding teamBinding) {
        char [][] qname = new char[][] {tb.internalName()};
        // move out until we find the source team:
        while (tb instanceof MemberTypeBinding) {
            tb = ((MemberTypeBinding)tb).enclosingType;
            if (tb.isTeam()) {
            	if (TypeBinding.equalsEquals(tb, teamBinding))
            		return qname;
            	else if (teamBinding.isCompatibleWith(tb))
            		return qname;
            } else {
                // prepend one component to qname:
                char[][] qn2 = new char[qname.length+1][];
                System.arraycopy(qname, 0, qn2, 1, qname.length);
                qn2[0] = tb.internalName();
                qname = qn2;
            }
        }

        return qname;
    }

    /**
     * Split the qualified name of a member type into a compound name.
     * (the field compoundName merges Outer$Inner into one element
     *  of the compound, which is not what we want here).
     * @param tb
     * @param includePackage should the package name(s) be included?
     * @param createTeamAnchor should a possible team anchor be included in the compound name?
     *        TODO(SH) saying yes here causes as to create old syntax AST.
     * @return non-null array of at least one component
     */
    public static char[][] compoundNameOfReferenceType(
            ReferenceBinding tb,
            boolean includePackage,
            boolean createTeamAnchor)
    {
    	if (tb instanceof ProblemReferenceBinding) {
    		ReferenceBinding closestMatch = (ReferenceBinding) tb.closestMatch();
    		if (closestMatch != null)
    			tb = closestMatch;
    	}
    	if (!tb.isValidBinding()) { // no further processing possible
    		if (includePackage)
    			return tb.compoundName;
    		int l = tb.compoundName.length;
    		return new char[][]{tb.compoundName[l-1]};
    	}
    	if (tb instanceof UnresolvedReferenceBinding) {
    		LookupEnvironment env = Config.getLookupEnvironment();
    		if (env == null)
    			throw new InternalCompilerError("No lookup environment configured"); //$NON-NLS-1$
    		tb = ((UnresolvedReferenceBinding)tb).resolve(env, false);
    	}
        if (   createTeamAnchor
        	&& tb instanceof DependentTypeBinding
           	&& ((DependentTypeBinding)tb).hasExplicitAnchor())
        {
        	DependentTypeBinding roleTypeBinding = (DependentTypeBinding)tb;

        	// for role types the prefix is a variable not a type:
        	ITeamAnchor[] path = roleTypeBinding._teamAnchor.getBestNamePath();

        	// If anchor is a field, prepend a team anchor with "Outer.this"
        	// for the type containing the anchor field.
        	char[] declaringClass = null;
        	int prefixLen = 0;
        	if (roleTypeBinding._teamAnchor instanceof FieldBinding) {
        		declaringClass = ((FieldBinding)(roleTypeBinding)._teamAnchor).declaringClass.internalName();
        			prefixLen = 2;
        	}
        	char[][] names = new char[path.length+1+prefixLen][];
        	if (declaringClass != null) {
        			// do prepend
	        	names[0] = declaringClass;
        		names[1] = "this".toCharArray(); //$NON-NLS-1$
        	}
        	for (int i = 0; i < path.length; i++) {
				names[i+prefixLen] = path[i].internalName();
			}
        	names[path.length+prefixLen] = tb.internalName();

        	return names;
        }
        char[][] packName = includePackage && (tb.getPackage() != null) ?
        			tb.getPackage().compoundName :
                    new char[0][];
        char[][] outerName = (tb.enclosingType() != null) ?
        			compoundNameOfReferenceType(tb.enclosingType(), false, createTeamAnchor) :
        	        new char[0][];
        char[][] result = new char[packName.length+outerName.length+1][];
        System.arraycopy(packName, 0, result, 0, packName.length);
        System.arraycopy(outerName, 0, result, packName.length, outerName.length);
        result[result.length-1] = tb.internalName();
        return result;
    }

    /**
     * Try to interpret a type name as a local type of a role.
     * Take the constantPoolName and chop off the team name which prefixes this name.
     *
     * @param teamBinding
     * @param compoundName
     * @return non-null char-array
     */
    public static char[] constantPoolNameRelativeToTeam(ReferenceBinding teamBinding, char[]compoundName) {
    	char[] teamName = teamBinding.constantPoolName();
    	if (!CharOperation.prefixEquals(teamName, compoundName))
    		return compoundName;
    	assert (compoundName[teamName.length] == '$');
    	return CharOperation.subarray(compoundName, teamName.length+1, -1);
    }

    /**
     * Compare two types trying to interpret type names as local types of roles, where
     * the constantPoolName must be investigated but the team name prefix chopped off.
     *
     * @param teamBinding enclosing team of the first type
     * @param role the first type itself
     * @param typeName relative name of the second type (ie., team prefix is already copped off).
     * @return the answer
     */
    public static boolean equalRoleLocal(ReferenceBinding teamBinding, ReferenceBinding role, char[] typeName)
    {
    	// TODO (SH) during CopyInheritanc constantPoolName is still null.
    	//           but do we need to map names of local types in accessor signatures??
    	if (role.constantPoolName() == null)
    		return false;
    	char[] relativeName = constantPoolNameRelativeToTeam(teamBinding, role.constantPoolName());
    	return CharOperation.equals(typeName, relativeName);
    }
    /**
     * Given a reference (read from source code) and a binding (read from
     * a resolved super-role) create a weakened type reference, i.e., if
     * the type is a role-type, create a new reference from the binding.
     * Precondition: both types are identical except for implicit inheritance.
     * @param origRef This reference may or may not need to be changed.
     *  In any case use its source positions.
     * @param binding this specifies the type we need to refer to.
     * @return either origRef or a fresh reference
     */
    public static TypeReference weakenTypeReferenceFromBinding(
            MethodScope scope,
            TypeReference origRef,
            TypeBinding origBinding,
            TypeBinding binding)
    {
        if (!(   (binding instanceof ReferenceBinding)
        	  || (binding instanceof ArrayBinding)))
            return origRef;
        binding = binding.erasure();
        origBinding = origBinding.erasure();
        if (binding instanceof RoleTypeBinding)
        	if (TypeBinding.equalsEquals(origBinding, ((RoleTypeBinding)binding).getRealType()))
        		return origRef;
        if (TypeBinding.equalsEquals(origBinding, binding))
            return origRef;
        AstGenerator gen = new AstGenerator(origRef.sourceStart, origRef.sourceEnd);
        return gen.typeReference(binding);
    }

    /**
     * Find a method in a super role
     * @param subTeam the Team containing subMethod
     * @param subMethod a method to match
     * @param superRole where to look
     * @param superTeam enclosing Team of superRole
     * @return a method or null
     */
    public static MethodBinding findMethodInSuperRole(
            ReferenceBinding subTeam,   MethodBinding subMethod,
            ReferenceBinding superRole, ReferenceBinding superTeam,
            int matchKind)
    {
        MethodBinding[] superMethods =superRole.methods();
        for (int i=0; i<superMethods.length; i++)
        {
            if (isEqualMethodSignature(superTeam, superMethods[i], subTeam, subMethod, matchKind))
                return superMethods[i];
        }
        return null;
    }

    public static boolean isOrgObjectteamsTeam(ReferenceBinding type) {
    	if (type == null)
    		return false;
        return CharOperation.equals(type.compoundName, IOTConstants.ORG_OBJECTTEAMS_TEAM);
    }

    public static boolean isOrgObjectteamsTeam(CompilationUnitDeclaration unit) {
    	if (   unit != null
    		&& unit.currentPackage != null
    		&& unit.types != null
    		&& unit.types.length > 0) {
    		return     CharOperation.equals(IOTConstants.ORG_OBJECTTEAMS, unit.currentPackage.tokens)
    				&& CharOperation.equals(IOTConstants.TEAM, unit.types[0].name);
    	}

    	return false;
    }

    public static boolean isVariableRef (Expression e) {
        return (e.bits & Binding.VARIABLE) != 0;
    }

	/**
	 * Find a fied in a type searching superclasses and enclosing classes.
	 * Note, that this method indeed finds private fields even via a super-class of type.
	 *
	 * @param type where to look
	 * @param token name of the field to look for
	 * @param isStaticScope is the field reference within a static scope?
	 * @param allowOuter is it legal to find the field in an enclosing type?
	 * @param requiredState when navigating to supertypes, is a certain state required for those?
	 *        (this does not apply to `type' itself and its enclosing).
	 * @return a field or null
	 */
	public static FieldBinding findField(
			ReferenceBinding type,
			char[]           token,
			boolean  		 isStaticScope,
			boolean          allowOuter,
			int              requiredState)
	{
		while (type != null) {           // loop inner->outer
			ReferenceBinding currentType = type;
			while (currentType != null) { // loop sub->super
				FieldBinding foundVar = currentType.getField(token, /*resolve*/true);
				if (foundVar != null) {
					if (isStaticScope && ! foundVar.isStatic())
						return new ProblemFieldBinding(foundVar, currentType, token, ProblemReasons.NonStaticReferenceInStaticContext);
					return foundVar;
				}
				currentType = currentType.superclass();
				if (currentType != null && requiredState != -1)
					Dependencies.ensureBindingState(currentType, requiredState);
			}
			if (!allowOuter)
				return null;
			isStaticScope = type.isStatic();
			type = type.enclosingType();
		}
		return null;
	}

	public static FieldBinding findField(ReferenceBinding type,
										 char[]           token,
										 boolean 		  isStaticScope,
										 boolean          allowOuter)
	{
		return findField(type, token, isStaticScope, allowOuter, -1);
	}
	/**
	 * Find a method in type or one of its super types.
	 * @param scope where the method shall be invoked from
	 * @param type  where to search
	 * @param selector name of the method
	 * @param params params
	 */
	public static MethodBinding findMethod(
			Scope scope,
			ReferenceBinding type,
			char[] selector,
			TypeBinding[] params)
	{
		return findMethod(scope, type, selector, params, /*decapsulationAllowed*/false, null);
	}
	/**
	 * Find a method in type or one of its super types.
	 * @param scope where the method shall be invoked from
	 * @param type  where to search
	 * @param selector name of the method
	 * @param params params
	 * @param decapsulationAllowed whether or not invisible methods should be found, too
	 * @param site invocation site if available
	 */
	public static @Nullable MethodBinding findMethod(
			final		Scope		 		scope,
						ReferenceBinding 	type,
						char[]	 			selector,
						TypeBinding[]		params,
						boolean        	decapsulationAllowed,
			@Nullable 	InvocationSite		site)
	{
		if (type == null || scope == null)
			return null;
		if (site == null) {
			final Expression[] fakeArguments = new Expression[params.length];
			for (int i = 0; i < params.length; i++) {
				fakeArguments[i] = new SingleNameReference(("fakeArg"+i).toCharArray(), 0L); //$NON-NLS-1$
				fakeArguments[i].resolvedType = params[i];
			}
			site = new InvocationSite() {
				@Override public int sourceStart() { return 0; }
				@Override public int sourceEnd() { return 0; }
				@Override public void setFieldIndex(int depth) { /* nop */ }
				@Override public void setDepth(int depth) { /* nop */ }

				@Override public void setActualReceiverType(ReferenceBinding receiverType) { /* nop */ }
				@Override public boolean receiverIsImplicitThis() { return false; }
				@Override public boolean isTypeAccess() { return false; }
				@Override public boolean isSuperAccess() { return false; }
				@Override public boolean isQualifiedSuper() { return false; }
				@Override public boolean checkingPotentialCompatibility() { return false; }
				@Override public void acceptPotentiallyCompatibleMethods(MethodBinding[] methods) { /* nop */ }

				@Override
				public TypeBinding invocationTargetType() {
					return scope.getJavaLangObject();
				}

				@Override
				public ExpressionContext getExpressionContext() {
					return ExpressionContext.ASSIGNMENT_CONTEXT;
				}

				@Override
				public TypeBinding[] genericTypeArguments() {
					return null;
				}

				@Override
				public InferenceContext18 freshInferenceContext(Scope someScope) {
					return new InferenceContext18(someScope, fakeArguments, this, null);
				}
			};
		}
		return scope.getMethod(type, selector, params, site);
	}

	/** Find a method with identical parameters after erasing. */
	public static MethodBinding findCompatibleMethod(ReferenceBinding site, MethodBinding template)
	{
		methods:
		for (MethodBinding existingMethod : site.getMethods(template.selector))
		{
			if (existingMethod.parameters.length != template.parameters.length)
				continue;
			for (int j = 0; j < template.parameters.length; j++) {
				if (TypeBinding.notEquals(existingMethod.parameters[j].erasure(), template.parameters[j].erasure()))
					continue methods;
			}
			return existingMethod;
		}
		return null;
	}
	/**
	 * Look for the method declaration matching the given selector and length of argument list.
	 * @param typeDeclaration
	 * @param selector
	 * @param nArgs
	 * @return a method or null
	 */
	public static AbstractMethodDeclaration findMethodDecl(
			TypeDeclaration typeDeclaration,
			char[]          selector,
			int             nArgs)
	{
		if (typeDeclaration.methods == null)
			return null;
		AbstractMethodDeclaration[] methods = typeDeclaration.methods;
		for (int i=0; i<methods.length; i++) {
			if (CharOperation.equals(methods[i].selector, selector))
			{
				if (methods[i].arguments == null) {
					if (nArgs == 0)
						return methods[i];
				} else if (methods[i].arguments.length == nArgs) {
					return methods[i];
				}
			}
		}
		return null;
	}

	/**
	 * Find a method just by its selector.
	 * Looks up the superclass/interfaces hierarchy.
	 *
	 * @param typeBinding
	 * @param selector
	 * @return first matching method
	 */
	public static MethodBinding getMethod(ReferenceBinding typeBinding, char[] selector) {
		if (typeBinding == null)
			return null;
		MethodBinding[] foundMethods = typeBinding.getMethods(selector);
		if (foundMethods != Binding.NO_METHODS)
			return foundMethods[0];
		MethodBinding foundMethod = getMethod(typeBinding.superclass(), selector);
		if (foundMethod != null)
			return foundMethod;
		ReferenceBinding[] superInterfaces = typeBinding.superInterfaces();
		for (int i = 0; i < superInterfaces.length; i++) {
			foundMethod = getMethod(superInterfaces[i], selector);
			if (foundMethod != null)
				return foundMethod;
		}
		return null;
	}

	/**
	 * When comparing two role types, allow the teams to be super/sub teams
	 * in either direction.
	 *
	 * TODO (SH): check:
	 * (1) does this method hide relevant incompatibilities?
	 * (2) do we need to apply this method in other places, too?
	 *
	 * @param one
	 * @param two
	 * @return the answer
	 */
	public static boolean areRoleTypesEqual(
			RoleTypeBinding one,
			RoleTypeBinding two)
	{
		if (!CharOperation.equals(one.sourceName(), two.sourceName()))
			return false;
		ReferenceBinding teamOne = one._staticallyKnownTeam;
		ReferenceBinding teamTwo = two._staticallyKnownTeam;
		if (teamOne.isRole() && teamTwo.isRole()) {
			ReferenceBinding outerOne = teamOne.enclosingType();
			ReferenceBinding outerTwo = teamTwo.enclosingType();
			if (TypeBinding.notEquals(outerOne, outerTwo)) {
				// raise nested teams to same level.
				if (outerOne.isCompatibleWith(outerTwo)) {
					teamTwo = (ReferenceBinding)TeamModel.strengthenRoleType(outerOne, teamTwo);
				} else if (outerTwo.isCompatibleWith(outerOne)) {
					teamOne = (ReferenceBinding)TeamModel.strengthenRoleType(outerTwo, teamOne);
				}
			}
			// in order to compare two team-as-role types take their interface parts:
			teamOne = teamOne.roleModel.getInterfacePartBinding();
			teamTwo = teamTwo.roleModel.getInterfacePartBinding();
		}
		if (teamOne.isCompatibleWith(teamTwo))
			return true;
		if (teamTwo.isCompatibleWith(teamOne))
			return true;
		return false;
	}
	/*
	 * This is the structure of confined types as seen by the compiler:
	 *
	 * predefined:
	 * IConfined          .superclass = null
	 * Team.IConfined     .superclass = null, superinterface = IConfined
	 * Team.Confined      .superclass = null
	 * Team.__OT__Confined.superclass = null, superinterface = Team.Confined
	 *
	 * client code:
	 * TX.IConfined       .superclass = OTC,  superinterface = Team.IConfined
	 * TX.Confined        .superclass = OTC,  superinterface = Team.Confined
	 * TX.__OT__Confined  .superclass = OTC,  superinterface = TX.Confined
	 * TX.R               .superclass = OTC,  superinterface = TX.IMyIFC
	 * TX.__OT__R         .superclass = OTC,  superinterface = TX.R
	 * (OTX = __OT__Confined, resolving to TX.__OT__Confined except for itself)
	 *
	 * Class-files have to differ from this view:
	 * For JVM-compatibility all superinterfaces must store Object as their superclass.
     * These interfaces are marked using OTClassFlags attribute.
	 *
	 */

	public static boolean isTopConfined(ReferenceBinding type) {
		char[][] compoundName= type.compoundName;
		if (    compoundName.length == 3
			&& (   CharOperation.equals(compoundName, IOTConstants.ORG_OBJECTTEAMS_ICONFINED)
				|| CharOperation.equals(compoundName, IOTConstants.ORG_OBJECTTEAMS_ITEAM_ICONFINED)
				|| CharOperation.equals(compoundName, IOTConstants.ORG_OBJECTTEAMS_TEAM_CONFINED)
				|| CharOperation.equals(compoundName, IOTConstants.ORG_OBJECTTEAMS_TEAM_OTCONFINED)))
		{
			return true;
		}
		char[] name= type.internalName();
		return type.isRole()
		    && (   CharOperation.equals(name, IOTConstants.ICONFINED)
				|| CharOperation.equals(name, IOTConstants.OTCONFINED)
				|| CharOperation.equals(name, IOTConstants.CONFINED));
	}

	public static boolean isConfined(TypeBinding type) {
		if (type == null || !type.isRole()) return false;
		ReferenceBinding currentType= (ReferenceBinding)type;
		while (currentType != null) {
			if (currentType.id == TypeIds.T_JavaLangObject)
				return false;
			currentType = currentType.superclass();
		}
		return true;
	}
	public static boolean isPredefinedRole(ReferenceBinding type) {
		char[] name = type.internalName();
		if (CharOperation.equals(name, IOTConstants.ROFI_CACHE))
			return true;
		if (!type.isRole())
			return false;
		return     CharOperation.equals(name, IOTConstants.ICONFINED)
				|| CharOperation.equals(name, IOTConstants.OTCONFINED)
				|| CharOperation.equals(name, IOTConstants.CONFINED)
				|| CharOperation.equals(name, IOTConstants.ILOWERABLE)
				|| CharOperation.equals(name, IOTConstants.IBOUNDBASE)
				|| CharOperation.equals(name, IOTConstants.IBOUNDBASE2);
	}

	public static boolean extendsOTConfined(TypeDeclaration type) {
		if (type.superclass instanceof QualifiedTypeReference)
			return CharOperation.equals(((QualifiedTypeReference)type.superclass).tokens,
									    IOTConstants.ORG_OBJECTTEAMS_TEAM_OTCONFINED);
		if (type.superclass instanceof SingleTypeReference)
			return CharOperation.equals(((SingleTypeReference)type.superclass).token,
									    IOTConstants.OTCONFINED);
		return false;
	}

	/**
	 * When asking for a field should synthetic fields be searched?
	 * @param scope        site of usage, if this is a generated methods, searching synthetics is OK
	 * @param receiverType class containing the field
	 * @param fieldName
	 * @return the answer
	 */
	public static boolean isSearchingForSyntheticField(MethodScope scope, TypeBinding receiverType, char[] fieldName) {
		return CharOperation.prefixEquals(TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX, fieldName)
		    && scope != null
			&& ((AbstractMethodDeclaration)scope.referenceContext).isGenerated
			&& receiverType instanceof ReferenceBinding
			&& ((ReferenceBinding)receiverType).isRole();
	}

	public static boolean isSourceTypeWithErrors (ReferenceBinding type) {
		if (type instanceof SourceTypeBinding) {
			SourceTypeBinding sourceType = (SourceTypeBinding)type;
			if (sourceType.scope != null)
				return sourceType.scope.referenceContext.hasErrors();
		}
		return false;
	}

	// _OT$base.Types need stripping:
	public static char[] stripTypeName(char[] typeName) {
		if (CharOperation.prefixEquals(IOTConstants._OT_BASE, typeName))
			typeName = CharOperation.subarray(typeName, IOTConstants.OT_DOLLAR_LEN, -1);
		return typeName;
	}

	public static boolean sameOrContained(ReferenceBinding binding, ReferenceBinding targetEnclosingType)
	{
		while (binding != null) {
			if (TypeBinding.equalsEquals(binding, targetEnclosingType))
				return true;
			binding = binding.enclosingType();
		}
		return false;
	}

	/** Does the unit contain any role class with a base class reference that could potentially represent an anchored type? */
	public static boolean containsAnchoredBaseclass(CompilationUnitDeclaration parsedUnit) {
		if (parsedUnit.types == null) return false;
		for (TypeDeclaration type : parsedUnit.types)
			if (containsAnchoredBaseclass(type))
				return true;
		return false;
	}

	private static boolean containsAnchoredBaseclass(TypeDeclaration type) {
		TypeReference baseRef = type.baseclass;
		if (baseRef instanceof ParameterizedSingleTypeReference) {
			 TypeReference[] typeArguments = ((ParameterizedSingleTypeReference)baseRef).typeArguments;
			 return typeArguments != null && typeArguments.length > 0 && typeArguments[0] instanceof TypeAnchorReference;
		} else if (baseRef instanceof QualifiedTypeReference) {
			return true;
		}
		TypeDeclaration[] members = type.memberTypes;
		if (members != null)
			for (TypeDeclaration member : members)
				if (containsAnchoredBaseclass(member))
					return true;
		return false;
	}
}
