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

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 |= AccOverriding;
        }
    	// 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);
				}
			}
		}
	}
}
