resolve several scoping issues in otredyn
 - use alien-scope-references where appropriate.

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
index f4ea79a..a40b21e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -24,6 +24,7 @@
 import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
+import org.eclipse.objectteams.otdt.internal.core.compiler.util.IAlienScopeTypeReference;
 import org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator;
 
 /**
@@ -195,7 +196,12 @@
 // SH}
 
 //{ObjectTeams: wrap declared type
-		variableType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(variableType, scope, this);
+		{
+			Scope typeScope = scope;
+			if (this.type instanceof IAlienScopeTypeReference)
+				typeScope = ((IAlienScopeTypeReference)this.type).getAlienScope();
+			variableType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(variableType, typeScope, this);
+		}
 // SH}
 		checkModifiers();
 		if (variableType != null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java
index f023013..e6aa417 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java
@@ -39,6 +39,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
 import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
 import org.eclipse.objectteams.otdt.core.compiler.Pair;
@@ -334,7 +335,7 @@
 					: gen.singleNameReference(CALLIN_ID);
 				
 				int callinIdCount = teamDecl.getTeamModel().getCallinIdCount();
-				boolean[] handledCallinIds = new boolean[callinIdCount];
+				boolean[] handledCallinIds = new boolean[callinIdCount]; // callinIds not handled here will be handled using a super-call.
 				// one case block per callin mapping:
 				for (CallinMappingDeclaration callinDecl : callinDecls) 
 				{
@@ -424,9 +425,19 @@
 							Expression rawArg = gen.arrayReference(gen.singleNameReference(ARGUMENTS), i);
 							Expression init = rawArg;
 							if (!baseParams[i].isTypeVariable())
-								init = gen.createCastOrUnboxing(rawArg, baseParams[i]);
-							// add to front so it is already available for the base predicate check:
-							blockStatements.add(i, gen.localVariable(baseArg.name, AstClone.copyTypeReference(baseArg.type), init));
+								init = gen.createCastOrUnboxing(rawArg, baseParams[i], callinDecl.scope);
+							if (hasBasePredicate) {
+								// add to front so it is already available for the base predicate check:
+								blockStatements.add(i, gen.localVariable(baseArg.name, AstClone.copyTypeReference(baseArg.type), init));
+							} else {
+								// otherwise give it a chance for expressions/types that depend on the role instance
+								blockStatements.add(gen.localVariable(baseArg.name,
+																	  gen.alienScopeTypeReference(baseArg.type, callinDecl.scope), 
+																	  new PotentialRoleReceiverExpression(
+																			  init,
+																			  roleVar,
+																			  gen.typeReference(roleType))));
+							}
 						}
 					}
 					
@@ -443,8 +454,16 @@
 					for (int i=0; i<roleParams.length; i++) {
 						Expression arg;
 						boolean needCast = false;
-						TypeBinding roleParam = roleParams[i].erasure(); // type vars of callin-decl and role are not in scope :(
-						needCast = roleParam != roleParams[i]; 
+						TypeBinding roleParam = roleParams[i];
+						if (roleParam.isTypeVariable()) {
+							needCast = true;
+							TypeVariableBinding tvb = (TypeVariableBinding) roleParam;
+							if (tvb.declaringElement instanceof MethodBinding) {
+								if (((MethodBinding)tvb.declaringElement).declaringClass == roleType)
+									// don't use type variable of target method, see test4140_callinReplaceCompatibility10s()
+									roleParam = roleParam.erasure();
+							}
+						}
 						if (callinDecl.mappings == null) {
 							arg = gen.arrayReference(gen.singleNameReference(ARGUMENTS), i);
 							if (roleParam.isBaseType()) {
@@ -462,9 +481,10 @@
 								arg = new PotentialRoleReceiverExpression(arg, roleVar, gen.typeReference(roleType.getRealClass()));
 						}
 		 				char[] localName = (OT_LOCAL+i).toCharArray();
+		 				TypeReference roleParamType = gen.typeReference(roleParam);
 		 				if (needCast)
-		 					arg = gen.castExpression(arg, gen.typeReference(roleParam), CastExpression.RAW);
-						blockStatements.add(gen.localVariable(localName, roleParam, arg));
+		 					arg = gen.castExpression(arg, gen.alienScopeTypeReference(roleParamType, callinDecl.scope), CastExpression.RAW);
+						blockStatements.add(gen.localVariable(localName, gen.alienScopeTypeReference(roleParamType, callinDecl.scope), arg));
 						callArgs[i+idx] = gen.singleNameReference(localName);
 
 					}
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 1ff003b..87aa991 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
@@ -20,9 +20,6 @@
 
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
-import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.TypeReference;
 import org.eclipse.jdt.internal.compiler.ast.Expression.DecapsulationState;
@@ -43,7 +40,6 @@
 import org.eclipse.objectteams.otdt.internal.core.compiler.model.TeamModel;
 import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance.CopyInheritance.SupertypeObligation;
 import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.StandardElementGenerator;
-import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstClone;
 import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstGenerator;
 import org.eclipse.objectteams.otdt.internal.core.compiler.util.Protections;
 
@@ -170,7 +166,7 @@
 			if (srcDecl.baseclass != null && destRoleDecl.baseclass == null) {
 				long pos= (((long)destRoleDecl.sourceStart)<<32)+destRoleDecl.sourceEnd;
 				// create a special type reference that uses the original scope for resolving:
-				destRoleDecl.baseclass= wrapBasetypeReference(srcDecl.baseclass, srcDecl.scope, pos);
+				destRoleDecl.baseclass= new AstGenerator(pos).alienScopeTypeReference(srcDecl.baseclass, (ClassScope) srcDecl.scope.parent);
 				destRoleDecl.baseclass.setBaseclassDecapsulation(DecapsulationState.REPORTED);
 				destRoleDecl.baseclass.bits |= ASTNode.IsGenerated;
 			}
@@ -178,32 +174,6 @@
 	}
 
 	/**
-	 * Wrap the baseclass reference from a tsuper role to a new type reference
-	 * yet using the original scope for resolving.
-	 */
-	private static TypeReference wrapBasetypeReference(
-							TypeReference original, ClassScope origScope, long pos)
-	{
-		if (original instanceof IAlienScopeTypeReference)
-			origScope = ((IAlienScopeTypeReference)original).getAlienScope();
-		if (origScope.parent.kind == Scope.CLASS_SCOPE)
-			origScope = (ClassScope)origScope.parent;
-
-		if (original instanceof ParameterizedSingleTypeReference) {
-			ParameterizedSingleTypeReference pstRef = (ParameterizedSingleTypeReference) original;
-			TypeReference[] typeArguments = AstClone.copyTypeArguments(original, pos, pstRef.typeArguments);
-			return new AlienScopeParameterizedSingleTypeReference(pstRef.token, typeArguments, pstRef.dimensions, pos, origScope);
-		} else if (original instanceof SingleTypeReference) {
-			SingleTypeReference singleTypeRef = (SingleTypeReference) original;
-			return new AlienScopeSingleTypeReference(singleTypeRef.token, pos, origScope);
-		} else if (original instanceof QualifiedTypeReference) {
-			QualifiedTypeReference qTypeRef= (QualifiedTypeReference)original;
-			return new AlienScopeQualifiedTypeReference(qTypeRef.tokens, qTypeRef.sourcePositions, origScope);
-		}
-		throw new InternalCompilerError("Unexpected base type reference: "+original); //$NON-NLS-1$
-	}
-
-	/**
 	 * Starting from the tsuper role's base class check whether implicit playedBy refinement
 	 * is involved. If so, create a weakened type to reflect the dual type of the base field.
 	 */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java
index 356c41c..2f9a2f3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java
@@ -1160,6 +1160,12 @@
 		else
 			return castExpression(expression, typeReference(expectedType), CastExpression.RAW);
 	}
+	public Expression createCastOrUnboxing(Expression expression, TypeBinding expectedType, Scope originalScope) {
+		if (expectedType.isBaseType())
+			return createUnboxing(expression, (BaseTypeBinding)expectedType);
+		else
+			return castExpression(expression, alienScopeTypeReference(typeReference(expectedType), originalScope), CastExpression.RAW);
+	}
 	
 	// ========= Method Mappings: =========
 	public CalloutMappingDeclaration calloutMappingDeclaration(
@@ -1233,4 +1239,30 @@
 		return new MarkerAnnotation(qualifiedTypeReference(compoundName), this.sourceStart);
 	}
 
+	/**
+	 * Wrap the baseclass reference from a tsuper role to a new type reference
+	 * yet using the original scope for resolving.
+	 * Also used for type references in callin wrappers
+	 */
+	public TypeReference alienScopeTypeReference(TypeReference original, Scope origScope)
+	{
+		if (original instanceof IAlienScopeTypeReference)
+			origScope = ((IAlienScopeTypeReference)original).getAlienScope();
+//		if (origScope.parent.kind == Scope.CLASS_SCOPE)
+//			origScope = (ClassScope)origScope.parent;
+	
+		if (original instanceof ParameterizedSingleTypeReference) {
+			ParameterizedSingleTypeReference pstRef = (ParameterizedSingleTypeReference) original;
+			TypeReference[] typeArguments = AstClone.copyTypeArguments(original, this.pos, pstRef.typeArguments);
+			return new AlienScopeParameterizedSingleTypeReference(pstRef.token, typeArguments, pstRef.dimensions, this.pos, origScope);
+		} else if (original instanceof SingleTypeReference) {
+			SingleTypeReference singleTypeRef = (SingleTypeReference) original;
+			return new AlienScopeSingleTypeReference(singleTypeRef.token, this.pos, origScope);
+		} else if (original instanceof QualifiedTypeReference) {
+			QualifiedTypeReference qTypeRef= (QualifiedTypeReference)original;
+			return new AlienScopeQualifiedTypeReference(qTypeRef.tokens, qTypeRef.sourcePositions, origScope);
+		}
+		throw new InternalCompilerError("Unexpected type reference: "+original); //$NON-NLS-1$
+	}
+
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/IAlienScopeTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/IAlienScopeTypeReference.java
similarity index 76%
rename from org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/IAlienScopeTypeReference.java
rename to org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/IAlienScopeTypeReference.java
index f99688f..7310874 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/IAlienScopeTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/IAlienScopeTypeReference.java
@@ -14,7 +14,7 @@
  * Contributors:
  * Technical University Berlin - Initial API and implementation
  **********************************************************************/
-package org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance;
+package org.eclipse.objectteams.otdt.internal.core.compiler.util;
 
 import org.eclipse.jdt.internal.compiler.CompilationResult.CheckPoint;
 import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
@@ -22,6 +22,7 @@
 import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
@@ -33,20 +34,20 @@
  * @author stephan
  * @since 1.2.1 (before that the implementing classes were anonymous classes)
  */
-interface IAlienScopeTypeReference {
-	ClassScope getAlienScope();
+public interface IAlienScopeTypeReference {
+	Scope getAlienScope();
 }
 
 	// ===== And now for some implementing classes: =====
 
 	class AlienScopeSingleTypeReference extends SingleTypeReference implements IAlienScopeTypeReference
 	{
-		ClassScope alienScope;
-		public AlienScopeSingleTypeReference(char[] source, long pos, ClassScope alienScope) {
+		Scope alienScope;
+		public AlienScopeSingleTypeReference(char[] source, long pos, Scope alienScope) {
 			super(source, pos);
 			this.alienScope = alienScope;
 		}
-		public ClassScope getAlienScope() { return this.alienScope; }
+		public Scope getAlienScope() { return this.alienScope; }
 		@Override
 		public TypeBinding checkResolveUsingBaseImportScope(Scope scope) {
 			return super.checkResolveUsingBaseImportScope(this.alienScope);
@@ -60,19 +61,24 @@
 				return result;
 			// remove problem binding if any:
 			this.resolvedType = null;
-			return super.resolveType(this.alienScope);
+			return super.resolveType(this.alienScope.classScope());
+		}
+		@Override
+		public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+			// this variant for use within callin wrappers:
+			return super.resolveType((BlockScope) this.alienScope, checkBounds);
 		}
 	}
 
 	// exactly like AlienScopeSingleTypeReference, but different super class
 	class AlienScopeParameterizedSingleTypeReference extends ParameterizedSingleTypeReference implements IAlienScopeTypeReference
 	{
-		ClassScope alienScope;
-		public AlienScopeParameterizedSingleTypeReference(char[] source, TypeReference[] typeArguments, int dimensions, long pos, ClassScope alienScope) {
+		Scope alienScope;
+		public AlienScopeParameterizedSingleTypeReference(char[] source, TypeReference[] typeArguments, int dimensions, long pos, Scope alienScope) {
 			super(source, typeArguments, dimensions, pos);
 			this.alienScope = alienScope;
 		}
-		public ClassScope getAlienScope() { return this.alienScope; }
+		public Scope getAlienScope() { return this.alienScope; }
 		@Override
 		public TypeBinding checkResolveUsingBaseImportScope(Scope scope) {
 			// `scope` may be stronger then `alienScope`, try it first:
@@ -93,18 +99,24 @@
 				return result;
 			// remove problem binding if any:
 			this.resolvedType = null;
-			return super.resolveType(this.alienScope);
+			return super.resolveType(this.alienScope.classScope());
+		}
+		@Override
+		public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+			// this variant for use within callin wrappers:
+			return super.resolveType((BlockScope) this.alienScope, checkBounds);
 		}
 	}
 	
 	class AlienScopeQualifiedTypeReference extends QualifiedTypeReference implements IAlienScopeTypeReference
 	{
-		ClassScope alienScope;
-		public AlienScopeQualifiedTypeReference(char[][] sources, long[] poss, ClassScope alienScope) {
+		Scope alienScope;
+		public AlienScopeQualifiedTypeReference(char[][] sources, long[] poss, Scope alienScope) {
 			super(sources, poss);
 			this.alienScope = alienScope;
+			this.isGenerated = true; // allow qualified reference to role
 		}
-		public ClassScope getAlienScope() { return this.alienScope; }
+		public Scope getAlienScope() { return this.alienScope; }
 		@Override
 		public TypeBinding checkResolveUsingBaseImportScope(Scope scope) {
 			return super.checkResolveUsingBaseImportScope(this.alienScope);
@@ -122,7 +134,12 @@
 			this.resolvedType = null;
 			if (cp != null)
 				referenceContext.compilationResult.rollBack(cp);
-			return super.resolveType(this.alienScope);
+			return super.resolveType(this.alienScope.classScope());
+		}
+		@Override
+		public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+			// this variant for use within callin wrappers:
+			return super.resolveType((BlockScope) this.alienScope, checkBounds);
 		}
 		@Override
 		protected void reportDeprecatedPathSyntax(Scope scope) {