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

import static org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.AccInterface;
import static org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.AccSynthetic;
import static org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers.AccOverridingRole;

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

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions.WeavingScheme;
import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
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.SyntheticMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
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.AbstractMethodMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.AbstractAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.CPTypeAnchorAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.CallinMethodMappingsAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.CalloutMappingsAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.OTSpecialAccessAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.OTSpecialAccessAttribute.CalloutToFieldDesc;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.RoleLocalTypesAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.SingleValueAttribute;
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.control.Dependencies;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
import org.eclipse.objectteams.otdt.internal.core.compiler.lifting.Lifting;
import org.eclipse.objectteams.otdt.internal.core.compiler.lifting.Lifting.InstantiationPolicy;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.CallinCalloutBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleFieldAccess;
import org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CalloutImplementor;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance.CopyInheritance;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance.TypeLevel;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.RoleSplitter;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer;

/**
 * This class augments and generalizes ReferenceBinding and MemberTypeDeclaration
 * to take some additional information for role classes.
 *
 * These are the main tasks:
 * <ul>
 *   <li>Store byte code from tsuper role before adjustment
 *   <li>Link to team, link ifc/class parts, link to tsuper role
 *   <li>record the need to create a concrete _OT$getBase() method.
 *   <li>Iterate through role hierarchies.
 * </ul>
 *
 * @author stephan
 * @version $Id: RoleModel.java 23416 2010-02-03 19:59:31Z stephan $
 */
public class RoleModel extends TypeModel
{
	// Flag constants for tagBits:
	// is parameterized type instantiated via tsuper-link?
	public static final int IsViewedAsTSuper = ASTNode.Bit1;

    // had the baseclass field/playedBy problems?
    public static final int BaseclassHasProblems = ASTNode.Bit2;

    // several issues making lifting impossible
    public static final int HasLiftingProblem = ASTNode.Bit3;


	// ========== Byte code related fields: ======================
	// name to use for ClassFileReader when re-interpreting existing constant pool
    public static final char[] NO_SOURCE_FILE = "<intermediate>".toCharArray(); //$NON-NLS-1$

	/** Temporarily store the ClassFile to initialize offsets later. */
    private ClassFile _classFile = null;

    /** The full byte code of this class. */
    private byte[] _classByteCode = null;

    private int    _headerOffset = 0;

    /** Offsets into the constant pool */
    private int[]  _constantPoolOffsets = null;

    /** A table of all offsets to methods within the byte code */
    private HashMap <MethodBinding, Integer> _methodByteCodeOffsets = new HashMap<MethodBinding, Integer>();

    // ========= Structure related fields: ============
    /** The Team containing this role. */
	private TeamModel   _teamModel;

    /**
     * The corresponding roles from super-Teams.
     * This is a list, because for each level of nesting a new super team arises:
     * super, tsuper, tsuper-of-tsuper etc.
     * Examples:
     *   a role T2M2R1 may have these tsupers: T2M1R1 and T1M2R1
     *   a role O2T2M2R1 has these: O2T2M1R1, O2T1M2R1 and O1T2M2R1
     * All remaining roles R1 are indirect tsupers as they can be reached via any
     * of the above.
     */
    private ReferenceBinding[] _tsuperRoleBindings = new ReferenceBinding[2]; // 2 should suffice for human understandable programs ;-}
    private int numTSuperRoles = 0;

    /** this is set while role-splitting */
    public TypeDeclaration _interfacePart = null;

    /** this is set while role-splitting */
    public TypeDeclaration _classPart = null;

    private ReferenceBinding _interfaceBinding = null; // only internal cache
    private ReferenceBinding _classBinding = null;

    /** Record here all types which are defined local to a method (RoleModel). */
    private LinkedList<RoleModel> _localTypes = new LinkedList<RoleModel>();

	/** The known sub roles (including this) as determined by RoleHierarchyAnalyzer.analyze(). */
	private RoleModel[] _subRoles = null;

    /** bound roles store here the topmost bound (super)role, which determines the cache to use: */
    public RoleModel _boundRootRole = null;

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

    /** will this role declare an abstract lower method? */
    public boolean _abstractLower = false;

    /** is this role refining the extends clause of its tsuper role? */
    public boolean _refinesExtends = false;

    /** does this bound role have a binding ambiguity prohibiting lifting? */
    public boolean _hasBindingAmbiguity = false;

    /** is the baseclass an (indirect) enclosing class? */
	public boolean _playedByEnclosing = false;

    /** map synthetic methods/fields of tsuper role to this role's */
    private HashMap<Binding, Binding> _syntheticMap = new HashMap<Binding, Binding>();

    /** is this role a local type? */
    public boolean _isLocalType;

	/** Remember which tsuper-features (methods & fields) have already been copied,
	 *  so that we can come back and copy more features (copyGeneratedFeatures)
	 *  without the risk of duplication.
	 */
	private HashSet<Binding> _copiedFeatureBindings = new HashSet<Binding>();


	/** Signal if a more specific role exists with unchanged playedBy. */
	public ReferenceBinding _supercededBy;


    /**
     * Constructor for use by BinaryTypeBinding only.
     */
    public RoleModel (ReferenceBinding roleBinding)
    {
        super(roleBinding);
        if (roleBinding.isLocalType())
        	this._isLocalType = true;
    }

    /**
     * Constructor for use by MemberTypeDeclaration only.
     */
    public RoleModel (TypeDeclaration roleAst)
    {
        super(roleAst);
        if (!TeamModel.isOrgObjectteamsTeam(roleAst.enclosingType))
        	addAttribute(WordValueAttribute.compilerVersionAttribute());
        if (roleAst.scope != null && roleAst.scope.parent instanceof MethodScope)
        	this._isLocalType = true;
    }

    public boolean hasState(int state) {
    	return this._state.getState() >= state;
	}

	/**  @return old state */
	@Override
	public int setState(int state) {
// FIXME(SH): should perhaps also set state of role-CUDs??
//            their state seems to skip many stages...
		int oldState = super.setState(state); // may also run pending jobs
		if (   oldState >= ITranslationStates.STATE_ROLE_FEATURES_COPIED
			&& state    <  ITranslationStates.STATE_BYTE_CODE_GENERATED)
		{
			// we are past STATE_ROLE_FEATURES_COPIED, take care to add generated features.
			// (This assumes, super team already has 'state').
			if (this._ast != null)
				CopyInheritance.copyGeneratedFeatures(this);
		}
// TODO(SH): enable only if needed, currently such behavior triggered only in setStateRecursive(CUD,state)
//    	if (   this._currentlyProcessingState == ITranslationStates.STATE_NONE
//        	&& this._requestedState > state)
//    	{
//    		this._currentlyProcessingState= this._requestedState;
//        	if (Dependencies.ensureRoleState(this, this._requestedState))
//        		this._requestedState= ITranslationStates.STATE_NONE;
//    	}
		return oldState;
	}

    /**
     * Override method from TypeModel:
     * Also recurse into role local types.
     */
	@Override
	public void setMemberState(int state) {
		super.setMemberState(state);
		if (   state <= ITranslationStates.STATE_ROLES_SPLIT
			|| state >= ITranslationStates.STATE_RESOLVED)
		{
	        Iterator<RoleModel> localTypes = localTypes();
	        while (localTypes.hasNext()) {
	        	RoleModel type = localTypes.next();
        		type.setState(state);
        		type.setMemberState(state);
	        }
		}
	}

	@Override
	public boolean isReadyToProcess(int state) {
		if (!this._state.isReadyToProcess(state))
			return false;
		// check the other model, too:
		RoleModel otherModel= null;
		if (this._interfaceBinding != null)
			otherModel= this._interfaceBinding.roleModel;
		if (otherModel == null || otherModel == this) {
			if (this._classBinding != null)
				otherModel= this._classBinding.roleModel;
		}
		if (otherModel != null && otherModel != this)
			return otherModel._state.isReadyToProcess(state);
		return true;
	}

	@Override
	public boolean isTeam() {
		if (this._ast != null)
			return this._ast.isTeam();
		return this._binding.isTeam();
	}

	public TeamModel getTeamModelOfThis() {
		// the class part has all the structure:
		getClassPartAst(); // initialize
		if (this._classPart != null && this._classPart.isTeam())
			return this._classPart.getTeamModel();
		getClassPartBinding(); // initialze
		if (this._classBinding != null && this._classBinding.isTeam())
			return this._classBinding.getTeamModel();
		return null;
	}


	public static boolean isClass(ReferenceBinding memberType) {
		if (!memberType.isRole())
			return memberType.isClass();
		ReferenceBinding realClass = memberType.getRealClass();
		return realClass != null && realClass.isClass();
	}


	public static boolean isInterface(ReferenceBinding memberType) {
		if (!memberType.isRole())
			return memberType.isInterface();
		// role can only be class or interface; test !class:
		ReferenceBinding realClass = memberType.getRealClass();
		return realClass == null || !realClass.isClass();
	}

	/** Is ifc the synthetic interface part of clazz? */
	public static boolean isSynthIfcOfClass(ReferenceBinding ifc, ReferenceBinding clazz) {
		if (ifc.isSynthInterface() && ifc.roleModel != null)
			if (TypeBinding.equalsEquals(ifc.roleModel.getClassPartBinding(), clazz))
				return true;
		return false;
	}


    public static void setTagBit(ReferenceBinding role, int tagBit) {
		role.roleModel.tagBits |= tagBit;
	}

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

    // ================= Byte code related methods =========================

    /** Store byte code information of a method */
    public void recordByteCode (
            MethodBinding method,
            byte[] code,
            int offset,
            int[] constantPoolOffsets)
    {
        this._methodByteCodeOffsets.put(method, new Integer(offset));
        if (this._classByteCode == null) {
            this._classByteCode = code;
            this._constantPoolOffsets = constantPoolOffsets;
        } else {
            assert(this._classByteCode == code);
            // when registering from IBinaryType, the code will not be modified any more.
        }
    }

    /** Store byte code information of a method */
    public static void maybeRecordByteCode(
            AbstractMethodDeclaration method,
            ClassFile file,
            int codeAttributeOffset)
    {
        TypeDeclaration clazz = method.scope.referenceType();
        if (clazz.isRole())
        {
            TypeDeclaration memberType = clazz;
            RoleModel role = memberType.getRoleModel();
            role.recordClassFile(method.binding, file, codeAttributeOffset);
        }
    }

    /**
     * Is this role expected to have byte code?
     * Reasons for not having byte code originate in ignoreFurtherInvestigation
     * and may be propagated via MethodBinding.bytecodeMissing.
     * If no method with bytecode exists, no bytes have been recorded here.
     */
    public boolean hasByteCode() {
    	if (this._classByteCode != null || this._classFile != null || this._classFilePath != null)
    		return true;
    	TypeDeclaration ast = this._ast;
    	if (ast == null)
    		ast = this._binding.isInterface() ? this._interfacePart : this._classPart;
    	if (ast == null) return false;
    	if (TypeModel.isIgnoreFurtherInvestigation(ast)) return false;
    	MethodBinding[] methods= ast.binding.methods();
    	for (MethodBinding methodBinding : methods) {
			if (!methodBinding.bytecodeMissing)
				return true;
		}
    	return false;
    }
    /** Get the byte code of this role class.
     *  Must be registered with (maybe)recordByteCode
     */
    public synchronized byte[] getByteCode ()
    {
        if (this._classByteCode == null) {
        	if (this._classFile == null && this._ast != null)
        		this._classFile = this._ast.compilationResult.findClassFile(this._binding);
            if (this._classFile != null) // nullified once a class file is re-used for a different type
            {
            	this._classByteCode = this._classFile.getBytes();
            	this._headerOffset = this._classFile.headerOffset;
            } else {
            	// restore bytes from class file on disk:
            	try {
            		ClassFileReader reader = read();
	            	if (reader == null) {
	        			if (Config.getConfig().ignoreMissingBytecode)
	        				return null;
	            		throw new InternalCompilerError("Class file was not yet written to disk"); //$NON-NLS-1$
	            	}
                	this._classByteCode = reader.getBytes();
                	this._headerOffset = reader.getHeaderOffset();
                	this._constantPoolOffsets = reader.getConstantPoolOffsets();
				} catch (Exception e) {
					throw new InternalCompilerError("cannot retrieve generated class file: "+e); //$NON-NLS-1$
            	}
            }
        }
        assert(this._classByteCode != null);
        return this._classByteCode;
    }

    /** Get the byte code offsets of this role's constant pool.
     *  Must be registered with (maybe)recordByteCode
     */
    public int[] getConstantPoolOffsets()
    {
        if (this._constantPoolOffsets == null)
            restoreCPOffsets();
        return this._constantPoolOffsets;
    }

    /** Get the offset where in the byte code 'method' start.
     *  Must be registered with (maybe)recordByteCode
     *  @return method offset or -1 if source method has no byte code due to errors.
     */
    public int getByteCodeOffset (MethodBinding method)
    {
    	if (getByteCode() == null)
    		return -1;
        Integer offset = this._methodByteCodeOffsets.get(method.original());
        if (offset == null)
        {
            if(!method.bytecodeMissing)
                throw new InternalCompilerError("Method has no byte code: "+method); // unexpectedly! //$NON-NLS-1$
            return -1;
        }
        return offset.intValue() + this._headerOffset;
    }

    @Override
    public synchronized void setClassFilePath(String classFilePath) {
       	super.setClassFilePath(classFilePath);
       	this._classFile = null; // don't use any more but retrieve using the class file path
       	if (isTeam())
       		getTeamModelOfThis().setClassFilePath(classFilePath);
    }
    /**
     *  Currently unusable, since bytecode may be needed any time again!
     */
    public synchronized void forgetByteCode() {
        this._methodByteCodeOffsets = new HashMap<MethodBinding, Integer>();
        this._classFile           = null;
        this._classByteCode       = null;
        this._constantPoolOffsets = null;
    }

    private synchronized void recordClassFile(MethodBinding method, ClassFile file, int offset)
    {
        this._methodByteCodeOffsets.put(method, new Integer(offset));
        if (   (this._classFile != null)
            && (this._classFile != file))
        {
            throw new InternalCompilerError("wrong ClassFile instance."); //$NON-NLS-1$
        }
        this._classFile = file;
    }

    private void restoreCPOffsets() {
        try {
            byte[] code = getByteCode();
            if (code != null) {
                ClassFileReader reader
                    = new ClassFileReader(code, NO_SOURCE_FILE); // not recording OT-attributes
                this._constantPoolOffsets = reader.getConstantPoolOffsets();
            }
        } catch (ClassFormatException ex) {
            throw new InternalCompilerError(ex.toString());
        }
    }

    // =================== structure related methods: =================
	/**
	 * Role name: for normal roles (with ifc part) strip of the __OT__.
	 * @return the name
	 */
	public char[] getName() {
		return this._binding != null ?
			this._binding.sourceName() :
		    this._ast.name;
	}

	/**
	 * Is this a real role from source code (not role nested)?
	 */
	public boolean isSourceRole() {
		return this._ast != null ? this._ast.isSourceRole() : this._binding.isSourceRole();
	}

	/** Answer whether the role is purely copied (aka phantom role) are exists in source. */
	public boolean isPurelyCopied() {
		if (this._ast != null)
			return this._ast.isPurelyCopied;
		else
			return (this._extraRoleFlags & IOTConstants.OT_CLASS_PURELY_COPIED) != 0;
	}

	// can be role file and/or purely copied
	private int _extraRoleFlags = 0;
	public boolean isRoleFile() {
		if (this._ast == null)
			return (this._extraRoleFlags & IOTConstants.OT_CLASS_ROLE_FILE) != 0;
		return this._ast.isRoleFile();
	}

	public void setExtraRoleFlags(int flags) {
		this._extraRoleFlags = flags;
		// FIXME(SH): for role files also mark enclosing team (-> role files attribute)
	}

	public int getExtraRoleFlags() {
		return this._extraRoleFlags;
	}

	public boolean isLocalType() {
		if (this._binding != null)
			return this._binding.isLocalType();
		if (this._classBinding != null)
			return this._classBinding.isLocalType();
		if (this._ast != null && this._ast.scope != null)
			return (this._ast.scope.parent.kind == Scope.METHOD_SCOPE);
		return false;
	}

    public TypeDeclaration getInterfaceAst()
    {
    	if (this._interfacePart != null)
    		return this._interfacePart;
    	if (this._ast == null)
    		return null; // neither class nor ifc ast present, must be binary.
    	if (   this._interfaceBinding != null
    		&& !this._ast.isInterface())
    	{
    		RoleModel interfaceModel = this._interfaceBinding.roleModel;
    		if (interfaceModel != null && interfaceModel != this) // model sharing didn't work
    			return interfaceModel.getInterfaceAst();
    	}
    	if ((this._ast.bits & ASTNode.IsLocalType) != 0)
    		return null;
    	assert this._ast.isInterface();
    	return this._ast;
    }

    public TypeDeclaration getClassPartAst()
    {
    	if (this._classPart != null)
        	return this._classPart;
    	if (this._ast != null && !this._ast.isInterface())
    		return this._classPart = this._ast;
    	if (this._classBinding != null) {
    		RoleModel classRole = this._classBinding.roleModel;
    		if (classRole != null)
    			return this._classPart = classRole._ast;
    	}
    	return null;
    }

    public ReferenceBinding getInterfacePartBinding()
    {
        if (this._interfaceBinding == null) {
            if (this._interfacePart != null)
                this._interfaceBinding = this._interfacePart.binding;
            else if (this._binding != null && this._binding.enclosingType() != null)
                this._interfaceBinding = this._binding.enclosingType().getMemberType(
                    this._binding.sourceName()); // chop off OT_DELIM

            // Sanity check:
            if (   this._interfaceBinding  != null && this._binding != null
            	&& this._interfaceBinding.isBinaryBinding() != this._binding.isBinaryBinding()) {
            	Scope scope = null;
            	if (!this._binding.isBinaryBinding())
            		scope = ((SourceTypeBinding)this._binding).scope;
            	else if (!this._interfaceBinding.isBinaryBinding())
            		scope = ((SourceTypeBinding)this._interfaceBinding).scope;
            	String message = "Mismatching binary/source class/interface parts: "+String.valueOf(this._binding.readableName())+" / "+String.valueOf(this._interfaceBinding.readableName()); //$NON-NLS-1$ //$NON-NLS-2$
            	if (scope != null) {
					scope.problemReporter().mismatchingRoleParts(this._interfaceBinding, scope.referenceType());
            	} else
            		throw new InternalCompilerError(message);
            }

        }
        return this._interfaceBinding;
    }

	public ReferenceBinding getClassPartBinding()
	{
		if (this._classBinding == null) {
			if (this._binding == null) return null; // assuming error
	        if (!this._binding.isInterface())
			    this._classBinding = this._binding;
	        else if (this._binding.isSynthInterface()) {
	        	if (this._classPart != null)
	        		this._classBinding = this._classPart.binding;
	        	if (this._classBinding == null)
	        		this._classBinding = this._binding.enclosingType().getMemberType(
	        				CharOperation.concat(IOTConstants.OT_DELIM_NAME, this._binding.internalName()));
	        }
		}
        return this._classBinding;
	}

    public void setTeamModel(TeamModel teamModel) {
        this._teamModel = teamModel;
    }

    public TeamModel getTeamModel() {
        if (this._teamModel == null) {
        	try {
        		if (this._binding != null)
        			this._teamModel = TeamModel.getEnclosingTeam(this._binding).getTeamModel();
        		else // ROFI: fallback if team model is required before a binding is created:
        			this._teamModel = this._ast.enclosingType.getTeamModel();
        	} catch (NullPointerException npe) {
        		throw new InternalCompilerError("Missing enclosing team for "+this+"\n" //$NON-NLS-1$ //$NON-NLS-2$
        									     +(this._ast != null ? this._ast : this._binding));
        	}
        }
        return this._teamModel;
    }

    /**
     * Retrieve the tsuper role with highest priority.
     *
     * Note, that more tsuper roles may exist due to team nesting.
     * TODO (SH): need to check all callers, whether reading just the first
     * tsuper role is OK!
     *
     * @return first tsuper role or null
     */
    public ReferenceBinding getTSuperRoleBinding() {
		return this._tsuperRoleBindings[this.numTSuperRoles > 0 ? this.numTSuperRoles-1 : 0];
	}

    /** Answer all direct tsuper roles of this role in ascending priority. */
    public ReferenceBinding[] getTSuperRoleBindings() {
    	ReferenceBinding[] tsupers = new ReferenceBinding[this.numTSuperRoles];
    	System.arraycopy(this._tsuperRoleBindings, 0, tsupers, 0, this.numTSuperRoles);
    	return tsupers;
    }

    /** Does this role have any tsuper role, other than the predefined roles from Team? */
    public boolean hasRelevantTSuperRole() {
    	return    this.numTSuperRoles > 0
    	       && !TypeAnalyzer.isPredefinedRole(getBinding());
    }

	/**
	 * Is role some kind of tsuper role of current?
	 * It could be that any enclosing teams are role-and-tsuper-role.
	 * Then from there on inwards only role names are compared.
	 */
	public boolean hasTSuperRole(ReferenceBinding role) {
		if (!role.isRole())
			return false;
		ReferenceBinding otherClass = null, otherIfc = null;
		if(role.isInterface()) {
			otherIfc = role;
			otherClass = role.getRealClass();
		} else {
			otherIfc = role.getRealType();
			otherClass = role;
		}
		Dependencies.ensureRoleState(this, ITranslationStates.STATE_LENV_CONNECT_TYPE_HIERARCHY);
		for (int i = 0; i < this.numTSuperRoles; i++) {
			ReferenceBinding other = this._tsuperRoleBindings[i].isInterface() ? otherIfc : otherClass;
			if (TypeBinding.equalsEquals(this._tsuperRoleBindings[i], other))
				return true;
			if (this._tsuperRoleBindings[i].roleModel.hasTSuperRole(other))
				return true;
		}
		ReferenceBinding outerRole = this._binding.enclosingType();
		if (outerRole.isRole()) {
			ReferenceBinding roleOuter = role.enclosingType();
			if (!roleOuter.isRole())
				return false;
			if (!outerRole.roleModel.hasTSuperRole(roleOuter))
				return false;
			return CharOperation.equals(role.internalName(), this._binding.internalName());
		}
		return false;
	}

	@Override
	public void setBinding (ReferenceBinding binding) {
        this._binding = binding;
        binding.roleModel = this;
    }

    // -------------- local types -----------------

    /**
     * An binary local type was requested during resolve.
     * Maybe fix enclosingType and enter to _localTypes.
     *
     * @param local
     */
    public void addBinaryLocalType (ReferenceBinding local) {
		if (local instanceof BinaryTypeBinding) {
			((BinaryTypeBinding)local).setEnclosingOfRoleLocal(this._binding);
		}
		this._localTypes.add(local.roleModel);
    }

    /**
     * A local type was read from source code.
     * Record it as part (though not member) of this role.
     * @param local
     */
    public void addLocalType (char[] constantPoolName, RoleModel local) {
    	this._localTypes.add(local);
    	local._isLocalType = true;
    	if (constantPoolName != null) {
    		if (this._ast != null) {
    			Scope scope = this._ast.scope;
    			if (scope != null) {
    				CompilationUnitScope cuScope = scope.compilationUnitScope();
    				cuScope.registerLocalType(constantPoolName, local.getAst());
    			}
    		}
    	}
    	if (this._attributes != null)
    		for (AbstractAttribute attribute : this._attributes)
    			if (attribute.nameEquals(IOTConstants.ROLE_LOCAL_TYPES))
    				return;
    	addAttribute(new RoleLocalTypesAttribute(this));
    }

    /**
     * The method at [sourceStart-sourceEnd] was found to have errors.
     * Purge all recorded local types contained in that method (based on source positions).
     * @param sourceStart
     * @param sourceEnd
     */
	public void purgeLocalTypes(int sourceStart, int sourceEnd) {
		Iterator<RoleModel> iterator = this._localTypes.iterator();
		while (iterator.hasNext()) {
			RoleModel role = iterator.next();
			TypeDeclaration ast = role.getAst();
			if (ast != null && sourceStart < ast.sourceStart && ast.declarationSourceEnd < sourceEnd) {
				iterator.remove();
			}
		}
	}

	public void maybeAddLocalToEnclosing() {
		ReferenceBinding enclosing= this._binding.enclosingType();
		if (enclosing != null && enclosing.isRole()) {
			enclosing.roleModel.addBinaryLocalType(this._binding);
		}
	}
    /**
     * Get source type bindings for all local types ready to
     * write the RoleLocalTypesAttribute.
     *
     * @return a new non-null array
     */
    public ReferenceBinding[] getLocalTypes() {
    	ReferenceBinding[] types = new ReferenceBinding[this._localTypes.size()];
    	int j = 0;
    	for (int i=0; i<types.length; i++) {
    		types[j] = this._localTypes.get(i).getBinding();
    		if (types[j] != null)
    			j++;
    	}
    	if (j != types.length)
        	System.arraycopy(types, 0,
        					 types = new ReferenceBinding[j], 0,
							 j);
   		return types;
    }

    /**
     * Get role models of all recorded local types of this role.
     * Resolve these types if needed.
     */
	public Iterator<RoleModel> localTypes() {
		return this._localTypes.iterator();
	}

	/**
	 * Find a type by  its compound name.
	 * First look in local types (including enclosing roles).
	 * Second use the environment for lookup.
	 * This method is needed since local types are not stored in the environment.
	 *
	 * @param environment
	 * @param compoundName
	 * @return type specified by compoundName
	 */
	@Override
	public ReferenceBinding findType(LookupEnvironment environment, char[][] compoundName)
	{
		char[][] myName = CharOperation.splitOn('/', this._binding.constantPoolName());
		if (   this._binding.isLocalType()
			&& CharOperation.equals(compoundName, myName))
			return this._binding;
		Iterator<RoleModel> locals = localTypes();
		while (locals.hasNext()) {
			RoleModel role = locals.next();
			char[][] roleName = CharOperation.splitOn('/', role.getBinding().constantPoolName());
			if (CharOperation.equals(compoundName, roleName))
				return role.getBinding();
		}
		if (this._binding.enclosingType().isRole())
			return this._binding.enclosingType().roleModel.findType(environment, compoundName);
		return environment.getType(compoundName);
	}

	/**
	 * Similar to the above, but comparison is made be relative names, ie., team names
	 * as prefix are chopped of. Instead of an environment the scope of this role is used.
	 *
	 * @param compoundName
	 * @return type as specified by compoundName
	 */
	public ReferenceBinding findTypeRelative(char[] compoundName)
	{
		ReferenceBinding teamBinding = TeamModel.getEnclosingTeam(this._binding);
		if (this._binding.isLocalType())
		{
			if (TypeAnalyzer.equalRoleLocal(teamBinding, this._binding, compoundName))
				return this._binding;
		} else {
			if (CharOperation.equals(this._binding.internalName(), compoundName))
				return this._binding;
		}
		Iterator<RoleModel> locals = localTypes();
		while (locals.hasNext())
		{
			RoleModel role = locals.next();
			if (TypeAnalyzer.equalRoleLocal(teamBinding, role.getBinding(), compoundName))
				return role.getBinding();
		}
		if (this._binding.enclosingType().isRole())
			return this._binding.enclosingType().roleModel.findTypeRelative(compoundName);
		if (this._ast != null)
			return (ReferenceBinding)this._ast.scope.getType(compoundName);
		return null;
	}

	private boolean hasCheckedBaseclass= false; // caching the result the below method
	private boolean isBound; // --"--
	/**
	 * @return is this role bound to a base type?
	 */
    public boolean isBound() {
    	if (this.hasCheckedBaseclass)
    		return this.isBound;
    	this.hasCheckedBaseclass= true;
    	if (   this._ast != null
    		&& this._ast.baseclass != null)
    		return this.isBound= true;
        if (this._binding != null) {
            if (this._binding.rawBaseclass() != null)
            	return this.isBound= true;
            ReferenceBinding superRole = this._binding.superclass();
			if (   superRole != null
            	&& superRole.isRole()
            	&& superRole.roleModel.isBound())
				return this.isBound= true;
        }
        for (int i=0; i<this.numTSuperRoles; i++) {
        	if (this._tsuperRoleBindings[i].roleModel.isBound())
        		return this.isBound= true;
        }
        return this.isBound= false;
    }

    public boolean hasBaseclassProblem() {
    	if ((this.tagBits & BaseclassHasProblems) != 0)
    		return true;
    	ReferenceBinding binding = (this._classBinding != null) ? this._classBinding : this._binding;
    	if (binding.superclass() != null) {
    		ReferenceBinding superclass = binding.superclass();
    		if (   (   superclass.isRole()
    				&& superclass.isHierarchyInconsistent())
    			|| (   (superclass.roleModel != null)
    		        && (superclass.roleModel.hasBaseclassProblem())))
    		{
    			this.tagBits |= BaseclassHasProblems;
    			return true;
    		}
    	}
    	return false;
    }

    public static boolean isRoleWithBaseProblem(TypeDeclaration declaration) {
        if (!declaration.isSourceRole())
            return false;
        return declaration.getRoleModel().hasBaseclassProblem();
    }

    public ReferenceBinding getBaseTypeBinding() {
        return this._binding.baseclass();
    }

    /**
     * Is current a direct supertype of model?
     * Considers superClass and superInterfaces
     */
    public boolean isSuperTypeOf(RoleModel model) {
        if (this._binding.isSuperclassOf(model.getBinding()))
            return true;
        ReferenceBinding[] superInterfaces =
        	(model.getInterfacePartBinding() != null) ?
                model.getInterfacePartBinding().superInterfaces():
        		model.getClassPartBinding().superInterfaces();
        if (superInterfaces != null)
        {
            for (int i=0; i<superInterfaces.length; i++) {
                if (TypeBinding.equalsEquals(superInterfaces[i], this._binding))
                    return true;
            }
        }
        return false;
    }

	public RoleModel getExplicitSuperRole()
	{
		ReferenceBinding superClass = this._binding.superclass();
		if(superClass.superclass() == null)
		{
			//superClass is java.lang.Object
			return null;
		}
		return this._binding.superclass().roleModel;
	}

	public RoleModel getImplicitSuperRole()
	{
		if(getTSuperRoleBinding() == null)
		{
			return null;
		}
		return getTSuperRoleBinding().roleModel;
	}


	/**
	 * Give the most general role type on the path between this role
	 * and it's tsub version which is visible in 'scope'.
	 * @pre startRole.baseclass() != null
	 * @return non-null
	 */
	public static ReferenceBinding getTopmostBoundRole(BlockScope scope, ReferenceBinding startRole) {
		ReferenceBinding current = startRole;
		ReferenceBinding candidate = null;
		while (current != null) {
			if (!current.isRole())
				return candidate;
			if (current.baseclass() != null) // true at least in first iteration.
				candidate = current;
			else
				return candidate;
			current = current.roleModel.getTSuperRoleBinding();
		}
		return candidate;
	}

	public RoleModel getCopyInheritanceSource() {
		if (!isPurelyCopied())
			return this;
		for (int i = 0; i < this._tsuperRoleBindings.length; i++) {
			if (this._tsuperRoleBindings[i] != null) {
				RoleModel model = this._tsuperRoleBindings[i].roleModel.getCopyInheritanceSource();
				if (model != null)
					return model;
			}
		}
		throw new InternalCompilerError("Unable to find real tsuper role of phantom role "+this);
	}

	/**
	 * Store the known sub roles (including this) as determined by RoleHierarchyAnalyzer.analyze().
	 *
	 * @param subRoles
	 */
	public void setSubRoles(RoleModel[] subRoles) {
		this._subRoles = subRoles;
	}

	/**
	 * Retrieve the known sub roles (including this) as determined by RoleHierarchyAnalyzer.analyze().
	 */
	public RoleModel[] getSubRoles() {
		return this._subRoles;
	}


    RoleModel getSuperIfcRole(int idx) {
        if (getInterfacePartBinding().superInterfaces() == null)
            return null;
        if (getInterfacePartBinding().superInterfaces().length <= idx)
            return null;
        ReferenceBinding ifc = getInterfacePartBinding().superInterfaces()[idx];
        if (ifc.isSourceRole())
            return ifc.roleModel;
        return null;
    }

    int getNumSuperIfc () {
        if (this._binding.superInterfaces() == null)
            return 0;
        return this._binding.superInterfaces().length;
    }

    public boolean isSynthInterface() {
        int AccSynthIfc = AccInterface|AccSynthetic;
        return (this._binding.modifiers & AccSynthIfc) == AccSynthIfc;
    }


    public boolean isRegularInterface() {
        return this._binding.isRegularInterface();
    }

    public boolean equals(RoleModel other) {
    	if (other == null) return false;
    	if (this._interfaceBinding != null && other._interfaceBinding != null)
    		return TypeBinding.equalsEquals(this._interfaceBinding, other._interfaceBinding);
    	if (this._classBinding != null && other._classBinding != null)
    		return TypeBinding.equalsEquals(this._classBinding, other._classBinding);
    	return this._ast == other._ast;
    }
    /**
     * Record the interface part of a copied role.
     * @param roleIfcs map of interface indexed by name (String)
     */
    public void recordIfcPart(HashMap<String,TypeDeclaration> roleIfcs) {
        if (this._interfacePart == null) {
        	// defensively search the interface part's name:
            String ifcName = null;
            if (this._binding != null)
            	ifcName = new String(this._binding.sourceName());
            else if (this._ast != null) {
            	if (RoleSplitter.isClassPartName(this._ast.name))
            		ifcName = new String(RoleSplitter.getInterfacePartName(this._ast.name));
            }
            // on incredibly broken code, ifcName may still be null (see TPX-423).
            if (ifcName != null) {
            	this._interfacePart = roleIfcs.get(ifcName);
            	checkClassAndIfcParts();
            } else {
            	assert this._ast == null || this._ast.ignoreFurtherInvestigation : "should only ever happen one erroneous code"; //$NON-NLS-1$
            }
        }

    }

    public void checkClassAndIfcParts() {
    	boolean hasError = false;
    	Scope scope = null;
    	char[] ifcName = null;
    	char[] className = null;
		if (this._interfacePart != null && this._classPart != null) {
			scope = this._classPart.scope;
			ifcName = this._interfacePart.name;
			className = this._classPart.name;
			if (this._interfacePart.enclosingType != this._classPart.enclosingType)
				hasError = true;
		}
		if (this._interfaceBinding != null && this._classBinding != null) {
			// binding names contain more information:
			ifcName = this._interfaceBinding.readableName();
			className = this._classBinding.readableName();
			if (TypeBinding.notEquals(this._interfaceBinding.enclosingType(), this._classBinding.enclosingType()))
				hasError = true;
		}
		if (hasError) {
			if (scope == null)
				if (this._ast != null)
					scope = this._ast.scope;
			if (scope == null)
				throw new InternalCompilerError("Multiple errors processing role "+toString()); //$NON-NLS-1$
			scope.problemReporter().inconsistentlyResolvedRole(this._ast, ifcName, className);
		}
	}

	/**
     * Once team and tsuper role are known, record this information.
     */
    public void connect(TeamModel teamModel, ReferenceBinding tsuperRole) {
        setTeamModel(teamModel);
        ReferenceBinding superTeamBinding = teamModel.getBinding().superclass();
        if (superTeamBinding instanceof ParameterizedTypeBinding && !(tsuperRole instanceof ParameterizedTypeBinding)) {
        	LookupEnvironment env = Config.getLookupEnvironment();
        	if (env != null) {
        		tsuperRole = env.createParameterizedType(tsuperRole, null, superTeamBinding);
        		RoleModel.setTagBit(tsuperRole, RoleModel.IsViewedAsTSuper);
        	}
        }
        boolean tsuperAlreadyPresent = false;
        for (int i = 0; i < this.numTSuperRoles; i++) {
			if (TypeBinding.equalsEquals(this._tsuperRoleBindings[i], tsuperRole)) {
				tsuperAlreadyPresent = true;
				break;
			}
		}
        if (!tsuperAlreadyPresent) {
	        if (this.numTSuperRoles == this._tsuperRoleBindings.length)
	        	System.arraycopy(
	        			this._tsuperRoleBindings, 0,
	        			this._tsuperRoleBindings = new ReferenceBinding[2*this.numTSuperRoles], 0,
						this.numTSuperRoles);
	        this._tsuperRoleBindings[this.numTSuperRoles++] = tsuperRole;
	        if (getAst() != null && getAst().isInterface())
	        	TypeLevel.addImplicitInheritance(getAst(), tsuperRole);
	        int otClassFlags = IOTConstants.OT_CLASS_FLAG_HAS_TSUPER;
	        if (tsuperRole.roleModel.hasFinalFieldInit())
	        	otClassFlags |= IOTConstants.OT_CLASS_HAS_FINAL_FIELD_INITS;
			WordValueAttribute.addClassFlags(this, otClassFlags);
	        if (this._binding != null)
	        	this._binding.modifiers |= AccOverridingRole;
        }
    	// invoked from copy role we have at least this state:
        this._state.inititalize(ITranslationStates.STATE_ROLES_SPLIT);
    }

    public boolean hasFinalFieldInit() {
    	AbstractAttribute attribute = getAttribute(IOTConstants.OT_CLASS_FLAGS);
    	if (attribute instanceof WordValueAttribute) {
    		if ((((WordValueAttribute) attribute).getValue() & IOTConstants.OT_CLASS_HAS_FINAL_FIELD_INITS) != 0)
    			return true;
    	}
    	if (this._classPart != null && this._classPart.fields != null) {
    		for (FieldDeclaration field : this._classPart.fields) {
				if (field.initialization != null && field.isFinal())
					return true;
			}
    	}
    	return false;
    }

    @Override
	protected String getKindString() {
        return "Role"; //$NON-NLS-1$
    }

	/**
	 * @param srcMethod
	 * @param dstMethod
	 */
	public void addSyntheticMethodMapping(MethodBinding srcMethod, MethodBinding dstMethod) {
		this._syntheticMap.put(srcMethod, dstMethod);
	}

	public MethodBinding mapSyntheticMethod (MethodBinding srcMethod) {
		if (srcMethod instanceof SyntheticRoleFieldAccess) {
			// matching by name
			ReferenceBinding dstType = getBinding();
			if (dstType.isBinaryBinding())
				return null; // will be found within methods
			SyntheticMethodBinding[] synthetics = ((SourceTypeBinding)dstType).syntheticMethods();
			if (synthetics == null)
				return null;
			for (SyntheticMethodBinding methodBinding : synthetics) {
				if (CharOperation.equals(methodBinding.selector, srcMethod.selector))
					return methodBinding;
			}
			return null;
		} else {
			// matching by map
			return (MethodBinding)this._syntheticMap.get(srcMethod);
		}
	}

	/**
	 * @param srcField a synthetic field from tsuper
	 * @param newField the synthetic new field copy
	 */
	public void addSyntheticFieldMapping(FieldBinding srcField, FieldBinding newField) {
		this._syntheticMap.put(srcField, newField);
	}

	public FieldBinding mapSyntheticField(FieldBinding srcField) {
		return (FieldBinding)this._syntheticMap.get(srcField);
	}

	/**
     * Record that the given method is only accessible using decapsulation.
	 * @param binding
	 */
	public int addInaccessibleBaseMethod(MethodBinding binding) {
		// push out to the team to ensure early evaluation by the OTRE:
		OTSpecialAccessAttribute specialAccess = getTeamModel().getSpecialAccessAttribute();
		ReferenceBinding declaringClass = binding.declaringClass;
		specialAccess.addAdaptedBaseClass(declaringClass);
		ReferenceBinding baseclass = this._binding.baseclass();
		boolean visibleInBaseClass = true;
		if (getWeavingScheme() == WeavingScheme.OTDRE) {
			TypeBinding declaringOriginal = declaringClass.original();
			if (binding.isPrivate()) {
				visibleInBaseClass = TypeBinding.equalsEquals(baseclass.original(), declaringOriginal);
			} else if (binding.isDefault()) {
				PackageBinding tgtPackage = declaringClass.fPackage;
				ReferenceBinding currentType = baseclass;
				while (currentType != null && TypeBinding.notEquals(currentType.original(), declaringOriginal)) {
					if (tgtPackage != currentType.fPackage) {
						visibleInBaseClass = false;
						break;
					}
					currentType = currentType.superclass();
				}
			}
		}
		return specialAccess.addDecapsulatedMethodAccess(baseclass, binding, visibleInBaseClass);
	}

	/**
	 * Record that a given field is accessed using callout.
	 * @param field
	 * @param calloutModifier either TokenNameget or TokenNameset (from TerminalTokens).
	 * @return the accessId (per team) for this field
	 */
	public int addAccessedBaseField(FieldBinding field, int calloutModifier, CalloutToFieldDesc cpInheritanceSrc) {
		// find appropriate target class
		ReferenceBinding targetClass = field.declaringClass; // default: the class declaring the field (could be super of bound base)
		if (!field.isStatic() && (field.isProtected() || field.isPublic()))
			targetClass = getBaseTypeBinding();	// use the specific declared bound class (avoids weaving into possibly inaccessible super base)

		// push out to the team to ensure early evaluation by the OTRE:
		OTSpecialAccessAttribute specialAccess = getTeamModel().getSpecialAccessAttribute();
		int accessId = specialAccess.addCalloutFieldAccess(field, targetClass, calloutModifier, cpInheritanceSrc);
		specialAccess.addAdaptedBaseClass(field.declaringClass);
		return accessId;
	}

	/**
	 * Record that a base call needs access to the base.super-method.
	 * @param baseMethod
	 */
	public void addMethodSuperAccess(MethodBinding baseMethod) {
		OTSpecialAccessAttribute specialAccess = getTeamModel().getSpecialAccessAttribute();
		specialAccess.addSuperMethodAccess(baseMethod);
	}

	/**
	 * Record that an inaccessible base is bound.
	 * @param baseclass
	 */
	public void markBaseClassDecapsulation(ReferenceBinding baseclass) {
		// push out to the team to ensure early evaluation by the OTRE:
		OTSpecialAccessAttribute specialAccess = getTeamModel().getSpecialAccessAttribute();
		specialAccess.addBaseClassDecapsulation(baseclass);
	}

	/** Hook into attribute writing in order to insert callout mappings attribute. */
    @Override
	public int writeAttributes(ClassFile file) {
    	if (this._binding.callinCallouts != null) {
    		for (int i = 0; i < this._binding.callinCallouts.length; i++) {
				if (this._binding.callinCallouts[i].type != CallinCalloutBinding.CALLIN) // callout or -override
				{
					addAttribute(new CalloutMappingsAttribute(this));
					break;
				}
			}
    	}
    	return super.writeAttributes(file);
    }

	@Override
	public CPTypeAnchorAttribute getTypeAnchors() {
		return this._binding.model.getTypeAnchors();
	}

	public void setErrorFlag(boolean flag) {
		if (this._ast != null)
			this._ast.ignoreFurtherInvestigation = flag;
		if (this._classPart != null)
			this._classPart.ignoreFurtherInvestigation = flag;
		if (this._interfacePart != null)
			this._interfacePart.ignoreFurtherInvestigation = flag;
	}

	public void recordCopiedFeature(Binding feature) {
		this._copiedFeatureBindings.add(feature);
	}
	public boolean hasAlreadyBeenCopied(Binding feature) {
		return this._copiedFeatureBindings.contains(feature);
	}

	/** The Attributename of this role's baseclass as it is used in bytecode attributes.
	 *  PRE: this is a bound role.
	 *  @param includeAnchor should anchored types be encoded in full?
	 */
	public char[] getBaseclassAttributename(boolean includeAnchor) {
		ReferenceBinding baseclass = getBinding().baseclass();
		char[] baseName = baseclass.getRealClass().attributeName();
		if (includeAnchor && RoleTypeBinding.isRoleWithExplicitAnchor(baseclass))
			return CharOperation.concat(baseName,
				   CharOperation.concat(SingleValueAttribute.ANCHOR_DELIM,
				   CharOperation.append(((RoleTypeBinding)baseclass)._teamAnchor.getBestName(), '>')));
		return baseName;
	}

	/* (non-Javadoc)
     * @see org.eclipse.objectteams.otdt.internal.core.compiler.model.TypeModel#cleanup()
     */
    @Override
	public void cleanup()
    {
        super.cleanup();
        this._copiedFeatureBindings = null;
    }

	public RoleModel getBoundRootRole() {
		if (this._boundRootRole != null)
			return this._boundRootRole;
		if (this._binding.isInterface() && this._classBinding != null)
		{
			RoleModel classPart = this._classBinding.roleModel;
			return classPart.getBoundRootRole();
		}
		return null;
	}

	public static int getDeclaredModifiers(ReferenceBinding typeBinding) {
		if (!typeBinding.isRole() || typeBinding.roleModel == null)
			return typeBinding.modifiers;
		ReferenceBinding classPartBinding = typeBinding.roleModel.getClassPartBinding();
		if (classPartBinding != null)
			return classPartBinding.modifiers;
		return typeBinding.modifiers;
	}

	public static boolean isRoleFromOuterEnclosing(SourceTypeBinding sourceType,
												   ReferenceBinding baseclass)
	{
		ReferenceBinding enclosingTeam = sourceType.enclosingType();
		if (enclosingTeam == null || !enclosingTeam.isTeam())
			return false;
		if (TypeBinding.equalsEquals(enclosingTeam, baseclass.enclosingType()))
			return false;
		while (true) {
			enclosingTeam = enclosingTeam.enclosingType();
			if (enclosingTeam == null || !enclosingTeam.isTeam())
				return false;
			if (TypeBinding.equalsEquals(enclosingTeam, baseclass.enclosingType()))
				return true;
		}
	}

	public boolean hasCallins() {
		if (this._attributes == null)
			return false;
		for (AbstractAttribute attribute : this._attributes)
			if (attribute.nameEquals(IOTConstants.CALLIN_METHOD_MAPPINGS)) {
				// don't report if all callins are inherited:
				if (!((CallinMethodMappingsAttribute)attribute).isInherited())
					return true;
			}

		return false;
	}

	/**
	 * After attributes are evaluated, each role class must check, whether it is
	 * supposed to implement method mappings inherited from a super interface.
	 */
	public void implementMethodBindingsFromSuperinterfaces() {
		if (this._ast == null || this._ast.isInterface() || this._binding == null || this._binding.isLocalType())
			return;
		ReferenceBinding interfacePartBinding = getInterfacePartBinding();
		if (interfacePartBinding == null) // paranoia
			return;
		ReferenceBinding[] superInterfaces = interfacePartBinding.superInterfaces();
		if (superInterfaces == null) // paranoia (null seen in real life)
			return;
		for (ReferenceBinding superInterface : superInterfaces)
		{
			if (!superInterface.isRole())
				continue;
			if (superInterface.roleModel.getState() < ITranslationStates.STATE_LATE_ATTRIBUTES_EVALUATED-1)
				continue; // not yet prepared
			if (!Dependencies.ensureBindingState(superInterface, ITranslationStates.STATE_LATE_ATTRIBUTES_EVALUATED))
				continue;
			CallinCalloutBinding[] methodMappings = superInterface.callinCallouts;
			if (methodMappings != null)
				for (CallinCalloutBinding mapping : methodMappings)
					if (mapping.isValidBinding() && mapping.isCallout())
						new CalloutImplementor(this).generateFromBinding(mapping);
		}
	}

	@Override
	public void evaluateLateAttributes(int state) {
		if (state == ITranslationStates.STATE_LATE_ATTRIBUTES_EVALUATED) {
			for (ReferenceBinding tsuperRole : this.getTSuperRoleBindings())
				Dependencies.ensureBindingState(tsuperRole, ITranslationStates.STATE_LATE_ATTRIBUTES_EVALUATED);
		}
		if (this._ast != null)
			CopyInheritance.copyGeneratedFeatures(this);
		super.evaluateLateAttributes(state);
	}

	public synchronized void releaseClassFile() {
		this._classFile= null;
	}

	/**
	 * Starting with this role look for subtypes that are bound, returning all top-bound roles.
	 * @return non-null
	 */
	public ReferenceBinding[] getBoundDescendants() {
		if (this._binding == null)
			return new ReferenceBinding[0];
		if (this._binding.baseclass() != null)
			return new ReferenceBinding[]{this._binding};

		ArrayList<ReferenceBinding> roles = new ArrayList<ReferenceBinding>();
		for (ReferenceBinding knownRole: getTeamModel().getKnownRoles()) {
			if (knownRole.baseclass() == null) 				continue; // not bound
			if (!knownRole.isCompatibleWith(this._binding)) continue; // not compatible
			if (knownRole.superclass().baseclass() != null) continue; // not top
			if (knownRole.isClass()) 						continue; // only record ifc to avoid dupes
			roles.add(knownRole);
		}
		return roles.toArray(new ReferenceBinding[roles.size()]);
	}

	/** recored here any unimplemented getBase method:
	 *    <_OT$AnyBase base R> _OT$getBase() { throw new AbstractMethodError(); }
	 */
	public MethodBinding unimplementedGetBase;
	/**
	 * If an unbound super role exists return its unimplemented getBase method.
	 */
	public MethodBinding getInheritedUnimplementedGetBase() {
		ReferenceBinding classPartBinding = getClassPartBinding();
		if (classPartBinding != null) {
			ReferenceBinding superclass = classPartBinding.superclass();
			while (superclass != null && superclass.isRole()) {
				RoleModel superRole = superclass.roleModel;
				if (superRole.unimplementedGetBase != null)
					return superRole.unimplementedGetBase;
				superclass = superclass.superclass();
			}
		}
		return null;
	}

	public static Lifting.InstantiationPolicy getInstantiationPolicy(ReferenceBinding roleClassBinding) {
		if ((roleClassBinding.getAnnotationTagBits() & TagBits.AnnotationInstantiation) != 0) {
			for (AnnotationBinding annotation : roleClassBinding.getAnnotations()) {
				if (annotation.getAnnotationType().id == IOTConstants.T_OrgObjectTeamsInstantiation) {
					for (ElementValuePair pair : annotation.getElementValuePairs()) {
						if (pair.value instanceof FieldBinding) {
							String name = String.valueOf(((FieldBinding) pair.value).name);
							try {
								return InstantiationPolicy.valueOf(name);
							} catch (IllegalArgumentException iae) {
								return InstantiationPolicy.ERROR;
							}
						}
					}
				}
			}
		}
		return InstantiationPolicy.ONDEMAND; // default
	}

	public static boolean areTypeParametersOfSameRole(TypeVariableBinding one, Binding two) {
		if (!(two instanceof TypeVariableBinding))
			return false;
		Binding declaring1 = one.declaringElement;
		Binding declaring2 = ((TypeVariableBinding)two).declaringElement;
		if (   !(declaring1 instanceof ReferenceBinding)
			|| !(declaring2 instanceof ReferenceBinding))
			return false;
		return TypeBinding.equalsEquals(((ReferenceBinding)declaring1).getRealType(), ((ReferenceBinding)declaring2).getRealType());
	}

	public void markCallinOverride(char[] name, RoleModel subRole) {
		if (this._ast == null || this._ast.callinCallouts == null)
			return;
		for (AbstractMethodMappingDeclaration mapping : this._ast.callinCallouts) {
			if (mapping instanceof CallinMappingDeclaration) {
				CallinMappingDeclaration callin = (CallinMappingDeclaration) mapping;
				if (callin.hasName() && CharOperation.equals(name, callin.name)) {
					callin.isOverriddenInTeam = true;
					this._ast.scope.problemReporter().callinOverriddenInTeam(callin, subRole);
				}
			}
		}
	}
}
