Additional tests & fixes re Bug 331877 -  [compiler][generics] implicit inheritance must apply substitution for type variables from outer scope
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/AbstractAttribute.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/AbstractAttribute.java
index 416ed50..a6e8afc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/AbstractAttribute.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/AbstractAttribute.java
@@ -38,6 +38,7 @@
 import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
 import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
 import org.eclipse.objectteams.otdt.internal.core.compiler.model.ModelElement;
+import org.eclipse.objectteams.otdt.internal.core.compiler.model.TypeModel;
 
 /**
  * MIGRATION_STATE: complete. 2 fixme(generic) remain.
@@ -94,7 +95,7 @@
     	return nameEquals(other._name);
     }
 
-    public void merge (ModelElement model, AbstractAttribute other) {
+    public void merge (ModelElement model, AbstractAttribute other, TypeModel superDeclaringType) {
     	throw new InternalCompilerError("Merge not supported for Attribute "+new String(this._name)); //$NON-NLS-1$
     }
 
@@ -110,7 +111,7 @@
      * API: Write this attribute to the class file.
      * Need to override in subclasses to do useful stuff.
      *
-     * @param file class file structure to write to.
+     * @param classFile class file structure to write to.
      */
     public void write(ClassFile classFile) {
         this._contents       = classFile.contents;
@@ -120,7 +121,7 @@
 
     /** Write the attribute into an allocated array of bytes. */
     public void generate(byte[] target, int offset, ConstantPool constantPool) {
-    	ClassFile dummyClass = new ClassFile() {};
+    	ClassFile dummyClass = new ClassFile() { /* empty body */};
     	dummyClass.contents = target;
     	dummyClass.contentsOffset = offset;
     	dummyClass.constantPool = constantPool;
@@ -294,7 +295,7 @@
      * @param fieldBinding
      * @return true if attribute actually matched and was processed.
      */
-    public boolean evaluate(FieldBinding binding) {
+    public boolean evaluate(FieldBinding fieldBinding) {
         // NOOP. Override to do useful things.
         return false;
     }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/CallinMethodMappingsAttribute.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/CallinMethodMappingsAttribute.java
index 187a2a6..608f51d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/CallinMethodMappingsAttribute.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/CallinMethodMappingsAttribute.java
@@ -33,6 +33,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
@@ -45,6 +46,7 @@
 import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.CallinCalloutBinding;
 import org.eclipse.objectteams.otdt.internal.core.compiler.model.ModelElement;
+import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel;
 import org.eclipse.objectteams.otdt.internal.core.compiler.model.TypeModel;
 
 /**
@@ -147,8 +149,8 @@
 
 	    /** Compute the name of the file containing the given callin mapping.
 	     *  Do consider packages but no projects or source folders.
-	     * @param decl
-	     * @return
+	     * @param decl the declaration who's declaring file is being requested
+	     * @return non-null source-folder relative file name
 	     */
 	    private char[] getFileName(CallinMappingDeclaration decl) {
 			CompilationUnitDeclaration compilationUnit = decl.scope.referenceCompilationUnit();
@@ -330,10 +332,9 @@
     /**
      * Read the attribute from byte code.
      *
-	 * @param info
-	 * @param readOffset
-	 * @param structOffset
-	 * @param constantPoolOffsets
+	 * @param reader				this reader holds the bytes to read
+	 * @param readOffset			offset where to start reading
+	 * @param constantPoolOffsets	constant pool offset to be used during reading 
 	 */
 	public CallinMethodMappingsAttribute(ClassFileStruct reader, int readOffset, int[] constantPoolOffsets) {
 		super(IOTConstants.CALLIN_METHOD_MAPPINGS);
@@ -348,7 +349,8 @@
 			this._mappings[i] = readMapping();
 	}
 
-	public void merge(ModelElement model, AbstractAttribute other)
+	@Override
+	public void merge(ModelElement model, AbstractAttribute other, TypeModel superDeclaringType)
 	{
 		assert other instanceof CallinMethodMappingsAttribute;
 		assert model instanceof TypeModel;
@@ -368,7 +370,7 @@
 			set.put(new String(mapping._mappingName), mapping.cloneForSubrole());
 			this._size += mapping.getSize();
 
-			newBindings.add(createBinding(typeBinding, mapping));
+			newBindings.add(createBinding(typeBinding, mapping, superDeclaringType));
 		}
 
 		// store combined array:
@@ -484,7 +486,7 @@
     		return;
     	CallinCalloutBinding[] callins = new CallinCalloutBinding[this._mappings.length];
     	for (int i = 0; i < this._mappings.length; i++) {
-			callins[i] = createBinding(roleBinding, this._mappings[i]);
+			callins[i] = createBinding(roleBinding, this._mappings[i], null);
 		}
     	if (callins.length > 0)
     		roleBinding.addCallinCallouts(callins);
@@ -492,10 +494,12 @@
 
     /**
 	 * @param roleBinding
-	 * @param mapping
+     * @param mapping
+     * @param superDeclaringType model of the (t)super type (role/team) that originally declared the method mapping,
+     * 			can be null to signal that the binding is not being copy-inherited.
 	 * @throws InternalCompilerError
 	 */
-	private CallinCalloutBinding createBinding(ReferenceBinding roleBinding, Mapping mapping)
+	private CallinCalloutBinding createBinding(ReferenceBinding roleBinding, Mapping mapping, TypeModel superDeclaringType)
 	{
 		CallinCalloutBinding result = null;
 		CallinCalloutBinding[] callinCallouts = roleBinding.callinCallouts;
@@ -519,6 +523,10 @@
 
 		ReferenceBinding currentType = roleBinding;
 		char[] roleSignature = mapping._roleSignature;
+		// generics:
+		ReferenceBinding tsuperRoleBinding = findTSuperTypeFromModel(roleBinding.roleModel, superDeclaringType.getBinding());
+		if (tsuperRoleBinding.isParameterizedType())
+			roleSignature = superDeclaringType.substituteSignature((ParameterizedTypeBinding)tsuperRoleBinding, mapping._roleSelector, roleSignature);
 		if (result.callinModifier == TerminalTokens.TokenNamereplace) {
 			// ignore generalized return by truncating the signature:
 			int closePos = CharOperation.indexOf(')', roleSignature);
@@ -570,6 +578,16 @@
 		return result;
 	}
 
+	private ReferenceBinding findTSuperTypeFromModel(RoleModel model, ReferenceBinding roleBinding) {
+		if (roleBinding == null)
+			return null;
+		for (ReferenceBinding tsuperBinding : model.getTSuperRoleBindings()) {
+			if (tsuperBinding.erasure() == roleBinding)
+				return tsuperBinding;
+		}
+		return null;
+	}
+
 	private CallinCalloutBinding findTSuperBinding(char[] name, ReferenceBinding roleType) {
 		ReferenceBinding[] tsuperRoles = roleType.roleModel.getTSuperRoleBindings();
 		for (int i = tsuperRoles.length-1; i >= 0; i--) { // check highest prio first (which comes last in the array)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/StaticReplaceBindingsAttribute.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/StaticReplaceBindingsAttribute.java
index 3ca083d..a19ff58 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/StaticReplaceBindingsAttribute.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/StaticReplaceBindingsAttribute.java
@@ -233,10 +233,9 @@
 	/**
      * Read the attribute from byte code.
      *
-	 * @param info
-	 * @param readOffset
-	 * @param structOffset
-	 * @param constantPoolOffsets
+	 * @param reader				this reader holds the bytes to read
+	 * @param readOffset			offset where to start reading
+	 * @param constantPoolOffsets	constant pool offset to be used during reading 
 	 */
 	public StaticReplaceBindingsAttribute(ClassFileStruct reader, int readOffset, int[] constantPoolOffsets) {
 		super(IOTConstants.STATIC_REPLACE_BINDINGS);
@@ -254,10 +253,10 @@
 	/**
 	 * Merge two attributes encoding method mappings from different roles of the same team.
 	 */
-	public void merge(ModelElement model, AbstractAttribute other)
+	public void merge(ModelElement model, AbstractAttribute superDeclaringType, ModelElement otherModel)
 	{
-		assert other instanceof StaticReplaceBindingsAttribute;
-		StaticReplaceBindingsAttribute otherSRBA = (StaticReplaceBindingsAttribute)other;
+		assert superDeclaringType instanceof StaticReplaceBindingsAttribute;
+		StaticReplaceBindingsAttribute otherSRBA = (StaticReplaceBindingsAttribute)superDeclaringType;
 
 		if (otherSRBA._mappings != null) {
 			// adding translated mappings
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementor.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementor.java
index 012a34e..5b0a492 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementor.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementor.java
@@ -165,7 +165,7 @@
         if (staticReplaces.size() > 0) {
         	CallinMappingDeclaration[] callins = new CallinMappingDeclaration[staticReplaces.size()];
         	staticReplaces.toArray(callins);
-        	this._role.getTeamModel().addOrMergeAttribute(new StaticReplaceBindingsAttribute(callins));
+        	this._role.getTeamModel().addOrMergeAttribute(new StaticReplaceBindingsAttribute(callins), null);
         }
 		return result;
 
@@ -533,12 +533,18 @@
 				receiver = gen.singleNameReference(ROLE_VAR_NAME);
 				needRoleVar = true;
 	
-				// private receiver needs to be casted to the class.
+				// receiver for private method (doesn't exist in ifc-part) needs to be casted to the class.
+				// Scope.findMethod() takes care of visibility if isMethodMappingWrapper() is detected.
 				if (roleMethodBinding.isPrivate())
 					receiver = gen.castExpression(
 										receiver,
 							            gen.typeReference(roleModel.getClassPartBinding()),
-										CastExpression.RAW);
+										CastExpression.NEED_CLASS);
+					// Note on using NEED_CLASS above:
+					// even if role is ParameterizedTypeBinding Scope.findMethod() must find a RoleTypeBinding
+					// in order to enter the branch that checks isMethodMappingWrapper()
+					// with CastExpression.RAW a RawTypeBinding might occur that is not recognized by Scope.findMethod()
+					// see testA12_genericRoleFeature16f() which reports bogus visibility problem is RAW is used.
 			}
 	
 			//MyRole _OT$role = _OT$liftToMyRole(_OT$base_arg);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/MethodModel.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/MethodModel.java
index 80e02df..810d9b9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/MethodModel.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/MethodModel.java
@@ -1,7 +1,7 @@
 /**********************************************************************
  * This file is part of "Object Teams Development Tooling"-Software
  *
- * Copyright 2004, 2008 Fraunhofer Gesellschaft, Munich, Germany,
+ * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany,
  * for its Fraunhofer Institute for Computer Architecture and Software
  * Technology (FIRST), Berlin, Germany and Technical University Berlin,
  * Germany.
@@ -10,7 +10,6 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * $Id: MethodModel.java 23417 2010-02-03 20:13:55Z stephan $
  *
  * Please visit http://www.eclipse.org/objectteams for updates and contact.
  *
@@ -64,15 +63,12 @@
 /**
  * A fragment of method {@link #toString()} has been copied from 
  * {@link AbstractMethodDeclaration} of the Eclipse JDT. 
- * 
- * MIGRATION_STATE: complete.
  *
  * What: Flag abstract creation methods in non-abstract team
  * Why:  Must forbid their use.
  *       Mediates between CopyInheritance.internalCreateCreationMethod() and MessageSend.resolve().
  *
  * @author stephan
- * @version $Id: MethodModel.java 23417 2010-02-03 20:13:55Z stephan $
  */
 public class MethodModel extends ModelElement {
 
@@ -91,11 +87,20 @@
         return model;
     }
     public static MethodModel getModel(MethodBinding binding) {
-    	MethodModel model = binding.model;
+    	MethodModel model = model(binding);
     	if (model == null)
     		model = new MethodModel(binding);
     	return model;
     }
+    // access even through parameterized method but don't create:
+    private static MethodModel model(MethodBinding method) {
+    	if (method.model != null)
+    		return method.model;
+    	MethodBinding original = method.original();
+    	if (original != method)
+    		return original.model;
+    	return null;
+    }
     public void linkBinding(MethodBinding binding) {
     	this._binding = binding;
 		binding.model = this;
@@ -156,8 +161,9 @@
 	}
 
 	public static boolean isRoleMethodInheritedFromNonPublicRegular(MethodBinding current) {
-		if (current.model == null) return false;
-		return current.model.problemDetail == ProblemDetail.RoleInheritsNonPublic;
+		MethodModel model = model(current);
+		if (model == null) return false;
+		return model.problemDetail == ProblemDetail.RoleInheritsNonPublic;
 	}
 
 	// TODO(SH): note that role feature bridges are not really faked, since they are actually generated (synthetic?)
@@ -170,13 +176,15 @@
     public CalloutMappingDeclaration _inferredCallout = null;
 
 	public static boolean isFakedMethod(MethodBinding abstractMethod) {
-		if (abstractMethod.model != null)
-				return abstractMethod.model._fakeKind != FakeKind.NOT_FAKED;
+		MethodModel model = model(abstractMethod);
+		if (model != null)
+				return model._fakeKind != FakeKind.NOT_FAKED;
 		return false;
 	}
 	public static boolean isFakedMethod(MethodBinding abstractMethod, FakeKind fakeKind) {
-		if (abstractMethod.model != null)
-			return abstractMethod.model._fakeKind == fakeKind;
+		MethodModel model = model(abstractMethod);
+		if (model != null)
+			return model._fakeKind == fakeKind;
 		return false;
 	}
 	private MethodModel(AbstractMethodDeclaration decl) {
@@ -240,9 +248,10 @@
 		getModel(methodDecl).addCallinFlag(flag);
 	}
 	public static boolean hasCallinFlag(MethodBinding method, int flag) {
-		if (method.model == null)
+		MethodModel model = model(method);
+		if (model == null)
 			return false;
-		return (method.model.callinFlags & flag) == flag;
+		return (model.callinFlags & flag) == flag;
 	}
 
 	private boolean isForbiddenCreationMethod = false;
@@ -424,6 +433,9 @@
 		AbstractMethodDeclaration ast = binding.sourceMethod();
 		if (ast != null)
 			return ast.ignoreFurtherInvestigation;
+		MethodBinding original = binding.original();
+		if (original != binding)
+			return hasProblem(original);
 		return false;
 	}
 	private void setCallsBaseCtor() {
@@ -489,8 +501,9 @@
 	 * Note: don't call before analyseCode because we may need our tsupers to be analysed, too.
 	 */
 	public static boolean callsBaseCtor(MethodBinding method) {
-		if (method.model != null) {
-			if (method.model._callsBaseCtor)
+		MethodModel model = model(method);
+		if (model != null) {
+			if (model._callsBaseCtor)
 				return true;
 		}
 
@@ -517,8 +530,9 @@
 	 * @return rewritten modifiers or -1 signaling no change.
 	 */
 	public static int rewriteModifiersForBytecode(MethodBinding methodBinding) {
-		if (methodBinding.model != null)
-			return methodBinding.model.rewriteModifiersForBytecode();
+		MethodModel model = model(methodBinding);
+		if (model != null)
+			return model.rewriteModifiersForBytecode();
 		return -1;
 	}
 
@@ -542,7 +556,7 @@
 	}
 
 	public static TypeBinding getReturnType(MethodBinding method) {
-		MethodModel model = method.model;
+		MethodModel model = model(method);
 		if (model != null && model._returnType != null)
 			return model._returnType;
 
@@ -679,9 +693,10 @@
 		return false;
 	}
 	public static CalloutMappingDeclaration getImplementingInferredCallout(MethodBinding binding) {
-		if (binding.model == null)
+		MethodModel model = model(binding);
+		if (model == null)
 			return null;
-		return binding.model._inferredCallout;
+		return model._inferredCallout;
 	}
 
 	public static ReferenceBinding getRoleDeclaringThisMethodMapping(AbstractMethodDeclaration methodDecl) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/ModelElement.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/ModelElement.java
index 670ed94..afed356 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/ModelElement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/ModelElement.java
@@ -1,7 +1,7 @@
 /**********************************************************************
  * This file is part of "Object Teams Development Tooling"-Software
  *
- * Copyright 2004, 2006 Fraunhofer Gesellschaft, Munich, Germany,
+ * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany,
  * for its Fraunhofer Institute for Computer Architecture and Software
  * Technology (FIRST), Berlin, Germany and Technical University Berlin,
  * Germany.
@@ -10,7 +10,6 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * $Id: ModelElement.java 23416 2010-02-03 19:59:31Z stephan $
  *
  * Please visit http://www.eclipse.org/objectteams for updates and contact.
  *
@@ -29,10 +28,7 @@
 import org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CallinImplementor;
 
 /**
- * MIGRATION_STATE: complete.
- *
  * @author stephan
- * @version $Id: ModelElement.java 23416 2010-02-03 19:59:31Z stephan $
  */
 public class ModelElement {
     /** OT-specific bytecode attributes for this model element. */
@@ -56,7 +52,13 @@
         }
     }
 
-    public void addOrMergeAttribute (AbstractAttribute attr) {
+    /**
+     * Add an attribute possibly merging it with an existing attribute of the same kind.
+     * @param attr
+     * @param superDeclaringType if null we're defining a new attribute, if non-null superDeclaringType 
+     * 		represents the type from which the attribute is being copy-inherited
+     */
+    public void addOrMergeAttribute (AbstractAttribute attr, TypeModel superDeclaringType) {
     	AbstractAttribute existingAttr = null;
     	if (this._attributes != null) {
 	    	for (int i = 0; i < this._attributes.length; i++) {
@@ -75,7 +77,7 @@
     		addAttribute(existingAttr = new CallinMethodMappingsAttribute(new CallinMappingDeclaration[0]));
     	}
 		// this call also creates bindings from the attribute:
-    	existingAttr.merge(this, attr);
+    	existingAttr.merge(this, attr, superDeclaringType);
     	if (attr.nameEquals(IOTConstants.CALLIN_METHOD_MAPPINGS))
     		CallinImplementor.checkCopyCallinBinding((CallinMethodMappingsAttribute)attr, this);
     }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/TypeModel.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/TypeModel.java
index 73e1a6a..2eacb08 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/TypeModel.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/TypeModel.java
@@ -1,7 +1,7 @@
 /**********************************************************************
  * This file is part of "Object Teams Development Tooling"-Software
  *
- * Copyright 2004, 2006 Fraunhofer Gesellschaft, Munich, Germany,
+ * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany,
  * for its Fraunhofer Institute for Computer Architecture and Software
  * Technology (FIRST), Berlin, Germany and Technical University Berlin,
  * Germany.
@@ -10,7 +10,6 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * $Id: TypeModel.java 23416 2010-02-03 19:59:31Z stephan $
  *
  * Please visit http://www.eclipse.org/objectteams for updates and contact.
  *
@@ -36,7 +35,9 @@
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
 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.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;
@@ -56,8 +57,6 @@
 import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer;
 
 /**
- * MIGRATION_STATE: complete
- *
  * Generalizes TeamModel and RoleModel
  * @author stephan
  */
@@ -407,6 +406,24 @@
 		this._typeAnchors.addTypeAnchor(anchor, cpIndex);
 	}
 	/**
+	 * Create a method signature for a method of this type but applying a given substitution.
+	 * @param substitution type binding defining the substitution of type parameters
+	 * @param selector	   method selector, must designate a method of this type
+	 * @param signature	   method signature, together with selector must uniquely designate a method of this type 
+	 * @return	new method signature with type parameter substitutions applied
+	 */
+	public char[] substituteSignature(ParameterizedTypeBinding substitution, char[] selector, char[] signature) {
+		if (this._binding != null) {
+			for (MethodBinding method : this._binding.getMethods(selector)) {
+				if (CharOperation.equals(signature, method.signature())) {
+					MethodBinding substituteMethod = substitution.createParameterizedMethod(method);
+					return substituteMethod.genericSignature();
+				}
+			}					
+		}
+		return signature;
+	}
+	/**
 	 * Some attributes can only be evaluated after translation reaches a specific state
 	 *	at end of FAULT_IN_TYPES:
 	 *	    CallinMethodMappingAttribute, CalloutMethodMappingAttribute
@@ -490,15 +507,15 @@
 	}
 	/**
 	 * supports CALLIN_METHOD_MAPPINGS_ATTRIBUTE and STATE_REPLACE_BINDINGS_ATTRIBUTE
-	 * @param otherModel
+	 * @param superDeclaringType represents the type from which the attribute is being copied
 	 * @param attributeName
 	 */
-	public void copyAttributeFrom(TypeModel otherModel, char[] attributeName) {
-		if (otherModel._attributes == null)
+	public void copyAttributeFrom(TypeModel superDeclaringType, char[] attributeName) {
+		if (superDeclaringType._attributes == null)
 			return;
-		for (int i = 0; i < otherModel._attributes.length; i++) {
-			if (otherModel._attributes[i].nameEquals(attributeName)) {
-				addOrMergeAttribute(otherModel._attributes[i]);
+		for (int i = 0; i < superDeclaringType._attributes.length; i++) {
+			if (superDeclaringType._attributes[i].nameEquals(attributeName)) {
+				addOrMergeAttribute(superDeclaringType._attributes[i], superDeclaringType);
 				return;
 			}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/TypeLevel.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/TypeLevel.java
index c523d3c..907fee8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/TypeLevel.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/TypeLevel.java
@@ -7,7 +7,6 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * $Id: TypeLevel.java 23417 2010-02-03 20:13:55Z stephan $
  *
  * Please visit http://www.eclipse.org/objectteams for updates and contact.
  *
@@ -282,6 +281,8 @@
 				throw new InternalCompilerError("superinterface not found for " //$NON-NLS-1$
 							+new String(destRole.internalName())+": " //$NON-NLS-1$
 							+new String(srcSuperIfcs[i].readableName()));
+			if (superTeam.isParameterizedType())
+				newSuperIfc = (ReferenceBinding) Scope.substitute((ParameterizedTypeBinding)superTeam, newSuperIfc);
 			newInterfaces.add(newSuperIfc);
 			destRole.scope.compilationUnitScope().recordSuperTypeReference(newSuperIfc);
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/ReflectionGenerator.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/ReflectionGenerator.java
index 93f90b6..d971c5e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/ReflectionGenerator.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/ReflectionGenerator.java
@@ -521,7 +521,7 @@
 		return gen.ifStatement(
 					gen.instanceOfExpression(
 					    gen.singleNameReference(_OT_ROLE_ARG),
-						gen.singleTypeReference(roleType)
+						gen.typeReference(roleType)
 					),
 					gen.block(new Statement[] {
 						gen.assignment(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/RoleSplitter.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/RoleSplitter.java
index b1b0c05..65c8d66 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/RoleSplitter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/RoleSplitter.java
@@ -426,7 +426,8 @@
 		    if (superClass.isDirectRole()) {
 		        TypeDeclaration interfaceAst = role.getInterfaceAst();
 		        if (interfaceAst != null) {
-					ReferenceBinding superIfc = superClass.transferTypeArguments(superClass.getRealType());
+		        	ReferenceBinding superIfc = superClass.enclosingType().getMemberType(superClass.sourceName());
+					superIfc = superClass.transferTypeArguments(superIfc);
 					// special: linking an ifc from a custom Confined type to "Confined" from the correct team
 					// (note that in this case the superclass is actually o.o.Team$__OT__Confined!)
 					if (   !CharOperation.equals(ifcPart.internalName(), IOTConstants.CONFINED)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/SwitchOnBaseTypeGenerator.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/SwitchOnBaseTypeGenerator.java
index 29a4cc4..cef1a2d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/SwitchOnBaseTypeGenerator.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/SwitchOnBaseTypeGenerator.java
@@ -127,7 +127,7 @@
 	        } else {
 		        if (s != null) {
 			        Expression condition = gen.instanceOfExpression(gen.singleNameReference(LOCAL_BASE_NAME),
-			        												gen.baseclassReference(object.getBaseTypeBinding()));
+			        												gen.baseclassReference(object.getBaseTypeBinding(), true/*erase*/));
 					IfStatement is = gen.ifStatement(condition, s);
 			        if (prevIf == null)
 			        	stmts[1] = is;				// this is the root "if"