/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 *
 * Copyright 2004, 2020 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
 *
 * 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.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions.WeavingScheme;
import org.eclipse.jdt.internal.compiler.impl.IntConstant;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodVerifier;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
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.VariableBinding;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.core.compiler.Pair;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.MethodSpec;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.RoleFileCache;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.AbstractAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.BoundClassesHierarchyAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.OTDynCallinBindingsAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.RoleBaseBindingsAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.WordValueAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
import org.eclipse.objectteams.otdt.internal.core.compiler.lifting.LiftingEnvironment;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.OTClassScope;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.TThisBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.Protections;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TSuperHelper;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer;

/**
 * This class models properties of Teams.
 * One instance of this class can be allocated for each ClassDeclaration
 * and/or ClassBinding.
 *
 * Tasks:
 * <ul>
 *   <li>Navigate to all roles.
 * </ul>
 *
 * @author stephan
 */
public class TeamModel extends TypeModel {

	// constants for bits in tagBits:
	public static final int CopyRolesFromTSuperMASK = 0x0FF;
	public static final int MaxTSuperRoles = 8; // so many bits allocated in CopyRolesFromTSuperMask

	// details of completeTypeBindings:
	public static final int BeginCopyRoles = ASTNode.Bit9;

	// can lifting fail due to role abstractness?
    public static final int HasAbstractRelevantRole = ASTNode.Bit10;

    // did a nested team require correction of team/role flags?
    public static final int HasClassKindProblem = ASTNode.Bit11;

	/** The Marker interface created for this Team (_TSuper__OT__TeamName); */
	public TypeDeclaration markerInterface;

    private RoleBaseBindingsAttribute roleBaseBindings = null;

    // pairs of base-role classes for which lifting would be ambiguous
    public List<Pair<ReferenceBinding, ReferenceBinding>> ambigousLifting = new ArrayList<Pair<ReferenceBinding,ReferenceBinding>>();

    /* store all role caches managed by this team. */
    public FieldDeclaration[] caches = new FieldDeclaration[0];

    /* the unique tthis binding for this team */
    private TThisBinding tthis; // will be initialized once _binding is set.

    /* a synthetic class for storing known role files */
    private RoleFileCache knownRoleFiles = null;

    private Map<String/*label*/,List<CallinInfo>> labelledCallinIds = null;

    /** Collection of various flags. */
    public int tagBits = 0;

    /* While loading a role file no further role file may pass the former role in translation. */
    public boolean _blockCatchup = false;

	public boolean _isCopyingLateRole = false;

	public LiftingEnvironment liftingEnv = null;

	public TeamModel(TypeDeclaration teamAst)
	{
		super(teamAst);
		if (teamAst.enclosingType == null && !isOrgObjectteamsTeam(teamAst))
			addAttribute(WordValueAttribute.compilerVersionAttribute());
		if (Config.clientIsBatchCompiler())
			this.knownRoleFiles = new RoleFileCache(teamAst);
	}
	static boolean isOrgObjectteamsTeam(TypeDeclaration typeAst) {
		if (typeAst != null && typeAst.scope != null) {
			return TypeAnalyzer.isOrgObjectteamsTeam(typeAst.scope.referenceCompilationUnit());
		}
		return false;
	}
	public TeamModel(ReferenceBinding teamBinding)
	{
		super(teamBinding);
		if (!teamBinding.isSynthInterface())
			// no tthis for nested team ifc-parts
			this.tthis = new TThisBinding(teamBinding);
		// TODO (SH): else part should be a InternalCompilerError?
		// cf. getTThis().
	}

    @Override
	public void setBinding (ReferenceBinding binding) {
        this._binding = binding;
        binding.setTeamModel(this);
		if (!binding.isSynthInterface())
			// no tthis for nested team ifc-parts
			this.tthis = new TThisBinding(binding);
    }

    public void addCache(FieldDeclaration cache) {
    	int len = this.caches.length;
    	System.arraycopy(
    			this.caches, 0,
				this.caches = new FieldDeclaration[len+1], 0,
				len);
    	this.caches[len] = cache;
    }

    public void addBoundClassLink(ReferenceBinding subClass, ReferenceBinding superClass) {
    	ensureRoleBaseBindingsAttribute();
    	BoundClassesHierarchyAttribute attribute = null;
    	for (int i = 0; i < this._attributes.length; i++) {
			if (this._attributes[i].nameEquals(IOTConstants.BOUND_CLASSES_HIERARCHY)) {
				attribute = (BoundClassesHierarchyAttribute)this._attributes[i];
				break;
			}
		}
    	if (attribute == null)
    		addAttribute(attribute = new BoundClassesHierarchyAttribute());
    	attribute.add(subClass.attributeName(), superClass.attributeName());
    }

    /**
     * Add a base class binding ready to write out as attribute.
     * @param roleName
     * @param baseName
     */
    public void addRoleBaseBindingAttribute(char[] roleName, char[] baseName, boolean baseIsInterface) {
    	ensureRoleBaseBindingsAttribute();
    	this.roleBaseBindings.add(roleName, baseName, baseIsInterface);
    }

    private void ensureRoleBaseBindingsAttribute() {
        if (this.roleBaseBindings == null) {
            this.roleBaseBindings = new RoleBaseBindingsAttribute();
            addAttribute(this.roleBaseBindings);
        }
	}
	/**
     * Set the given state for all contained roles.
     */
    @Override
	public void setMemberState(int state)
    {
        RoleModel[] roles = getRoles(true);
        if (roles != null)
        {
            for (int i=0; i<roles.length; i++)
            {
                RoleModel role = roles[i];
                role.setMemberState(state);
                role.setState(state);
                if (   (role.getBinding() != null)
					&& (role.getBinding().isTeam()))
                {
                    TeamModel teamModel = role.getBinding().getTeamModel();
                    teamModel.setState(state);
                    teamModel.setMemberState(state);
                }
            }
        }
    }

    /**
     * Set the given state for all contained roles, but not for roles-as-teams
     */
    public void setMemberStateShallow(int state)
    {
        RoleModel[] roles = getRoles(true);
        if (roles != null)
        {
            for (int i=0; i<roles.length; i++)
            {
                RoleModel role = roles[i];
                role.setMemberState(state);
                role.setState(state);
            }
        }
    }

	public TeamModel getSuperTeam()
	{
        TypeBinding superBinding = null;
        if (this._ast != null)
		{
            if (this._ast.superclass != null)
                superBinding = this._ast.superclass.resolveType(this._ast.scope);
		} else {
            superBinding = this._binding.superclass();
		}
	    if (superBinding instanceof ReferenceBinding)
	    	return ((ReferenceBinding)superBinding).getTeamModel();

		return null;
	}

	/**
     * Get all roles represented by their RoleModel.
     * Considers Ast or Bindings, whatever is more appropriate.
     * SH: used to ensure STATE_ROLE_INHERITANCE for this team, which is now
     *     moved to CalloutImplementor.getRoleModelForType() to make this
     *     method reusable.
 	 * Does not take external roles into account, yet.
     *
     * @returns all direct roles for this Team.
     */
	public RoleModel[] getRoles(boolean includeSynthInterfaces)
	{
		List<RoleModel> list = new LinkedList<RoleModel>();
		if(this._binding != null)
		{
			// if binding exists, it may contain reused binary roles
			// which are not present in _ast, so prefer binding.
			ReferenceBinding[] roleBindings = this._binding.memberTypes();
			for (int i = 0; i < roleBindings.length; i++)
            {
                ReferenceBinding binding = roleBindings[i];
                if (binding.isEnum())
                	continue;
                if(includeSynthInterfaces || binding.isDirectRole())
                {
                	if (binding.roleModel != null)
                		list.add(binding.roleModel);
                }
            }
		}
		else
		{

			TypeDeclaration[] roles = this._ast.memberTypes;
			if (roles != null)
			{
				for (int idx = 0; idx<roles.length; idx++)
				{
			  		if ((roles[idx].modifiers & ClassFileConstants.AccEnum) != 0)
			  			continue; // enums are not roles
					if (includeSynthInterfaces || roles[idx].isSourceRole())
					{
                		RoleModel roleModel = roles[idx].getRoleModel(this);
                		if (roleModel != null)
                			list.add(roleModel);
					}
				}
			}
		}
		return list.toArray(new RoleModel[list.size()]);
	}

	/** Answer the number of roles, binding(preferred) or ast. */
	public int getNumRoles() {
		if (this._binding != null)
			return this._binding.memberTypes().length;
		if (this._ast.memberTypes == null)
			return 0;
		return this._ast.memberTypes.length;
	}

	/** Try to re-interpret this team type as a role and answer its role model. */
	public RoleModel getRoleModelOfThis() {
		if (this._ast != null)
			return this._ast.getRoleModel();
		return this._binding.roleModel;
	}

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

    /** This Method includes the interface part of nested teams. */
    public static boolean isAnyTeam(ReferenceBinding type) {
    	if (type.isTeam())
    		return true;
		if (type.isRole()) {
	    	ReferenceBinding classPartBinding = type.roleModel.getClassPartBinding();
	    	if (classPartBinding != null)
	    		return classPartBinding.isTeam();
		}
    	return false;
    }

    /** This Method includes the interface part of nested teams.*/
	public static boolean isAnyTeam(TypeDeclaration typeDecl) {
		if (typeDecl.isTeam())
			return true;
		if (typeDecl.isRole() && typeDecl.isInterface())
		{
			TypeDeclaration classPart = typeDecl.getRoleModel().getClassPartAst();
			if (classPart != null)
				return classPart.isTeam();
		}
		return false;
	}

    public static boolean setTagBit(ReferenceBinding teamBinding, int tagBit) {
		TeamModel model = teamBinding.getTeamModel();
		if ((model.tagBits & tagBit) != 0)
			return false; // was already set
		model.tagBits |= tagBit;
		return true;
	}

	public static boolean hasTagBit(ReferenceBinding typeBinding, int tagBit) {
		if (typeBinding._teamModel == null)
			return false;
		return (typeBinding._teamModel.tagBits & tagBit) != 0;
	}

    @Override
	protected String getKindString()
    {
        return "Team"; //$NON-NLS-1$
    }
	public TThisBinding getTThis() {
		if (this.tthis == null)
			throw new InternalCompilerError("no tthis for "+new String(getBinding().readableName())); //$NON-NLS-1$
		return this.tthis;
	}
	/**
	 * Find an enclosing type of nestedType that is a team.
	 * @param nestedType
	 * @return team or null
	 */
	public static ReferenceBinding getEnclosingTeam(ReferenceBinding nestedType) {
		ReferenceBinding outer = nestedType.enclosingType();
		while (outer != null) {
			if (outer.isTeam())
				return outer;
			outer = outer.enclosingType();
		}
		return null;
	}

	public static TypeDeclaration getOutermostTeam(TypeDeclaration type) {
		if (!type.isTeam())
			return getOutermostTeam(type.enclosingType);
		TypeDeclaration result = type;
		while (type != null && type.isTeam()) {
			result = type;
			type = type.enclosingType;
		}
		return result;
	}
	private static ReferenceBinding normalizeTeam(ReferenceBinding teamBinding) {
		if (teamBinding == null)
			return null;
	    if (teamBinding.isRole() && teamBinding.isSynthInterface())
	    	return teamBinding.roleModel.getClassPartBinding();
		return teamBinding;
	}
	/**
	 * Starting a site and moving outwards find a team that contains
	 * roleType or a tsub-role (ie., the resulting team may be a
	 * subteam of roleType's enclosing team.
	 *
	 * @param site
	 * @param roleType
	 * @return a team type.
	 */
	public static ReferenceBinding findEnclosingTeamContainingRole(
	        ReferenceBinding site,
	        ReferenceBinding roleType)
	{
		site = normalizeTeam(site);
	    while (site != null) {
	        if (TeamModel.isTeamContainingRole(site, roleType))
	            return site;
	        site = site.enclosingType();
	    }
	    return null;
	}

	/**
	 * Answer whether a team contains a given role (team may be more
	 * specific than the role's enclosing team).
	 *
	 * @param teamBinding the team containing the role or a subteam
	 * @param roleBinding
	 * @return the answer
	 */
	public static boolean isTeamContainingRole (
	        ReferenceBinding teamBinding,
	        ReferenceBinding roleBinding)
	{
	    return levelFromEnclosingTeam(teamBinding, roleBinding) != 0;
	}

	/**
	 * Try to interpret teamCandidate as an enclosing team of roleType.
	 *
	 * @param teamCandidate
	 * @param roleType
	 * @return the number of nesting levels that role type lies within teamCandidate, 0 if no match.
	 */
	public static int levelFromEnclosingTeam(
			ReferenceBinding teamCandidate,
			ReferenceBinding roleType)
	{
		int l = 1;
	    if (teamCandidate == null)
	        return 0;
	    teamCandidate = normalizeTeam(teamCandidate);
	    if (!teamCandidate.isTeam())
	    	return 0;
	    if (!roleType.isRole())
	    	return 0;
	    if (roleType.isParameterizedType())
	    	roleType = ((ParameterizedTypeBinding)roleType).genericType();
    	ReferenceBinding roleOuter = (ReferenceBinding) roleType.enclosingType().erasure();
    	if (TypeBinding.equalsEquals(roleOuter, teamCandidate))
    		return 1; // shortcut
	    if (teamCandidate.isRole()) {
	    	ReferenceBinding outerTeam = teamCandidate.enclosingType();
	    	int l2 = levelFromEnclosingTeam(outerTeam, roleOuter);
	    	if (l2 > 0) {
	    		if (l2 == 1)
	    			roleOuter = outerTeam.getMemberType(roleOuter.internalName());
	    		l = l2;
	    	}
	    	// else nested teamCandidate might extend a non-nested team.
	    }
	    ReferenceBinding member = teamCandidate.getMemberType(roleType.internalName());
	    if (member == null) {
	    	// several levels away, e.g., role nested (anonymous?):
	    	if (roleOuter.isRole()) {
	    		int l2 = levelFromEnclosingTeam(teamCandidate, roleOuter);
	    		if (l2 > 0)
	    			return l2 + 1;
	    	}
	    	return 0;
	    }
	    if (areTypesCompatible(teamCandidate, roleOuter))
	    	return l;
		return 0;
	}
	public static boolean isTeamAccessingAbstractStaticRoleMethod(ReferenceBinding type, MethodBinding method) {
		int abstractStatic = ClassFileConstants.AccAbstract | ClassFileConstants.AccStatic;
		if ((method.modifiers & abstractStatic) != abstractStatic)
			return false;
		return isTeamContainingRole(type, method.declaringClass);
	}
	public static boolean areTypesCompatible(ReferenceBinding type1, ReferenceBinding type2)
	{
		if (type1.isRole() && type2.isRole()) {
			if (!type1.isInterface())
				type1 = type1.roleModel.getInterfacePartBinding();
			if (!type2.isInterface())
				type2 = type2.roleModel.getInterfacePartBinding();
		}
		return type1.isCompatibleWith(type2);
	}
	/**
	 * Are (direct role?) types comparable disregarding for the moment that their team instances
	 * need to be compared, too?
	 * Role nested types are not handled here, since they are not wrapped.
	 *
	 * (Used for checking whether a cast is legal and requires instance comparison).
	 * @param expressionType
	 * @param castType
	 * @return the answer
	 */
	public static boolean isComparableToRole(ReferenceBinding expressionType, ReferenceBinding castType) {
		if (!castType.isDirectRole())
			return false;
		return
			   castType.getRealType().isCompatibleWith(expressionType.getRealType())
			|| expressionType.getRealType().isCompatibleWith(castType.getRealType());
	}

	/**
	 * Is left compatible to right, or are both corresponding roles
	 * of compatible enclosing teams (recursively).
	 * (Used for checking compatible refinement of a role's superclass).
	 */
	public static boolean areCompatibleEnclosings(ReferenceBinding left, ReferenceBinding right)
	{
		if (areTypesCompatible(left, right))
			return true;
		if (!CharOperation.equals(left.sourceName(), right.sourceName()))
			return false;
		ReferenceBinding leftEnclosing = left.enclosingType();
		ReferenceBinding rightEnclosing = right.enclosingType();
		if (leftEnclosing == null || rightEnclosing == null)
			return false;
		if (leftEnclosing.isTeam() && rightEnclosing.isTeam())
			return areCompatibleEnclosings(leftEnclosing, rightEnclosing);
		return false;
	}

	/**
	 * Get the most suitable RoleTypeBinding for roleType in a tthis context defined by scope.
	 * Strengthening reverses the effect of signature weakening.
	 *
	 * (Used for determining the statically known role type for lifting)
	 *
	 * @param site     (guaranteed to be within the context of a team)
	 * @param roleType (guaranteed to be a role or an array thereof)
	 * @return found role - need not be a RoleTypeBinding
	 */
	public static TypeBinding strengthenRoleType (
			ReferenceBinding site,
			TypeBinding roleType)
	{
		ReferenceBinding enclosingTeam = site;
	    enclosingTeam = normalizeTeam(enclosingTeam);
		if (!enclosingTeam.isTeam())
			enclosingTeam = getEnclosingTeam(site);
		if (enclosingTeam == null)
			return roleType; // this site cannot strengthen the role type.
		if (roleType.isLocalType())
			return roleType;
		int dimensions = roleType.dimensions();
		ReferenceBinding roleRefType = (ReferenceBinding)roleType.leafComponentType();
		ReferenceBinding roleEnclosing = roleRefType.enclosingType();
		if (roleEnclosing.isRole() && TypeBinding.notEquals(roleEnclosing.erasure(), site.erasure())) {
			// first strengthen enclosing team if it is nested:
			ReferenceBinding strengthenedEnclosing = null;
			if (TypeBinding.notEquals(roleEnclosing.erasure().enclosingType(), enclosingTeam.erasure().enclosingType()))
				strengthenedEnclosing = (ReferenceBinding)strengthenRoleType(site, roleEnclosing);
			if (strengthenedEnclosing != null && TypeBinding.notEquals(strengthenedEnclosing.erasure(), site.erasure())) {
				// we indeed found a better site, so start over:
				return strengthenRoleType(strengthenedEnclosing, roleType);
			}
		}
		// check success:
		if (!(   roleRefType.isRole()         							 // need a role
			  && areCompatibleEnclosings(enclosingTeam, roleEnclosing))) // teams must be compatible
		{
			if (enclosingTeam.isRole()) // try via outer team:
				return strengthenRoleType(enclosingTeam.enclosingType(), roleType);
			return roleType;
		}
		if (roleRefType instanceof RoleTypeBinding) {
			RoleTypeBinding rtb = (RoleTypeBinding)roleRefType;

			if (! (rtb._teamAnchor instanceof TThisBinding))
				return roleType; // don't instantiate explicit team anchor.
		}
		// lookup adjusted role type:
		roleRefType = enclosingTeam.getMemberType(roleRefType.internalName());
		if (roleRefType == null) {
			if (enclosingTeam.isBinaryBinding()) {
				ReferenceBinding current= enclosingTeam;
				// search a role type to report against (for aborting):
				while (current != null && current.isBinaryBinding())
					current= current.enclosingType();
				if (current != null) {
					Scope scope= ((SourceTypeBinding)current).scope;
					if (scope != null) {
						scope.problemReporter().missingRoleInBinaryTeam(roleType.constantPoolName(), enclosingTeam);
						return null;
					}
				}
			}
			if (Protections.hasClassKindProblem(enclosingTeam))
				return roleType; // can't do better..
			if (!enclosingTeam.isBinaryBinding()) {
				Scope scope= ((SourceTypeBinding)enclosingTeam.getRealType()).scope;
				scope.problemReporter().missingCopiedRole(roleType, enclosingTeam);
			} else if (!site.isBinaryBinding()) {
				Scope scope= ((SourceTypeBinding)site.getRealType()).scope;
				scope.problemReporter().missingCopiedRole(roleType, enclosingTeam);
			} else {
				throw new InternalCompilerError("could not find role "+String.valueOf(roleType.constantPoolName()) //$NON-NLS-1$
												+" in "+String.valueOf(site.constantPoolName()) +" and could not report regularly"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			return roleType; // can't do better, but shouldn't reach here, because missingCopiedRole triggers AbortType.
		}
		VariableBinding anchor = enclosingTeam.getTeamModel().getTThis();
		if (roleType.isParameterizedType()) {
			// consult original role type for type arguments & type annotations:
			ParameterizedTypeBinding ptb = (ParameterizedTypeBinding)roleType;
			TypeBinding parameterized = ptb.environment.createParameterizedType(roleRefType, ptb.arguments, anchor, -1, roleRefType.enclosingType(), ptb.getTypeAnnotations());
			if (dimensions > 0)
				return ptb.environment.createArrayType(parameterized, dimensions);
			return parameterized;
		}
		return anchor.getRoleTypeBinding(roleRefType, dimensions);
	}
	/**
	 * Starting at site look for an enclosing type that is compatible to targetEnclosing.
	 */
	public static ReferenceBinding strengthenEnclosing(ReferenceBinding site, ReferenceBinding targetEnclosing) {
		ReferenceBinding currentEnclosing = site;
		while (TypeBinding.notEquals(targetEnclosing, currentEnclosing)) {
			if (currentEnclosing.isCompatibleWith(targetEnclosing)) {
				return currentEnclosing;
			}
			currentEnclosing = currentEnclosing.enclosingType();
			if (currentEnclosing == null)
				throw new InternalCompilerError("Target class for callin binding not found: "+String.valueOf(targetEnclosing.readableName())); //$NON-NLS-1$
		}
		return targetEnclosing;
	}

	/**
	 * Find a role type from a given reference binding.
	 * Should only be used if no scope is available!
	 *
	 * @param site
	 * @param className
	 * @return role or null
	 */
	public static ReferenceBinding findMemberTypeInContext(ReferenceBinding site, char[] className) {
		while (site != null) {
			ReferenceBinding roleType = site.getMemberType(className);
			if (roleType != null)
				return roleType;
			site = site.enclosingType();
		}
		return null;
	}

	public static boolean isMoreSpecificThan(ReferenceBinding type1, ReferenceBinding type2)
	{
		if (type1.isCompatibleWith(type2))
			return true;
		if (!CharOperation.equals(type1.sourceName(), type2.sourceName()))
			return false;
		ReferenceBinding enclosingType1 = type1.enclosingType();
		ReferenceBinding enclosingType2 = type2.enclosingType();
		if (enclosingType1 != null && enclosingType2 != null)
			return isMoreSpecificThan(enclosingType1, enclosingType2);
		return false;
	}
	/**
	 * performs role type strengthening, preforms static adjustment (OTJLD 2.3.3(a).
	 * Respects arrays and checks compatibility.
	 * @param scope client context, guaranteed to be a team or a role
	 * @param provided
	 * @param required
	 * @param doAdjust should the adjusted role be returned (as opposed to just the strengthened)?
	 * @param location where to report errors against
	 * @return an exact role or null
	 */
	public static TypeBinding getRoleToLiftTo (
			Scope scope,
			TypeBinding provided,
			TypeBinding required,
			boolean doAdjust,
			ASTNode location)
	{
		ReferenceBinding requiredRef = null;
		if (   required.isArrayType()
			&& (required.leafComponentType() instanceof ReferenceBinding))
		{
			requiredRef = (ReferenceBinding)required.leafComponentType();
		} else if (required instanceof ReferenceBinding) {
			requiredRef = (ReferenceBinding)required;
		}
		if (   requiredRef != null
			&& requiredRef.isRole())
		{
			requiredRef = (ReferenceBinding)strengthenRoleType(
					scope.enclosingSourceType(),
					requiredRef);
			ReferenceBinding foundRole = null;
			if (requiredRef.baseclass() == null) {
				foundRole = adjustRoleToLiftTo(scope, provided, requiredRef, location);
				if (foundRole != null && !doAdjust)
					foundRole = requiredRef; // successful but revert to unadjusted
			} else {
				if (!provided.leafComponentType().isBaseType()) {
					ReferenceBinding providedLeaf = (ReferenceBinding)provided.leafComponentType();
					providedLeaf = RoleTypeCreator.maybeInstantiateFromPlayedBy(scope, providedLeaf);
					if (   providedLeaf.isCompatibleWith(requiredRef.baseclass())
						&& required.dimensions() == provided.dimensions())
					{
						foundRole = requiredRef;
					}
				}
// FIXME(SH): unneeded?
//				// just check definite binding ambiguity:
//				adjustRoleToLiftTo(scope, provided, requiredRef, location);
			}
			if (foundRole != null) {
				// success by translation
				if (required.dimensions() == 0)
					return foundRole;
				else
					return scope.createArrayType(foundRole, required.dimensions());
			}
		}
		return null;
	}

	/**
	 * Perform static adjustment according to OTJLD 2.3.3(a).
	 */
	private static ReferenceBinding adjustRoleToLiftTo(
			Scope scope,
			TypeBinding provided,
			ReferenceBinding required,
			ASTNode location)
	{
		ReferenceBinding mostGeneralFound = null;
		ReferenceBinding mostSpecificFound = null;

		ReferenceBinding enclosingTeam = required.enclosingType();
		ReferenceBinding[] roleTypes = enclosingTeam.memberTypes();
		ReferenceBinding requiredLeaf = (ReferenceBinding)required.leafComponentType();
		requiredLeaf = requiredLeaf.getRealType();
		for (int i = 0; i < roleTypes.length; i++) {
			if (TSuperHelper.isMarkerInterface(roleTypes[i]))
				continue;
			RoleModel currentRole = roleTypes[i].roleModel;
			if (currentRole == null) {
				if (scope.referenceContext().hasErrors())
					continue;
				throw new InternalCompilerError("Role model of "+String.valueOf(roleTypes[i].readableName())+" is unexpectedly null"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			ReferenceBinding currentRoleIfc = currentRole.getInterfacePartBinding();
			ReferenceBinding currentBase = currentRole.getBaseTypeBinding();

			if (TypeBinding.equalsEquals(mostGeneralFound, currentRoleIfc))
				continue; // already seen (happens because class/ifc part show the same role)

			if (   currentBase != null
				&& provided.leafComponentType().isCompatibleWith(currentBase)
				&& currentRoleIfc.isCompatibleWith(requiredLeaf))
			{
				if (mostGeneralFound == null) {
					mostGeneralFound = currentRoleIfc;
					mostSpecificFound = currentRoleIfc;
				} else {
					if (mostGeneralFound.isCompatibleWith(currentRoleIfc)) {
						mostGeneralFound = currentRoleIfc; // new type is more general
					} else if (   currentRoleIfc.isCompatibleWith(mostSpecificFound)) {
						mostSpecificFound = currentRoleIfc;// new type is more specific
					} else { // non-linear relation between different candidates.
						return required; // revert to non-specific required type (additionally LFE is declared by the lift method)
					}
				}
			}
		}
		return mostGeneralFound;
	}


	// ==== Facade for RoleFileCache: ====

	/**
	 *  Setup a structure for persistent storage of a list of know.
	 *  role files.
	 * @param scope TODO
	 * @param environment lookup new types here.
	 */
	public void setupRoFiCache(Scope scope, LookupEnvironment environment) {
		if (this.knownRoleFiles != null)
			this.knownRoleFiles.createTypeAndBinding(scope, environment);
	}

	/**
	 * Has the role files cache been initialized properly for 'receiverType'?
	 */
	public static boolean hasRoFiCache(ReferenceBinding receiverType) {
		if (!receiverType.isTeam())
			return false;
		TeamModel model = receiverType.getTeamModel();
		if (model.knownRoleFiles == null)
			return false;
		return model.knownRoleFiles.isValid;
	}

	/**
	 * Ensure all known roles (role files) are loaded.
	 */
	public void readKnownRoleFiles() {
		if (this.knownRoleFiles != null)
			this.knownRoleFiles.readKnownRoles();
	}
	/**
	 * Generate the byte code to store the cache of known role files.
	 *
	 * @param classFile class file of the enclosing team.
	 */
	public void generateRoFiCache(ClassFile classFile) {
		if (this.knownRoleFiles != null && !Protections.hasClassKindProblem(this._binding))
			this.knownRoleFiles.generateCode(classFile);
	}
	/**
	 * Register a role file by its (relative) type name.
	 *
	 * @param name
	 */
	public void addKnownRoleFile(char[] name, ReferenceBinding role) {
		if (this.knownRoleFiles != null)
			this.knownRoleFiles.addRoleFile(name);
		if (this._ast != null && (this._ast.scope instanceof OTClassScope))
			((OTClassScope) this._ast.scope).recordBaseClassUse(role.baseclass); // avoid evaluating baseclass()
	}

	/**
	 * Get all known roles, those that are listed in memberTypes as well
	 * as those only recorded in knownRoleFiles (which might be binary
	 * even if the team is a SourceTypeBinding), but exclude the RoFi cache itself.
	 * @return intended to be a non-null array.
	 */
	public ReferenceBinding[] getKnownRoles() {
		ReferenceBinding[] members = this._binding.memberTypes();
		HashSet<String> roleNames = new HashSet<String>();
		for (int i = 0; i < members.length; i++) {
			if (!RoleFileCache.isRoFiCache(members[i]) && !members[i].isEnum())
				roleNames.add(new String(members[i].internalName()));
		}
		if (this.knownRoleFiles == null) {
			if (roleNames.size() == members.length) // nothing filtered?
				return members;
			// faster to re-iterate the array than performing the lookup below:
			ReferenceBinding[] result = new ReferenceBinding[roleNames.size()];
			int j=0;
			for (int i = 0; i < members.length; i++) {
				if (roleNames.remove(new String(members[i].internalName()))) // this also avoids duplicates in result
					result[j++] = members[i];
			}
			return result;
		}
		char[][] roleFileNames = this.knownRoleFiles.getNames();
		for (int i = 0; i < roleFileNames.length; i++) {
			roleNames.add(new String(roleFileNames[i]));
		}
		int len = roleNames.size();
		int i=0;
		ReferenceBinding[] result = new ReferenceBinding[len];
		for (Iterator<String> iter = roleNames.iterator(); iter.hasNext();) {
			String name= iter.next();
			result[i++] = this._binding.getMemberType(name.toCharArray());
		}
		return result;
	}

	public boolean containsRoFi(boolean ignoreConverted) {
		TypeDeclaration ast = getAst();
		if (ast != null && ast.memberTypes != null) {
			for (TypeDeclaration role : ast.memberTypes)
				if (role != null && role.isRoleFile())
					if (!(ignoreConverted && role.isConverted))
						return true;
		}
		return false;
	}

	public TypeBinding getMarkerInterfaceBinding(Scope scope) {
		if (this.markerInterface != null)
			return this.markerInterface.binding;
		if (   this._binding != null
			&& this._binding.superclass() != null)
		{
			// has not been generated yet, but perhaps this can indeed by repaired now:
			TSuperHelper.addMarkerInterface(this, this._binding.superclass());
			return this.markerInterface.binding;
		}
		PackageBinding pkgBinding = scope.compilationUnitScope().fPackage;
		char[] markerName = "MissingTSuperMarker".toCharArray(); //$NON-NLS-1$
		char[][] compoundName = this._binding != null ?
									CharOperation.arrayConcat(this._binding.compoundName, markerName) :
									new char[][] { markerName };
		return scope.compilationUnitScope().environment.createMissingType(pkgBinding, compoundName);
	}
//{OTDyn:
	// in nested teams the outermost team assigns locally unique IDs to callins (baseMethodSpec, to be precise).
	private int nextCallinID = 0;
	private TeamModel getOutermostTeam() {
		if (isRole())
			return this._binding.enclosingType().getTeamModel().getOutermostTeam();
		return this;
	}
	public void recordLabelledCallin(String label, MethodBinding baseMethod, int callinId, ReferenceBinding declaringRoleClass) {
		List<CallinInfo> existing = getCallinsForLabel(label, declaringRoleClass);
		if (existing == null) {
			existing = new ArrayList<>();
			this.labelledCallinIds.put(label, existing);
		}
		existing.add(new CallinInfo(declaringRoleClass, callinId, baseMethod));
	}
	/** local structure for storing information about the callin-callinId mapping. */
	static class CallinInfo {
		ReferenceBinding roleClass;
		int callinId;
		MethodBinding baseMethod;
		public CallinInfo(ReferenceBinding roleClass, int callinId, MethodBinding baseMethod) {
			this.roleClass = roleClass;
			this.callinId = callinId;
			this.baseMethod = baseMethod;
		}
	}
	public List<CallinInfo> getCallinsForLabel(String label, ReferenceBinding declaringRoleClass) {
		if (this.labelledCallinIds == null) {
			this.labelledCallinIds = new HashMap<>();
			TeamModel superTeam = getSuperTeam();
			if (superTeam != null) {
				// FIXME: Check if binary team has the (label,baseM->callinId) info.
				ReferenceBinding tsuperRole = null;
				ReferenceBinding currentRole = declaringRoleClass;
				while (tsuperRole == null && currentRole != null && currentRole.isRole()) {
					for (ReferenceBinding tsuper : currentRole.roleModel.getTSuperRoleBindings()) {
						if (TypeBinding.equalsEquals(tsuper.enclosingType(), superTeam.getBinding())) {
							tsuperRole = tsuper;
							break;
						}
					}
					currentRole = currentRole.superclass();
				}
				if (tsuperRole != null) {
					List<CallinInfo> inherited = superTeam.getCallinsForLabel(label, tsuperRole);
					if (inherited != null) {
						this.labelledCallinIds.put(label, inherited);
						int max = inherited.stream().map(p->p.callinId).max(Integer::compareTo).get();
						this.nextCallinID = Math.max(this.nextCallinID, max+1);
					}
				}
			}
		}
		return this.labelledCallinIds.get(label);
	}
	/**
	 * Assign a fresh callin ID for this method spec, and store it in the method spec.
	 * This method, however, respects overriding of named callins.
	 */
	public int getNewCallinId(MethodSpec baseMethodSpec, char[] label) {
		TeamModel outermostTeam = getOutermostTeam();
		String labelString = null;
		ReferenceBinding declaringRoleClass = baseMethodSpec.declaringRoleClass;
		if (label != null) {
			labelString = new String(label);
			List<CallinInfo> existing = outermostTeam.getCallinsForLabel(labelString, declaringRoleClass);
			if (existing != null) {
				LookupEnvironment environment = this._ast.scope.environment();
				for (CallinInfo entry : existing) {
					TypeBinding existingRole = strengthenRoleType(this._binding, entry.roleClass).original();
					if (!existingRole.isCompatibleWith(declaringRoleClass)
							&&!declaringRoleClass.isCompatibleWith(existingRole))
						continue; // provably unrelated roles, callin cannot override
					MethodBinding baseMethod = baseMethodSpec.resolvedMethod;
					if (baseMethod == entry.baseMethod
							|| MethodVerifier.doesMethodOverride(baseMethodSpec.resolvedMethod, entry.baseMethod, environment)) {
						return entry.callinId;
					}
				}
			}
		}
		int callinID = baseMethodSpec.callinID = outermostTeam.nextCallinID++;
		if (labelString != null) {
			outermostTeam.recordLabelledCallin(labelString, baseMethodSpec.resolvedMethod, callinID, declaringRoleClass);
		}
		return callinID;
	}
	/** Record the fact that the given callinID has been assigned in the context of this team. */
	public void recordCallinId(int callinIdMax) {
		TeamModel outermostTeam = getOutermostTeam();
		outermostTeam.nextCallinID = Math.max(outermostTeam.nextCallinID, callinIdMax+1);
	}
	/** Answer the number callinIDs assigned in the context of this team. */
	public int getCallinIdCount() {
		return getOutermostTeam().nextCallinID;
	}
	public boolean hasTSuperTeamMethod(char[] selector) {
		if (!isRole())
			return false;
		RoleModel role = getRoleModelOfThis();
			for (ReferenceBinding tsuperTeam : role.getTSuperRoleBindings())
				if (tsuperTeam.isTeam()) {
					if (tsuperTeam.getMethods(selector) != Binding.NO_METHODS)
						return true;
				}
		return false;
	}
	@Override
	public void addOrMergeAttribute(AbstractAttribute attr) {
		if (attr instanceof OTDynCallinBindingsAttribute) {
			OTDynCallinBindingsAttribute filteredAttr = ((OTDynCallinBindingsAttribute)attr).filteredCopy(this._binding);
			if (filteredAttr != null) {
				super.addOrMergeAttribute(filteredAttr);
				filteredAttr.createBindings(this, false);
			}
			recordCallinId(((OTDynCallinBindingsAttribute)attr).getCallinIdMax());
		} else {
			super.addOrMergeAttribute(attr);
		}
	}
// SH}
	public boolean isAmbiguousLifting(ReferenceBinding staticRole, ReferenceBinding baseBinding) {
		for (Pair<ReferenceBinding, ReferenceBinding> pair : this.ambigousLifting) {
			if (TypeBinding.equalsEquals(pair.first, baseBinding) && TypeBinding.equalsEquals(pair.second, staticRole))
				return true;
		}
		return false;
	}
	/**
	 * Can lifting to the given role potentially fail at runtime?
	 * @param role role to lift to.
	 * @return the IProblem value to be used when reporting hidden-lifting-problem against a callin binding or 0.
	 */
	public int canLiftingFail(ReferenceBinding role) {
		if ((this.tagBits & HasAbstractRelevantRole) != 0 && role.isAbstract())
			return IProblem.CallinDespiteAbstractRole;
		for (Pair<ReferenceBinding, ReferenceBinding> pair : this.ambigousLifting) {
			if (role.getRealClass().isCompatibleWith(pair.second) && pair.first.isCompatibleWith(role.baseclass()))
				return IProblem.CallinDespiteBindingAmbiguity;
		}
		return 0;
	}

//	=======================================================================================
//	=  Support for ensuring uniqueness of accessIds among a team and all its super teams. =

	public static interface UpdatableAccessId {
		void update(int offset);
	}

	public static class UpdatableIntLiteral extends IntLiteral implements UpdatableAccessId {
		int val;
		public UpdatableIntLiteral(int val, int start, int end) {
			super(String.valueOf(val).toCharArray(), null, start, end);
			this.val = val;
		}
		@Override
		public void update(int offset) {
			this.constant = IntConstant.fromValue(this.val + offset);
		}
	}

	/** Region of ids used by this team and its supers. */
	int accessIdOffset = -1;
	/** accessIds that may require updating. */
	List<UpdatableAccessId> updatableAccessIds = null;

	public void recordUpdatableAccessId(UpdatableAccessId updatableAccessId) {
		if (this.updatableAccessIds == null)
			this.updatableAccessIds = new ArrayList<>();
		this.updatableAccessIds.add(updatableAccessId);
	}

	/** Update all recorded accessIds to stay clear of id ranges used by super teams. */
	public int updateDecapsAccessIds() {
		if (this.accessIdOffset > -1 || getWeavingScheme() == WeavingScheme.OTRE) return this.accessIdOffset;

		this.accessIdOffset = 0;

		TeamModel superTeam = getSuperTeam();
		if (superTeam != null)
			this.accessIdOffset += superTeam.updateDecapsAccessIds();

		// update ASTs above super's id range if needed:
		if (this.updatableAccessIds != null && this.accessIdOffset > 0)
			for (UpdatableAccessId updater : this.updatableAccessIds)
				updater.update(this.accessIdOffset);

		if (this._specialAccess != null) {
			// update attribute if needed:
			this._specialAccess.accessIdOffset = this.accessIdOffset;
			// include local value in the total offset:
			this.accessIdOffset += this._specialAccess.nextAccessId;
		}
		return this.accessIdOffset;
	}
}
